Release orchestration and project scaffolding across package ecosystems
Project description
rlsbl
Release orchestration and project scaffolding for npm, PyPI, Go, and 15 more release targets.
Install
From PyPI:
uv tool install rlsbl
From npm (wrapper):
npm i -g rlsbl
Quick start
rlsbl scaffold # set up CI/CD, hooks, changelog, pipelines
# ... develop, commit ...
rlsbl release init # scaffold .rlsbl/releases/unreleased.toml
# ... edit bump type, targets, pipelines ...
rlsbl release run # bump, tag, push, publish, create GitHub Release
rlsbl watch <sha> # monitor CI for that release
Commands
All commands auto-detect targets (versioning) from project files (package.json, pyproject.toml, go.mod) and pipelines (publishing) from .rlsbl/config.json. Targets handle version bumps; pipelines handle where releases are published.
[selfdoc: no strictcli app found in 'rlsbl/']
Global flags: --help, --version, --dry-run, --yes, --quiet.
Release flow
When you run rlsbl release run:
- Reads
.rlsbl/releases/unreleased.tomlfor bump type (patch/minor/major) and target selection - Verifies
ghCLI is installed and authenticated - Checks working tree is clean (use
--allow-dirtyto override) - Fetches origin and verifies local branch is not behind remote
- Reads the current version from the primary project file
- Computes the new version; confirms the tag does not already exist
- Validates JSONL changelog via the check system
- Runs
.rlsbl/hooks/pre-checks.shif present (user-owned, non-zero aborts) - Runs built-in tests and lint
- Runs
.rlsbl/hooks/pre-release.shif present (scaffold-managed, non-zero aborts) - Acquires advisory lockfile (
.rlsbl/lock) to prevent concurrent operations - Writes the new version to all detected project files and
.rlsbl/version - Commits the version bump (uses
safegitif available) - Tags and pushes to
origin - Finalizes JSONL changelog (renames
unreleased.jsonl, generates CHANGELOG.md) - Creates a GitHub Release with the changelog entry as notes
- Runs publish pipelines (configured in
.rlsbl/config.jsonunderpipelines) - Runs
.rlsbl/hooks/post-release.shif present (non-fatal) - Prints
Watch CI: rlsbl watch <sha>
Use --dry-run to preview without changes. Use --yes for non-interactive mode (CI, AI agents).
Create the release file with rlsbl release init, which auto-detects project targets and scaffolds the TOML file.
First release: if the current version has never been tagged, release publishes it as-is (bump type is ignored).
Pre-release versions (e.g. 1.0.0-beta.1) are supported.
Scaffold
rlsbl scaffold # create or update CI/CD for all detected registries
rlsbl scaffold --force # overwrite managed files (user-owned files still preserved)
rlsbl scaffold --no-commit # skip auto-commit of scaffolded files
Created files are committed automatically by default.
| File | Purpose |
|---|---|
.github/workflows/ci.yml |
CI workflow (lint, test) |
.github/workflows/publish.yml |
Publish on GitHub Release (OIDC) |
CHANGELOG.md |
Version changelog |
LICENSE |
MIT license (author and year filled in) |
.gitignore |
Standard ignores for the ecosystem |
CLAUDE.md |
AI assistant instructions |
.claude/settings.json |
Claude Code settings |
.rlsbl/hooks/pre-checks.sh |
User-customizable pre-checks validation |
.rlsbl/hooks/pre-release.sh |
User-customizable pre-release validation |
.rlsbl/hooks/post-release.sh |
User-customizable post-release actions |
.git/hooks/pre-push |
Captures push refs, runs rlsbl check --tag prepush |
.rlsbl/bases/ |
Three-way merge bases for scaffold |
Three-way merge: Bases are stored at scaffold time. On re-run, user customizations and template updates merge via git merge-file. Conflicts get git-style conflict markers.
User-owned files (CHANGELOG.md, LICENSE, hooks) are never overwritten, even with --force.
Customizing CI without conflicts: Instead of editing ci.yml or publish.yml (which can produce merge conflicts on re-scaffold), put extra jobs in a separate workflow file scaffold never touches:
.github/workflows/ci-custom.yml-- runs alongsideci.yml.github/workflows/publish-custom.yml-- runs alongsidepublish.yml
See docs/ci-customization.md for an example.
Runs config migrations when .rlsbl/config-schema.json exists.
Check system
rlsbl includes 53 checks across 7 tags.
| Tag | Checks | Description |
|---|---|---|
project |
12 | Version, name, license, description consistency; config schema; private hook/workflow; npm mismatch; target readability; selfdoc drift |
release |
4 | Local/remote tag, GitHub Release, branch sync |
changelog |
9 | Hash resolution, range, coverage, orphans, schema, user-facing, batch limits, entry |
workspace |
9 | CI router, CI sync, targets, unregistered, stale entries, dev-node boundary, dead packages, subtree remote, layers |
quality |
8 | Dead modules, circular deps, library lint, deps unused/undeclared/runtime-test-only/dev-in-lib, scaffold checks, test suite |
| (untagged) | 4 | Additional validation checks |
rlsbl check --all # run all 50 checks
rlsbl check --tag changelog # run checks by tag
rlsbl check --name lock # run a single check
Config management
Schema-driven configuration migration system for projects that ship user-facing config files.
rlsbl migrate # run pending migrations
rlsbl migrate --status # show migration status
rlsbl migrate --dry-run # preview changes
Library API
from rlsbl.lib import ConfigMigrator, load_schema, migrate
# One-liner: load schema and run all pending migrations
result = migrate(".") # returns {filename: was_written} or None
Undo
rlsbl release undo # interactive: confirms before each destructive step
rlsbl release undo --yes # non-interactive: auto-confirms, auto-pushes
Reverts the last release:
- Deletes the GitHub Release
- Deletes the git tag (remote + local)
- Reverts the version bump commit (if HEAD matches the tag)
- Pushes the revert commit (with confirmation, or automatic with
--yes)
On partial failure, prints a structured summary table with remediation commands for each failed step.
Pre-push hook
The .git/hooks/pre-push hook captures push refs from git and runs rlsbl check --tag prepush, which enforces:
- Changelog coverage -- every pushed commit must have a JSONL entry
- Gitignore guard -- rlsbl-managed files must not be gitignored
- Manual push warning -- warns when pushing to a release branch outside
rlsbl release - Test suite -- runs project tests (single-project) or affected project tests (monorepo)
Old hooks that call rlsbl pre-push-check still work but show a deprecation warning. Run rlsbl scaffold to update to the current hook format.
To reinstall manually:
echo '#!/usr/bin/env bash' > .git/hooks/pre-push
echo 'export RLSBL_PUSH_STDIN="$(cat)"' >> .git/hooks/pre-push
echo 'exec rlsbl check --tag prepush' >> .git/hooks/pre-push
chmod +x .git/hooks/pre-push
Ecosystem tagging
scaffold and release add an "rlsbl" keyword to project manifests and set the rlsbl topic on the GitHub repository, making projects discoverable via rlsbl discover.
To disable:
| Method | Scope |
|---|---|
--no-tag flag |
Single invocation |
{"tag": false} in .rlsbl/config.json |
This project |
{"tag": false} in ~/.rlsbl/config.json |
All projects |
Monorepo
Manage multi-package workspaces with rlsbl monorepo:
monorepo init/monorepo add/monorepo remove-- workspace managementmonorepo sync-- synchronize CI workflowsmonorepo graph-- export dependency graph (JSON, DOT, text)monorepo snapshot-- committed JSON artifact of workspace statemonorepo impact-- change analysis across the dependency graphmonorepo release run-- batch release in topological order
Supports architectural layer rules via [layers] in workspace.toml for enforcing dependency direction.
Environment variables
| Variable | Default | Description |
|---|---|---|
RLSBL_PUSH_TIMEOUT |
120 |
Timeout in seconds for git push operations |
RLSBL_VERSION |
-- | Set when running pre-release and post-release hooks; contains the version being released |
RLSBL_DIST_DIR |
-- | Set when running custom_assets build commands; points to the distribution directory for output files |
GITHUB_TOKEN |
-- | Used by gh CLI for GitHub API calls; discover works unauthenticated for public repos |
First publish
| Registry | Setup | Then |
|---|---|---|
| npm | Add NPM_TOKEN secret to GitHub repo (Settings > Secrets > Actions) |
CI publishes on GitHub Release |
| PyPI | Set up Trusted Publishing (OIDC, no tokens needed) | CI publishes via OIDC |
| Go | Push tag -- Go modules are published by the tag itself | pkg.go.dev indexes automatically |
Requirements
- Python 3.11+
- GitHub CLI (
gh), installed and authenticated - git
- Node 24+ (for npm CI/publish templates)
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rlsbl-0.84.0.tar.gz.
File metadata
- Download URL: rlsbl-0.84.0.tar.gz
- Upload date:
- Size: 1.4 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
74ed0966cf2651d89a4852b237d287d7164af23f08156e3a245c71fb235882f3
|
|
| MD5 |
dc84722fc554e49d5967b7474d5d74e9
|
|
| BLAKE2b-256 |
4d642489b187b87f07a7d2784b0cdb2a8e97d5ce0501ef65dc98365862cdf393
|
Provenance
The following attestation bundles were made for rlsbl-0.84.0.tar.gz:
Publisher:
publish.yml on smm-h/rlsbl
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rlsbl-0.84.0.tar.gz -
Subject digest:
74ed0966cf2651d89a4852b237d287d7164af23f08156e3a245c71fb235882f3 - Sigstore transparency entry: 1940963630
- Sigstore integration time:
-
Permalink:
smm-h/rlsbl@144601303b97d126e74fe82f7a975554da3651ab -
Branch / Tag:
refs/tags/v0.84.0 - Owner: https://github.com/smm-h
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@144601303b97d126e74fe82f7a975554da3651ab -
Trigger Event:
release
-
Statement type:
File details
Details for the file rlsbl-0.84.0-py3-none-any.whl.
File metadata
- Download URL: rlsbl-0.84.0-py3-none-any.whl
- Upload date:
- Size: 406.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
5c8ca225d698966757fd94f5728d1a11a67b8f7de8ba446de9ad86d86a71ec9d
|
|
| MD5 |
744e284fa86f4cd47b54b9f9991f76fe
|
|
| BLAKE2b-256 |
77cdae5f982bcb10b975d9b546d6c461941f9aff626ba5437e9fa8674b08e078
|
Provenance
The following attestation bundles were made for rlsbl-0.84.0-py3-none-any.whl:
Publisher:
publish.yml on smm-h/rlsbl
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
rlsbl-0.84.0-py3-none-any.whl -
Subject digest:
5c8ca225d698966757fd94f5728d1a11a67b8f7de8ba446de9ad86d86a71ec9d - Sigstore transparency entry: 1940963686
- Sigstore integration time:
-
Permalink:
smm-h/rlsbl@144601303b97d126e74fe82f7a975554da3651ab -
Branch / Tag:
refs/tags/v0.84.0 - Owner: https://github.com/smm-h
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@144601303b97d126e74fe82f7a975554da3651ab -
Trigger Event:
release
-
Statement type: