Image Scan #2971
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Image Scan | |
| on: | |
| schedule: | |
| # everyday at midnight. | |
| - cron: "0 0 * * *" | |
| workflow_dispatch: {} | |
| push: | |
| # TODO: add this once we have all images in the metadata.yaml | |
| # paths: | |
| # - '**/metadata.yaml' | |
| branches: | |
| - main | |
| paths-ignore: | |
| - ".claude/**" | |
| permissions: | |
| security-events: write | |
| jobs: | |
| build-deps: | |
| name: Build dependencies | |
| outputs: | |
| local-artifact-mirror-image: ${{ steps.local-artifact-mirror.outputs.image }} | |
| operator-image: ${{ steps.operator.outputs.image }} | |
| operator-chart: ${{ steps.operator.outputs.chart }} | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| fetch-depth: 0 # fetch all history so that we can get the previous tag | |
| - name: Install dagger | |
| run: | | |
| curl -fsSL https://dl.dagger.io/dagger/install.sh | sh | |
| sudo mv ./bin/dagger /usr/local/bin/dagger | |
| - name: Build and push local-artifact-mirror image | |
| id: local-artifact-mirror | |
| run: | | |
| make -C local-artifact-mirror build-ttl.sh | |
| echo "image=$(cat local-artifact-mirror/build/image)" >> $GITHUB_OUTPUT | |
| - name: Build and push operator image | |
| id: operator | |
| run: | | |
| make -C operator build-ttl.sh build-chart-ttl.sh | |
| echo "image=$(cat operator/build/image)" >> $GITHUB_OUTPUT | |
| echo "chart=$(cat operator/build/chart)" >> $GITHUB_OUTPUT | |
| buildtools: | |
| name: Build buildtools | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Setup go | |
| uses: actions/setup-go@v6 | |
| with: | |
| go-version-file: go.mod | |
| cache-dependency-path: "**/*.sum" | |
| - name: Build buildtools | |
| run: | | |
| make buildtools | |
| - name: Upload buildtools artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: buildtools | |
| path: output/bin/buildtools | |
| output-matrix: | |
| name: Build output matrix | |
| runs-on: ubuntu-latest | |
| needs: | |
| - build-deps | |
| - buildtools | |
| outputs: | |
| matrix: ${{ steps.build-matrix.outputs.matrix }} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - name: Setup go | |
| uses: actions/setup-go@v6 | |
| with: | |
| go-version-file: go.mod | |
| cache-dependency-path: "**/*.sum" | |
| - name: Install dagger | |
| run: | | |
| curl -fsSL https://dl.dagger.io/dagger/install.sh | sh | |
| sudo mv ./bin/dagger /usr/local/bin/dagger | |
| - name: Download buildtools artifact | |
| uses: actions/download-artifact@v8 | |
| with: | |
| name: buildtools | |
| path: output/bin | |
| - name: Update embedded-cluster-operator metadata.yaml | |
| env: | |
| IMAGES_REGISTRY_SERVER: ttl.sh | |
| OPERATOR_CHART: ${{ needs.build-deps.outputs.operator-chart }} | |
| OPERATOR_IMAGE: ${{ needs.build-deps.outputs.operator-image }} | |
| run: | | |
| ./scripts/ci-update-operator-metadata.sh | |
| - name: Build | |
| run: | | |
| export LOCAL_ARTIFACT_MIRROR_IMAGE=${{ needs.build-deps.outputs.local-artifact-mirror-image }} | |
| make embedded-cluster-linux-amd64 | |
| - name: List images | |
| run: | | |
| ./output/bin/embedded-cluster version list-images > images.txt | |
| - name: Upload images artifact | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: images | |
| path: images.txt | |
| - name: Build images matrix | |
| id: build-matrix | |
| run: | | |
| IMAGES="[$(awk '{print $1}' images.txt | xargs -n1 | awk '{print "\""$1"\","}' | sed '$ s/.$//')]" | |
| echo "matrix=$(jq -cn --argjson images "$IMAGES" '{image: $images}')" >> $GITHUB_OUTPUT | |
| scan: | |
| runs-on: ubuntu-latest | |
| needs: [output-matrix] | |
| strategy: | |
| fail-fast: false | |
| matrix: ${{fromJson(needs.output-matrix.outputs.matrix)}} | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| - uses: ./.github/actions/scan-image | |
| id: scan-image | |
| with: | |
| image-ref: "${{ matrix.image }}" | |
| upload-sarif: ${{ github.ref == 'refs/heads/main' }} | |
| fail-build: "false" | |
| severity-cutoff: "medium" | |
| output-file: "results.sarif" | |
| retention-days: "90" | |
| category-prefix: "image-scan-" | |
| only-fixed: "true" | |
| - name: Upload scan output | |
| if: ${{ !cancelled() }} | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: scan-output-${{ steps.scan-image.outputs.safe-name }} | |
| path: scan-output.txt | |
| retention-days: 1 | |
| collect-scan-results: | |
| name: Collect and print image scan results | |
| runs-on: ubuntu-latest | |
| needs: [scan] | |
| # always() prevents GitHub's implicit success() check from skipping this job when | |
| # scan fails due to vulnerabilities. The needs.scan.result check still ensures we | |
| # skip if scan was cancelled or never ran (e.g. output-matrix failed). | |
| if: always() && (needs.scan.result == 'success' || needs.scan.result == 'failure') | |
| steps: | |
| - name: Download all scan outputs | |
| uses: actions/download-artifact@v8 | |
| with: | |
| pattern: scan-output-* | |
| path: scan-outputs | |
| merge-multiple: false | |
| - name: Combine into scan-results.txt | |
| run: | | |
| for f in scan-outputs/scan-output-*/scan-output.txt; do | |
| [ -f "$f" ] || continue | |
| cat "$f" | |
| echo "" | |
| done > scan-results.txt | |
| - name: Print image scan results to console | |
| run: | | |
| cat scan-results.txt | |
| echo '## Image Scan Results' >> "$GITHUB_STEP_SUMMARY" | |
| echo '```' >> "$GITHUB_STEP_SUMMARY" | |
| cat scan-results.txt >> "$GITHUB_STEP_SUMMARY" | |
| echo '```' >> "$GITHUB_STEP_SUMMARY" | |
| - name: Upload scan-results.txt | |
| uses: actions/upload-artifact@v7 | |
| with: | |
| name: scan-results | |
| path: scan-results.txt | |
| retention-days: 90 |