From bd80d7e58593a37e0550cbaca00815deee68b32b Mon Sep 17 00:00:00 2001 From: UebelAndre Date: Wed, 8 Jul 2026 07:04:50 -0700 Subject: [PATCH] Add attestation to releases --- .github/workflows/release.yml | 58 ++++++++++++------------------- .github/workflows/release_prep.sh | 35 +++++++++++++++++++ 2 files changed, 58 insertions(+), 35 deletions(-) create mode 100755 .github/workflows/release_prep.sh diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 87eff2b..fca237c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -7,53 +7,41 @@ on: # yamllint disable rule:truthy - "*.*.*" jobs: - pkg: - runs-on: ubuntu-latest - - steps: - - name: Checkout - uses: actions/checkout@v6 - - - name: Create release archive and notes - # Set by GH actions, see - # https://docs.github.com/en/actions/learn-github-actions/environment-variables#default-environment-variables - run: ./ci/package.sh "${{ github.ref_name }}" - - - name: Archive release artifacts - uses: actions/upload-artifact@v6 - with: - name: release - path: release/* - retention-days: 5 - + # Delegate the release archive build + attestation + GitHub release + # creation to the bazel-contrib reusable workflow. BCR's verifier + # only trusts attestations whose builder ID matches this reusable + # workflow path; rolling our own actions/attest-build-provenance + # would produce a valid SLSA attestation that BCR would still reject. + # + # The reusable workflow calls .github/workflows/release_prep.sh + # (hardcoded path) with the tag as $1, expects release notes on + # stdout, and expects release_files to be produced in cwd. release: - runs-on: ubuntu-latest permissions: contents: write - needs: pkg - steps: - - name: Download release artifacts - uses: actions/download-artifact@v7 - with: - name: release - - - name: Release - uses: softprops/action-gh-release@v2 - with: - generate_release_notes: true - body_path: release_notes.md - fail_on_unmatched_files: true - files: rules_shellcheck-*.tar.gz + # id-token: write + attestations: write let the reusable + # workflow run actions/attest-build-provenance and attach a + # BCR-trusted SLSA attestation to the release. + id-token: write + attestations: write + uses: bazel-contrib/.github/.github/workflows/release_ruleset.yaml@v7.6.0 + with: + release_files: rules_shellcheck-*.tar.gz + prerelease: false + tag_name: ${{ github.ref_name }} bcr-publish: needs: [release] uses: bazel-contrib/publish-to-bcr/.github/workflows/publish.yaml@v1.1.0 permissions: contents: write + # Propagate id-token: write + attestations: write so the + # reusable publish workflow can read the release's attestation + # and re-attest the BCR entry files. id-token: write attestations: write with: - tag_name: ${{ needs.release.outputs.release_version }} + tag_name: ${{ github.ref_name }} registry_fork: aignas/bazel-central-registry author_name: aignas author_email: 240938+aignas@users.noreply.github.com diff --git a/.github/workflows/release_prep.sh b/.github/workflows/release_prep.sh new file mode 100755 index 0000000..4115497 --- /dev/null +++ b/.github/workflows/release_prep.sh @@ -0,0 +1,35 @@ +#!/usr/bin/env bash +# Build the rules_shellcheck release archive and emit release notes. +# Invoked by bazel-contrib/.github/.github/workflows/release_ruleset.yaml +# at the hardcoded path `.github/workflows/release_prep.sh`. +# +# Args: +# $1: tag name (e.g. 0.4.0). Passed through as the --embed_label +# value so the archive is stamped with the release version. +# +# Side effects: +# Writes rules_shellcheck-${TAG}.tar.gz to the current directory — +# the location the `release_files` glob in release.yml expects. +# +# Output: +# Release notes to stdout. The reusable workflow redirects stdout +# into release_notes.txt for the GitHub release body; every other +# line goes to stderr so it doesn't pollute the notes. + +set -euo pipefail + +# Redirect stdout to stderr; keep fd 3 for the final release-notes write. +exec 3>&1 1>&2 + +TAG="${1:?tag_name required}" + +# Reuse the existing //:release target — same tarball and rendered +# notes that ci/package.sh produces for PR validation, minus the +# example-validation loop (release_ruleset already runs bazel test). +bazel run --stamp --embed_label "${TAG}" //:release -- release + +# //:release writes into ./release/; move the archive up so the +# `release_files: rules_shellcheck-*.tar.gz` glob picks it up. +mv "release/rules_shellcheck-${TAG}.tar.gz" . + +cat "release/release_notes.md" >&3