From 89199517f996b690af338dba288ca2f3842e7c3b Mon Sep 17 00:00:00 2001 From: Richard Wall Date: Wed, 5 Aug 2026 22:06:44 +0100 Subject: [PATCH 1/3] Demo the oci-security-scan makefile-modules branch Point the go and oci-build modules at the wallrj/makefile-modules oci-security-scan branch (cert-manager/makefile-modules#688), which adds oci-scan- targets for every entry in build_names (manager AND approver here) and an oci_scan_extra_images variable, used to also scan the livenessprobe and csi-node-driver-registrar sidecar images. The govulncheck workflow becomes a combined nightly security-scan (govulncheck + trivy image scan) over the default branch, the two newest release branches and the latest released tag. DO NOT MERGE until makefile-modules#688 is merged and klone.yaml is repointed at upstream main. Signed-off-by: Richard Wall Co-Authored-By: Claude Fable 5 --- .github/workflows/govulncheck.yaml | 70 ++++++++++++++++--- klone.yaml | 12 ++-- make/00_mod.mk | 6 ++ .../base/.github/workflows/govulncheck.yaml | 70 ++++++++++++++++--- make/_shared/oci-build/00_mod.mk | 18 +++++ make/_shared/oci-build/01_mod.mk | 29 ++++++++ 6 files changed, 179 insertions(+), 26 deletions(-) diff --git a/.github/workflows/govulncheck.yaml b/.github/workflows/govulncheck.yaml index 7e23bdb3..0b58f9ca 100644 --- a/.github/workflows/govulncheck.yaml +++ b/.github/workflows/govulncheck.yaml @@ -1,10 +1,17 @@ # THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. # Edit https://github.com/cert-manager/makefile-modules/blob/main/modules/go/base/.github/workflows/govulncheck.yaml instead. -# Run govulncheck at midnight every night on the main branch, -# to alert us to recent vulnerabilities which affect the Go code in this -# project. -name: govulncheck +# Nightly security scan. Runs govulncheck against the Go code and, where the +# repository builds OCI images, oci-security-scan, which uses trivy to check +# the images for fixable vulnerabilities of severity MEDIUM, HIGH or CRITICAL. +# Scans the default branch, the two newest release branches and the latest +# release tag, to give early warning when a released image, or an image we are +# about to release, contains known vulnerabilities. +# +# This file keeps its historic "govulncheck" name so that GitHub continues to +# treat it as the same registered workflow (which allows workflow_dispatch on +# any branch) and to avoid leaving stale workflow files in downstream repos. +name: security-scan on: workflow_dispatch: {} schedule: @@ -14,24 +21,67 @@ permissions: contents: read jobs: - govulncheck: + list-refs: runs-on: ubuntu-latest if: github.repository == 'cert-manager/csi-driver-spiffe' + outputs: + refs: ${{ steps.list-refs.outputs.refs }} + steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - # Adding `fetch-depth: 0` makes sure tags are also fetched. We need - # the tags so `git describe` returns a valid version. - # see https://github.com/actions/checkout/issues/701 for extra info about this option + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: { fetch-depth: 0 } + # Scan the branch this workflow runs on (usually the default branch), + # the two newest release branches, and the latest tag which is not a + # pre-release. + - id: list-refs + run: | + refs="$( + { + echo "${{ github.ref_name }}" + git branch --remotes --list 'origin/release-*' --format='%(refname:lstrip=3)' --sort=-version:refname \ + | grep -E '^release-[0-9]+\.[0-9]+$' | head -n 2 + git tag --list 'v*' --sort=-version:refname | grep -v '[-]' | head -n 1 + } | jq --raw-input . | jq --slurp --compact-output 'map(select(. != "")) | unique' + )" + echo "refs=${refs}" >> "$GITHUB_OUTPUT" + + security-scan: + runs-on: ubuntu-latest + + needs: list-refs + + strategy: + fail-fast: false + matrix: + ref: ${{ fromJSON(needs.list-refs.outputs.refs) }} + + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + ref: ${{ matrix.ref }} + # Adding `fetch-depth: 0` makes sure tags are also fetched. We need + # the tags so `git describe` returns a valid version. + # see https://github.com/actions/checkout/issues/701 for extra info about this option + fetch-depth: 0 + - id: go-version run: | make print-go-version >> "$GITHUB_OUTPUT" - - uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 + - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 with: go-version: ${{ steps.go-version.outputs.result }} - run: make verify-govulncheck + + # Only repositories which build OCI images have the oci-security-scan + # target; older release branches and tags may not have it yet either. + - run: | + if make --dry-run oci-security-scan >/dev/null 2>&1; then + make oci-security-scan + else + echo "::notice::The oci-security-scan target does not exist on ${{ matrix.ref }}; skipping." + fi diff --git a/klone.yaml b/klone.yaml index 63ed17c7..c8994e8f 100644 --- a/klone.yaml +++ b/klone.yaml @@ -28,9 +28,9 @@ targets: repo_hash: e0878ff3ab29a9d2af7b7eae8a98356ad388c931 repo_path: modules/generate-verify - folder_name: go - repo_url: https://github.com/cert-manager/makefile-modules.git - repo_ref: main - repo_hash: e0878ff3ab29a9d2af7b7eae8a98356ad388c931 + repo_url: https://github.com/wallrj/makefile-modules.git + repo_ref: oci-security-scan + repo_hash: 4564294457c235cd1acc5ec25e2e1c12ddaa6b87 repo_path: modules/go - folder_name: helm repo_url: https://github.com/cert-manager/makefile-modules.git @@ -58,9 +58,9 @@ targets: repo_hash: e0878ff3ab29a9d2af7b7eae8a98356ad388c931 repo_path: modules/licenses - folder_name: oci-build - repo_url: https://github.com/cert-manager/makefile-modules.git - repo_ref: main - repo_hash: e0878ff3ab29a9d2af7b7eae8a98356ad388c931 + repo_url: https://github.com/wallrj/makefile-modules.git + repo_ref: oci-security-scan + repo_hash: 4564294457c235cd1acc5ec25e2e1c12ddaa6b87 repo_path: modules/oci-build - folder_name: oci-publish repo_url: https://github.com/cert-manager/makefile-modules.git diff --git a/make/00_mod.mk b/make/00_mod.mk index 9e969f38..88c00f5b 100644 --- a/make/00_mod.mk +++ b/make/00_mod.mk @@ -59,6 +59,12 @@ nodedriverregistrar_image_name_source := registry.k8s.io/sig-storage/csi-node-dr nodedriverregistrar_image_name := quay.io/jetstack/csi-node-driver-registrar nodedriverregistrar_image_tag := v2.17.0 +# Scan the third party sidecar images which are deployed alongside the +# csi-driver-spiffe images. +oci_scan_extra_images := \ + $(livenessprobe_image_name_source):$(livenessprobe_image_tag) \ + $(nodedriverregistrar_image_name_source):$(nodedriverregistrar_image_tag) + define helm_values_mutation_function $(YQ) \ '( .app.driver.livenessProbeImage._defaultReference = ":$(livenessprobe_image_tag)" ) | \ diff --git a/make/_shared/go/base/.github/workflows/govulncheck.yaml b/make/_shared/go/base/.github/workflows/govulncheck.yaml index 9c6c2cfb..9a264705 100644 --- a/make/_shared/go/base/.github/workflows/govulncheck.yaml +++ b/make/_shared/go/base/.github/workflows/govulncheck.yaml @@ -1,10 +1,17 @@ # THIS FILE IS AUTOMATICALLY GENERATED. DO NOT EDIT. # Edit https://github.com/cert-manager/makefile-modules/blob/main/modules/go/base/.github/workflows/govulncheck.yaml instead. -# Run govulncheck at midnight every night on the main branch, -# to alert us to recent vulnerabilities which affect the Go code in this -# project. -name: govulncheck +# Nightly security scan. Runs govulncheck against the Go code and, where the +# repository builds OCI images, oci-security-scan, which uses trivy to check +# the images for fixable vulnerabilities of severity MEDIUM, HIGH or CRITICAL. +# Scans the default branch, the two newest release branches and the latest +# release tag, to give early warning when a released image, or an image we are +# about to release, contains known vulnerabilities. +# +# This file keeps its historic "govulncheck" name so that GitHub continues to +# treat it as the same registered workflow (which allows workflow_dispatch on +# any branch) and to avoid leaving stale workflow files in downstream repos. +name: security-scan on: workflow_dispatch: {} schedule: @@ -14,24 +21,67 @@ permissions: contents: read jobs: - govulncheck: + list-refs: runs-on: ubuntu-latest if: github.repository == '{{REPLACE:GH-REPOSITORY}}' + outputs: + refs: ${{ steps.list-refs.outputs.refs }} + steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - # Adding `fetch-depth: 0` makes sure tags are also fetched. We need - # the tags so `git describe` returns a valid version. - # see https://github.com/actions/checkout/issues/701 for extra info about this option + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 with: { fetch-depth: 0 } + # Scan the branch this workflow runs on (usually the default branch), + # the two newest release branches, and the latest tag which is not a + # pre-release. + - id: list-refs + run: | + refs="$( + { + echo "${{ github.ref_name }}" + git branch --remotes --list 'origin/release-*' --format='%(refname:lstrip=3)' --sort=-version:refname \ + | grep -E '^release-[0-9]+\.[0-9]+$' | head -n 2 + git tag --list 'v*' --sort=-version:refname | grep -v '[-]' | head -n 1 + } | jq --raw-input . | jq --slurp --compact-output 'map(select(. != "")) | unique' + )" + echo "refs=${refs}" >> "$GITHUB_OUTPUT" + + security-scan: + runs-on: ubuntu-latest + + needs: list-refs + + strategy: + fail-fast: false + matrix: + ref: ${{ fromJSON(needs.list-refs.outputs.refs) }} + + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + ref: ${{ matrix.ref }} + # Adding `fetch-depth: 0` makes sure tags are also fetched. We need + # the tags so `git describe` returns a valid version. + # see https://github.com/actions/checkout/issues/701 for extra info about this option + fetch-depth: 0 + - id: go-version run: | make print-go-version >> "$GITHUB_OUTPUT" - - uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 + - uses: actions/setup-go@b7ad1dad31e06c5925ef5d2fc7ad053ef454303e # v7.0.0 with: go-version: ${{ steps.go-version.outputs.result }} - run: make verify-govulncheck + + # Only repositories which build OCI images have the oci-security-scan + # target; older release branches and tags may not have it yet either. + - run: | + if make --dry-run oci-security-scan >/dev/null 2>&1; then + make oci-security-scan + else + echo "::notice::The oci-security-scan target does not exist on ${{ matrix.ref }}; skipping." + fi diff --git a/make/_shared/oci-build/00_mod.mk b/make/_shared/oci-build/00_mod.mk index 71a444e2..ab5d4b48 100644 --- a/make/_shared/oci-build/00_mod.mk +++ b/make/_shared/oci-build/00_mod.mk @@ -32,6 +32,22 @@ CGO_ENABLED ?= 0 GOEXPERIMENT ?= # empty by default oci_platforms ?= linux/amd64,linux/arm/v7,linux/arm64,linux/ppc64le +# Extra images (e.g. third party sidecar images which are deployed alongside +# the images built by this repository) to be scanned by oci-security-scan, +# for example: +# oci_scan_extra_images := registry.k8s.io/sig-storage/livenessprobe:v2.18.0 +oci_scan_extra_images ?= + +# The trivy policy applied by the oci-scan-* targets: report only +# vulnerabilities which have a known fix and a severity of MEDIUM, HIGH or +# CRITICAL, and fail if any are found. The secret scanner is disabled because +# it is slow. +trivy_scan_flags ?= \ + --scanners vuln \ + --severity MEDIUM,HIGH,CRITICAL \ + --ignore-unfixed \ + --exit-code 1 + # Default variables per build_names entry # # $1 - build_name @@ -120,10 +136,12 @@ $(foreach build_name,$(build_names),$(eval $(call check_per_build_variables,$(bu # - oci-build-$(build_name)__local = build the oci directory (local arch: linux/$(HOST_ARCH)) # - oci-load-$(build_name) = load the image into docker using the oci_$(build_name)_image_name_development variable # - docker-tarball-$(build_name) = build a "docker load" compatible tarball of the image +# - oci-scan-$(build_name) = scan the image for known vulnerabilities using trivy oci_build_targets := $(build_names:%=oci-build-%) oci_build_targets += $(build_names:%=oci-build-%__local) oci_load_targets := $(build_names:%=oci-load-%) docker_tarball_targets := $(build_names:%=docker-tarball-%) +oci_scan_targets := $(build_names:%=oci-scan-%) # Derive config based on user config # diff --git a/make/_shared/oci-build/01_mod.mk b/make/_shared/oci-build/01_mod.mk index 026e46b8..57a2a166 100644 --- a/make/_shared/oci-build/01_mod.mk +++ b/make/_shared/oci-build/01_mod.mk @@ -81,3 +81,32 @@ endif .PHONY: $(docker_tarball_targets) $(docker_tarball_targets): docker-tarball-%: oci-build-%__local | $(NEEDS_GO) $(NEEDS_IMAGE-TOOL) $(IMAGE-TOOL) convert-to-docker-tar $(CURDIR)/$(oci_layout_path_$*).local $(docker_tarball_path_$*) $(oci_$*_image_name_development):$(oci_$*_image_tag) + +.PHONY: $(oci_scan_targets) +## Scan the OCI image (local architecture) for OS and library +## vulnerabilities which have a known fix and a severity of +## MEDIUM, HIGH or CRITICAL, using trivy +## (https://github.com/aquasecurity/trivy). +## @category [shared] Build +$(oci_scan_targets): oci-scan-%: docker-tarball-% | $(NEEDS_TRIVY) + $(TRIVY) image \ + --input $(docker_tarball_path_$*) \ + $(trivy_scan_flags) + +.PHONY: oci-scan-extra-images +## Scan the images listed in oci_scan_extra_images (e.g. third party sidecar +## images which are deployed alongside the images built by this repository) +## for known vulnerabilities, using trivy. +## @category [shared] Build +oci-scan-extra-images: | $(NEEDS_TRIVY) + @for image in $(oci_scan_extra_images); do \ + echo "Scanning $$image"; \ + $(TRIVY) image $$image $(trivy_scan_flags) || exit 1; \ + done + +.PHONY: oci-security-scan +## Scan all the OCI images built by this repository, and any extra images +## listed in oci_scan_extra_images, for known vulnerabilities; failing if any +## fixable vulnerabilities of severity MEDIUM, HIGH or CRITICAL are found. +## @category [shared] Build +oci-security-scan: $(oci_scan_targets) oci-scan-extra-images From f76185442c15a10e2c50acc278b6eb18a1394ceb Mon Sep 17 00:00:00 2001 From: Richard Wall Date: Wed, 5 Aug 2026 22:23:49 +0100 Subject: [PATCH 2/3] Write trivy scan reports to the GitHub job summary Pull in the updated oci-security-scan module branch: scan reports are appended to the GitHub Actions job summary (guarded on GITHUB_STEP_SUMMARY so GitLab and local runs are unchanged), because the trivy table is hard to read in the raw job log. Signed-off-by: Richard Wall Co-Authored-By: Claude Fable 5 --- klone.yaml | 4 ++-- make/_shared/oci-build/01_mod.mk | 35 ++++++++++++++++++++++++++++---- 2 files changed, 33 insertions(+), 6 deletions(-) diff --git a/klone.yaml b/klone.yaml index c8994e8f..9050ba42 100644 --- a/klone.yaml +++ b/klone.yaml @@ -30,7 +30,7 @@ targets: - folder_name: go repo_url: https://github.com/wallrj/makefile-modules.git repo_ref: oci-security-scan - repo_hash: 4564294457c235cd1acc5ec25e2e1c12ddaa6b87 + repo_hash: 049ae805adc020f43e98f2fd5760ccc51dfa4598 repo_path: modules/go - folder_name: helm repo_url: https://github.com/cert-manager/makefile-modules.git @@ -60,7 +60,7 @@ targets: - folder_name: oci-build repo_url: https://github.com/wallrj/makefile-modules.git repo_ref: oci-security-scan - repo_hash: 4564294457c235cd1acc5ec25e2e1c12ddaa6b87 + repo_hash: 049ae805adc020f43e98f2fd5760ccc51dfa4598 repo_path: modules/oci-build - folder_name: oci-publish repo_url: https://github.com/cert-manager/makefile-modules.git diff --git a/make/_shared/oci-build/01_mod.mk b/make/_shared/oci-build/01_mod.mk index 57a2a166..b64b094d 100644 --- a/make/_shared/oci-build/01_mod.mk +++ b/make/_shared/oci-build/01_mod.mk @@ -82,6 +82,26 @@ endif $(docker_tarball_targets): docker-tarball-%: oci-build-%__local | $(NEEDS_GO) $(NEEDS_IMAGE-TOOL) $(IMAGE-TOOL) convert-to-docker-tar $(CURDIR)/$(oci_layout_path_$*).local $(docker_tarball_path_$*) $(oci_$*_image_name_development):$(oci_$*_image_tag) +# Run "trivy image $2 $(trivy_scan_flags)" and print the report to stdout. +# When running in GitHub Actions (detected by GITHUB_STEP_SUMMARY being set; +# some repos using this module run CI on GitLab instead) the report is also +# appended to the job summary under the heading $1, because trivy's table +# format is hard to read in the raw job log. +# +# $1 - summary heading +# $2 - trivy image arguments (an image reference or --input ) +define trivy_scan +report=$$(mktemp); \ +$(TRIVY) image $2 $(trivy_scan_flags) --output $$report; \ +code=$$?; \ +cat $$report; \ +if [ -n "$${GITHUB_STEP_SUMMARY:-}" ]; then \ + { echo "### $1"; echo '```'; cat $$report; echo '```'; echo; } >> "$$GITHUB_STEP_SUMMARY"; \ +fi; \ +rm -f $$report; \ +exit $$code +endef + .PHONY: $(oci_scan_targets) ## Scan the OCI image (local architecture) for OS and library ## vulnerabilities which have a known fix and a severity of @@ -89,9 +109,8 @@ $(docker_tarball_targets): docker-tarball-%: oci-build-%__local | $(NEEDS_GO) $( ## (https://github.com/aquasecurity/trivy). ## @category [shared] Build $(oci_scan_targets): oci-scan-%: docker-tarball-% | $(NEEDS_TRIVY) - $(TRIVY) image \ - --input $(docker_tarball_path_$*) \ - $(trivy_scan_flags) + @echo "Scanning $(oci_$*_image_name_development):$(oci_$*_image_tag)" + @$(call trivy_scan,$(oci_$*_image_name_development):$(oci_$*_image_tag),--input $(docker_tarball_path_$*)) .PHONY: oci-scan-extra-images ## Scan the images listed in oci_scan_extra_images (e.g. third party sidecar @@ -101,7 +120,15 @@ $(oci_scan_targets): oci-scan-%: docker-tarball-% | $(NEEDS_TRIVY) oci-scan-extra-images: | $(NEEDS_TRIVY) @for image in $(oci_scan_extra_images); do \ echo "Scanning $$image"; \ - $(TRIVY) image $$image $(trivy_scan_flags) || exit 1; \ + report=$$(mktemp); \ + $(TRIVY) image $$image $(trivy_scan_flags) --output $$report; \ + code=$$?; \ + cat $$report; \ + if [ -n "$${GITHUB_STEP_SUMMARY:-}" ]; then \ + { echo "### $$image"; echo '```'; cat $$report; echo '```'; echo; } >> "$$GITHUB_STEP_SUMMARY"; \ + fi; \ + rm -f $$report; \ + [ $$code -eq 0 ] || exit $$code; \ done .PHONY: oci-security-scan From cb46d59959276ccb44f9707745a2bb4bdc6450c5 Mon Sep 17 00:00:00 2001 From: Richard Wall Date: Wed, 5 Aug 2026 22:31:35 +0100 Subject: [PATCH 3/3] Scan all images even when an earlier scan finds vulnerabilities Pull in the updated oci-security-scan module branch so that every image report appears in the log and job summary, instead of stopping at the first vulnerable image. Signed-off-by: Richard Wall Co-Authored-By: Claude Fable 5 --- .github/workflows/govulncheck.yaml | 4 +++- klone.yaml | 4 ++-- .../_shared/go/base/.github/workflows/govulncheck.yaml | 4 +++- make/_shared/oci-build/01_mod.mk | 10 +++++----- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/.github/workflows/govulncheck.yaml b/.github/workflows/govulncheck.yaml index 0b58f9ca..8bbaeac7 100644 --- a/.github/workflows/govulncheck.yaml +++ b/.github/workflows/govulncheck.yaml @@ -79,9 +79,11 @@ jobs: # Only repositories which build OCI images have the oci-security-scan # target; older release branches and tags may not have it yet either. + # --keep-going so that one vulnerable image does not prevent the + # remaining images from being scanned and reported. - run: | if make --dry-run oci-security-scan >/dev/null 2>&1; then - make oci-security-scan + make --keep-going oci-security-scan else echo "::notice::The oci-security-scan target does not exist on ${{ matrix.ref }}; skipping." fi diff --git a/klone.yaml b/klone.yaml index 9050ba42..ba6fc49b 100644 --- a/klone.yaml +++ b/klone.yaml @@ -30,7 +30,7 @@ targets: - folder_name: go repo_url: https://github.com/wallrj/makefile-modules.git repo_ref: oci-security-scan - repo_hash: 049ae805adc020f43e98f2fd5760ccc51dfa4598 + repo_hash: 9f38f78fc9d3e9cdd00f57dc3202e82f9be2d123 repo_path: modules/go - folder_name: helm repo_url: https://github.com/cert-manager/makefile-modules.git @@ -60,7 +60,7 @@ targets: - folder_name: oci-build repo_url: https://github.com/wallrj/makefile-modules.git repo_ref: oci-security-scan - repo_hash: 049ae805adc020f43e98f2fd5760ccc51dfa4598 + repo_hash: 9f38f78fc9d3e9cdd00f57dc3202e82f9be2d123 repo_path: modules/oci-build - folder_name: oci-publish repo_url: https://github.com/cert-manager/makefile-modules.git diff --git a/make/_shared/go/base/.github/workflows/govulncheck.yaml b/make/_shared/go/base/.github/workflows/govulncheck.yaml index 9a264705..bcdb3883 100644 --- a/make/_shared/go/base/.github/workflows/govulncheck.yaml +++ b/make/_shared/go/base/.github/workflows/govulncheck.yaml @@ -79,9 +79,11 @@ jobs: # Only repositories which build OCI images have the oci-security-scan # target; older release branches and tags may not have it yet either. + # --keep-going so that one vulnerable image does not prevent the + # remaining images from being scanned and reported. - run: | if make --dry-run oci-security-scan >/dev/null 2>&1; then - make oci-security-scan + make --keep-going oci-security-scan else echo "::notice::The oci-security-scan target does not exist on ${{ matrix.ref }}; skipping." fi diff --git a/make/_shared/oci-build/01_mod.mk b/make/_shared/oci-build/01_mod.mk index b64b094d..494bf4c7 100644 --- a/make/_shared/oci-build/01_mod.mk +++ b/make/_shared/oci-build/01_mod.mk @@ -118,18 +118,18 @@ $(oci_scan_targets): oci-scan-%: docker-tarball-% | $(NEEDS_TRIVY) ## for known vulnerabilities, using trivy. ## @category [shared] Build oci-scan-extra-images: | $(NEEDS_TRIVY) - @for image in $(oci_scan_extra_images); do \ + @failed=0; \ + for image in $(oci_scan_extra_images); do \ echo "Scanning $$image"; \ report=$$(mktemp); \ - $(TRIVY) image $$image $(trivy_scan_flags) --output $$report; \ - code=$$?; \ + $(TRIVY) image $$image $(trivy_scan_flags) --output $$report || failed=1; \ cat $$report; \ if [ -n "$${GITHUB_STEP_SUMMARY:-}" ]; then \ { echo "### $$image"; echo '```'; cat $$report; echo '```'; echo; } >> "$$GITHUB_STEP_SUMMARY"; \ fi; \ rm -f $$report; \ - [ $$code -eq 0 ] || exit $$code; \ - done + done; \ + exit $$failed .PHONY: oci-security-scan ## Scan all the OCI images built by this repository, and any extra images