• v0.40.2 41fea23c99

    v0.40.2
    All checks were successful
    changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 6s
    changelog-body-check / check (pull_request) Successful in 0s
    check-self-bootstrap / check (pull_request) Has been skipped
    fragment-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 5s
    fragment-check / changelog fragment-kind (pull_request) Successful in 6s
    fragment-check / check (pull_request) Successful in 0s
    go-ci / lint + build + test (pull_request) Successful in 24s
    manifest-check / manifest-vs-tag consistency (pull_request) Successful in 7s
    manifest-check / check (pull_request) Successful in 0s
    register-check / register-drift check (pull_request) Successful in 7s
    register-check / check (pull_request) Successful in 0s
    tests / bats (pull_request) Successful in 23s
    tests / shellcheck (pull_request) Successful in 7s
    check-self-bootstrap / check (push) Successful in 3s
    go-ci / lint + build + test (push) Successful in 22s
    release / decide + act (push) Successful in 9s
    release / release (push) Successful in 0s
    tests / bats (push) Successful in 23s
    tests / shellcheck (push) Successful in 7s
    goreleaser / build + publish rt asset (push) Successful in 1m29s
    mirror-on-cut / mirror-1 (release) Successful in 2s
    mirror-on-cut / mirror (release) Successful in 0s
    goreleaser / adopters can fetch the published asset (push) Successful in 3m5s
    Stable

    release-bot released this 2026-08-19 12:21:11 +02:00 | 965 commits to main since this release

    Added

    None.

    Changed

    None.

    Fixed

    The FETCH arm adopters use is now exercised by this repo's CI. A tag-triggered job runs the composite bootstrap against the tag just published, executes the fetched binary, and measures the cache-hit path.

    The toolkit's own wrappers pin @main, so the #456 override sent every reusable down the BUILD arm. The FETCH arm was therefore unexercised here by construction, and it broke for every adopter at v0.34.0 with CI green throughout.

    Sentence splitting now decides where sentences end instead of pattern-matching punctuation. The old splitter broke on any ., ! or ? followed by whitespace, wherever it sat.

    That was wrong in two directions. Punctuation inside a code span or after an abbreviation split one over-long sentence into two short ones, so the density check passed prose it should have refused. Punctuation followed by a closing marker, as in the house **Lead.** Prose shape, suppressed the split and made the check refuse prose that was fine.

    The new predicate asks whether each occurrence is sentence-final. It splits at indices rather than rewriting text, so a sentence's words are never lost or double-counted by the fix itself.

    • gates: skip closers when deciding an abbreviation, and correct the policy (#738)
    • gates: abbreviations need a per-occurrence decision too (#738)

    Removed

    None.

    Deprecated

    None.

    Upgrade

    None.

    Downloads
  • v0.40.1 c8d7307aae

    v0.40.1
    All checks were successful
    changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 6s
    check-self-bootstrap / check (pull_request) Has been skipped
    changelog-body-check / check (pull_request) Successful in 0s
    fragment-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 5s
    fragment-check / changelog fragment-kind (pull_request) Successful in 11s
    fragment-check / check (pull_request) Successful in 0s
    go-ci / lint + build + test (pull_request) Successful in 21s
    manifest-check / manifest-vs-tag consistency (pull_request) Successful in 7s
    manifest-check / check (pull_request) Successful in 0s
    register-check / register-drift check (pull_request) Successful in 7s
    register-check / check (pull_request) Successful in 0s
    tests / bats (pull_request) Successful in 22s
    tests / shellcheck (pull_request) Successful in 7s
    check-self-bootstrap / check (push) Successful in 5s
    go-ci / lint + build + test (push) Successful in 43s
    release / decide + act (push) Successful in 10s
    release / release (push) Successful in 0s
    tests / bats (push) Successful in 23s
    tests / shellcheck (push) Successful in 7s
    goreleaser / build + publish rt asset (push) Successful in 1m28s
    mirror-on-cut / mirror-1 (release) Successful in 1s
    mirror-on-cut / mirror (release) Successful in 0s
    Stable

    release-bot released this 2026-08-19 10:23:44 +02:00 | 972 commits to main since this release

    Added

    None.

    Changed

    None.

    Fixed

    A failed cut can no longer stamp the same version twice. Both changelog emit paths now refuse a ## [X.Y.Z] heading the file already carries, naming the existing section's line number.

    The state this catches is stamped-but-uncut: a cut stamps the version, fails before tagging, then the next run sees no tag and stamps again. The duplicate is dangerous rather than untidy. Everything extracting a version's section takes the first match and stops, so the second block is dropped silently while the file still parses and every gate passes.

    The post-cut manifest check can read the default branch again. Its fetch ran without credentials, so it reported the branch unreadable and refused a cut that had in fact succeeded.

    The branch read now happens in the workflow step, which holds a credential, and the result is passed to rt manifest-postcondition. The decision is unchanged. Readable-and-absent stays distinct from unreadable: only the first is evidence, so an unreachable branch still refuses to grade rather than convicting a cut.

    • release: the readable-and-absent path aborted before rt was called

    Removed

    None.

    Deprecated

    None.

    Upgrade

    None.

    Downloads
  • v0.40.0 11aa1d3bc0

    v0.40.0
    Some checks failed
    changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 6s
    changelog-body-check / check (pull_request) Successful in 0s
    check-self-bootstrap / check (pull_request) Has been skipped
    fragment-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 5s
    fragment-check / changelog fragment-kind (pull_request) Successful in 6s
    fragment-check / check (pull_request) Successful in 0s
    go-ci / lint + build + test (pull_request) Successful in 22s
    manifest-check / manifest-vs-tag consistency (pull_request) Successful in 7s
    manifest-check / check (pull_request) Successful in 0s
    register-check / register-drift check (pull_request) Successful in 7s
    register-check / check (pull_request) Successful in 0s
    tests / bats (pull_request) Successful in 22s
    tests / shellcheck (pull_request) Successful in 7s
    check-self-bootstrap / check (push) Successful in 3s
    go-ci / lint + build + test (push) Successful in 23s
    release / decide + act (push) Failing after 9s
    release / release (push) Failing after 0s
    tests / bats (push) Successful in 22s
    tests / shellcheck (push) Successful in 7s
    goreleaser / build + publish rt asset (push) Successful in 1m34s
    mirror-on-cut / mirror-1 (release) Successful in 2s
    mirror-on-cut / mirror (release) Successful in 0s
    Stable

    release-bot released this 2026-08-19 09:53:59 +02:00 | 979 commits to main since this release

    Added

    None.

    Changed

    The cut path no longer sources forgejo-api.sh.

    Its seven forge callsites are now three rt verbs: manifest-pr, close-stale-rolling-pr (#87) and default-branch (#370/#379). The first opens, assigns and auto-merges the manifest PR — ADR-0007 path γ.

    Task verbs, not thin API wrappers: the orchestration and the jq post-processing moved into Go where they are tested, rather than staying in YAML where they were not.

    Fixed

    A cut can no longer finish green with no manifest bookkeeping. A new post-condition step verifies that the manifest either landed on the default branch or has an open manifest PR, and refuses the cut otherwise.

    The two guards that existed before both cited this defect and neither could fire on it. They lived inside the act on decision step, and the idempotency precheck can decide skip and exit that step with status 0 before either runs. A guard inside the step it must outlive is not a post-condition.

    A fragment whose body is joined into its header is now rejected.

    The blank line between them is load-bearing — without it the composer emits one run-on bullet, and every existing check passed on that shape.

    release-toolkit's OWN fragment-check wrapper also drops its paths: filter, so it posts a status on every PR and can finally be a required context.

    Adopters choose: omit the filter to make it requireable, or keep it and stay advisory. docs/integration.md states the trade.

    • docs: the adopter-facing cut walkthrough named bash scripts that no longer exist (#713)

      docs/integration.md described the release path in the present tense using release-decide.sh, release-prep.sh and draft-release.sh, retired by #607 and #705. Those now read rt decide, rt prep and rt release. Historical passages and quoted examples are unchanged, because they describe what was true when written.

    The adopter guide no longer contradicts the gate it documents.

    docs/integration.md still showed fragment-check with a paths: filter and said day-to-day PRs pay zero CI cost, after release-toolkit's own wrapper had dropped it.

    The recipe now omits the filter and states the trade. A filtered workflow does not run, so it posts no status, so it can never be a required context.

    • docs: Lookout's two findings + the bare-stem class they exposed
    • changelog: 'docs' is not a recognized fragment kind

    Removed

    None.

    Deprecated

    None.

    Upgrade

    None.

    Downloads
  • v0.39.0 64b6ebf8e7

    v0.39.0
    All checks were successful
    changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 6s
    changelog-body-check / check (pull_request) Successful in 0s
    check-self-bootstrap / check (pull_request) Has been skipped
    fragment-check / toolkit-self gate (PR's own rt) (pull_request) Successful in 4s
    fragment-check / changelog fragment-kind (pull_request) Successful in 6s
    fragment-check / check (pull_request) Successful in 0s
    go-ci / lint + build + test (pull_request) Successful in 21s
    manifest-check / manifest-vs-tag consistency (pull_request) Successful in 7s
    manifest-check / check (pull_request) Successful in 0s
    register-check / register-drift check (pull_request) Successful in 7s
    register-check / check (pull_request) Successful in 0s
    tests / bats (pull_request) Successful in 22s
    tests / shellcheck (pull_request) Successful in 7s
    check-self-bootstrap / check (push) Successful in 3s
    go-ci / lint + build + test (push) Successful in 21s
    release / decide + act (push) Successful in 8s
    release / release (push) Successful in 0s
    tests / bats (push) Successful in 22s
    tests / shellcheck (push) Successful in 7s
    goreleaser / build + publish rt asset (push) Successful in 1m26s
    mirror-on-cut / mirror-1 (release) Successful in 1s
    mirror-on-cut / mirror (release) Successful in 0s
    Stable

    release-bot released this 2026-08-19 08:39:33 +02:00 | 992 commits to main since this release

    Added

    None.

    Changed

    • fragment-check: grades changelog density and FAILS on a violation, so a dense fragment is caught on its own PR instead of at cut time (#621)

      The density rules were already enforced, but only against the composed CHANGELOG.md. rt prep recreates that file from the fragments on every compose, so a fix applied there is regenerated away. This grades the same checks, from the same implementation, at the layer where a fix survives. Set density: 'false' to opt out. Pass the five threshold inputs to match your changelog-body-check wiring, or the two layers can disagree.

    Fixed

    • changelog-body-check: check 7 now names every over-threshold sentence, not just the longest one in each paragraph (#621)

      A second long sentence in the same paragraph used to be invisible. A fixer who cleared the named list and pushed then got a fresh FAIL that read as a new problem. Measured at eight over-threshold sentences reported as five. Verdicts are unchanged: the same text fails, and the report is now the complete work list.

    • changelog-body-check: check 3 no longer refuses a dependency pin that outranks the version being cut (#658)

      A pin naming another repository states a fact about a shipped release. Check 3 read every @vX.Y.Z as a forward reference, so a consumer whose dependencies outranked it could not cut at all. Repo identity now comes from GITHUB_REPOSITORY or FORGEJO_REPOSITORY.

      The match is a prefix, so the Actions uses: path form is still caught as a self-reference. A bare pin carrying no owner is still checked, which is the deliberate safe direction. With neither variable set the behaviour is unchanged. The PASS line now names the pins it exempted, and a FAIL names the pin rather than only its version.

    A cut-safeguard refusal now says what it refused about. The decline path emits safeguard_version and prep_sha alongside safeguard_fail.

    The workflow has named all three in its ::error:: since #663 and consumed all three as env vars, but only one was ever emitted. Operators read a prepare commit for v? … Prepare commit graded: unknown while the same log printed both values six lines above.

    • prep: --dry-run now names the working-tree paths it changed, and its help text stops calling itself preview-only (#700)

      The flag skips the branch checkout, commit, push and PR call. It still rewrites the changelog, bumps version_files, runs post_bump_hooks and deletes consumed fragments, so a run read as side-effect-free left a dirty tree. Staged paths are reported separately because git checkout -- . does not restore them. The disclosure is derived from git rather than from a fixed list.

    • ci: the positive control must survive -e when the gate refuses

    • changelog: split the #658 fragment paragraph that fails the density gate

    • prep: the staged-class undo verb deleted uncommitted operator work

    • changelog: the #700 fragment repeated the claim the PR exists to correct

    • prep: give a COMPLETE undo for staged paths, and stop claiming git writes are skipped

    Removed

    None.

    Deprecated

    None.

    Upgrade

    None.

    Internal

    • tests: Bats CI now prints captured command output when an assertion fails, while keeping passing-test output hidden (#686)
    Downloads
  • v0.38.0 82d4aa0932

    v0.38.0
    All checks were successful
    changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 6s
    changelog-body-check / check (pull_request) Successful in 0s
    check-self-bootstrap / check (pull_request) Has been skipped
    fragment-check / changelog fragment-kind (pull_request) Successful in 6s
    fragment-check / check (pull_request) Successful in 0s
    go-ci / lint + build + test (pull_request) Successful in 21s
    manifest-check / manifest-vs-tag consistency (pull_request) Successful in 6s
    manifest-check / check (pull_request) Successful in 0s
    register-check / register-drift check (pull_request) Successful in 7s
    register-check / check (pull_request) Successful in 0s
    tests / bats (pull_request) Successful in 22s
    tests / shellcheck (pull_request) Successful in 7s
    check-self-bootstrap / check (push) Successful in 3s
    go-ci / lint + build + test (push) Successful in 21s
    release / decide + act (push) Successful in 8s
    release / release (push) Successful in 0s
    tests / bats (push) Successful in 23s
    tests / shellcheck (push) Successful in 7s
    goreleaser / build + publish rt asset (push) Successful in 1m24s
    mirror-on-cut / mirror-1 (release) Successful in 1s
    mirror-on-cut / mirror (release) Successful in 0s
    Stable

    release-bot released this 2026-08-18 23:44:23 +02:00 | 1011 commits to main since this release

    Added

    None.

    Changed

    None.

    Fixed

    • decide: --dry-run no longer skips the cut-safeguard layers, and an ungraded layer stops declaring a pass (#689)

      A dry run short-circuited both safeguard layers and the rolling-PR bump-label read, then reported mode=cut for a base a real run had refused seconds earlier. layer2=skip rendered identically to layer2=pass. The layers are reads, so they now run under --dry-run exactly as on a real run. The gate also requires an affirmative pass instead of merely "not a failure", so a layer that could not be graded declines the cut rather than clearing it.

    • docs: examples/README.md no longer hard-codes a "current" toolkit version that the release rewrite cannot update (#716)

      The setup step tells adopters to replace the uses: pin, and the release rewrite updates that pin on every cut. The parenthetical beside it named a fixed version and was updated by nothing, so it had said "v0.25.0 is current" for thirteen minor releases. It now points at the README Status section, which is the surface that actually tracks the current tag.

    • changelog: split the #689 fragment sentence that fails the density gate

    Removed

    • release path: the bash PR-CI gates and their differential oracle are gone; rt is the sole implementation (#607)

      The four gates already ran as rt subcommands, so no adopter action is needed and no gate behaviour changes. What goes is the parallel bash: eleven scripts, two now-unreferenced libs, and their bats suites. With them go the 22 equivalence tests, which existed only to prove the two implementations agreed. A fix now lands once instead of twice.

    The dead draft-release.sh component is retired — the script plus the three libraries whose only consumer it was (lib/changelog.sh, lib/config.sh, lib/semver.sh). 1,907 lines, reachable from nothing: the cut has published through rt release since the Go port landed.

    One bats test was ported to Go first. It was the only artifact verifying a claim the source makes in a comment: that scaffold and check 2 agree by construction.

    Deprecated

    None.

    Upgrade

    None.

    Downloads
  • v0.37.2 4f9ee6bed3

    v0.37.2
    All checks were successful
    changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 6s
    changelog-body-check / check (pull_request) Successful in 0s
    check-self-bootstrap / check (pull_request) Has been skipped
    fragment-check / changelog fragment-kind (pull_request) Successful in 6s
    fragment-check / check (pull_request) Successful in 0s
    go-ci / lint + build + test (pull_request) Successful in 35s
    manifest-check / manifest-vs-tag consistency (pull_request) Successful in 6s
    manifest-check / check (pull_request) Successful in 0s
    register-check / register-drift check (pull_request) Successful in 6s
    register-check / check (pull_request) Successful in 0s
    tests / bats (pull_request) Successful in 2m20s
    tests / shellcheck (pull_request) Successful in 9s
    check-self-bootstrap / check (push) Successful in 3s
    go-ci / lint + build + test (push) Successful in 36s
    release / decide + act (push) Successful in 8s
    release / release (push) Successful in 0s
    tests / bats (push) Successful in 2m19s
    tests / shellcheck (push) Successful in 9s
    goreleaser / build + publish rt asset (push) Successful in 1m19s
    mirror-on-cut / mirror-1 (release) Successful in 1s
    mirror-on-cut / mirror (release) Successful in 0s
    Stable

    release-bot released this 2026-08-18 13:22:23 +02:00 | 1021 commits to main since this release

    Added

    None.

    Changed

    None.

    Fixed

    The PR-lookup test seam no longer makes a live forge call when it is configured without its membership companion. #690 made an absent sha fall through to the membership lookup, mirroring production's 404. But in test mode with the membership seam unset, that widening reached the real forge silently. The calling arm passed either way, so nothing surfaced it. An unconfigured downstream seam is now a refusal rather than a fall-through.

    Removed

    None.

    Deprecated

    None.

    Upgrade

    None.

    Downloads
  • v0.37.1 a57b70ce69

    v0.37.1
    All checks were successful
    changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 6s
    changelog-body-check / check (pull_request) Successful in 0s
    check-self-bootstrap / check (pull_request) Has been skipped
    fragment-check / changelog fragment-kind (pull_request) Successful in 7s
    fragment-check / check (pull_request) Successful in 0s
    go-ci / lint + build + test (pull_request) Successful in 36s
    manifest-check / manifest-vs-tag consistency (pull_request) Successful in 6s
    manifest-check / check (pull_request) Successful in 0s
    register-check / register-drift check (pull_request) Successful in 6s
    register-check / check (pull_request) Successful in 0s
    tests / bats (pull_request) Successful in 2m20s
    tests / shellcheck (pull_request) Successful in 9s
    check-self-bootstrap / check (push) Successful in 3s
    go-ci / lint + build + test (push) Successful in 37s
    release / decide + act (push) Successful in 24s
    release / release (push) Successful in 0s
    tests / bats (push) Successful in 2m21s
    tests / shellcheck (push) Successful in 9s
    goreleaser / build + publish rt asset (push) Successful in 1m24s
    mirror-on-cut / mirror-1 (release) Successful in 1s
    mirror-on-cut / mirror (release) Successful in 0s
    Stable

    release-bot released this 2026-08-18 12:27:36 +02:00 | 1027 commits to main since this release

    Added

    None.

    Changed

    None.

    Fixed

    release-decide.sh's #417 orphan check no longer refuses a legitimate cut when a release-plumbing fixup lands above the prepare commit.

    The walk broke on the first bump-worthy subject. A fix(changelog): commit one row above the prepare commit therefore made that prepare commit unreachable, and with it the #259 buried-prepare skip.

    The discriminator is now file scope rather than commit type. A bump-worthy commit touching only release-managed files — changelog, manifest, version_files — is reconciliation rather than adopter work. Anything that cannot be proven to be plumbing still fires.

    The #417 FATAL now names the commit that triggered it. That subject was captured and discarded before.

    • register-check.sh: the allow-list wildcard semantics were misdescribed (#655)

      Both comment blocks called * pathname expansion; one added that it stops at a path segment. The implementation is bash [[ == ]], where * crosses /. The error is silent in the dangerous direction: *.md allow-lists every .md in the tree, and a check that skips too much reads as a clean scan.

    release-decide's cut-safeguard now grades a prepare commit that is not its own PR's tip.

    Layer 2/3 asked the forge which PR was merged AS a given commit. That question is answerable only for a PR's tip. Under fast-forward-only, a fixup merged above the prepare makes the prepare non-tip. The lookup then found nothing, and the safeguard declined a legitimate cut.

    The lookup now also asks which merged PR CONTAINS the commit. It reads each PR's own commit list over a bounded window. This resolves a buried prepare under every merge style. Being a forge call, it does not depend on clone depth.

    The sha-translation helper that existed only to feed the tip-keyed lookup is deleted.

    • forgejo: bound the membership walk in ONE ordered request, matching bash

    Removed

    None.

    Deprecated

    None.

    Upgrade

    None.

    Downloads
  • v0.37.0 8bfbbc3030

    v0.37.0
    All checks were successful
    changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 6s
    changelog-body-check / check (pull_request) Successful in 0s
    check-self-bootstrap / check (pull_request) Has been skipped
    fragment-check / changelog fragment-kind (pull_request) Successful in 6s
    fragment-check / check (pull_request) Successful in 0s
    go-ci / lint + build + test (pull_request) Successful in 37s
    manifest-check / manifest-vs-tag consistency (pull_request) Successful in 6s
    manifest-check / check (pull_request) Successful in 0s
    register-check / register-drift check (pull_request) Successful in 6s
    register-check / check (pull_request) Successful in 0s
    tests / bats (pull_request) Successful in 2m20s
    tests / shellcheck (pull_request) Successful in 9s
    check-self-bootstrap / check (push) Successful in 3s
    go-ci / lint + build + test (push) Successful in 36s
    release / decide + act (push) Successful in 8s
    release / release (push) Successful in 0s
    tests / bats (push) Successful in 2m19s
    tests / shellcheck (push) Successful in 9s
    goreleaser / build + publish rt asset (push) Successful in 1m29s
    mirror-on-cut / mirror-1 (release) Successful in 1s
    mirror-on-cut / mirror (release) Successful in 0s
    Stable

    release-bot released this 2026-08-17 22:39:25 +02:00 | 1039 commits to main since this release

    Added

    None.

    Changed

    • changelog-body-check gate: now runs rt changelog-body-check instead of the bash script (#607)

      Gate 3 of 4, and the last PR-CI validator on bash. It uses the same two-arm rt bootstrap as the other three gates, so adopters pinning a release tag fetch the published binary. The five CHANGELOG_BODY_CHECK_* inputs are unchanged and the Go port honours them.

    Fixed

    • release: the cut log now says whether the manifest was updated or created (#673)

      The manifest write forks on whether the file is present in the checkout. Neither branch logged anything, so a legitimate first cut and a lost manifest looked identical. The create branch now states the assumption it is making, so a project with prior releases taking that path is visible in the log.

    • release: the post-cut manifest check can run again — it had no credentials (#673)

      The check added in #637 fetches the default branch to confirm the bookkeeping commit landed. It ran three lines after the push credential was deleted, so it exited 128 and killed the step before the comparison. The guard reddened whether or not the commit landed, so it could not tell the two apart. It now scopes a credential to its own fetch.

    • reusable-release: the create echo names the ASSUMPTION, not the key count (#673)

    • pr-ci: gate 3 was missing the version-tag cache restore (@lookout #676)

    • pr-ci: make the changelog-body-check gate re-run when the gate itself changes

    Removed

    None.

    Deprecated

    None.

    Upgrade

    None.

    Downloads
  • v0.36.0 f2c85841c5

    v0.36.0
    Some checks failed
    changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 4s
    changelog-body-check / check (pull_request) Successful in 0s
    check-self-bootstrap / check (pull_request) Has been skipped
    fragment-check / changelog fragment-kind (pull_request) Successful in 6s
    fragment-check / check (pull_request) Successful in 0s
    go-ci / lint + build + test (pull_request) Successful in 35s
    manifest-check / manifest-vs-tag consistency (pull_request) Successful in 6s
    manifest-check / check (pull_request) Successful in 0s
    register-check / register-drift check (pull_request) Successful in 6s
    register-check / check (pull_request) Successful in 0s
    tests / bats (pull_request) Successful in 2m19s
    tests / shellcheck (pull_request) Successful in 9s
    check-self-bootstrap / check (push) Successful in 3s
    go-ci / lint + build + test (push) Successful in 36s
    release / decide + act (push) Failing after 8s
    release / release (push) Failing after 0s
    tests / bats (push) Successful in 2m19s
    tests / shellcheck (push) Successful in 9s
    goreleaser / build + publish rt asset (push) Successful in 1m56s
    mirror-on-cut / mirror-1 (release) Successful in 1s
    mirror-on-cut / mirror (release) Successful in 0s
    Stable

    release-bot released this 2026-08-17 14:43:59 +02:00 | 1047 commits to main since this release

    Added

    • composite action: caches the rt binary, cutting warm installs from ~10s to under a second (#606)

      The checksum verify still runs on cache hits — a restored binary is re-verified against the release manifest before anything executes it. No action needed: adopters already on uses: frankenbit/release-toolkit@vX.Y.Z get this on their next run.

    Changed

    • fragment-check gate: now runs rt fragment-check instead of the bash script (#607)

      The workflow's inputs are unchanged — valid_kinds and fragment_length_warn_chars reach rt through the same env vars the script read, verified by differential run. Adopters pinned to a release tag get a cached rt (~48ms warm, #606); no action needed.

    Fixed

    • fetch-rt: the "not listed in checksums.txt" error can now actually print (#606)

      The branch was unreachable under set -euo pipefail, so a release published with incomplete assets failed with a bare non-zero exit and no diagnostic. Anyone who hit that case saw no reason for it.

    • config: config_render_tag now fails when the tag format cannot be resolved (#625)

      With no release-toolkit.yml it returned success and an empty string. Callers' || printf 'v%s' fallbacks therefore never fired, and rt decide emitted an empty next_tag. The bash path now matches the Go path, which already fell back to v.

    • changelog-body-check: density checks now read lists, quotes and tables (#632)

      Checks 7 and 9 scanned plain paragraphs only, so the same over-long sentence failed as a paragraph and passed as a bullet. Markers are now stripped and the remainder scanned. A blockquote over the ceiling names itself in the failure, and the message names the variable that raises the ceiling.

    • release: post-cut manifest bookkeeping is written again, and verified on the branch (#637)

      The idempotency pre-check read the workspace copy, which rt release now writes itself. It saw its own run's work, assumed a prior run had landed the commit, and skipped the push. It now reads the remote branch tip, and a post-condition refuses when the commit did not land.

    • changelog-body-check: honour CHANGELOG_BODY_CHECK_{SENTENCE_MAX,SENTENCE_WARN,PAREN_DEPTH_MAX,PARAGRAPH_MAX,PARAGRAPH_WARN} env vars in the Go port — previously hardcoded, making the failure message's advice to set these vars incorrect (#652). Invalid (non-integer) values now exit 2 rather than silently falling back to the default.

    • release: the cut safeguard grades the prepare commit, and a decline now fails the run (#663)

      Layers 2 and 3 were keyed on HEAD_SHA, which asks whether the last merge came from the rolling branch, not whether the prepare commit did. Those diverge on the buried-prepare path, so a follow-up commit on top declined a valid cut. The gate now keys on the prepare commit's own sha. A decline is now an ::error:: and a non-zero exit, not a bare echo in a step that exits 0.

    • release: the Go decide port's prepare-sha resolution is now pinned by tests (#663)

      The #663 fix landed in both implementations, but only the Bash half had arms. Reverting the Go keying, or neutering the resolver, left internal/decide and cmd/rt fully green. The byte-oracle cannot cover it either: it runs --dry-run, where Layer 2/3 are SKIP. Adds a merge-commit fixture with a live Layer-2 lookup, a stray-prepare pin, and a direct resolver test over all three shapes.

    • changelog: split 37-word density failure in 652 fragment

    • release-decide: resolve the prepare's OWNING MERGE, and make the seam as strict as production

    • register-check: the allow-list wildcard bullet was WRONG, not just loose

    • fragment-check: drop || true — the runnability check could not fail

    • changelog-body-check: #632 blockquotes REFUSE with a named override

    Removed

    None.

    Deprecated

    None.

    Upgrade

    None.

    Downloads
  • v0.35.0 ff2f352bdb

    v0.35.0
    All checks were successful
    changelog-body-check / changelog body Cold-Read linter (pull_request) Successful in 4s
    check-self-bootstrap / check (pull_request) Has been skipped
    changelog-body-check / check (pull_request) Successful in 0s
    fragment-check / changelog fragment-kind (pull_request) Successful in 4s
    fragment-check / check (pull_request) Successful in 0s
    go-ci / lint + build + test (pull_request) Successful in 31s
    manifest-check / manifest-vs-tag consistency (pull_request) Successful in 5s
    manifest-check / check (pull_request) Successful in 0s
    register-check / register-drift check (pull_request) Successful in 4s
    register-check / check (pull_request) Successful in 0s
    tests / bats (pull_request) Successful in 2m9s
    tests / shellcheck (pull_request) Successful in 8s
    check-self-bootstrap / check (push) Successful in 3s
    go-ci / lint + build + test (push) Successful in 31s
    release / decide + act (push) Successful in 7s
    release / release (push) Successful in 0s
    tests / bats (push) Successful in 2m8s
    tests / shellcheck (push) Successful in 8s
    goreleaser / build + publish rt asset (push) Successful in 1m19s
    mirror-on-cut / mirror-1 (release) Successful in 1s
    mirror-on-cut / mirror (release) Successful in 0s
    Stable

    release-bot released this 2026-07-31 16:03:19 +02:00 | 1071 commits to main since this release

    Added

    • decide: cut prereleases via --prerelease alpha|beta|rc (#476)

      Emits 1.0.0-alpha.1, then alpha.2, then beta.1. The core bump comes from --bump-override when given, and is omitted while a series continues.

    • semver: semver_bump_prerelease + semver.BumpPrerelease for the alpha→beta→rc cadence (#476)

      Level and label select the move: start a series (0.34.0 + major/alpha → 1.0.0-alpha.1), increment (alpha.1 → alpha.2), or promote (alpha.3 → beta.1). Any derivation that would sort below its input is refused rather than emitted.

    • ci: fail when the release-shape rt binary grows >20% over the last release's asset (#605)

      A step-change guard, not an absolute ceiling. With no reachable baseline it still passes, but loudly: a green there means the check could not run, not that the size is fine.

    • decide: refuse a prerelease cut whose computed tag already exists

    Changed

    None.

    Fixed

    • manifest-check: check prerelease manifests against prerelease tags (#476)

      A manifest at 1.0.0-alpha.1 was compared against the last stable tag, reported "ahead", and passed even when it was behind v1.0.0-alpha.2. The mode follows the manifest's own version, so there is no flag to set; stable manifests are unchanged.

    • prep: walk a prerelease section from the preceding prerelease tag, not the last stable (#476)

      Each -alpha.N / -beta.N / -rc.N section lists only what is new in it rather than repeating the whole series. Stable cuts are unchanged.

    • semver: compare large numeric prerelease identifiers by digit count, then lexically (#612)

      Previously 1.0.0-alpha.0 compared as higher than 1.0.0-alpha.18446744073709551615. Exact at any length, with shell and Go agreeing.

    • ci: attribute a size red to the change that caused it

    • semver: bound the prerelease counter so the two sides cannot diverge

    Removed

    None.

    Deprecated

    None.

    Upgrade

    None.

    Downloads