Repository navigation
v0.127.0
Source walks read only what git lists and survive any syntax-tree depth; scaffold fixes for monorepo members, npm, pgdesign, and scratch directories; a Go toolchain-line check; claim-name registry logins; monorepo cleanup --no-auto-commit
Context
A generated protobuf file in a gitignored third-party clone crashed rlsbl rewrite go-module-path with a RecursionError, which exposed two defects at once: every tree-sitter walker recursed once per syntax-tree level, and the source walk ignored .gitignore despite its docstring. Scaffolding a family of repositories then surfaced the rest: release state written into releasable monorepo members, a fixed npm Node matrix, a crash on an npm target with no package.json, silent tracking under ignore-everything scratch directories, and a pgdesign CI whose Go-version file nothing created. The new refusals (a package.json without engines.node, tracked files in a scratch directory) and the new release-blocking go-toolchain-declared check make this a minor release.
Breaking
- The scaffolded npm CI tests exactly the Node lines
engines.nodeadmits, and a package withoutengines.nodeis refused. Thenode-versionmatrix of an npm project'sci.yml(npm, pnpm, and yarn alike) used to be a fixed[20, 22, 24]; it is now every supported Node line (20, 22, 24) whose newest release satisfiespackage.json'sengines.noderange (>=22gives[22, 24]).rlsbl scaffoldrefuses a package that declares noengines.node, naming the declaration to add (e.g."engines": {"node": ">=22"}), and refuses a range it cannot read or one that admits none of those lines. rlsbl scaffoldrefuses whileexperiments/orscreenshots/holds tracked files. Scaffold makes git ignore everything in those scratch directories, so files already committed there would stay tracked while every new file beside them is silently ignored. The refusal lists each tracked file (the scratch.gitignoreand a Go project'sgo.modthere are scaffold's own and never count) and the remedies: move them to a committed home, e.g.mkdir -p assets && git mv screenshots/hero.png assets/hero.png, or rename the directory if it is not scratch space; commit the move and re-run.- New release-blocking check
go-toolchain-declared: a Go target'sgo.modmust carry atoolchainline.actions/setup-goinstalls the Go that line names and, without it, thegodirective's version (the oldest Go consumers may build with), so CI was testing on a Go nobody develops with. The check (tagsprojectandpreflight, so it blocks a release) asks only whether the line is present and never compares it with the Go installed on the machine; each finding names the remedy,go mod edit -toolchain=<version>in the module's directory (e.g.-toolchain=go1.26.6).
Features
- The pgdesign target's scaffold creates
.go-versionbesidepgdesign.tomlwhen it is missing. Its CI installs the Go that file names; scaffold seeds it from the Go on this machine (go env GOVERSION), never rewrites an existing one (change the version by editing the file), and when there is no go command refuses, naming the file and the one line to write. rlsbl claim-nameuses the registry's own login when no token is set. npm claims useNPM_TOKENwhen it is set and otherwise npm's own~/.npmrclogin (npm login); PyPI claims useUV_PUBLISH_TOKENorPYPI_TOKENwhen set and otherwise the token in~/.pypirc's[pypi]section. A claim is refused only when neither source exists, and the refusal names both; no token is ever printed.rlsbl monorepo cleanuptakes--auto-commit/--no-auto-commit. Same name and behavior as rlsbl's other committing commands: the deletions are still committed by default, and--no-auto-commitleaves them uncommitted and prints what to commit.
Fixes
- Scaffolded Go-installing CI reads the Go version from a file. The pgdesign target's CI installs the Go declared in
.go-versionnext topgdesign.tomlinstead of the floatingstable(scaffold creates that file when it is missing; see below). The Go target's CI no longer renders a# go.mod: go Xcomment restating the floor, and explains thatsetup-goreads go.mod'stoolchainline first: declare the development Go there (go mod edit -toolchain=go1.26.6) so CI tests with it whilegostays the consumers' floor. rlsbl rewrite go-module-pathno longer crashes on deeply nested generated code, and no source walk reads gitignored files. A generated file whose expression nests thousands of levels deep (a protobuf descriptor built as one long string concatenation) crashed the rewrite with a bare RecursionError; every syntax-tree walker in the Go, npm, and Python linters now handles any depth, and a file that cannot be analyzed is named in the error. The rewrite, the linters, and the dependency and ldflags checks now consider exactly whatgit ls-files --cached --others --exclude-standardlists: tracked files plus untracked files that are not ignored, so a gitignored third-party clone is never touched, and a directory outside any git work tree is refused.- Scaffolding a releasable monorepo member no longer leaves release state the
releasable-residuecheck refuses. The member's three-way merge bases are kept in its releasable's state directory (.rlsbl-monorepo/releasables/<name>/bases/<member path>/) instead of the member's.rlsbl/bases/, and no.rlsbl/versionmarker is written into the member. A member scaffolded before this has amanaged-files.jsonbut no bases at the new location, so the next scaffold refuses and names the one-time heal (create that directory and re-run: each base is reconstructed from the last scaffold commit);rlsbl monorepo cleanupthen removes the old per-member copies. - The
[tool.pytest.ini_options]table scaffold adds topyproject.tomlis separated from the next table by a blank line. The next table header used to follow on the line right afternorecursedirs. - Scaffold names why it removes an existing
publish.yml. A project that gets no publish workflow (a monorepo member declaredreleasable = false, a project withpublish_mode: "none", or a workspace root) has an earlier scaffold'spublish.ymlremoved on re-scaffold; the file report now says why (e.g.removed (this member releases nothing (releasable = false), so it gets no publish workflow)) instead of a bareremoved (orphan). - An npm target whose directory has no
package.jsonis refused with the workspace member and the missing file named.rlsbl scaffoldcrashed with aFileNotFoundErrortraceback, andrlsbl monorepo syncprinted one per member and generated the router anyway; both now stop with e.g.workspace member 'protocols' (protocols/) has an npm target, but protocols/npm/package.json does not exist, naming the two ways out (create the package, or remove the npm entry from the targets list that declares it, which for a releasable member is the releasable'sconfig.json). rlsbl check-name --helpstates the exit codes. 0 when every name is available, 2 when any check ended in an error, and 1 otherwise; taken, invalid, and discouraged all exit 1, so a discouraged Go name exits 1 even though Go accepts it (unchanged behavior, now documented).- Committing a file saferm already removed no longer fails where safegit is not installed. saferm stages a tracked file's removal in the git index, and rlsbl's plain-git commit path then ran
git addon that path, which git refuses ("pathspec did not match"); scaffold, sync, absorb, and cleanup commits could fail that way on a machine without safegit, such as a CI runner. The already-staged removal is now committed as it stands.