Skip to content

v0.132.0

Choose a tag to compare

@smm-h smm-h released this 09 Oct 14:33
· 114 commits to main since this release

rlsbl rewritten in Go: one binary, published to npm and PyPI as per-platform packages and wheels and installable with go install, with the release record in the .strictmetadata layout. The Python package is gone.

Context

The stricttools projects are moving to Go; the source checks rlsbl ran moved to strictcode.

Breaking

  • rlsbl is rewritten in Go. One rlsbl binary replaces the Python package. It is distributed as the Go module github.com/stricttools/rlsbl, as npm packages under the existing rlsbl name (the binary in one package per platform, rlsbl-linux-x64, rlsbl-linux-arm64, rlsbl-darwin-x64, and rlsbl-darwin-arm64, selected through optionalDependencies), and as PyPI wheels under the existing rlsbl name. There are no Windows packages, and rlsbl's Python modules can no longer be imported.
  • rlsbl's records move to .strictmetadata/. rlsbl reads nothing of the old layout (.rlsbl/, .rlsbl-monorepo/, and each member's .rlsbl/). Run rlsbl migrate records once in every repository, with --dry-run first: it converts the declarations, changelogs, release files and archives, batch release files, transition record, scaffold state, hook scripts, and options entries, writes the lifecycle-and-license record (--licenses states a license the manifests do not), removes the old layout through saferm, and commits. rlsbl monorepo cleanup removes old-layout residue, in a standalone repository too.
  • One declarations file. config.json, workspace.toml, and releasable.toml are replaced by .strictmetadata/releasables/releasables.toml, declaring the layout, release branches, releasables, members, targets, pipelines, hooks, and checks; its [timeouts] table (push_seconds, ci_seconds, check_seconds, hook_seconds) replaces the push_timeout, ci_timeout, check_timeout, and hook_timeout keys, and behavior switches are options entries in .strictmetadata/options/, written with rlsbl options set. rlsbl migrate records writes both.
  • The release targets are go, npm, and pypi. The spec target is removed, and rlsbl migrate records refuses a configuration naming any target other than go, npm, and pypi, naming the hand edit.
  • Changelog format version 2. Each releasable's changelog lives in .strictmetadata/changelog/<releasable>/, every entry carries an id, and an entry naming more commits than the per-entry limit carries its reason through rlsbl changelog add --batch-reason, which replaces --allow-batch and the batch_limits exclusions; rlsbl migrate records restamps existing entries.
  • The pre-release channel is removed. Versions are MAJOR.MINOR.PATCH: a release file carrying preid, blog, or bump = "prerelease" is refused, and rlsbl migrate records folds a pre-release's changelog entries into the stable version it preceded.
  • Removed subsystems. Member layering (the [layers] key and the layers-violations check), deploy configuration (a server releasable declares a deploy_command instead), subtree mirror publication, the launcher artifact, local asset upload (assets and custom_assets; the publish workflow builds and attaches release archives in CI), the Cloudflare Pages pipeline (selfdoc deploys documentation sites), blog-on-release, and the requires-services (with the services and test_env keys), private-hook-stale, and mixed-tag-schemes checks are removed.
  • Removed commands and flags. rlsbl deploy, rlsbl prs, rlsbl pre-push-check, rlsbl monorepo mirror, rlsbl monorepo snapshot, rlsbl monorepo snapshot-check (rlsbl monorepo graph --json gives the same inventory on demand), rlsbl transition record, rlsbl release undo --target, and rlsbl changelog amend --id are removed.
  • Source checks move to strictcode. The lint, format, and type-check tool options, the dependency-declaration checks, and the dead-modules, circular-deps, library-lint, dead-workspace-packages, ruff-lint, and strictspec certificate checks leave rlsbl; the rlsbl:strictcode option (error by default) runs strictcode analyze as a release check and refuses a missing strictcode, and rlsbl migrate records moves their settings into strictcode.toml.
  • The lifecycle-and-license record. Each repository's .strictmetadata/lifecycle-and-license/lifecycle-and-license.toml holds each releasable's dated lifecycle, license, and identities. A release or resume of a releasable on hold or retired is refused; a proprietary releasable requires a private repository and refuses every public output (registry packages, attestations, the Go module proxy, public docs); a Go library target on a private repository is refused; and rlsbl monorepo init, rlsbl monorepo add, and rlsbl monorepo absorb creating a releasable require --license.
  • Changed flags. rlsbl release reconcile takes --mode plan or --mode apply instead of --plan and --apply; rlsbl monorepo release init requires --releasables or --all, writing no table for every releasable unasked; and rlsbl monorepo graph requires --format.
  • Preflight checks always run. A declared pre_release hook replaces only a member's built-in tests, never the preflight checks, and customized hook scripts become hooks declared in releasables.toml, moved by rlsbl migrate records to .strictmetadata/release-hooks/.
  • A release refuses an origin remote whose host is a domain other than github.com; SSH host aliases without a dot are accepted.
  • A release file whose exclude names a target a pipeline publishes is refused, naming the pipeline: every pipeline publishes on every release, so the excluded target was published anyway. Delete the pipeline from releasables.toml to release without publishing that target.
  • rlsbl is a Go binary. The npm and PyPI packages rlsbl now install the Go binary, through per-platform packages (rlsbl-linux-x64, rlsbl-linux-arm64, rlsbl-darwin-x64, rlsbl-darwin-arm64 on npm, platform wheels on PyPI) for Linux and macOS on x64 and arm64; there is no Windows build. go install github.com/stricttools/rlsbl/cmd/rlsbl@v0 and the archives on each GitHub Release install it too. The Python package and its python -m rlsbl entry point are gone.

