diff --git a/.github/workflows/cut-release.yml b/.github/workflows/cut-release.yml new file mode 100644 index 0000000..a97956a --- /dev/null +++ b/.github/workflows/cut-release.yml @@ -0,0 +1,65 @@ +name: cut release + +# mint is the ONLY thing that cuts a release tag — never a hand-pushed tag. +# Dispatch this (Actions UI) to run, entirely in CI: +# mint version → bump jsr.json + package.json + prepend CHANGELOG + consume +# the .release/ intents +# commit the bump to main +# mint release → cut + PUSH the v tag, which drives publish.yml +# (JSR, keyless OIDC) + release.yml (in-toto provenance) +# +# No-op when there are no intents. REQUIRES: the workflow may push to `main` +# (allow GitHub Actions in branch protection, or swap in a deploy/app token). +on: + workflow_dispatch: {} + +permissions: + contents: write # push the version-bump commit + the release tag + +concurrency: + group: cut-release + cancel-in-progress: false + +jobs: + cut: + runs-on: ubuntu-latest + steps: + - name: Checkout main + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + with: + fetch-depth: 0 + - name: Checkout mint + uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + with: + repository: bounded-systems/mint + ref: v0.5.0 + path: .mint + - name: Setup Node + uses: actions/setup-node@a0853c24544627f65ddf259abe73b1d18a591444 # v5 + with: + node-version: "22" + - name: Install mint deps + working-directory: .mint + run: npm ci --no-audit --no-fund + - name: Git identity + run: | + git config user.name "mint" + git config user.email "noreply@anthropic.com" + - name: mint version — bump + changelog + consume intents + id: mv + run: | + out="$(node .mint/mint.mjs version)"; printf '%s\n' "$out" + next="$(printf '%s\n' "$out" | grep -oE '→ [0-9]+\.[0-9]+\.[0-9]+' | head -1 | tr -dc '0-9.')" + if [ -z "$next" ]; then + echo "released=false" >> "$GITHUB_OUTPUT" + else + echo "released=true" >> "$GITHUB_OUTPUT" + echo "next=$next" >> "$GITHUB_OUTPUT" + fi + - name: Commit the bump, then mint release (cut + push the tag) + if: steps.mv.outputs.released == 'true' + run: | + git add -A + git commit -m "chore(release): v${{ steps.mv.outputs.next }}" + git push origin HEAD:main + node .mint/mint.mjs release # cuts + pushes v diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..ff45dd2 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,20 @@ +name: release + +# Release provenance via the bounded-systems mint capability. On a v tag +# (cut by `mint release`), emits the deterministic in-toto release Statement +# (tag -> version plan -> commit) and keyless-signs it (cosign/OIDC). The JSR +# publish stays in publish.yml; this job owns VERSION + TAG provenance only. +# Pinned to an immutable mint ref. +on: + push: + tags: ["v*"] + +permissions: + contents: write # create / upload to the GitHub release + id-token: write # OIDC — cosign keyless signing + +jobs: + release: + uses: bounded-systems/mint/.github/workflows/release-provenance.yml@v0.5.0 # mint + with: + ref: v0.5.0 diff --git a/.github/workflows/version.yml b/.github/workflows/version.yml new file mode 100644 index 0000000..29f0f56 --- /dev/null +++ b/.github/workflows/version.yml @@ -0,0 +1,18 @@ +name: version + +# Versioning via the bounded-systems mint capability. Validates .release/ intents +# (fails closed on a malformed one) and previews the next version on every PR. +# Pinned to an immutable mint ref; bump when mint tags. +on: + push: + branches: [main] + pull_request: + +permissions: + contents: read + +jobs: + version: + uses: bounded-systems/mint/.github/workflows/version.yml@v0.5.0 # mint + with: + ref: v0.5.0 diff --git a/.release/README.md b/.release/README.md new file mode 100644 index 0000000..4646b6b --- /dev/null +++ b/.release/README.md @@ -0,0 +1,18 @@ +# Release intents + +This repo uses [@bounded-systems/mint](https://github.com/bounded-systems/mint) for +versioning. Each PR with a user-facing change drops an intent file here; mint +resolves the strongest bump and cuts the release deterministically. + +Format — `.release/.md`: + + --- + bump: minor # patch | minor | major + --- + short summary of the change (becomes the changelog line) + +The `version` CI job runs `mint plan`, which validates every intent and previews +the next version. At release time `mint version` bumps every manifest present +(`jsr.json` + `package.json`), prepends `CHANGELOG.md`, and consumes the intents; +`mint release` cuts the `v` tag, which drives `publish.yml` (JSR, +keyless OIDC) and `release.yml` (in-toto provenance).