chore(release-automation): R5 — retire bespoke version-bump tooling#153
Merged
githubrobbi merged 2 commits intomainfrom May 8, 2026
Merged
chore(release-automation): R5 — retire bespoke version-bump tooling#153githubrobbi merged 2 commits intomainfrom
githubrobbi merged 2 commits intomainfrom
Conversation
Phase R5 of `docs/architecture/release-automation-plan.md`. Deletes the
parallel `auto-tag-release.yml` + `update_all_versions.rs` + `version-bump`
recipes track that has been driving releases since v0.4.x; release-plz
(R4 active since 2026-05-08) is now the sole version-bump + tag creator.
This is the point-of-no-return milestone for the release-automation
initiative; the bespoke flow can no longer be the fallback on the next
push to `main`.
Removed (~1430 LOC):
- `.github/workflows/auto-tag-release.yml` (168 LOC).
- `build/update_all_versions.rs` (1073 LOC).
- `scripts/ci/ci-pipeline.rs` (53 LOC) — Phase 7 deprecation shim;
`REMOVE-AFTER: v0.5.73` marker satisfied at v0.5.92.
- `increment_version` + `version_bump` fns in
`scripts/ci-pipeline/src/version.rs`.
- `STEP_VERSION_INCREMENT` from `ALL_STEPS` in
`scripts/ci-pipeline/src/workflow.rs`.
- Version-bump step from `run_enhanced_phase2` (ship.rs) and
`phase2_optimized` (phases.rs).
- `version-bump` recipe in `just/build.just`.
- Version-bump step from `quick-deploy` recipe in `just/dev.just`.
- `!build/update_all_versions.rs` carve-out in `.gitignore`.
Added (~140 LOC, mostly comments + workflow YAML):
- `detect-release-bump` short-circuit job in
`.github/workflows/release-cache-warm.yml` — diffs
`[workspace.package].version` between `HEAD` and `HEAD~1` and
skips the warm matrix when the push is a version bump (saves
~165 runner-min/release because `release.yml` rebuilds + caches
that same dep graph anyway).
- Bridge step in `release-plz.yml`'s release job —
`gh workflow run release.yml ...` after release-plz creates the
workspace tag. Replaces the GITHUB_TOKEN anti-loop workaround
that R4 deferred to a future GitHub App / PAT setup; uses
`workflow_dispatch` (explicitly carved out of the anti-loop
policy) instead. Flips `git_release_enable = false` in
`release-plz.toml` so `release.yml` owns the GitHub Release page
(avoids the body-overwrite race that softprops/action-gh-release
would otherwise hit when run against a release-plz-created
Release with `body_path: release-notes.md`).
Doc updates:
- `docs/architecture/release-automation-plan.md` — flip R5 row to
🟢, append four deviation log entries (v0.5.91 immutable-release
lockout, R5-before-R4-bakein pragmatic acceleration, R5
cache-warm short-circuit, R5 downstream-trigger bridge resolves
prior R4 deferred row).
- `docs/architecture/dev-flow-implementation-plan.md` — tick the
final Phase 7 bake-in checkbox (deprecation shim retired,
`REMOVE-AFTER: v0.5.73` satisfied at v0.5.92).
- `CONTRIBUTING.md` — rewrite the Release row in the four-layer
quality-gates matrix to describe the post-R5 release-plz flow.
- `docs/publishing.md` — flip R3.5 / R5 / R6 status rows to landed;
R4 stays 🟡 (active, bake-in pending first release-plz-driven
release).
- `docs/architecture/security/supply-chain-posture.md` — replace
`auto-tag-release.yml` reference with the post-R5 chain.
- Trailing comments in `release-plz.toml`, `Cargo.toml`,
`scripts/ci-pipeline/Cargo.toml`, `.gitignore`, and
`scripts/ci-pipeline/src/{version,workflow,ship,phases}.rs`
rewritten to describe the post-R5 steady state and explicitly
note the R5 retirement of any pre-R5 tooling they referenced.
Validation:
- `cargo check --workspace --locked --all-targets` green.
- `cargo clippy -p uffs-ci-pipeline --locked --all-targets
-- -D warnings` green.
- `cargo fmt --all` green.
- `actionlint` on the two modified workflow YAML files green.
- `just gates-drift` — manifest + consumers agree (23 gates).
R4 bake-in completes naturally on the next `feat:` / `fix:` / `perf:` /
`security:` commit to `main`, which release-plz will turn into the
first end-to-end release-plz-driven release (v0.5.93). At that point
the R4 row in the dashboard flips to 🟢 in a follow-up commit.
Refs: #148 (R4 active-mode flip), #145 (R3.5 internal-dep version
requirements + R6 metadata), #151 (`release_always = false` gate),
#152 (v0.5.92 manual bootstrap after v0.5.91 immutable-release
lockout).
Comment-only follow-up to R5 retirement (auto-tag-release.yml was deleted in the prior commit on this branch). No behaviour change.
githubrobbi
added a commit
that referenced
this pull request
May 8, 2026
…ty:` (#154) Brings forward the Phase R1b "decide whether to keep top-level `security:` or migrate to `chore(security):`" sub-question and resolves it: top-level `security:` is no longer an accepted Conventional Commits type anywhere in the toolchain. Security work uses `fix(security):` (patch + Security changelog row) or `chore(security):` (no bump + Security changelog row). Background — four regexes had drifted into two camps: Strict (11 standard CC types): - scripts/ci/check_commit_subjects.sh (commit-msg + pre-push hook) - .github/workflows/commitlint.yml (PR-title advisory check) Permissive (11 + top-level `security:`): - cliff.toml::commit_parsers - release-plz.toml::release_commits The permissive carve-out tolerated PRs #31, #33, #34 — three early- project commits that used `security:` as a top-level type before the commit-msg hook was installed. Since the hook landed, no future commit can use that prefix on `main`, so the cliff.toml + release-plz.toml allowances are dead code preemptively allowing what no longer reaches the codebase. The dedicated `^fix\(security\)` and `^chore\(security\)` parsers in `cliff.toml` already route security work to the dedicated **### Security** changelog section without the top-level type. Changes: - `release-plz.toml::release_commits`: ^(feat|fix|perf|security)(\\(.+\\))?: → ^(feat|fix|perf)(\\(.+\\))?: Plus a comment block explaining the security-encoding convention and pointing to CONTRIBUTING.md. - `cliff.toml::commit_parsers`: Drop the `^security(\\([a-z0-9-]+\\))?:` line and its carve-out comment. The two scope-based parsers (`^fix\\(security\\)` + `^chore\\(security\\)`) remain, so the Security changelog section is unaffected. - `CONTRIBUTING.md` § "Commit message conventions": Add a "Security commits" paragraph explicitly codifying `fix(security):` + `chore(security):` as the canonical encodings and stating that top-level `security:` is NOT an allowed type. Cross-reference the commit-msg hook + commitlint workflow + the release-plz `release_commits` filter. - `docs/architecture/release-automation-plan.md`: Append a deviation log entry "R1b CC-type convergence (early)" documenting the decision, the dead-code rationale, and that historical PRs #31/#33/#34 remain in the changelog. No code changes. Pure regex + comment + docs convergence. Validation: - `git grep -nE "release_commits|\\^security|security:"` in `cliff.toml` + `release-plz.toml` shows the four regexes now agree (11 standard CC types only). - No CHANGELOG churn — the historical PR #31/#33/#34 entries are not regenerated by `git-cliff` because they predate the most recent tag. - `taplo fmt --check` on the two TOML files green. Refs: #153 (R5 retirement, where the drift was first surfaced). Plan impact: brings R1b's enforcement decision forward by ~1 phase. Does NOT change the R1a → R1b advisory→required scheduling for the commitlint workflow itself; only resolves the orthogonal type-list sub-question.
githubrobbi
added a commit
that referenced
this pull request
May 8, 2026
…R6 deviation row 5 — Path A) (#155) * fix(release-automation): converge CC regexes — drop top-level `security:` Brings forward the Phase R1b "decide whether to keep top-level `security:` or migrate to `chore(security):`" sub-question and resolves it: top-level `security:` is no longer an accepted Conventional Commits type anywhere in the toolchain. Security work uses `fix(security):` (patch + Security changelog row) or `chore(security):` (no bump + Security changelog row). Background — four regexes had drifted into two camps: Strict (11 standard CC types): - scripts/ci/check_commit_subjects.sh (commit-msg + pre-push hook) - .github/workflows/commitlint.yml (PR-title advisory check) Permissive (11 + top-level `security:`): - cliff.toml::commit_parsers - release-plz.toml::release_commits The permissive carve-out tolerated PRs #31, #33, #34 — three early- project commits that used `security:` as a top-level type before the commit-msg hook was installed. Since the hook landed, no future commit can use that prefix on `main`, so the cliff.toml + release-plz.toml allowances are dead code preemptively allowing what no longer reaches the codebase. The dedicated `^fix\(security\)` and `^chore\(security\)` parsers in `cliff.toml` already route security work to the dedicated **### Security** changelog section without the top-level type. Changes: - `release-plz.toml::release_commits`: ^(feat|fix|perf|security)(\\(.+\\))?: → ^(feat|fix|perf)(\\(.+\\))?: Plus a comment block explaining the security-encoding convention and pointing to CONTRIBUTING.md. - `cliff.toml::commit_parsers`: Drop the `^security(\\([a-z0-9-]+\\))?:` line and its carve-out comment. The two scope-based parsers (`^fix\\(security\\)` + `^chore\\(security\\)`) remain, so the Security changelog section is unaffected. - `CONTRIBUTING.md` § "Commit message conventions": Add a "Security commits" paragraph explicitly codifying `fix(security):` + `chore(security):` as the canonical encodings and stating that top-level `security:` is NOT an allowed type. Cross-reference the commit-msg hook + commitlint workflow + the release-plz `release_commits` filter. - `docs/architecture/release-automation-plan.md`: Append a deviation log entry "R1b CC-type convergence (early)" documenting the decision, the dead-code rationale, and that historical PRs #31/#33/#34 remain in the changelog. No code changes. Pure regex + comment + docs convergence. Validation: - `git grep -nE "release_commits|\\^security|security:"` in `cliff.toml` + `release-plz.toml` shows the four regexes now agree (11 standard CC types only). - No CHANGELOG churn — the historical PR #31/#33/#34 entries are not regenerated by `git-cliff` because they predate the most recent tag. - `taplo fmt --check` on the two TOML files green. Refs: #153 (R5 retirement, where the drift was first surfaced). Plan impact: brings R1b's enforcement decision forward by ~1 phase. Does NOT change the R1a → R1b advisory→required scheduling for the commitlint workflow itself; only resolves the orthogonal type-list sub-question. * fix(release-automation): scope publishability to polars-free crates (R6→R8 deviation row 5 — Path A) Resolves the `release-plz-pr` job hard-failing on every push to `main` with `failed to select a version for chrono` from the polars subtree's `cargo package` step. See `docs/architecture/release-automation-plan.md` deviation log row "R6 → R8 publishability resolution (Path A)" for the full diagnostic trail. TL;DR root cause: polars git/rev pin → polars-arrow declares chrono ^0.4.42 crates.io polars 0.53.0 → polars-arrow declares chrono <=0.4.41 These are mutually exclusive — no chrono version satisfies both. `cargo package` strips the git rev (publishing simulation) and falls back to crates.io polars 0.53.0; the conflict surfaces on every release-plz invocation. Why not "drop the git rev" (Path B-i)? Probed on 2026-05-08. Crates.io polars 0.53.0 has accumulated multiple nightly-rust-API regressions that the in-workspace git rev actively patches: - polars-arrow-0.53.0/src/bitmap/bitmask.rs:2 → `std::simd::{LaneCount, SupportedLaneCount}` shapes don't exist in current nightly (`nightly-2026-05-08`). - polars-ops-0.53.0/src/chunked_array/strings/case.rs:79 → `core::unicode::{Case_Ignorable, Cased}` (Cased missing, Case_Ignorable private). Dropping the git rev breaks `cargo build --workspace`. The git rev is load-bearing, not opportunistic. Path B-i abandoned. What this PR does (Path A): 1. Adds `publish = false` to the 8 polars-tainted crates' Cargo.toml: - uffs-polars (direct polars dep — root of the subtree) - uffs-mft (direct uffs-polars dep, ~28 import sites) - uffs-format (transitive via uffs-mft) - uffs-core (direct + transitive, ~54 import sites) - uffs-daemon (transitive via uffs-mft + uffs-core) - uffs-client (transitive via uffs-format → uffs-mft) - uffs-mcp (transitive via uffs-client → …) - uffs-cli (transitive via uffs-client + uffs-format → …) Each crate's comment block explains its specific role in the subtree and points at the deviation log row. 2. Updates `release-plz.toml`: replaces the 8 corresponding `[[package]] changelog_path = "CHANGELOG.md"` blocks with `release = false` so release-plz skips them entirely (no version bump computation, no `cargo package` step at all). The 4 polars- free crates (`uffs-time`, `uffs-text`, `uffs-security`, `uffs-broker`) keep their `changelog_path` entries and remain release-eligible. 3. Updates `crates-io-dry-run.yml` doc-comments: the workflow's jq filter (`select(.publish != [])`) already skips publish=false crates automatically, so no logic change needed; the header comments are refreshed to mark the polars/chrono known-expected failure as RESOLVED. 4. Appends a new deviation log row to release-automation-plan.md §8 documenting the probe-and-pivot trail and the re-enable procedure (5 steps, all reversible) for when polars upstream publishes a release containing the nightly-API patches. Verification: - `cargo build --workspace` ✓ (1m 40s, post-changes) - `cargo package -p uffs-time --no-verify --allow-dirty` ✓ (representative polars-free crate) - `cargo metadata` jq partition matches expectation: publishable (4): uffs-broker, uffs-security, uffs-text, uffs-time non-publishable (12): 8 newly-tagged + 4 pre-existing internal tools (uffs-ci-pipeline, uffs-diag, uffs-gen-hooks, uffs-gen-workflow) Plan impact: - R6 PARTIALLY RESOLVED — publishability invariant scoped to 4 of 12 originally-publishable crates. - R7 (OIDC scaffolding) unaffected — the dormancy gate doesn't care which crates are publishable. - R8 dress rehearsal still feasible on its originally-chosen leaf target `uffs-time` (polars-free). - R9 (full publish) DEFERRED until polars upstream ships a compatible release; track via `crates-io-dry-run.yml` weekly. End-user impact: - `cargo install uffs-cli` is now blocked. `just use` (GitHub Releases tarball install — the recommended path) is unaffected. - Daily development workflows (`cargo build`, `cargo test`, `just ship`, `just use`) all work unchanged. Refs: deviation log row "R6 → R8 publishability resolution (Path A)" in docs/architecture/release-automation-plan.md
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Phase R5 of
docs/architecture/release-automation-plan.md. Deletes the parallelauto-tag-release.yml+update_all_versions.rs+version-bumprecipes track that has been driving releases since v0.4.x; release-plz (R4 active since 2026-05-08) is now the sole version-bump + tag creator. This is the point-of-no-return milestone for the release-automation initiative — the bespoke flow is no longer the fallback on the next push tomain.Net diff: 22 files changed, +393 / −1546 LOC (net −1153 LOC).
Removed (~1430 LOC)
.github/workflows/auto-tag-release.yml(168 LOC)build/update_all_versions.rs(1073 LOC) — bespoke version-bump rust-scriptscripts/ci/ci-pipeline.rs(53 LOC) — Phase 7 deprecation shim;REMOVE-AFTER: v0.5.73marker satisfied at v0.5.92increment_version+version_bumpfns inscripts/ci-pipeline/src/version.rsSTEP_VERSION_INCREMENTfromALL_STEPSinscripts/ci-pipeline/src/workflow.rsrun_enhanced_phase2(ship.rs) andphase2_optimized(phases.rs)version-bumprecipe injust/build.justquick-deployrecipe injust/dev.just!build/update_all_versions.rscarve-out in.gitignoreAdded (~140 LOC, mostly comments + workflow YAML)
detect-release-bumpshort-circuit job inrelease-cache-warm.ymlDiffs
[workspace.package].versionbetweenHEADandHEAD~1and skips the warm matrix when the push is a version bump. Saves ~165 runner-min/release becauserelease.ymlrebuilds + caches that same dep graph anyway.Was originally scoped as a separate "tiny surgical PR" but folded into R5 since it's small and conceptually adjacent.
Bridge step in
release-plz.yml's release jobgh workflow run release.yml ...after release-plz creates the workspace tag. Replaces the GITHUB_TOKEN anti-loop workaround that R4 deferred to a future GitHub App / PAT setup; usesworkflow_dispatch(explicitly carved out of the anti-loop policy by GitHub) instead.Also flips
git_release_enable = falseinrelease-plz.tomlsorelease.ymlowns the GitHub Release page (avoids the body-overwrite race that softprops/action-gh-release would otherwise hit when run against a release-plz-created Release withbody_path: release-notes.md).Doc updates
docs/architecture/release-automation-plan.md— flip R5 row to 🟢, append four deviation log entries:docs/architecture/dev-flow-implementation-plan.md— tick the final Phase 7 bake-in checkbox; deprecation shim retired,REMOVE-AFTER: v0.5.73satisfied at v0.5.92.CONTRIBUTING.md— rewrite the Release row in the four-layer quality-gates matrix to describe the post-R5 release-plz flow.docs/publishing.md— flip R3.5 / R5 / R6 status rows to landed; R4 stays 🟡 (active, bake-in pending first release-plz-driven release).docs/architecture/security/supply-chain-posture.md— replace theauto-tag-release.ymlreference with the post-R5 chain.release-plz.toml,Cargo.toml,scripts/ci-pipeline/Cargo.toml,.gitignore, andscripts/ci-pipeline/src/{version,workflow,ship,phases}.rsrewritten to describe the post-R5 steady state and explicitly note the R5 retirement of any pre-R5 tooling they referenced.Validation
cargo check --workspace --locked --all-targetscargo clippy -p uffs-ci-pipeline --locked --all-targets -- -D warningscargo fmt --allactionlintonrelease-plz.yml+release-cache-warm.ymljust gates-driftlint-pre-push(full Tier 1 gate, 19 jobs)Pre-push gate ran every CI-equivalent check locally including
lint-ci-windows(cross-compiled clippy),vet,deny,nextest,rustdoc -D warnings, etc. See the push log in the commit checks for the full breakdown.R4 bake-in
R4 stays 🟡 in the dashboard until the first release-plz-driven release lands. After R5 merges, the next
feat:/fix:/perf:/security:commit tomainwill trigger release-plz to open arelease-plz-vX.Y.ZPR; merging that PR produces v0.5.93 end-to-end through the new flow. At that point R4 flips to 🟢 in a follow-up dashboard-only commit.Rollback
Fully reversible —
git revertof this single PR restoresauto-tag-release.yml+update_all_versions.rs+ theversion-bumprecipes; the bespoke flow is back operational with one merge. No data has moved.Refs
release_always = falseto gate tag creation #151 (release_always = falsegate)