@@ -496,6 +496,39 @@ jobs:
496496 env :
497497 CODER_BASE_IMAGE_TAG : ${{ steps.image-base-tag.outputs.tag }}
498498
499+ - name : SBOM Generation and Attestation
500+ if : ${{ !inputs.dry_run }}
501+ env :
502+ COSIGN_EXPERIMENTAL : " 1"
503+ run : |
504+ set -euxo pipefail
505+
506+ # Generate SBOM for multi-arch image with version in filename
507+ echo "Generating SBOM for multi-arch image: ${{ steps.build_docker.outputs.multiarch_image }}"
508+ syft "${{ steps.build_docker.outputs.multiarch_image }}" -o spdx-json > coder_${{ steps.version.outputs.version }}_sbom.spdx.json
509+
510+ # Attest SBOM to multi-arch image
511+ echo "Attesting SBOM to multi-arch image: ${{ steps.build_docker.outputs.multiarch_image }}"
512+ cosign clean --force=true "${{ steps.build_docker.outputs.multiarch_image }}"
513+ cosign attest --type spdxjson \
514+ --predicate coder_${{ steps.version.outputs.version }}_sbom.spdx.json \
515+ --yes \
516+ "${{ steps.build_docker.outputs.multiarch_image }}"
517+
518+ # If latest tag was created, also attest it
519+ if [[ "${{ steps.build_docker.outputs.created_latest_tag }}" == "true" ]]; then
520+ latest_tag="$(./scripts/image_tag.sh --version latest)"
521+ echo "Generating SBOM for latest image: ${latest_tag}"
522+ syft "${latest_tag}" -o spdx-json > coder_latest_sbom.spdx.json
523+
524+ echo "Attesting SBOM to latest image: ${latest_tag}"
525+ cosign clean --force=true "${latest_tag}"
526+ cosign attest --type spdxjson \
527+ --predicate coder_latest_sbom.spdx.json \
528+ --yes \
529+ "${latest_tag}"
530+ fi
531+
499532 - name : GitHub Attestation for Docker image
500533 id : attest_main
501534 if : ${{ !inputs.dry_run }}
@@ -612,16 +645,27 @@ jobs:
612645 fi
613646 declare -p publish_args
614647
648+ # Build the list of files to publish
649+ files=(
650+ ./build/*_installer.exe
651+ ./build/*.zip
652+ ./build/*.tar.gz
653+ ./build/*.tgz
654+ ./build/*.apk
655+ ./build/*.deb
656+ ./build/*.rpm
657+ ./coder_${{ steps.version.outputs.version }}_sbom.spdx.json
658+ )
659+
660+ # Only include the latest SBOM file if it was created
661+ if [[ "${{ steps.build_docker.outputs.created_latest_tag }}" == "true" ]]; then
662+ files+=(./coder_latest_sbom.spdx.json)
663+ fi
664+
615665 ./scripts/release/publish.sh \
616666 "${publish_args[@]}" \
617667 --release-notes-file "$CODER_RELEASE_NOTES_FILE" \
618- ./build/*_installer.exe \
619- ./build/*.zip \
620- ./build/*.tar.gz \
621- ./build/*.tgz \
622- ./build/*.apk \
623- ./build/*.deb \
624- ./build/*.rpm
668+ "${files[@]}"
625669 env :
626670 GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
627671 CODER_GPG_RELEASE_KEY_BASE64 : ${{ secrets.GPG_RELEASE_KEY_BASE64 }}
@@ -663,6 +707,15 @@ jobs:
663707 ./build/*.apk
664708 ./build/*.deb
665709 ./build/*.rpm
710+ ./coder_${{ steps.version.outputs.version }}_sbom.spdx.json
711+ retention-days : 7
712+
713+ - name : Upload latest sbom artifact to actions (if dry-run)
714+ if : inputs.dry_run && steps.build_docker.outputs.created_latest_tag == 'true'
715+ uses : actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
716+ with :
717+ name : latest-sbom-artifact
718+ path : ./coder_latest_sbom.spdx.json
666719 retention-days : 7
667720
668721 - name : Send repository-dispatch event
0 commit comments