Skip to main content

Release orchestration and project scaffolding for npm, PyPI, and Go

Project description

rlsbl

rlsbl

Release orchestration and project scaffolding CLI for npm, PyPI, and Go. Pure Python, no dependencies.

Install

From PyPI:

uv tool install rlsbl

From npm (wrapper):

npm i -g rlsbl

Quick start

rlsbl scaffold          # set up CI/CD, hooks, changelog
# ... develop, commit ...
rlsbl release minor     # bump, tag, push, create GitHub Release
rlsbl watch <sha>       # monitor CI for that release

Commands

All commands auto-detect registries from project files (package.json, pyproject.toml, go.mod). Use --registry <npm|pypi|go> to target a specific one.

Command Description
release [patch|minor|major] Bump version, commit, tag, push, create GitHub Release
scaffold [--force] [--update] Scaffold CI/CD, hooks, and release infrastructure
status Show version, branch, last tag, changelog coverage, CI presence
check <name> Check name availability on npm/PyPI (parallel variant queries)
config [show|init|migrate|status] Manage project configuration and schema migrations
undo [--yes] Revert the last release (tag, commit, GitHub Release)
discover [--mine] List rlsbl ecosystem projects via GitHub topic search
watch [<sha>] Monitor CI runs for a commit (parallel polling), notify on completion
unreleased [--json] List commits since last tag, report changelog coverage
prs List open pull requests for the current repo
record-gif Record a demo GIF with vhs
pre-push-check Verify CHANGELOG entry exists for the current version

Global flags: --help, --version, --registry <npm|pypi|go>, --no-tag.

Release flow

When you run rlsbl release [patch|minor|major]:

  1. Verifies gh CLI is installed and authenticated
  2. Checks working tree is clean
  3. Reads the current version from the primary project file
  4. Computes the new version; confirms the tag does not already exist
  5. Validates CHANGELOG.md contains a ## <new-version> section
  6. Runs .rlsbl/hooks/pre-release.sh if present (non-zero exit aborts; receives RLSBL_VERSION)
  7. Acquires advisory lockfile (.rlsbl/lock) to prevent concurrent operations
  8. Writes the new version to all detected project files and .rlsbl/version
  9. Adds rlsbl keyword to manifests if ecosystem tagging is enabled
  10. Verifies no unexpected files were modified (race condition guard)
  11. Commits the version bump (uses safegit if available)
  12. Tags and pushes to origin
  13. Creates a GitHub Release with the changelog entry as notes
  14. Adds rlsbl topic to the GitHub repo (if tagging enabled)
  15. Runs .rlsbl/hooks/post-release.sh if present (non-fatal; receives RLSBL_VERSION)
  16. Prints Watch CI: rlsbl watch <sha>

Use --dry-run to preview without changes. Use --yes for non-interactive mode (CI, AI agents).

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 CI/CD for all detected registries
rlsbl scaffold --update     # three-way merge template updates with user customizations
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-release.sh User-customizable pre-release validation
.rlsbl/hooks/post-release.sh User-customizable post-release actions
.git/hooks/pre-push One-liner: exec rlsbl pre-push-check "$@"
.rlsbl/bases/ Three-way merge bases for --update

Three-way merge (--update): Bases are stored at scaffold time. On --update, 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.

Runs config migrations when .rlsbl/config-schema.json exists.

Config management

Schema-driven configuration migration system for projects that ship user-facing config files.

rlsbl config init      # scaffold config migration infrastructure
rlsbl config migrate   # run pending migrations
rlsbl config status    # show migration status
rlsbl config show      # show resolved project configuration

config init creates .rlsbl/config-schema.json and a defaults/ directory. Migrations support deep merge, flat merge, and list-by-key merge strategies with versioned schema tracking and atomic writes.

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 undo         # interactive: confirms before each destructive step
rlsbl undo --yes   # non-interactive: auto-confirms, auto-pushes

Reverts the last release:

  1. Deletes the GitHub Release
  2. Deletes the git tag (remote + local)
  3. Reverts the version bump commit (if HEAD matches the tag)
  4. 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 calls rlsbl pre-push-check, which:

  1. Detects project type (package.json, pyproject.toml, or VERSION)
  2. Extracts the current version
  3. Checks that CHANGELOG.md contains a ## <version> heading
  4. Blocks the push if the entry is missing

To reinstall manually:

echo '#!/bin/sh' > .git/hooks/pre-push && echo 'exec rlsbl pre-push-check "$@"' >> .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

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
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 Run uv publish once, then set up Trusted Publishing 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rlsbl-0.11.2.tar.gz (120.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

rlsbl-0.11.2-py3-none-any.whl (73.3 kB view details)

Uploaded Python 3

File details

Details for the file rlsbl-0.11.2.tar.gz.

File metadata

  • Download URL: rlsbl-0.11.2.tar.gz
  • Upload date:
  • Size: 120.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for rlsbl-0.11.2.tar.gz
Algorithm Hash digest
SHA256 ea2150bf28c6f8ba1539ec4de97656bfdc49475d7abcfe48041a4519b31fc2c9
MD5 65cd6ab3d05e07ca4cab72d55ce27854
BLAKE2b-256 b2d829065f21c2d775b27812dac1884cf989b053cc43106048ddd3787c9a2087

See more details on using hashes here.

Provenance

The following attestation bundles were made for rlsbl-0.11.2.tar.gz:

Publisher: publish.yml on smm-h/rlsbl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rlsbl-0.11.2-py3-none-any.whl.

File metadata

  • Download URL: rlsbl-0.11.2-py3-none-any.whl
  • Upload date:
  • Size: 73.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for rlsbl-0.11.2-py3-none-any.whl
Algorithm Hash digest
SHA256 3ee9e29a876d30e3197c2f7cbff3dd575ccd44510bbc6da5700f47a4da1669d9
MD5 12152e1f6820882252e55a0bb171fc85
BLAKE2b-256 0ccbcca3a64506b29601d53d69b0d67f4a07bc76d0bc6d4186b160d95078c68d

See more details on using hashes here.

Provenance

The following attestation bundles were made for rlsbl-0.11.2-py3-none-any.whl:

Publisher: publish.yml on smm-h/rlsbl

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page