Repository navigation
v0.109.0
Structured external checks, declarative dead-module exclusions, check-name --json, launcher shim generation, and deterministic check verdicts
Context
Check verdicts no longer depend on which tools a machine has installed: missing tools now hard-fail instead of silently skipping, both in checks and in release test runners.
external_checks gained an explicit structured/freeform schema with rlsbl-composed argv and competing-scope guards (breaking: the kind key is now required).
dead-modules gained a reason-gated committed exclusion list.
check-name gained --json plus a fix making multi-target checks actually check every target.
The launcher pipeline kind is now end-to-end functional with checksum-verified download shims.
rename-releasable crash recovery and batch-archival guards were hardened, and the release preflight now prints a positive success summary.
Breaking
- Structured external checks.
external_checksentries now require an explicitkindmarker (structuredorfreeform); missing/unknownkindand unknown keys are hard errors. Structured entries (mypy,ruff-check,ruff-format) run via rlsbl-composed, shell-freeuv runargv, honor the configured check timeout, and emit a competing-scope guard that rejects tool config which would silently override or narrow the declaredpaths.
Features
- Releases now confirm which preflight checks passed. The release log prints a positive summary ("Preflight: N checks passed (...)") for every check that ran, including config-declared external checks, so a green preflight is visible rather than silent.
- Launcher packages now ship working download logic. npm and PyPI
artifact: "launcher"pipelines generate platform-aware shims that download the wrapped binary from its GitHub Release, SHA-256-verify it against the release's checksums.txt before installing, and fail loudly on tampering or a missing asset. Scaffold fills the launcher manifest's non-name fields once (never inventing the package name), and a publish workflow verify step probes both the binary asset and checksums.txt so goreleaser naming drift becomes a red CI job instead of broken installs. - Declarative dead-module exclusions. Files that are legitimately unreachable by design (demo apps, tool configs) can be listed in
.rlsbl/dead-modules.tomlwith a mandatory reason; entries never act as entry points (no laundering), and stale entries hard-fail a newdead-modules-stalecheck.
Fixes
- rename-releasable crash recovery. A crash mid-rename no longer lets a re-run push the alias tag over an uncommitted rename with a stale publish gate; re-runs now heal completely. The command also asks for confirmation before pushing (bypass with --yes) and no longer demands gh auth for renames that create no tag.
- Batch release safety. A failed push no longer lets the batch repair pass archive the batch as complete on local-only tag evidence; a batch with an unfinished (in-progress) release is left intact for resume or rollback.
- Checks no longer lie on misconfigured machines. github-release, workspace-unbuildable, and ruff-lint now hard-fail when their tool is missing (or gh is unauthenticated) instead of silently skipping; ruff-lint reports exact violation counts (was ~10x inflated line counts) and enforces a minimum ruff version.
- Releases no longer silently skip tests. When a required test tool (uv, pytest, npm, mvn) is missing, or a package.json/pom.xml manifest is corrupt or absent for a declared target, the test step now hard-fails instead of passing silently.
rlsbl check-name --target npm --target pypinow checks every target, not just the first. Multi-target name checks previously stopped after the first registry.