You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 02a9815
Browse filesBrowse the repository at this point in the historyBrowse files
feat(release): ship the publish-go-live tag ruleset, keep -sig out of the pipeline
`tags-sig-signed.json` requires a verified signature only on the `vX.Y.Z-sig` provenance companions — the publish-go-live counterpart to `tags-signed.json`, so a repository imports it instead of hand-retargeting the signed ruleset's conditions.
The reference release pipeline, and this repository's own `release.yml`, now exclude `v*-sig` from the tag trigger: a signed companion carries no changelog section or candidate marker, so pushing one drove the release pipeline into a version-coherence failure; it routes to the attest workflow instead.
Copy file name to clipboardExpand all lines: CHANGELOG.md
+10Lines changed: 10 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -3,6 +3,16 @@
3
3
All notable changes to this project are documented in this file.
4
4
The format follows [Keep a Changelog](https://keepachangelog.com); releases are cut from the `[Unreleased]` section by this repository's own `changelog` action — the flow dogfoods itself.
5
5
6
+
## [Unreleased]
7
+
8
+
### Added
9
+
10
+
-`tags-sig-signed.json` ruleset: requires a verified signature only on the `vX.Y.Z-sig` provenance companions, the publish-go-live counterpart to `tags-signed.json`. Import it instead of hand-retargeting the signed ruleset's conditions.
11
+
12
+
### Fixed
13
+
14
+
- The reference release pipeline in `docs/release-flow.md`, and this repository's own `release.yml`, exclude `v*-sig` from the tag trigger (`tags: ["v*", "!v*-sig"]`). A signed provenance companion carries no changelog section or candidate marker, so pushing one used to spuriously drive the release pipeline into a version-coherence failure; it now routes solely to the attest workflow.
Copy file name to clipboardExpand all lines: README.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -210,7 +210,7 @@ steps:
210
210
Promotes a candidate from within the pipeline, or defers to the release manager — governed by `sign-tags`.
211
211
`manual` (the mode an active signature-requiring tag ruleset implies when nothing is configured) is a no-op beside the guidance: a human signs.
212
212
`off`creates the annotated, unsigned final tag on the built commit with the marker's message, publishes the draft, and optionally advances the moving major — one job, since a workflow-token tag push triggers no second run.
213
-
Unreadable rulesets resolve to `manual`; the shipped [`/.github/rulesets/`](.github/rulesets) files set up the signed alternative.
213
+
Unreadable rulesets resolve to `manual`; the shipped [`/.github/rulesets/`](.github/rulesets) files set up the signed alternative, and `tags-sig-signed.json` the publish-go-live one (signatures on the `vX.Y.Z-sig` companions only).
The retargeted ruleset below governs the companion's *form* — if one exists it must carry a verified signature — and nothing requires one to exist.
155
+
The `tags-sig-signed` ruleset below governs the companion's *form* — if one exists it must carry a verified signature — and nothing requires one to exist.
156
156
What makes the companion load-bearing is a step that reads it: [`require-signed-release`](#registry-publication-behind-a-signature) gates registry publication on exactly this, so on a crate repository an unattested release rehearses the upload instead of performing it.
157
157
A repository with nothing to publish — this one — gets provenance only, and the companion is genuinely optional.
158
158
Any tag name works; `attestation-tags` narrows what counts, so a repository that would rather keep the `v*` namespace to releases can attest with `sig/vX.Y.Z` and leave `git describe` alone.
159
159
160
-
The tag ruleset must not require signatures on the versions themselves — GitHub creates them unsigned — so `required_signatures` retargets to the companions:
160
+
The tag ruleset must not require signatures on the versions themselves — GitHub creates them unsigned — so signatures are required only on the companions. Import the shipped ruleset (the publish-go-live counterpart to `tags-signed.json`):
161
161
162
162
```sh
163
-
gh api repos/{owner}/{repo}/rulesets/{id} | jq '{name, target, enforcement,
rules: [.rules[] | if (.parameters // null) == null then {type} else {type, parameters} end]}' \
167
-
| gh api -X PUT repos/{owner}/{repo}/rulesets/{id} --input -
163
+
gh api repos/{owner}/{repo}/rulesets --input .github/rulesets/tags-sig-signed.json
168
164
```
169
165
166
+
It requires a verified signature on the `vX.Y.Z-sig` companions and leaves the release tags unsigned. An existing all-`v*` `tags-signed` ruleset must be removed or retargeted first, or it rejects the unsigned release tag GitHub creates on publish.
167
+
170
168
The guidance step checks this alignment at candidate time and errors while everything is still a draft when a signature rule covers the version itself — the misconfiguration never gets as far as a tag the repository would reject, or one an admin bypass would let fail the gate after going live.
171
169
This repository releases itself in this mode; the signed mode stays the reference default.
172
170
@@ -281,7 +279,9 @@ name: Release
281
279
on:
282
280
push:
283
281
branches: ["release/v**"]
284
-
tags: ["v*"]
282
+
# `!v*-sig` keeps the signed provenance companion out of this pipeline: it
283
+
# carries no changelog section or marker and routes to the attest workflow.
284
+
tags: ["v*", "!v*-sig"]
285
285
workflow_dispatch: # cut-release dispatches the first run explicitly
286
286
287
287
permissions:
@@ -420,6 +420,7 @@ jobs:
420
420
- **Actions may create pull requests** (Settings → Actions → General) — `cut-release` opens the merge-back pull request with the workflow token; without the setting the cut fails at that step.
421
421
- **Tag ruleset**: let Actions create `v*-rc*` marker tags; keep final `v*` tags restricted to release managers and — to back the workflow's signature preference with real enforcement — require signatures.
422
422
The shipped [`tags-signed.json`](../.github/rulesets/tags-signed.json) and [`tags-maintainer-only.json`](../.github/rulesets/tags-maintainer-only.json) carry exactly this shape.
423
+
In the publish-go-live mode, import [`tags-sig-signed.json`](../.github/rulesets/tags-sig-signed.json) in place of `tags-signed.json`: signatures are required only on the `vX.Y.Z-sig` companions, and the release tags GitHub creates on publish stay unsigned.
423
424
The markers are pushed unsigned with the workflow token, so a rule covering all tags blocks the candidate loop: exclude `v*-rc*` from every creation-restricting and signature-requiring tag rule, and give the release managers a bypass on the final `v*` restriction so the signed tag can be pushed at all.
424
425
The optional moving-major step force-moves a bare `v<MAJOR>` tag unsigned, so automating it means excluding those names too; without the step, re-tagging the major stays a manual, signed act.
425
426
`require-signed-tag`warns when the workflow enforces signatures but no active tag ruleset does.
0 commit comments