Skip to main content

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

Project description

rlsbl

rlsbl

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

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-init      # scaffold .rlsbl/releases/unreleased.toml
# ... edit bump type, targets ...
rlsbl release           # 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 --target <npm|pypi|go> to target a specific one.

Command Description
check Run project checks
release Bump the project version, validate the changelog, commit, tag, push, and create a GitHub Release. Reads bump type and target selection from .rlsbl/releases/unreleased.toml (create with rlsbl release-init). Supports dry-run preview and non-interactive mode for CI.
release-init Scaffold a .rlsbl/releases/unreleased.toml file by auto-detecting project targets. The generated file contains a default bump type (patch), an include list of all detected targets, and per-target configuration sections for Flutter targets.
status Display the current project version, branch, last release tag, unreleased commit count, and changelog coverage. Outputs plain text by default or structured JSON with the --json flag.
scaffold Generate or update CI/CD workflows, git hooks, changelog, and license files for the detected release target. Use --update for three-way merge preserving customizations, or --force to overwrite all files.
check-name Query npm, PyPI, or other registries to check whether one or more package names are available. Accepts multiple names as positional arguments and respects a configurable delay between checks.
edit-release Sync the GitHub Release notes for a given version with the corresponding CHANGELOG.md entry. Defaults to the current version if none is specified. Use --dry-run to preview changes without updating GitHub.
undo Revert the most recent release by deleting the GitHub Release, removing the git tag from local and remote, and reverting the version bump commit. Requires a manual git push afterward to finalize.
yank Mark a past release as deprecated (soft yank) or delete it (hard yank). Soft yank marks the GitHub Release as pre-release and prepends a deprecation notice. Hard yank deletes the release entirely while preserving the git tag.
discover Search GitHub for repositories tagged with the rlsbl topic and list them. Use --mine to filter results to only your own repositories. Requires the gh CLI to be authenticated.
watch Poll GitHub Actions CI workflow runs for a specific commit SHA and report pass or fail status. Defaults to HEAD if no SHA is provided. Useful after rlsbl release to monitor the publish pipeline.
pre-push-check Verify that CHANGELOG.md contains an entry matching the current project version. Designed to run as a git pre-push hook to prevent pushing releases without documented changes.
prs List all open pull requests for the current repository using the GitHub CLI. Shows PR number, title, author, and branch for a quick overview of pending work.
unreleased List commits between the latest release tag and HEAD, and check whether each has a corresponding changelog entry. Outputs a coverage report in plain text or JSON to help prepare the next release.
targets List all release targets detected in the current project directory, showing which ecosystems (npm, PyPI, Go, Cargo, etc.) are active based on manifest files found.
record-gif Record an animated GIF demo of rlsbl commands using the vhs terminal recorder. Configurable width, height, font size, and duration for consistent, reproducible demo recordings.
migrate Run pending configuration migrations to update .rlsbl config files to the latest schema. Use --dry-run to preview changes without applying, or --status to see which migrations are pending.
deploy Run the configured deployment pipeline for the project. Supports named deploy targets, dry-run preview of what would be deployed, and a --force flag to override branch restrictions.
commit Commit one or more files with an Autogenerated trailer, marking the commit as machine-generated so it is automatically exempted from changelog coverage checks.
changelog Structured changelog management using JSONL entries. Add and generate CHANGELOG.md from per-commit changelog entries stored in unreleased.jsonl for precise, auditable release notes.
changelog add Append a structured changelog entry to the project's unreleased.jsonl file. Each entry includes a human-readable description, an entry type (feature, fix, or breaking), and optional commit hashes linking it to specific changes. The file is auto-committed unless --no-commit is passed. Use --no-user-facing to mark internal changes that should not appear in the published changelog.
changelog generate Compile all validated JSONL changelog entries into a formatted CHANGELOG.md file. Groups entries by type (features, fixes, breaking changes) under the appropriate version heading, preserving existing changelog content for previous releases. Use --dry-run to preview the generated Markdown output without writing to disk, which is useful for reviewing before committing.
changelog amend Append a changelog entry to a released version's JSONL file. Temporarily unlocks the read-only file, appends the entry, re-locks it, regenerates CHANGELOG.md, and syncs GitHub Release notes. Use --no-resolve to skip hash validation for old or amended commits.
monorepo Manage monorepo workspaces with multiple independently-versioned projects. Initialize workspaces, add or remove projects, sync CI workflows, check name availability, and analyze dependency graphs. Provides 10 monorepo subcommands and supports all 14 release targets in a single workspace.toml.
monorepo init Create a new monorepo workspace by generating the .rlsbl-monorepo directory and an empty workspace.toml configuration file at the current directory. This must be run at the repository root before adding individual projects with the add subcommand. Each workspace tracks multiple independently-versioned projects that share a single git repository.
monorepo add Register a project directory in the monorepo workspace.toml configuration. The path argument specifies the project's location relative to the repo root. Optionally set a display name, target registry for publishing, glob patterns for change detection, a subtree remote URL for split publishing, inter-project dependencies, and a library flag to mark shared code packages.
monorepo remove Unregister a project from the monorepo workspace.toml by its path. This removes the project entry from the workspace configuration file but does not delete any files, directories, or git history on disk. The project's code remains intact and can be re-added later with the add subcommand if needed.
monorepo list Display all projects registered in the monorepo workspace.toml file. For each project, shows the project name, relative path from the repo root, target registry for publishing, and any configured options such as watch patterns, subtree remotes, inter-project dependencies, and whether the project is marked as a library.
monorepo sync Copy and merge CI workflow files from each project's individual scaffold into the shared .github/workflows directory at the repository root. This ensures that every project in the workspace has its publish and test pipelines properly configured as GitHub Actions workflows, even when projects use different target registries or have custom workflow steps.
monorepo status Show the current version, last release tag, and number of unreleased commits for every project in the monorepo workspace. Provides a quick overview of which projects have pending changes and are ready for their next release. Projects with zero unreleased commits are shown as up-to-date.
monorepo check-names Check package name availability on a target registry for all projects in the monorepo workspace. Queries the registry API for each project name and reports whether it is available or already taken. Supports optional prefix and suffix arguments to test naming conventions like scoped packages, with a configurable delay between registry queries to avoid rate limiting.
monorepo release-order Compute and display the topological release order for all projects in the monorepo workspace based on their declared depends-on relationships. Projects with no dependencies are listed first, followed by projects that depend on them, ensuring each project is released only after its dependencies. Detects and reports circular dependency errors.
monorepo outdated Scan all projects in the monorepo workspace for intra-workspace dependencies that reference older versions than what is currently available in the workspace. Lists each outdated dependency with the referenced version and the latest available version, helping identify which downstream projects need a version bump after upstream releases.
monorepo snapshot Generate a committed JSON artifact at .rlsbl-monorepo/snapshot.json summarizing all packages, versions, dependencies, and graph structure. Use --check to verify the snapshot is up-to-date without regenerating it (exits 1 if stale).
monorepo graph Export the monorepo dependency graph in JSON, DOT (Graphviz), or indented text tree format. Supports filtering by a root package (transitive deps) or reverse package (transitive rdeps), with optional depth limiting. Use --output to write to a file instead of stdout.
monorepo impact Analyze the impact of changes to a package, file, or git diff range on the monorepo dependency graph. Shows direct and transitive dependents, test scope, and release candidates. Supports package names, file paths, and --since for git-based change detection.
monorepo release Execute a batch release of multiple monorepo packages in topological order. Reads package configurations from .rlsbl-monorepo/releases/unreleased.toml. Each package is released sequentially using the single-package release flow, with leaves (no dependencies) released first. Supports --dry-run, --yes, --allow-dirty flags.
dev Developer utilities for locally working with rlsbl projects, including editable installs that mirror the project's release target (pypi -> uv tool install -e, npm -> npm link, go -> go install).
dev install Install the project locally for development using the detected target's editable install command. --global (default) installs system-wide across 8 supported targets (pypi, npm, go, cargo, zig, swift, deno, hex), while --venv installs into the project's local environment instead. In monorepo mode, pair with --all, --include, or --exclude. Use --uninstall to reverse a previous install.

