@@ -496,6 +496,37 @@ jobs:
496
496
env :
497
497
CODER_BASE_IMAGE_TAG : ${{ steps.image-base-tag.outputs.tag }}
498
498
499
+ - name : SBOM Generation and Attestation
500
+ if : ${{ !inputs.dry_run }}
501
+ run : |
502
+ set -euxo pipefail
503
+
504
+ # Generate SBOM for multi-arch image with version in filename
505
+ echo "Generating SBOM for multi-arch image: ${{ steps.build_docker.outputs.multiarch_image }}"
506
+ syft "${{ steps.build_docker.outputs.multiarch_image }}" -o spdx-json > coder_${{ steps.version.outputs.version }}_sbom.spdx.json
507
+
508
+ # Attest SBOM to multi-arch image
509
+ echo "Attesting SBOM to multi-arch image: ${{ steps.build_docker.outputs.multiarch_image }}"
510
+ COSIGN_EXPERIMENTAL=1 cosign clean "${{ steps.build_docker.outputs.multiarch_image }}"
511
+ COSIGN_EXPERIMENTAL=1 cosign attest --type spdxjson \
512
+ --predicate coder_${{ steps.version.outputs.version }}_sbom.spdx.json \
513
+ --yes \
514
+ "${{ steps.build_docker.outputs.multiarch_image }}"
515
+
516
+ # If latest tag was created, also attest it
517
+ if [[ "${{ steps.build_docker.outputs.created_latest_tag }}" == "true" ]]; then
518
+ latest_tag="$(./scripts/image_tag.sh --version latest)"
519
+ echo "Generating SBOM for latest image: ${latest_tag}"
520
+ syft "${latest_tag}" -o spdx-json > coder_latest_sbom.spdx.json
521
+
522
+ echo "Attesting SBOM to latest image: ${latest_tag}"
523
+ COSIGN_EXPERIMENTAL=1 cosign clean "${latest_tag}"
524
+ COSIGN_EXPERIMENTAL=1 cosign attest --type spdxjson \
525
+ --predicate coder_latest_sbom.spdx.json \
526
+ --yes \
527
+ "${latest_tag}"
528
+ fi
529
+
499
530
- name : GitHub Attestation for Docker image
500
531
id : attest_main
501
532
if : ${{ !inputs.dry_run }}
@@ -612,16 +643,27 @@ jobs:
612
643
fi
613
644
declare -p publish_args
614
645
646
+ # Build the list of files to publish
647
+ files=(
648
+ ./build/*_installer.exe
649
+ ./build/*.zip
650
+ ./build/*.tar.gz
651
+ ./build/*.tgz
652
+ ./build/*.apk
653
+ ./build/*.deb
654
+ ./build/*.rpm
655
+ ./coder_${{ steps.version.outputs.version }}_sbom.spdx.json
656
+ )
657
+
658
+ # Only include the latest SBOM file if it was created
659
+ if [[ "${{ steps.build_docker.outputs.created_latest_tag }}" == "true" ]]; then
660
+ files+=(./coder_latest_sbom.spdx.json)
661
+ fi
662
+
615
663
./scripts/release/publish.sh \
616
664
"${publish_args[@]}" \
617
665
--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
666
+ "${files[@]}"
625
667
env :
626
668
GITHUB_TOKEN : ${{ secrets.GITHUB_TOKEN }}
627
669
CODER_GPG_RELEASE_KEY_BASE64 : ${{ secrets.GPG_RELEASE_KEY_BASE64 }}
@@ -663,6 +705,15 @@ jobs:
663
705
./build/*.apk
664
706
./build/*.deb
665
707
./build/*.rpm
708
+ ./coder_${{ steps.version.outputs.version }}_sbom.spdx.json
709
+ retention-days : 7
710
+
711
+ - name : Upload latest sbom artifact to actions (if dry-run)
712
+ if : inputs.dry_run && steps.build_docker.outputs.created_latest_tag == 'true'
713
+ uses : actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
714
+ with :
715
+ name : latest-sbom-artifact
716
+ path : ./coder_latest_sbom.spdx.json
666
717
retention-days : 7
667
718
668
719
- name : Send repository-dispatch event
0 commit comments