name: Docker Image CI
on:
push:
tags: ['v[0-9].[0-9]+.[0-9]+']
branches:
- main
pull_request:
jobs:
security-scan-source:
name: Security Scan - Source Code & Dependencies
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
steps:
- name: Check out code
uses: actions/checkout@v3
- name: Install Grype
run: |
curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin
- name: Scan source code and dependencies
run: |
echo "🔍 Scanning source code and dependencies for vulnerabilities..."
grype dir:. --only-fixed -o table > /tmp/grype-source.txt || true
SCAN_OUTPUT=$(grype dir:. --only-fixed -o json)
CRITICAL=$(echo "$SCAN_OUTPUT" | jq '[.matches[] | select(.vulnerability.severity == "Critical")] | length')
HIGH=$(echo "$SCAN_OUTPUT" | jq '[.matches[] | select(.vulnerability.severity == "High")] | length')
MEDIUM=$(echo "$SCAN_OUTPUT" | jq '[.matches[] | select(.vulnerability.severity == "Medium")] | length')
# Create Job Summary with table
echo "## 🔒 Security Scan - Source Code & Dependencies" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Severity | Count | Status |" >> $GITHUB_STEP_SUMMARY
echo "|----------|-------|--------|" >> $GITHUB_STEP_SUMMARY
echo "| 🔴 Critical | $CRITICAL | $([ $CRITICAL -eq 0 ] && echo '✅' || echo '⚠️') |" >> $GITHUB_STEP_SUMMARY
echo "| 🟠 High | $HIGH | $([ $HIGH -eq 0 ] && echo '✅' || echo '⚠️') |" >> $GITHUB_STEP_SUMMARY
echo "| 🟡 Medium | $MEDIUM | $([ $MEDIUM -eq 0 ] && echo '✅' || echo '⚠️') |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [ "$CRITICAL" -gt 0 ] || [ "$HIGH" -gt 0 ]; then
echo "⚠️ **Found $CRITICAL Critical and $HIGH High vulnerabilities with available fixes**" >> $GITHUB_STEP_SUMMARY
else
echo "✅ **No Critical or High vulnerabilities found**" >> $GITHUB_STEP_SUMMARY
fi
# Add collapsible full scan results
echo "" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "📋 Full Scan Results
" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
cat /tmp/grype-source.txt >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo " " >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
build:
runs-on: ${{ matrix.runner }}
strategy:
matrix:
include:
- platform: amd64
runner: ubuntu-latest
- platform: arm64
runner: ubuntu-24.04-arm
steps:
- name: Check out code
uses: actions/checkout@v3
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Test Build the Docker images
if: github.event_name == 'pull_request'
run: |
./containers/compile_dockerfile.sh
docker buildx build --no-cache \
--platform linux/${{ matrix.platform }} \
-t quay.io/krkn-chaos/krkn:pr-${{ github.event.pull_request.number }}-${{ matrix.platform }} \
-t quay.io/redhat-chaos/krkn:pr-${{ github.event.pull_request.number }}-${{ matrix.platform }} \
containers/ \
--build-arg PR_NUMBER=${{ github.event.pull_request.number }} \
--load
- name: Install Grype
if: github.event_name == 'pull_request'
run: |
curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin
- name: Scan Docker image for vulnerabilities
if: github.event_name == 'pull_request'
run: |
IMAGE_NAME="quay.io/krkn-chaos/krkn:pr-${{ github.event.pull_request.number }}-${{ matrix.platform }}"
echo "🔍 Scanning Docker image: $IMAGE_NAME"
grype "$IMAGE_NAME" --only-fixed -o table > /tmp/grype-image-${{ matrix.platform }}.txt || true
SCAN_OUTPUT=$(grype "$IMAGE_NAME" --only-fixed -o json)
CRITICAL=$(echo "$SCAN_OUTPUT" | jq '[.matches[] | select(.vulnerability.severity == "Critical")] | length')
HIGH=$(echo "$SCAN_OUTPUT" | jq '[.matches[] | select(.vulnerability.severity == "High")] | length')
MEDIUM=$(echo "$SCAN_OUTPUT" | jq '[.matches[] | select(.vulnerability.severity == "Medium")] | length')
# Create Job Summary with table
echo "## 🐳 Docker Image Security Scan - ${{ matrix.platform }}" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| Severity | Count | Status |" >> $GITHUB_STEP_SUMMARY
echo "|----------|-------|--------|" >> $GITHUB_STEP_SUMMARY
echo "| 🔴 Critical | $CRITICAL | $([ $CRITICAL -eq 0 ] && echo '✅' || echo '⚠️') |" >> $GITHUB_STEP_SUMMARY
echo "| 🟠 High | $HIGH | $([ $HIGH -eq 0 ] && echo '✅' || echo '⚠️') |" >> $GITHUB_STEP_SUMMARY
echo "| 🟡 Medium | $MEDIUM | $([ $MEDIUM -eq 0 ] && echo '✅' || echo '⚠️') |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
if [ "$CRITICAL" -gt 0 ] || [ "$HIGH" -gt 0 ]; then
echo "⚠️ **Found $CRITICAL Critical and $HIGH High vulnerabilities with available fixes**" >> $GITHUB_STEP_SUMMARY
else
echo "✅ **No Critical or High vulnerabilities found**" >> $GITHUB_STEP_SUMMARY
fi
# Add collapsible full scan results
echo "" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "📋 Full Scan Results
" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
cat /tmp/grype-image-${{ matrix.platform }}.txt >> $GITHUB_STEP_SUMMARY
echo '```' >> $GITHUB_STEP_SUMMARY
echo " " >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
- name: Login to krkn-chaos quay
if: startsWith(github.ref, 'refs/tags')
uses: docker/login-action@v3
with:
registry: quay.io
username: ${{ secrets.QUAY_USERNAME }}
password: ${{ secrets.QUAY_PASSWORD }}
- name: Build and push krkn-chaos images
if: startsWith(github.ref, 'refs/tags')
run: |
./containers/compile_dockerfile.sh
TAG=${GITHUB_REF#refs/tags/}
docker buildx build --no-cache \
--platform linux/${{ matrix.platform }} \
--provenance=false \
-t quay.io/krkn-chaos/krkn:latest-${{ matrix.platform }} \
-t quay.io/krkn-chaos/krkn:${TAG}-${{ matrix.platform }} \
containers/ \
--build-arg TAG=${TAG} \
--push --load
- name: Login to redhat-chaos quay
if: startsWith(github.ref, 'refs/tags')
uses: docker/login-action@v3
with:
registry: quay.io
username: ${{ secrets.QUAY_USER_1 }}
password: ${{ secrets.QUAY_TOKEN_1 }}
- name: Push redhat-chaos images
if: startsWith(github.ref, 'refs/tags')
run: |
TAG=${GITHUB_REF#refs/tags/}
docker tag quay.io/krkn-chaos/krkn:${TAG}-${{ matrix.platform }} quay.io/redhat-chaos/krkn:${TAG}-${{ matrix.platform }}
docker tag quay.io/krkn-chaos/krkn:${TAG}-${{ matrix.platform }} quay.io/redhat-chaos/krkn:latest-${{ matrix.platform }}
docker push quay.io/redhat-chaos/krkn:${TAG}-${{ matrix.platform }}
docker push quay.io/redhat-chaos/krkn:latest-${{ matrix.platform }}
manifest:
runs-on: ubuntu-latest
needs: build
if: startsWith(github.ref, 'refs/tags')
steps:
- name: Login to krkn-chaos quay
uses: docker/login-action@v3
with:
registry: quay.io
username: ${{ secrets.QUAY_USERNAME }}
password: ${{ secrets.QUAY_PASSWORD }}
- name: Create and push KrknChaos manifests
run: |
TAG=${GITHUB_REF#refs/tags/}
docker manifest create quay.io/krkn-chaos/krkn:${TAG} \
quay.io/krkn-chaos/krkn:${TAG}-amd64 \
quay.io/krkn-chaos/krkn:${TAG}-arm64
docker manifest push quay.io/krkn-chaos/krkn:${TAG}
docker manifest create quay.io/krkn-chaos/krkn:latest \
quay.io/krkn-chaos/krkn:latest-amd64 \
quay.io/krkn-chaos/krkn:latest-arm64
docker manifest push quay.io/krkn-chaos/krkn:latest
- name: Login to redhat-chaos quay
uses: docker/login-action@v3
with:
registry: quay.io
username: ${{ secrets.QUAY_USER_1 }}
password: ${{ secrets.QUAY_TOKEN_1 }}
- name: Create and push RedHat Chaos manifests
run: |
TAG=${GITHUB_REF#refs/tags/}
docker manifest create quay.io/redhat-chaos/krkn:${TAG} \
quay.io/redhat-chaos/krkn:${TAG}-amd64 \
quay.io/redhat-chaos/krkn:${TAG}-arm64
docker manifest push quay.io/redhat-chaos/krkn:${TAG}
docker manifest create quay.io/redhat-chaos/krkn:latest \
quay.io/redhat-chaos/krkn:latest-amd64 \
quay.io/redhat-chaos/krkn:latest-arm64
docker manifest push quay.io/redhat-chaos/krkn:latest
- name: Rebuild krkn-hub
uses: redhat-chaos/actions/krkn-hub@main
with:
QUAY_USER: ${{ secrets.QUAY_USERNAME }}
QUAY_TOKEN: ${{ secrets.QUAY_PASSWORD }}
AUTOPUSH: ${{ secrets.AUTOPUSH }}
security-badge:
permissions:
contents: write
name: Generate Security Badge
runs-on: ubuntu-latest
needs:
- build
if: github.ref == 'refs/heads/main' && github.event_name == 'push'
steps:
- name: Check out code
uses: actions/checkout@v3
- name: Check out doc repo
uses: actions/checkout@master
with:
repository: krkn-chaos/krkn-lib-docs
path: krkn-lib-docs
ssh-key: ${{ secrets.KRKN_LIB_DOCS_PRIV_KEY }}
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3
- name: Build image for security scan
run: |
./containers/compile_dockerfile.sh
docker buildx build --no-cache \
--platform linux/amd64 \
-t krkn-chaos/krkn:security-scan \
containers/ \
--load
- name: Install Grype
run: |
curl -sSfL https://raw.githubusercontent.com/anchore/grype/main/install.sh | sh -s -- -b /usr/local/bin
- name: Scan and generate security badge
run: |
# Scan with grype (no --only-fixed to get all CVEs for baseline)
SCAN_OUTPUT=$(grype krkn-chaos/krkn:security-scan -o json)
# Count vulnerabilities by severity
CRITICAL=$(echo "$SCAN_OUTPUT" | jq '[.matches[] | select(.vulnerability.severity == "Critical")] | length')
HIGH=$(echo "$SCAN_OUTPUT" | jq '[.matches[] | select(.vulnerability.severity == "High")] | length')
MEDIUM=$(echo "$SCAN_OUTPUT" | jq '[.matches[] | select(.vulnerability.severity == "Medium")] | length')
TOTAL=$(echo "$SCAN_OUTPUT" | jq '[.matches[]] | length')
# Determine badge color based on severity
if [ $CRITICAL -gt 0 ]; then
COLOR="critical"
elif [ $HIGH -gt 10 ]; then
COLOR="important"
elif [ $HIGH -gt 5 ]; then
COLOR="orange"
elif [ $HIGH -gt 0 ]; then
COLOR="yellow"
else
COLOR="brightgreen"
fi
echo "Security Scan Results:"
echo " Critical: $CRITICAL"
echo " High: $HIGH"
echo " Medium: $MEDIUM"
echo " Total: $TOTAL"
echo " Badge Color: $COLOR"
# Generate detailed badge: "C:0 H:7 M:3"
curl "https://img.shields.io/badge/security-C:$CRITICAL%20H:$HIGH%20M:$MEDIUM-$COLOR" > ./krkn-lib-docs/security_badge_krkn.svg
- name: Push updated Security Badge
run: |
cd krkn-lib-docs
git add .
git config user.name "krkn-chaos"
git config user.email "krkn-actions@users.noreply.github.com"
git commit -m "[KRKN] Security Badge ${GITHUB_REF##*/}" || echo "no changes to commit"
git push