Global flags: --help, --version, --dry-run, --yes, --quiet.

Release flow

When you run rlsbl release:

  1. Reads .rlsbl/releases/unreleased.toml for bump type (patch/minor/major) and target selection
  2. Verifies gh CLI is installed and authenticated
  3. Checks working tree is clean (use --allow-dirty to override)
  4. Fetches origin and verifies local branch is not behind remote
  5. Reads the current version from the primary project file
  6. Computes the new version; confirms the tag does not already exist
  7. Validates JSONL changelog via the check system
  8. Runs .rlsbl/hooks/pre-checks.sh if present (user-owned, non-zero aborts)
  9. Runs built-in tests and lint
  10. Runs .rlsbl/hooks/pre-release.sh if present (scaffold-managed, non-zero aborts)
  11. Acquires advisory lockfile (.rlsbl/lock) to prevent concurrent operations
  12. Writes the new version to all detected project files and .rlsbl/version
  13. Commits the version bump (uses safegit if available)
  14. Tags and pushes to origin
  15. Finalizes JSONL changelog (renames unreleased.jsonl, generates CHANGELOG.md)
  16. Creates a GitHub Release with the changelog entry as notes
  17. Runs secondary release targets (e.g., docs via selfdoc)
  18. Runs .rlsbl/hooks/post-release.sh if present (non-fatal)
  19. 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 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-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 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.

