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