Skip to content

v0.127.0

Choose a tag to compare

@smm-h smm-h released this 24 Sep 21:14
· 1325 commits to main since this release

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.node admits, and a package without engines.node is refused. The node-version matrix of an npm project's ci.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 satisfies package.json's engines.node range (>=22 gives [22, 24]). rlsbl scaffold refuses a package that declares no engines.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 scaffold refuses while experiments/ or screenshots/ 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 .gitignore and a Go project's go.mod there 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's go.mod must carry a toolchain line. actions/setup-go installs the Go that line names and, without it, the go directive's version (the oldest Go consumers may build with), so CI was testing on a Go nobody develops with. The check (tags project and preflight, 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-version beside pgdesign.toml when 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-name uses the registry's own login when no token is set. npm claims use NPM_TOKEN when it is set and otherwise npm's own ~/.npmrc login (npm login); PyPI claims use UV_PUBLISH_TOKEN or PYPI_TOKEN when 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 cleanup takes --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-commit leaves 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-version next to pgdesign.toml instead of the floating stable (scaffold creates that file when it is missing; see below). The Go target's CI no longer renders a # go.mod: go X comment restating the floor, and explains that setup-go reads go.mod's toolchain line first: declare the development Go there (go mod edit -toolchain=go1.26.6) so CI tests with it while go stays the consumers' floor.
  • rlsbl rewrite go-module-path no 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 what git ls-files --cached --others --exclude-standard lists: 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-residue check 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/version marker is written into the member. A member scaffolded before this has a managed-files.json but 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 cleanup then removes the old per-member copies.
  • The [tool.pytest.ini_options] table scaffold adds to pyproject.toml is separated from the next table by a blank line. The next table header used to follow on the line right after norecursedirs.
  • Scaffold names why it removes an existing publish.yml. A project that gets no publish workflow (a monorepo member declared releasable = false, a project with publish_mode: "none", or a workspace root) has an earlier scaffold's publish.yml removed 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 bare removed (orphan).
  • An npm target whose directory has no package.json is refused with the workspace member and the missing file named. rlsbl scaffold crashed with a FileNotFoundError traceback, and rlsbl monorepo sync printed 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's config.json).
  • rlsbl check-name --help states 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 add on 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.