Release #86
Workflow file for this run
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release | |
| on: | |
| push: | |
| tags: | |
| - "v*.*.*" | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| concurrency: | |
| group: release-${{ github.ref }} | |
| cancel-in-progress: false | |
| jobs: | |
| validate: | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 30 | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| - name: Set up Go | |
| uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 | |
| with: | |
| go-version-file: go.mod | |
| cache: true | |
| cache-dependency-path: | | |
| go.sum | |
| - name: Run test suite | |
| run: make test | |
| - name: Run go vet | |
| run: go vet ./... | |
| release: | |
| needs: validate | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 45 | |
| permissions: | |
| contents: write | |
| packages: write | |
| id-token: write # required for cosign keyless signing | |
| outputs: | |
| hashes: ${{ steps.hash.outputs.hashes }} | |
| steps: | |
| - name: Check out repository | |
| uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 | |
| with: | |
| fetch-depth: 0 | |
| - name: Set up Go | |
| uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0 | |
| with: | |
| go-version-file: go.mod | |
| cache: true | |
| cache-dependency-path: | | |
| go.sum | |
| - name: Mint package-manager token | |
| uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 | |
| id: package-token | |
| with: | |
| client-id: ${{ vars.RELEASE_BOT_CLIENT_ID }} | |
| private-key: ${{ secrets.RELEASE_BOT_PRIVATE_KEY }} | |
| owner: bomly-dev | |
| repositories: | | |
| homebrew-tap | |
| scoop-bucket | |
| permission-contents: write | |
| permission-pull-requests: write | |
| - name: Mint release token | |
| # Used as GoReleaser's GITHUB_TOKEN to create the draft release on this | |
| # repo and upload its assets (archives, packages, checksums, signature). | |
| # The release stays a draft here (see .goreleaser.yaml) — actual | |
| # publishing happens in the `publish` job below, after the SLSA | |
| # provenance file is also attached. | |
| uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 | |
| id: release-token | |
| with: | |
| client-id: ${{ vars.RELEASE_BOT_CLIENT_ID }} | |
| private-key: ${{ secrets.RELEASE_BOT_PRIVATE_KEY }} | |
| owner: bomly-dev | |
| repositories: bomly-cli | |
| permission-contents: write | |
| - name: Install cosign | |
| uses: sigstore/cosign-installer@6f9f17788090df1f26f669e9d70d6ae9567deba6 # v4.1.2 | |
| - name: Run GoReleaser | |
| uses: goreleaser/goreleaser-action@f06c13b6b1a9625abc9e6e439d9c05a8f2190e94 # v7.2.3 | |
| with: | |
| distribution: goreleaser | |
| version: v2.16.0 | |
| args: release --clean | |
| env: | |
| GITHUB_TOKEN: ${{ steps.release-token.outputs.token }} | |
| TAP_GITHUB_TOKEN: ${{ steps.package-token.outputs.token }} | |
| SCOOP_GITHUB_TOKEN: ${{ steps.package-token.outputs.token }} | |
| WINGET_GITHUB_TOKEN: ${{ secrets.WINGET_GITHUB_TOKEN }} | |
| - name: Generate artifact hashes for SLSA provenance | |
| id: hash | |
| run: echo "hashes=$(base64 -w0 < dist/SHA256SUMS)" >> "$GITHUB_OUTPUT" | |
| provenance: | |
| needs: release | |
| permissions: | |
| actions: read # detect the workflow that triggered this run | |
| id-token: write # sign the provenance | |
| contents: write # upload the provenance to the release | |
| # The SLSA generator MUST be pinned by a full vX.Y.Z tag, not a commit SHA or | |
| # shorter tag — slsa-verifier resolves the builder identity from this exact ref, | |
| # and SHA-pinning breaks that resolution. See .github/pinact.yaml, which excludes | |
| # this line from automated re-pinning. | |
| # | |
| # upload-assets is deliberately false: its underlying action | |
| # (softprops/action-gh-release) finds a release by tag, and GitHub's | |
| # "get release by tag" API does not return drafts. Against our still-draft | |
| # release, it can't find one — so it creates a *second*, non-draft release | |
| # for the same tag instead, which immediately and permanently marks that | |
| # tag as immutable (even if the bad release is later deleted). The | |
| # `publish` job uploads this provenance file itself, by release ID, to | |
| # avoid that entirely. | |
| uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0 | |
| with: | |
| base64-subjects: ${{ needs.release.outputs.hashes }} | |
| upload-assets: false | |
| publish: | |
| needs: [release, provenance] | |
| if: startsWith(github.ref, 'refs/tags/') | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Mint release token | |
| uses: actions/create-github-app-token@bcd2ba49218906704ab6c1aa796996da409d3eb1 # v3.2.0 | |
| id: release-token | |
| with: | |
| client-id: ${{ vars.RELEASE_BOT_CLIENT_ID }} | |
| private-key: ${{ secrets.RELEASE_BOT_PRIVATE_KEY }} | |
| owner: bomly-dev | |
| repositories: bomly-cli | |
| permission-contents: write | |
| - name: Download SLSA provenance | |
| uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 | |
| with: | |
| name: ${{ needs.provenance.outputs.provenance-name }} | |
| - name: Attach provenance and publish release | |
| # Uploads the provenance file directly to the draft release by ID | |
| # (not by tag — see the `provenance` job comment for why), then | |
| # finalizes the draft into a published release now that every asset | |
| # is attached. Must run last: immutable releases reject new assets | |
| # once published. | |
| # | |
| # Uses the release-bot app token, not the default GITHUB_TOKEN: GitHub | |
| # does not start new workflow runs from events triggered by the | |
| # default token, so a release published with it would never fire the | |
| # `release: published` trigger on "Release lifecycle sync" | |
| # (notify-landing-yank.yml) — and the landing-page docs sync would | |
| # silently never run. An app token is attributed to the app, so the | |
| # publish event cascades. | |
| env: | |
| GH_TOKEN: ${{ steps.release-token.outputs.token }} | |
| RELEASE_TAG: ${{ github.ref_name }} | |
| PROVENANCE_FILE: ${{ needs.provenance.outputs.provenance-name }} | |
| run: | | |
| set -euo pipefail | |
| release_id="$(gh api "repos/bomly-dev/bomly-cli/releases?per_page=100" | \ | |
| jq -r --arg tag "$RELEASE_TAG" '.[] | select(.tag_name == $tag and .draft == true) | .id' | head -n1)" | |
| if [ -z "$release_id" ]; then | |
| echo "::error::No draft release found for tag ${RELEASE_TAG}" | |
| exit 1 | |
| fi | |
| curl -fsSL \ | |
| -X POST \ | |
| -H "Authorization: Bearer ${GH_TOKEN}" \ | |
| -H "Content-Type: application/octet-stream" \ | |
| --data-binary "@${PROVENANCE_FILE}" \ | |
| "https://uploads.github.com/repos/bomly-dev/bomly-cli/releases/${release_id}/assets?name=${PROVENANCE_FILE}" \ | |
| > /dev/null | |
| gh release edit "$RELEASE_TAG" --draft=false --repo bomly-dev/bomly-cli |