From 5f96b5d1b572ef666e81555ce5d43b6fd1c03f91 Mon Sep 17 00:00:00 2001 From: Rouel Soberano <96156061+rsoberano-ld@users.noreply.github.com> Date: Tue, 25 Jun 2024 15:20:41 -0700 Subject: [PATCH] build: fix docker container provenance generation using json matrix strategy (#407) **Requirements** - [ ] I have added test coverage for new or changed functionality - [ ] I have followed the repository's [pull request submission guidelines](../blob/master/CONTRIBUTING.md#submitting-pull-requests) - [ ] I have validated my changes against all supported platform versions **Related issues** Provide links to any issues in this repository or elsewhere relating to this pull request. **Describe the solution you've provided** The SLSA generator for docker container only accepts one image/digest combination at a time, whereas `goreleaser` may publish multiple image/digests in one release. The goal here is to have the goreleaser step output a JSON array with image and digest properties for each image published, like so: ``` [{"image":"launchdarkly/ld-relay","digest":"sha256:abbeec99b023cd040fa89b3c30335fd123680a20a6abdff023eb1f23d65217e9"},{"image":"launchdarkly/ld-relay","digest":"sha256:abbeec99b023cd040fa89b3c30335fd123680a20a6abdff023eb1f23d65217e9"},{"image":"launchdarkly/ld-relay","digest":"sha256:abbeec99b023cd040fa89b3c30335fd123680a20a6abdff023eb1f23d65217e9"},{"image":"launchdarkly/ld-relay","digest":"sha256:abbeec99b023cd040fa89b3c30335fd123680a20a6abdff023eb1f23d65217e9"},{"image":"launchdarkly/ld-relay","digest":"sha256:abbeec99b023cd040fa89b3c30335fd123680a20a6abdff023eb1f23d65217e9"},{"image":"launchdarkly/ld-relay","digest":"sha256:abbeec99b023cd040fa89b3c30335fd123680a20a6abdff023eb1f23d65217e9"},{"image":"launchdarkly/ld-relay","digest":"sha256:ae50b3993d45ffcec26a602abbec7d4fc6f0859d7efaf8786d547d7e9f2fba47"},{"image":"launchdarkly/ld-relay","digest":"sha256:ae50b3993d45ffcec26a602abbec7d4fc6f0859d7efaf8786d547d7e9f2fba47"},{"image":"launchdarkly/ld-relay","digest":"sha256:ae50b3993d45ffcec26a602abbec7d4fc6f0859d7efaf8786d547d7e9f2fba47"},{"image":"launchdarkly/ld-relay","digest":"sha256:c6f2c654806e8adad6e0f98ab326517b02ce13e6ffb385e6d2537dade1be13c4"},{"image":"launchdarkly/ld-relay","digest":"sha256:c6f2c654806e8adad6e0f98ab326517b02ce13e6ffb385e6d2537dade1be13c4"},{"image":"launchdarkly/ld-relay","digest":"sha256:c6f2c654806e8adad6e0f98ab326517b02ce13e6ffb385e6d2537dade1be13c4"}] ``` Then we pass this JSON array as a matrix strategy for the provenance generator, with the idea that the provenance generator __should__ run once per image/digest combo in the array. Github actions are super finicky with formatting and JSON handling though, so I'm not 100% sure if this will work as we have it here - need to be able to test this somehow. **Describe alternatives you've considered** Provide a clear and concise description of any alternative solutions or features you've considered. **Additional context** Add any other context about the pull request here. --- .github/actions/publish/action.yml | 19 ++++++------------- .github/workflows/manual-publish.yml | 9 +++++---- .github/workflows/release-please.yml | 9 +++++---- 3 files changed, 16 insertions(+), 21 deletions(-) diff --git a/.github/actions/publish/action.yml b/.github/actions/publish/action.yml index f2a0d53e..e133693e 100644 --- a/.github/actions/publish/action.yml +++ b/.github/actions/publish/action.yml @@ -15,12 +15,9 @@ outputs: hashes: description: sha256sum hashes of built artifacts value: ${{ steps.binary.outputs.hashes }} - image: - description: built docker image names - value: ${{ steps.image.outputs.name }} - digest: - description: built docker image digests - value: ${{ steps.image.outputs.digest }} + images_and_digests: + description: built docker image names and digests in JSON format + value: ${{ steps.image.outputs.images_and_digests }} runs: using: composite @@ -57,19 +54,15 @@ runs: checksum_file=$(echo "$ARTIFACTS" | jq -r '.[] | select (.type=="Checksum") | .path') echo "hashes=$(cat $checksum_file | base64 -w0)" >> "$GITHUB_OUTPUT" - - name: Image digest - id: image + - name: Output image and digest + id: image shell: bash env: ARTIFACTS: "${{ steps.goreleaser.outputs.artifacts }}" run: | # Generate image digest set -euo pipefail - image_and_digest=$(echo "$ARTIFACTS" | jq -r '.[] | select (.type=="Docker Manifest") | .path') - image=$(echo "${image_and_digest}" | cut -d'@' -f1 | cut -d':' -f1) - digest=$(echo "${image_and_digest}" | cut -d'@' -f2) - { echo 'name<> "$GITHUB_OUTPUT" - { echo 'digest<> "$GITHUB_OUTPUT" + echo "images_and_digests=$(echo "$ARTIFACTS" | jq -c '. | map(select (.type=="Docker Manifest") | .image=(.path | split(":")[0]) | .digest=(.extra | .Digest) | {image, digest})')" >> "$GITHUB_OUTPUT" - name: Upload Release Artifacts shell: bash diff --git a/.github/workflows/manual-publish.yml b/.github/workflows/manual-publish.yml index c715731f..5db84831 100644 --- a/.github/workflows/manual-publish.yml +++ b/.github/workflows/manual-publish.yml @@ -24,8 +24,7 @@ jobs: contents: write # Needed to upload release artifacts outputs: hashes: ${{ steps.publish.outputs.hashes }} - image: ${{ steps.publish.outputs.image }} - digest: ${{ steps.publish.outputs.digest }} + images_and_digests: ${{ steps.publish.outputs.images_and_digests }} steps: - uses: actions/checkout@v4 with: @@ -70,9 +69,11 @@ jobs: id-token: write packages: write uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v1.10.0 + strategy: + matrix: ${{fromJson(needs.build-publish.outputs.images_and_digests)}} with: - image: ${{ needs.build-publish.outputs.image }} - digest: ${{ needs.build-publish.outputs.digest }} + image: ${{ matrix.image }} + digest: ${{ matrix.digest }} registry-username: ${{ github.actor }} secrets: registry-password: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/release-please.yml b/.github/workflows/release-please.yml index 66e04812..1ce2b304 100644 --- a/.github/workflows/release-please.yml +++ b/.github/workflows/release-please.yml @@ -26,8 +26,7 @@ jobs: contents: write # Needed to upload release artifacts outputs: hashes: ${{ steps.publish.outputs.hashes }} - image: ${{ steps.publish.outputs.image }} - digest: ${{ steps.publish.outputs.digest }} + images_and_digests: ${{ steps.publish.outputs.images_and_digests }} needs: [ release-please, go-versions ] if: ${{ needs.release-please.outputs.release_created == 'true' }} runs-on: ubuntu-latest @@ -76,9 +75,11 @@ jobs: id-token: write packages: write uses: slsa-framework/slsa-github-generator/.github/workflows/generator_container_slsa3.yml@v1.10.0 + strategy: + matrix: ${{fromJson(needs.release-relay.outputs.images_and_digests)}} with: - image: ${{ needs.release-relay.outputs.image }} - digest: ${{ needs.release-relay.outputs.digest }} + image: ${{ matrix.image }} + digest: ${{ matrix.digest }} registry-username: ${{ github.actor }} secrets: registry-password: ${{ secrets.GITHUB_TOKEN }}