From 8c4fb12b380fbfccd6e3621e14bf589e1c548da3 Mon Sep 17 00:00:00 2001 From: AlexFernandes-MOVAI Date: Wed, 1 Jul 2026 23:54:18 +0100 Subject: [PATCH 1/2] feat: update CycloneDX SBOM action inputs and improve digest handling --- .../actions/attach-cyclonedx-sbom/action.yml | 25 +++---- .github/workflows/docker-workflow.yml | 69 ++++++++++--------- 2 files changed, 46 insertions(+), 48 deletions(-) diff --git a/.github/actions/attach-cyclonedx-sbom/action.yml b/.github/actions/attach-cyclonedx-sbom/action.yml index b66f8497..e5246d70 100644 --- a/.github/actions/attach-cyclonedx-sbom/action.yml +++ b/.github/actions/attach-cyclonedx-sbom/action.yml @@ -6,9 +6,8 @@ inputs: description: Fully qualified image reference with tag required: true digest: - description: Image digest (sha256:...) for exact pushed reference; if omitted, digest is resolved from image - required: false - default: "" + description: Image digest (sha256:...) for exact pushed reference + required: true sbom_file: description: Output file for generated CycloneDX JSON required: false @@ -25,7 +24,7 @@ inputs: runs: using: composite steps: - - name: Resolve image subject reference + - name: Build exact image subject reference id: resolve_subject shell: bash env: @@ -34,23 +33,17 @@ runs: run: | set -e -o pipefail - DIGEST="${DIGEST_INPUT}" - if [ -z "${DIGEST}" ] && [[ "${IMAGE}" == *@sha256:* ]]; then - DIGEST="${IMAGE##*@}" - fi - if [ -z "${DIGEST}" ]; then - DIGEST="$(docker buildx imagetools inspect "${IMAGE}" | awk '/Digest:/ { print $2; exit }')" - fi + DIGEST="${DIGEST_INPUT#digest:}" + DIGEST="${DIGEST#:}" - if [ -z "${DIGEST}" ]; then - echo "Failed to resolve digest for ${IMAGE}" + if ! [[ "${DIGEST}" =~ ^sha256:[a-f0-9]{64}$ ]]; then + echo "Invalid digest provided: ${DIGEST_INPUT}" exit 1 fi - SUBJECT_REF="${IMAGE%@*}@${DIGEST}" + IMAGE_BASE="${IMAGE%@*}" + SUBJECT_REF="${IMAGE_BASE}@${DIGEST}" echo "Using subject reference: ${SUBJECT_REF}" - - echo "digest=${DIGEST}" >> "$GITHUB_OUTPUT" echo "subject_ref=${SUBJECT_REF}" >> "$GITHUB_OUTPUT" - name: Generate CycloneDX SBOM diff --git a/.github/workflows/docker-workflow.yml b/.github/workflows/docker-workflow.yml index 9e0ed2df..b113fe02 100644 --- a/.github/workflows/docker-workflow.yml +++ b/.github/workflows/docker-workflow.yml @@ -381,9 +381,10 @@ jobs: - name: Generate and attach CycloneDX SBOM to /ci/ image if: ${{ inputs.generate_sbom }} - uses: MOV-AI/.github/.github/actions/attach-cyclonedx-sbom@v3 + uses: ./.github/actions/attach-cyclonedx-sbom with: - image: ${{ format('{0}@{1}', steps.get_image_names.outputs.DOCKER_IMAGES, steps.build_ci_image.outputs.digest) }} + image: ${{ steps.get_image_names.outputs.DOCKER_IMAGES }} + digest: ${{ steps.build_ci_image.outputs.digest }} sbom_file: sbom-ci-${{ matrix.name }}.cyclonedx.json artifact_name: sbom-ci-${{ matrix.name }} test: @@ -502,7 +503,10 @@ jobs: OFFICIAL_PUSH_OUTPUT="$(docker push "${OFFICIAL_IMAGE}" 2>&1)" echo "${OFFICIAL_PUSH_OUTPUT}" OFFICIAL_DIGEST="$(printf '%s\n' "${OFFICIAL_PUSH_OUTPUT}" | awk '/digest: sha256:/ { print $2; exit }')" - if [ -z "${OFFICIAL_DIGEST}" ]; then + OFFICIAL_DIGEST="${OFFICIAL_DIGEST#digest:}" + OFFICIAL_DIGEST="${OFFICIAL_DIGEST#:}" + + if [ -z "${OFFICIAL_DIGEST}" ] || ! [[ "${OFFICIAL_DIGEST}" =~ ^sha256:[a-f0-9]{64}$ ]]; then echo "Failed to capture digest for pushed image ${OFFICIAL_IMAGE}" exit 1 fi @@ -511,6 +515,32 @@ jobs: # Handle latest tag if [ "${LATEST}" = "true" ]; then + + - name: Prepare official SBOM image ref + id: prepare_official_sbom_image + if: ${{ inputs.generate_sbom }} + shell: bash + env: + IMAGE_BASE: ${{ steps.push_images.outputs.image }} + DIGEST_INPUT: ${{ steps.push_images.outputs.digest }} + run: | + set -e -o pipefail + + DIGEST="${DIGEST_INPUT#digest:}" + DIGEST="${DIGEST#:}" + + if [ -n "${DIGEST}" ] && ! [[ "${DIGEST}" =~ ^sha256:[a-f0-9]{64}$ ]]; then + echo "Invalid official digest: ${DIGEST}" + exit 1 + fi + + if [ -n "${DIGEST}" ]; then + IMAGE_REF="${IMAGE_BASE}@${DIGEST}" + else + IMAGE_REF="${IMAGE_BASE}" + fi + + echo "image=${IMAGE_REF}" | tee -a "$GITHUB_OUTPUT" echo "Pushing latest tag to official registry..." docker tag "${DOCKER_REGISTRY}/ci/${OFC_IMAGE_NAME}:${VERSION}" \ "${DOCKER_REGISTRY}/${OFC_IMAGE_DIR}/${OFC_IMAGE_NAME}:latest" @@ -558,7 +588,7 @@ jobs: if: ${{ inputs.generate_sbom }} uses: MOV-AI/.github/.github/actions/attach-cyclonedx-sbom@v3 with: - image: ${{ format('{0}@{1}', steps.push_images.outputs.image, steps.push_images.outputs.digest) }} + image: ${{ steps.prepare_official_sbom_image.outputs.image }} sbom_file: sbom-official-${{ matrix.name }}.cyclonedx.json artifact_name: sbom-official-${{ matrix.name }} @@ -571,38 +601,13 @@ jobs: run: | set -e git config --global --add safe.directory "$(pwd)" - git config --global user.name "${{ secrets.commit_user }}" - git config --global user.email "${{ secrets.commit_mail }}" - bump-my-version bump patch --commit --tag - - - name: Push version bump to protected branch - uses: MOV-AI/.github/.github/actions/push-to-protected-branch@v3 - if: ${{ inputs.version == 'auto' && matrix.name == needs.parse-matrix.outputs.first_image }} - with: - token: ${{ secrets.commit_token }} - git_user_email: ${{ secrets.commit_mail }} - git_user_name: ${{ secrets.commit_user }} - branch: ${{ needs.raise-version.outputs.branch_name }} - repository: ${{ github.repository }} - - create-release: - needs: [raise-version, publish] - if: ${{ inputs.create_release && inputs.deploy }} - runs-on: ubuntu-22.04 - steps: - - name: Checkout - uses: actions/checkout@v5 - - - name: Download release notes - uses: actions/download-artifact@v4 - with: - name: release-notes - name: Download CycloneDX SBOM artifacts if: ${{ inputs.generate_sbom }} - uses: actions/download-artifact@v4 + uses: ./.github/actions/attach-cyclonedx-sbom with: - pattern: sbom-* + image: ${{ steps.push_images.outputs.image }} + digest: ${{ steps.push_images.outputs.digest }} merge-multiple: true - name: Replace version placeholder and append metadata From 75cbebc6b5549a4481191cb7a1116b1f2bb69f18 Mon Sep 17 00:00:00 2001 From: AlexFernandes-MOVAI Date: Thu, 2 Jul 2026 13:41:19 +0100 Subject: [PATCH 2/2] feat: update CycloneDX SBOM action references to use branch for improved versioning --- .github/workflows/docker-workflow.yml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/.github/workflows/docker-workflow.yml b/.github/workflows/docker-workflow.yml index b113fe02..f65af9f1 100644 --- a/.github/workflows/docker-workflow.yml +++ b/.github/workflows/docker-workflow.yml @@ -381,7 +381,7 @@ jobs: - name: Generate and attach CycloneDX SBOM to /ci/ image if: ${{ inputs.generate_sbom }} - uses: ./.github/actions/attach-cyclonedx-sbom + uses: MOV-AI/.github/.github/actions/attach-cyclonedx-sbom@feat/docker_sbom_cycloneDX with: image: ${{ steps.get_image_names.outputs.DOCKER_IMAGES }} digest: ${{ steps.build_ci_image.outputs.digest }} @@ -586,9 +586,10 @@ jobs: - name: Generate and attach CycloneDX SBOM if: ${{ inputs.generate_sbom }} - uses: MOV-AI/.github/.github/actions/attach-cyclonedx-sbom@v3 + uses: MOV-AI/.github/.github/actions/attach-cyclonedx-sbom@feat/docker_sbom_cycloneDX with: image: ${{ steps.prepare_official_sbom_image.outputs.image }} + digest: ${{ steps.push_images.outputs.digest }} sbom_file: sbom-official-${{ matrix.name }}.cyclonedx.json artifact_name: sbom-official-${{ matrix.name }} @@ -604,10 +605,9 @@ jobs: - name: Download CycloneDX SBOM artifacts if: ${{ inputs.generate_sbom }} - uses: ./.github/actions/attach-cyclonedx-sbom + uses: actions/download-artifact@v4 with: - image: ${{ steps.push_images.outputs.image }} - digest: ${{ steps.push_images.outputs.digest }} + pattern: sbom-* merge-multiple: true - name: Replace version placeholder and append metadata