feat: add dual-side diagnostic overview and fail-safe gating #10

Merged
Philipp merged 4 commits from feat-diagnostic-overview-and-gating into main 2026-09-13 20:52:55 +02:00
Showing only changes of commit 86a00c54dc - Show all commits
+46 -36
View File
@@ -24,6 +24,10 @@ inputs:
description: Whether to append the generated reports to the job summary ($GITHUB_STEP_SUMMARY) description: Whether to append the generated reports to the job summary ($GITHUB_STEP_SUMMARY)
required: false required: false
default: 'true' default: 'true'
use-inbuild-sbom:
description: Whether to inspect and use built-in image SBOM attestations. If false, generates SBOM directly from images with Trivy.
required: false
default: 'false'
outputs: outputs:
delta-report: delta-report:
@@ -58,14 +62,15 @@ runs:
- name: Install and Verify Trivy - name: Install and Verify Trivy
shell: bash shell: bash
run: | run: |
mkdir -p "$HOME/.cache/trivy-bin" "$HOME/.local/bin" set -euo pipefail
echo "$HOME/.local/bin" >> "$GITHUB_PATH"
ARCH=$(uname -m) mkdir -p "$HOME/.local/bin" "$HOME/.cache/trivy-bin"
case "$ARCH" in echo "$HOME/.local/bin" >> "$GITHUB_PATH"
ARCH="$(uname -m)"
case "${ARCH}" in
x86_64) T_ARCH="64bit" ;; x86_64) T_ARCH="64bit" ;;
aarch64|arm64) T_ARCH="ARM64" ;; aarch64|arm64) T_ARCH="ARM64" ;;
*) echo "Unsupported architecture: $ARCH"; exit 1 ;; *) echo "::error::Unsupported architecture: ${ARCH}"; exit 1 ;;
esac esac
checksums_file="${{ github.action_path }}/checksums.txt" checksums_file="${{ github.action_path }}/checksums.txt"
@@ -100,64 +105,69 @@ runs:
head_sbom_err="" head_sbom_err=""
target_sbom_err="" target_sbom_err=""
use_inbuild="${{ inputs.use-inbuild-sbom }}"
# --- Head Image SBOM Extraction --- # --- Head Image SBOM Extraction ---
echo "Extracting platform SBOMs for head image: ${{ inputs.head-image }}..." if [ "$use_inbuild" = "true" ]; then
docker buildx imagetools inspect "${{ inputs.head-image }}" \ echo "Attempting extraction of built-in SBOM attestations for head image: ${{ inputs.head-image }}..."
--format '{{ json (index .SBOM "linux/amd64").SPDX }}' > sboms/head/sbom-amd64.spdx.json 2>/dev/null || true
cleanup_file sboms/head/sbom-amd64.spdx.json
docker buildx imagetools inspect "${{ inputs.head-image }}" \
--format '{{ json (index .SBOM "linux/arm64").SPDX }}' > sboms/head/sbom-arm64.spdx.json 2>/dev/null || true
cleanup_file sboms/head/sbom-arm64.spdx.json
# If single-arch, extract root .SPDX
if [ ! -f sboms/head/sbom-amd64.spdx.json ] && [ ! -f sboms/head/sbom-arm64.spdx.json ]; then
docker buildx imagetools inspect "${{ inputs.head-image }}" \ docker buildx imagetools inspect "${{ inputs.head-image }}" \
--format '{{ json .SBOM.SPDX }}' > sboms/head/sbom-amd64.spdx.json 2>/dev/null || true --format '{{ json (index .SBOM "linux/amd64").SPDX }}' > sboms/head/sbom-amd64.spdx.json 2>/dev/null || true
cleanup_file sboms/head/sbom-amd64.spdx.json cleanup_file sboms/head/sbom-amd64.spdx.json
docker buildx imagetools inspect "${{ inputs.head-image }}" \
--format '{{ json (index .SBOM "linux/arm64").SPDX }}' > sboms/head/sbom-arm64.spdx.json 2>/dev/null || true
cleanup_file sboms/head/sbom-arm64.spdx.json
# If single-arch, extract root .SPDX
if [ ! -f sboms/head/sbom-amd64.spdx.json ] && [ ! -f sboms/head/sbom-arm64.spdx.json ]; then
docker buildx imagetools inspect "${{ inputs.head-image }}" \
--format '{{ json .SBOM.SPDX }}' > sboms/head/sbom-amd64.spdx.json 2>/dev/null || true
cleanup_file sboms/head/sbom-amd64.spdx.json
fi
fi fi
# Fallback to generating head SBOM with Trivy if attestation missing # Generate head SBOM with Trivy if attestation not used or missing
if [ ! -f sboms/head/sbom-amd64.spdx.json ] && [ ! -f sboms/head/sbom-arm64.spdx.json ]; then if [ ! -f sboms/head/sbom-amd64.spdx.json ] && [ ! -f sboms/head/sbom-arm64.spdx.json ]; then
echo "Head image lacks SBOM attestation; generating with Trivy..." echo "Generating SBOM for head image directly with Trivy: ${{ inputs.head-image }}..."
if ! trivy image --skip-version-check --format spdx-json --output sboms/head/sbom-amd64.spdx.json "${{ inputs.head-image }}"; then if ! trivy image --skip-version-check --format spdx-json --output sboms/head/sbom-amd64.spdx.json "${{ inputs.head-image }}"; then
head_sbom_err="Failed to generate fallback SBOM with Trivy for head image" head_sbom_err="Failed to generate SBOM with Trivy for head image"
fi fi
cleanup_file sboms/head/sbom-amd64.spdx.json cleanup_file sboms/head/sbom-amd64.spdx.json
fi fi
if [ ! -f sboms/head/sbom-amd64.spdx.json ] && [ ! -f sboms/head/sbom-arm64.spdx.json ] && [ -z "$head_sbom_err" ]; then if [ ! -f sboms/head/sbom-amd64.spdx.json ] && [ ! -f sboms/head/sbom-arm64.spdx.json ] && [ -z "$head_sbom_err" ]; then
head_sbom_err="No SBOM attestation found and head image could not be inspected" head_sbom_err="No SBOM generated and head image could not be inspected"
fi fi
# --- Target Image SBOM Extraction --- # --- Target Image SBOM Extraction ---
echo "Extracting platform SBOMs for target image: ${{ inputs.target-image }}..." if [ "$use_inbuild" = "true" ]; then
docker buildx imagetools inspect "${{ inputs.target-image }}" \ echo "Attempting extraction of built-in SBOM attestations for target image: ${{ inputs.target-image }}..."
--format '{{ json (index .SBOM "linux/amd64").SPDX }}' > sboms/target/sbom-amd64.spdx.json 2>/dev/null || true
cleanup_file sboms/target/sbom-amd64.spdx.json
docker buildx imagetools inspect "${{ inputs.target-image }}" \
--format '{{ json (index .SBOM "linux/arm64").SPDX }}' > sboms/target/sbom-arm64.spdx.json 2>/dev/null || true
cleanup_file sboms/target/sbom-arm64.spdx.json
if [ ! -f sboms/target/sbom-amd64.spdx.json ] && [ ! -f sboms/target/sbom-arm64.spdx.json ]; then
docker buildx imagetools inspect "${{ inputs.target-image }}" \ docker buildx imagetools inspect "${{ inputs.target-image }}" \
--format '{{ json .SBOM.SPDX }}' > sboms/target/sbom-amd64.spdx.json 2>/dev/null || true --format '{{ json (index .SBOM "linux/amd64").SPDX }}' > sboms/target/sbom-amd64.spdx.json 2>/dev/null || true
cleanup_file sboms/target/sbom-amd64.spdx.json cleanup_file sboms/target/sbom-amd64.spdx.json
docker buildx imagetools inspect "${{ inputs.target-image }}" \
--format '{{ json (index .SBOM "linux/arm64").SPDX }}' > sboms/target/sbom-arm64.spdx.json 2>/dev/null || true
cleanup_file sboms/target/sbom-arm64.spdx.json
if [ ! -f sboms/target/sbom-amd64.spdx.json ] && [ ! -f sboms/target/sbom-arm64.spdx.json ]; then
docker buildx imagetools inspect "${{ inputs.target-image }}" \
--format '{{ json .SBOM.SPDX }}' > sboms/target/sbom-amd64.spdx.json 2>/dev/null || true
cleanup_file sboms/target/sbom-amd64.spdx.json
fi
fi fi
# Fallback to generating target SBOM with Trivy if attestation missing # Generate target SBOM with Trivy if attestation not used or missing
if [ ! -f sboms/target/sbom-amd64.spdx.json ] && [ ! -f sboms/target/sbom-arm64.spdx.json ]; then if [ ! -f sboms/target/sbom-amd64.spdx.json ] && [ ! -f sboms/target/sbom-arm64.spdx.json ]; then
echo "Target image lacks SBOM attestation; attempting to generate with Trivy..." echo "Generating SBOM for target image directly with Trivy: ${{ inputs.target-image }}..."
if ! trivy image --skip-version-check --format spdx-json --output sboms/target/sbom-amd64.spdx.json "${{ inputs.target-image }}"; then if ! trivy image --skip-version-check --format spdx-json --output sboms/target/sbom-amd64.spdx.json "${{ inputs.target-image }}"; then
target_sbom_err="Failed to generate fallback SBOM with Trivy for target image" target_sbom_err="Failed to generate SBOM with Trivy for target image"
fi fi
cleanup_file sboms/target/sbom-amd64.spdx.json cleanup_file sboms/target/sbom-amd64.spdx.json
fi fi
if [ ! -f sboms/target/sbom-amd64.spdx.json ] && [ ! -f sboms/target/sbom-arm64.spdx.json ] && [ -z "$target_sbom_err" ]; then if [ ! -f sboms/target/sbom-amd64.spdx.json ] && [ ! -f sboms/target/sbom-arm64.spdx.json ] && [ -z "$target_sbom_err" ]; then
target_sbom_err="No SBOM attestation found and target baseline image could not be inspected" target_sbom_err="No SBOM generated and target baseline image could not be inspected"
fi fi
# Report on both sides # Report on both sides