Customizing CI without conflicts: Instead of editing ci.yml or publish.yml (which can produce merge conflicts on --update), put extra jobs in a separate workflow file scaffold never touches:

  • .github/workflows/ci-custom.yml -- runs alongside ci.yml
  • .github/workflows/publish-custom.yml -- runs alongside publish.yml

See docs/ci-customization.md for an example.

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

Check system

28 project checks organized by tag:

Tag Checks Description
project 5 Version, name, license, description consistency; lockfile presence
release 4 Local/remote tag, GitHub Release, branch sync
changelog 8 Hash resolution, range, coverage, orphans, schema, batch limits, entry
workspace 5 CI router, CI sync, targets, unregistered, stale entries
quality 1 Library lint
(untagged) 5 Layer violations, dependency validation (unused/undeclared/stale)
rlsbl check --all              # run all 28 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 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

Monorepo

Manage multi-package workspaces with rlsbl monorepo:

  • monorepo init / monorepo add / monorepo remove -- workspace management
  • monorepo sync -- synchronize CI workflows
  • monorepo graph -- export dependency graph (JSON, DOT, text)
  • monorepo snapshot -- committed JSON artifact of workspace state
  • monorepo impact -- change analysis across the dependency graph
  • monorepo release -- 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
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

rlsbl-0.41.7.tar.gz (666.8 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.41.7-py3-none-any.whl (244.6 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for rlsbl-0.41.7.tar.gz
Algorithm Hash digest
SHA256 66d85361eecb9fb6439d7041661365019bcc6373fb8363595928cf1d8350ca78
MD5 d20757cac839dd68a3d21796df68e064
BLAKE2b-256 99fc04afd9aa853bfb740cb5682b1c86236e8012c0631cc053d9c4b65292cf0f

See more details on using hashes here.

Provenance

The following attestation bundles were made for rlsbl-0.41.7.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.41.7-py3-none-any.whl.

File metadata

  • Download URL: rlsbl-0.41.7-py3-none-any.whl
  • Upload date:
  • Size: 244.6 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.41.7-py3-none-any.whl
Algorithm Hash digest
SHA256 cc89ba0563f0e55c8a62b57bffe4c229d08d4b96d495913cccc947eaf2b7351f
MD5 ee394adf3eca340d4cd7662051764dfa
BLAKE2b-256 bdaf8d93aa6c3463ed006585a7c14ae03088f93ea8dfab92382cb6d14b1b17ed

See more details on using hashes here.

Provenance

The following attestation bundles were made for rlsbl-0.41.7-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