Features

  • New rlsbl transition public-client --subject <name> --reason <text> declares that a subject of a confidential repository has a public client, taking its registry names and the repository's names out of the confidential-name index; transition show lists the declarations, and the index no longer holds releasable names or identity values, nor matches a name inside a URL or a dotted hostname
  • New rlsbl transition commands keep the lifecycle-and-license record: transition show prints the record with every rule's verdict, transition lifecycle, transition license, transition identity, and transition unversioned-tag record periods and tags, transition classify makes a releasable proprietary, transition declassify squashes the proprietary history and takes a repository public, and transition init-minimal-record writes a minimal record into a repository rlsbl does not manage.
  • Confidential names stay out of public output. The confidential-names check refuses a tracked file or changelog entry of a public repository carrying a name from the machine-local confidential-name index, every GitHub Release body rlsbl writes is scanned the same way, and every mutating command keeps the index in step with the lifecycle-and-license record.
  • A release refuses a packed artifact (an npm tarball, a wheel, or a Go module zip) carrying a file from outside the releasable's members, naming each file.
  • rlsbl monorepo graph --json prints the dependency graph as a document: the members in topological order with their versions, targets, releasables, flags, dependencies, and dependents, and the edges in the same order.
  • npm ships Go binaries. A go binary pipeline publishes to npm as one package per platform, selected through the main package's optionalDependencies by os and cpu, with no postinstall script.
  • rlsbl rewrite project-name records each renamed identity in the lifecycle-and-license record as a pending identity, one per registry carrying the name, which takes effect with the next release.
  • rlsbl release deprecate and rlsbl release yank accept the latest release, which they used to refuse in favor of rlsbl release undo.
  • rlsbl scaffold refuses to write a new VERSION that would disagree with a target's version.

