From 05dab68911645f7ded90e09285cc905a56ff7460 Mon Sep 17 00:00:00 2001 From: "Jason M. Gates" Date: Tue, 15 Jul 2025 10:57:07 -0600 Subject: [PATCH] patch: Add SLSA provenance to release assets See https://slsa.dev/ for motivation. Creating a patch release to ensure these additions to the automated release process work. Note that the `release` job has been subdivided, because the SLSA provenance reusable workflow cannot be used as a step within a job, but must be used as a job on its own. --- .github/workflows/semantic-release.yml | 71 ++++++++++++++++++++++++-- 1 file changed, 67 insertions(+), 4 deletions(-) diff --git a/.github/workflows/semantic-release.yml b/.github/workflows/semantic-release.yml index 955248d..4874dac 100644 --- a/.github/workflows/semantic-release.yml +++ b/.github/workflows/semantic-release.yml @@ -8,10 +8,12 @@ on: permissions: contents: read +concurrency: + group: release + jobs: release: runs-on: ubuntu-latest - concurrency: release environment: release permissions: id-token: write @@ -37,12 +39,73 @@ jobs: ssh_private_signing_key: ${{ secrets.SEMANTIC_RELEASE_PRIVATE_KEY }} ssh_public_signing_key: ${{ secrets.SEMANTIC_RELEASE_PUBLIC_KEY }} - - name: Publish to PyPI - uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc # release/v1 + - name: Hash Build Artifacts + if: steps.release.outputs.released == 'true' + id: hash + run: | + cd dist + echo "hashes=$(find . -type f -exec sha256sum {} + | sort | base64 | tr -d '\n')" >> "$GITHUB_OUTPUT" + + - name: Upload Build Artifacts if: steps.release.outputs.released == 'true' + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: dist + path: dist/ + + outputs: + hashes: ${{ steps.hash.outputs.hashes }} + released: ${{ steps.release.outputs.released }} + + provenance: + needs: release + if: ${{ needs.release.outputs.released == 'true' }} + permissions: + actions: read + id-token: write + contents: write + uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0 + with: + base64-subjects: "${{ needs.release.outputs.hashes }}" + + publish: + runs-on: ubuntu-latest + needs: [release, provenance] + if: ${{ needs.release.outputs.released == 'true' && needs.provenance.outputs.outcome == 'success' }} + environment: release + permissions: + id-token: write + + steps: + - name: Harden Runner + uses: step-security/harden-runner@6c439dc8bdf85cadbbce9ed30d1c7b959517bc49 # v2.12.2 + with: + egress-policy: audit + + - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 + with: + fetch-depth: 0 + token: ${{ secrets.GH_TOKEN }} + + - name: Download Build Artifacts + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 + with: + name: dist + path: dist + + - name: Download Provenance + uses: actions/download-artifact@d3f86a106a0bac45b974a628896c90dbdf5c8093 # v4.3.0 + with: + name: ${{ needs.provenance.outputs.provenance-name }} + path: dist - name: Publish to GitHub Releases uses: python-semantic-release/publish-action@b717f67f7e7e9f709357bce5a542846503ce46ec # v10.2.0 - if: steps.release.outputs.released == 'true' with: github_token: ${{ secrets.GH_TOKEN }} + + - name: Remove Provenance for PyPI Upload + run: rm -f dist/${{ needs.provenance.outputs.provenance-name }} + + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@76f52bc884231f62b9a034ebfe128415bbaabdfc # release/v1