Fixes

  • Commands that create a .strictmetadata directory's manifest.toml while writing a record (rlsbl release backfill, rlsbl release abandon) now commit the manifest with the record instead of leaving it uncommitted
  • A refusing command prints no partial report: rlsbl status refusing a member with several targets and no --target no longer prints an empty status block before the error
  • transition show holds the confidential-names rule for a confidential repository whose public-client declarations leave it no name to protect, expecting no index entry, instead of calling it public
  • After a three-way merge conflict is resolved, the next rlsbl scaffold commits the resolved file and its new merge base, which it used to leave uncommitted.
  • The npm-token-synced check runs inside rlsbl check, rlsbl failing-checks, and a release's --dry-run; it failed there because listing the npm tokens was not an allowed read.
  • A go binary pipeline whose main package is not at the module root gets a .goreleaser.yml and archives named after that package (./cmd/tool builds tool), not after the module path's last element; and rlsbl scaffold keeps the version.go it wrote into the main package instead of removing it on the next run and writing it again on the one after.
  • rlsbl scaffold writes a stub go.mod into the .strictmetadata/ of a Go module below the repository root when that module tracks files there (the strictcli schema dump), so the module zip leaves them out and the upload-private-paths check's fix clears it.
  • The npm-token-synced check reads npm 10's token listing, where a revoked token carries its revocation time; it reported that npm token list --json printed no list of tokens.
  • A release no longer fails in the release checkout of a repository whose working tree holds an uncommitted go.work: every program the release starts, the strictcli schema dump's entry-point detection, the preflight checks, and the packed-artifact listing included, gets the release's GOWORK (the checkout's own committed go.work, or off), so Go never picks up the working tree's go.work from the checkout below it.
  • The PyPI binary wheels a pypi go-binary pipeline publishes carry the project's readme as their description, with its content type, and its keywords and classifiers, so the PyPI project page shows the readme; a readme whose suffix names no content type, or a readme table without one, is refused.
  • rlsbl scaffold removes the stored merge base of a file it no longer renders when the file was deleted already, as its refusal of an edited file of that sort says to do; the base was left behind under .strictmetadata/.scaffold-bases/.
  • A release no longer builds a pypi target whose only pipelines are go-binary pipelines: its wheels are assembled in CI from the release archives, and the local uv build made a package that never shipped, and failed for a pyproject.toml declaring no build system.
  • rlsbl release run --watch and release resume --watch wait up to five minutes and twenty seconds for the npm and PyPI listings to show a version CI published, longer than npm's CDN serves a cached package document; with 50 seconds, a publish that succeeded was reported as never reaching npm.
  • A commit rlsbl makes leaves out a path whose working tree matches HEAD while its index does not, such as a scaffolded file deleted through saferm (which stages the deletion) and written back unchanged by the next rlsbl scaffold; safegit refused the whole commit, so the scaffold failed after writing its files.
  • The confidential-names check and the release scan every commit a push of the branch carries (from origin's branch to the release commit): each commit message and every text file a commit adds or changes, so a name added and removed again before the push is refused, naming the commit, the path, and the term. Before, only the current tree and the published texts were scanned.
  • A releasable's tags are recognized only as its tag format's prefix, a MAJOR.MINOR.PATCH version, then the format's suffix, everywhere: an identity's tag_patterns glob (v*) no longer claims video-proc@v0.1.0 or makes that tag's owner ambiguous, and a workspace's publish router judges the published tag by the same rule, its wait-for-ci job naming the matched tag scheme in an output each publish job's condition reads, instead of prefix conditions. Run rlsbl scaffold to regenerate the publish workflows.
  • rlsbl release scrub no longer refuses changelog commit ids that named no commit before its rewrite either (left by an earlier rewrite): it lists them and goes on, and refuses only an id that named a commit the rewrite replaced and names none after it. Such ids are first remapped through the rewrite's own commit map, then safegit's rewrite journal.
  • rlsbl release scrub and rlsbl transition declassify give a safegit history rewrite five minutes plus 50ms for each commit of the repository, instead of a fixed ten minutes an entire-history scrub of a long history exceeded, and require safegit 0.31.1, whose rewrites fit that bound.
  • A rlsbl release scrub stopped by an out-of-date generated changelog is finished by regenerating it with rlsbl changelog generate --no-auto-commit and running the scrub again, which commits it with the scrub's records; the refusal used to say to commit the regenerated changelog, after which the scrub refused to resume.
  • A release is no longer refused for a dev overlay of a package no pyproject.toml of the releasable declares; the version-skew check asks PyPI only about overlaid packages the release depends on.
  • A release of a repository that commits a go.work no longer puts Go commands outside its checkout in that workspace: the tests of a Go project that build throwaway modules failed inside the release, listing no package.