rlsbl 0.117.2 → 0.118.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +86 -54
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -29,7 +29,7 @@ rlsbl scaffold # set up CI/CD, hooks, changelog, pipelines
|
|
|
29
29
|
# ... develop, commit ...
|
|
30
30
|
rlsbl release init # scaffold .rlsbl/releases/unreleased.toml
|
|
31
31
|
# ... edit bump type, targets, pipelines ...
|
|
32
|
-
rlsbl release run # bump,
|
|
32
|
+
rlsbl release run # bump, push the candidate, wait for CI, tag, publish
|
|
33
33
|
rlsbl watch <sha> # monitor CI for that release
|
|
34
34
|
```
|
|
35
35
|
|
|
@@ -40,7 +40,7 @@ All commands auto-detect targets (versioning) from project files (`package.json`
|
|
|
40
40
|
| Command | Description |
|
|
41
41
|
| --- | --- |
|
|
42
42
|
| `check` | Run project checks registered via the check framework and report results |
|
|
43
|
-
| `status` | Display the current project version, branch,
|
|
43
|
+
| `status` | Display the current project version, branch, latest release, unreleased commit count, and changelog coverage. The latest release comes from the project's release archives and is annotated when this checkout does not contain it. Outputs plain text by default or structured JSON with the --json flag. |
|
|
44
44
|
| `scaffold` | Generate or update CI/CD workflows, git hooks, changelog, and license files. Safe to run repeatedly -- three-way merges template changes with your customizations. Existing files with no stored merge base are healed from their last scaffold commit before merging. |
|
|
45
45
|
| `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. |
|
|
46
46
|
| `claim-name` | Claim a name on a package registry by publishing a minimal placeholder package. Runs check-name first, then publishes if available. |
|
|
@@ -48,7 +48,7 @@ All commands auto-detect targets (versioning) from project files (`package.json`
|
|
|
48
48
|
| `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. |
|
|
49
49
|
| `pre-push-check` | Removed. This command no longer performs any check: it always exits 1 with instructions. The pre-push hook now runs `rlsbl check --tag prepush` instead, so a repo whose hook still calls pre-push-check needs `rlsbl scaffold` to regenerate it. |
|
|
50
50
|
| `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. |
|
|
51
|
-
| `unreleased` | List commits between the
|
|
51
|
+
| `unreleased` | List the commits between the release this checkout is anchored to 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. |
|
|
52
52
|
| `targets` | List all release targets detected in the current project directory, showing which ecosystems (npm, PyPI, Go, etc.) are active based on manifest files found. |
|
|
53
53
|
| `deploy` | Run the configured deployment pipeline for the project. Supports named deploy targets and dry-run preview of what would be deployed. Branch restrictions are always enforced. |
|
|
54
54
|
| `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. |
|
|
@@ -61,69 +61,68 @@ All commands auto-detect targets (versioning) from project files (`package.json`
|
|
|
61
61
|
| `release undo` | Revert a release. Without --version, reverts the latest release (deletes GitHub Release, removes git tag, reverts version bump commit). With --version, reverts a non-latest release if it is provably unpublished (probes registries for evidence, deletes GitHub Release + tag only, un-finalizes changelog). |
|
|
62
62
|
| `release deprecate` | Mark a past release as deprecated. Sets the GitHub Release pre-release flag and prepends a deprecation notice to the release notes. Use --reason to explain why and --use to suggest a replacement version. |
|
|
63
63
|
| `release yank` | Remove a published version from package registries. Probes each configured target's registry to determine publication status, then executes registry-specific removal: npm deprecate, Go retract, or PyPI manual checklist. Also marks the GitHub Release as pre-release with a yank notice. |
|
|
64
|
-
| `release scrub` | Scrub sensitive content from git history and update release metadata to match the rewritten commits. Supports 3 modes: match (--pattern), file (--file), or recipe (--recipe). After rewriting, remaps commit hashes in JSONL changelog files, regenerates CHANGELOG.md, force-pushes, and
|
|
65
|
-
| `release reconcile` | Reconcile release metadata with
|
|
66
|
-
| **changelog** | Structured changelog management using JSONL entries
|
|
64
|
+
| `release scrub` | Scrub sensitive content from git history and update release metadata to match the rewritten commits. Supports 3 modes: match (--pattern), file (--file), or recipe (--recipe). After rewriting, remaps commit hashes in JSONL changelog files, regenerates CHANGELOG.md, force-pushes, re-points the tags, and rewrites each tag's GitHub Release document in place. A Release is never deleted, so a failure mid-step leaves the previous document standing rather than a tag with no Release at all. |
|
|
65
|
+
| `release reconcile` | Reconcile this project's published release metadata with what its own records say it released: push the refs origin is missing, re-point the ones a recorded rewrite moved, and create the GitHub Releases that are absent. Merges four explanation sources -- safegit's rewrite journal, the release ledger's anchors, the lineage records, and the committed scrub archives -- into one preview whose verdicts are materialize, already-correct, re-point-with-lease, refuse-foreign, or refuse-identity-mismatch. Fail-closed: one ref origin holds that no record explains aborts the whole reconcile, and nothing anywhere is repaired. Consent is file-driven: --plan writes the plan, --apply performs it. |
|
|
66
|
+
| **changelog** | Structured changelog management using JSONL entries, each typed feature, fix or breaking. Add and generate CHANGELOG.md from per-commit changelog entries stored in unreleased.jsonl for precise, auditable release notes. |
|
|
67
67
|
| `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 by default. Use --no-user-facing to mark internal changes that should not appear in the published changelog. |
|
|
68
68
|
| `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. |
|
|
69
69
|
| `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-validate-hashes to skip hash validation for old or amended commits. |
|
|
70
70
|
| `changelog edit` | Modify an existing changelog entry in unreleased or released JSONL files. Finds the entry by commit hash or entry ID, applies field changes (type, description, user-facing status), and rewrites the file atomically. For released files, temporarily unlocks the read-only file, regenerates CHANGELOG.md, and syncs GitHub Release notes. |
|
|
71
71
|
| `changelog remap` | Remap stale commit hashes in JSONL changelog files using a mapping of old SHAs to new SHAs. Reads the mapping from a file (--map-file), the safegit rewrite journal (--from-journal), or stdin (--stdin). At least one source is required. Auto-commits with Autogenerated trailer. |
|
|
72
|
-
| **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.
|
|
73
|
-
| `monorepo init` | Create a new monorepo workspace by generating the .rlsbl-monorepo directory and
|
|
74
|
-
| `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.
|
|
72
|
+
| **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 17 monorepo subcommands: init, add, remove, list, sync, status, check-names, outdated, snapshot, snapshot-check, mirror, graph, impact, extract, absorb, cleanup, rename-releasable. Plus 1 subgroup: release. Supports all 17 release targets in a single workspace.toml (the app help enumerates them). |
|
|
73
|
+
| `monorepo init` | Create a new monorepo workspace by generating the .rlsbl-monorepo directory and a workspace.toml at the current directory, carrying the mandatory root member whose kind you declare and a [[releasables]] section. 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. |
|
|
74
|
+
| `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. Optional settings cover display name, target registry, inter-project dependencies, releasable membership, registry identity, and flags marking the project as a shared library or a dev-only leaf. The mirror destination is not among them: it is a releasable-level key, declared in workspace.toml beside the releasable it binds. What CI reacts to is not among them: the router's paths filters are derived from the workspace, never declared per project. |
|
|
75
75
|
| `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. |
|
|
76
|
-
| `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
|
|
76
|
+
| `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 subtree remotes, inter-project dependencies, and whether the project is marked as a library. |
|
|
77
77
|
| `monorepo sync` | Inline every project's CI jobs into a single generated ci-router.yml (and publish jobs into publish.yml) in the shared .github/workflows directory at the repository root. Jobs are inlined rather than routed via reusable-workflow calls because GitHub rejects workflows that reference 20 or more reusable workflows. Stale per-project workflow copies at the root are removed via saferm. |
|
|
78
78
|
| `monorepo status` | Show the current version, last release tag, and changelog coverage for every project in the monorepo workspace. Coverage is the real JSONL figure -- the commits since the project's last tag, scoped to the project and minus the exempt ones, rendered covered/tracked with an (N exempted) suffix, or 'no changelog' when the project has no changes directory. Provides a quick overview of which projects have pending changes and are ready for their next release. |
|
|
79
79
|
| `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. |
|
|
80
80
|
| `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. |
|
|
81
81
|
| `monorepo snapshot` | Regenerate the committed JSON artifact at .rlsbl-monorepo/snapshot.json summarizing all packages, versions, dependencies, and graph structure, and commit it. Verifying without regenerating is a separate command, `rlsbl monorepo snapshot-check`. Under --dry-run the artifact is computed but neither written nor committed, and the preview names both steps. |
|
|
82
82
|
| `monorepo snapshot-check` | Verify that .rlsbl-monorepo/snapshot.json matches the workspace it describes, without regenerating it. Exits 1 when the artifact is stale or missing. This is the read-only half of the former `monorepo snapshot --check` flag; `rlsbl monorepo snapshot` is the half that writes. |
|
|
83
|
-
| `monorepo mirror` | Reconcile a monorepo project's subtree mirror toward its desired state. The mirror is a tool-owned, derived artifact: it observes the remote, then converges it to exactly one scaffold commit atop the current deterministic subtree split, force-pushing (with lease) as the routine write. A tripwire refuses to touch a mirror carrying foreign (hand-authored) commits. Use --dry-run to print a plan (converged, behind, scaffold-missing, contract-violated, or virgin) without writing. |
|
|
83
|
+
| `monorepo mirror` | Reconcile a monorepo project's subtree mirror toward its desired state. The mirror is a tool-owned, derived artifact: it observes the remote, then converges it to exactly one scaffold commit atop the current deterministic subtree split, force-pushing (with lease) as the routine write. A tripwire refuses to touch a mirror carrying foreign (hand-authored) commits. Use --dry-run to print a plan (converged, scaffold-stale, behind, scaffold-missing, contract-violated, lineage-undetermined, or virgin) without writing. |
|
|
84
84
|
| `monorepo graph` | Export the monorepo dependency graph as DOT (Graphviz) or an indented text tree; the framework-owned --json yields the same graph as a structured document. Supports filtering by a root package (transitive deps) or reverse package (transitive rdeps), with optional depth limiting. Use --output to write the rendering to a file instead of stdout. |
|
|
85
85
|
| `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 as a human report, or as a structured document under the framework-owned --json. Supports package names, file paths, and --since for git-based change detection. |
|
|
86
|
-
| `monorepo extract` | Extract a
|
|
87
|
-
| `monorepo absorb` | Absorb an external repository
|
|
88
|
-
| `monorepo
|
|
89
|
-
| `monorepo cleanup` | Remove per-package release-state residue from releasable member packages: .rlsbl/changes/, .rlsbl/releases/, .rlsbl/bases/, .rlsbl/lint/, .rlsbl/version, per-package CHANGELOG.md, and .rlsbl/config.json when identical to the releasable-level config. Per-package hooks/ directories are preserved (live feature), and members whose path is the workspace root are exempt. Deletions go through saferm (audit trail, recoverable) and are committed automatically. Requires an explicit-mode workspace ([[releasables]] in workspace.toml). Detect residue first with `rlsbl check --name releasable-residue`. |
|
|
90
|
-
| `monorepo migrate-releasable` | Migrate a releasable from per-package release state to the releasable model. Detects current state, consolidates per-package changelogs and versions into the releasable directory, creates a releasable-format migration tag, and removes orphaned per-package .rlsbl/changes/ and .rlsbl/releases/ directories. Requires the workspace to be in explicit mode (with [[releasables]] in workspace.toml). |
|
|
86
|
+
| `monorepo extract` | Extract a releasable out of the monorepo into its own repository. The releasable is the portable unit: its members' history is filtered into a new repo (hoisted to the root when it has a single member), its whole release state -- version, changelog, release archives with their anchors, config and hooks -- is transplanted, the anchors and changelog hashes are remapped onto the rewritten commits, and its tags are translated to the destination's scheme with one boundary alias at the current version. The source loses the members, the releasable and its state in one commit, with the CI router re-synced and the snapshot regenerated. Refuses a mirrored releasable, one owning the root member, and a remaining member that depends on a departing one (naming the rewrite command that severs the edge). Use --dry-run to see the whole plan first. |
|
|
87
|
+
| `monorepo absorb` | Absorb an external repository into this workspace as a releasable. The source's history is rewritten under the destination path and merged in (full history, rewritten paths), its version tags are imported under the destination's tag scheme with one boundary alias at the current version, and its whole release state -- changelog, release archives with their anchors, config and version -- moves into a releasable's state directory with every hash and anchor remapped onto the rewritten commits. Without --releasable a singleton releasable named after the member is created, with its tag_format written explicitly. Nothing is fetched as a tag, so a tag this repository already owns is never moved or deleted; a colliding tag name or version is refused before anything is written. A crashed run is completed by re-running it. Use --dry-run to see the whole plan first. |
|
|
88
|
+
| `monorepo cleanup` | Remove per-package release-state residue from releasable member packages: .rlsbl/changes/, .rlsbl/releases/, .rlsbl/bases/, .rlsbl/lint/, .rlsbl/version, per-package CHANGELOG.md, and .rlsbl/config.json when identical to the releasable-level config. Per-package hooks/ directories are preserved (live feature), and members whose path is the workspace root are exempt. Deletions go through saferm (audit trail, recoverable) and are committed automatically. Detect residue first with `rlsbl check --name releasable-residue`. |
|
|
91
89
|
| `monorepo rename-releasable` | Rename a releasable group. Rewrites the [[releasables]] name and every member's releasable field in workspace.toml (preserving comments), moves the state directory, drops the stale changelog validation cache, re-runs monorepo sync, and commits it all as one commit. When tag_format contains {name}, a boundary alias tag for the current version is created at the old tag's commit and pushed; historical releases stay under the old prefix. Idempotent: re-running heals a crash between the commit and the tag push. |
|
|
92
90
|
| **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). |
|
|
93
|
-
| `dev install` | Install the project locally for development by running each detected target's own install command. --target is required and names the install mode
|
|
91
|
+
| `dev install` | Install the project locally for development by running each detected target's own install command. --target is required and names the install mode: global installs onto the machine (pypi via `uv tool install -e`, npm via `npm link`), venv installs into the project's local environment instead; a target that does not support the chosen mode is skipped with a reason. --target global is supported by 7 targets: npm, pypi, go, swift, hex, deno, zig. --target venv is supported by 4 targets: npm, pypi, hex, deno. --uninstall reverses a previous install on 3 targets: npm, pypi, deno. In monorepo mode, pair with --all, --include, or --exclude. |
|
|
94
92
|
| `dev sync` | Overlay local editable checkouts of sibling projects onto this project's locked environment. Reads dev-sources.toml.local-only for overlay entries, runs uv sync --inexact excluding overlaid packages, then uv pip install -e per entry. Requires UV_NO_SYNC=1 in the environment to prevent bare uv run from reverting overlays. |
|
|
95
93
|
| `dev status` | Report the state of local dev-sync overlays: for each package recorded in the dev-overlays sentinel, show its declared editable checkout path and version alongside the venv's actual install (editable at the expected path, WIPED back to a registry wheel, or missing entirely). Exits 1 if any overlay drifted so scripts and pre-run guards can detect a silent wipe by a bare uv sync or uv run; exits 0 when all overlays are intact or none are declared. |
|
|
94
|
+
| **rewrite** | Sweeping rewrites of the current working tree, each previewed before it is performed. Every command in this group observes the tree, reports a per-file plan with occurrence counts, and refuses to apply when a count moved between the preview and the write. |
|
|
95
|
+
| `rewrite go-module-path` | Rename a Go module path across the repository. Rewrites the module-path tokens in every go.mod (the module directive plus any require, replace, exclude or retract reference from a nested module) and every Go import site under the old path, located by the tree-sitter import scanner and rewritten line-anchored. Containment is boundary-aware, so a neighbouring module whose path merely begins with the same letters is left alone. Comments, non-Go files and vendored trees are never touched. Use --dry-run to print the per-file plan with occurrence counts. |
|
|
96
|
+
| `rewrite uv-path-sources` | Convert path- and workspace-sourced Python dependencies into registry constraints floored at the version uv.lock resolves. Covers [project].dependencies, every [project.optional-dependencies] extra and every PEP 735 [dependency-groups] group, and deletes the matching [tool.uv.sources] entry so it stops overriding the new constraint. Each converted name is added to internal_dep_floors in .rlsbl/config.json. A locked version that is not published on PyPI is a hard error naming the remedy (release that dependency first), and so is a registry probe that fails to answer. Use --dry-run to print the per-dependency plan with entry counts. |
|
|
96
97
|
|
|
97
98
|
Global flags: `--help`, `--version`, `--dry-run`, `--approve-consequential`, `--quiet`, `--verbose`.
|
|
98
99
|
|
|
99
100
|
## Release flow
|
|
100
101
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
18. Runs `.rlsbl/hooks/post-release.sh` if present (non-fatal)
|
|
121
|
-
19. Prints `Watch CI: rlsbl watch <sha>`
|
|
102
|
+
`rlsbl release run` reads `.rlsbl/releases/unreleased.toml` for the bump type, the
|
|
103
|
+
description and the target selection, then:
|
|
104
|
+
|
|
105
|
+
1. Verifies `gh` auth and a clean working tree (`--allow-dirty` accepts a dirty one), computes the new version and confirms its tag does not exist
|
|
106
|
+
2. Validates the JSONL changelog and regenerates CHANGELOG.md from it
|
|
107
|
+
3. Runs `.rlsbl/hooks/pre-checks.sh` (user-owned), the strictcli schema dump, `selfdoc gen` and `selfdoc check`, the built-in tests and lint, and `.rlsbl/hooks/pre-release.sh` (scaffold-managed) -- any non-zero aborts
|
|
108
|
+
4. Writes the new version to every detected target file and `.rlsbl/version`, commits it with the tag string as the message, and pushes that commit **untagged**: the release candidate
|
|
109
|
+
5. Waits in-process for the repository's own push-triggered CI to conclude on that exact commit
|
|
110
|
+
6. Finalizes the changelog (renames `unreleased.jsonl` to the version's file, opens a fresh one, regenerates CHANGELOG.md), archives the release file, tags the **CI-verified commit**, pushes the finalization commits and the tags, and creates the GitHub Release with the version's changelog section as notes
|
|
111
|
+
7. Uploads assets, runs each pipeline's `publish` (configured in `.rlsbl/config.json`), deploys, runs `.rlsbl/hooks/post-release.sh` (non-fatal), and prints `Watch CI: rlsbl watch <sha>`
|
|
112
|
+
|
|
113
|
+
Everything above the candidate push is reversible; everything below it is not. A red
|
|
114
|
+
CI verdict therefore leaves nothing behind but a commit on the branch -- no tag, no
|
|
115
|
+
GitHub Release, no finalized changelog, nothing on any registry. Fix forward on the
|
|
116
|
+
release branch and `rlsbl release resume` completes the *same* version; a failed
|
|
117
|
+
release never burns it.
|
|
118
|
+
|
|
119
|
+
The step-by-step pipeline, including what each step does in monorepo and releasable
|
|
120
|
+
mode, is in [docs/release-workflow.md](docs/release-workflow.md).
|
|
122
121
|
|
|
123
122
|
Use `--dry-run` to preview without changes: mutating operations are recorded and printed as a
|
|
124
123
|
would-do log rather than performed. A small set of commands declares itself `consequential`
|
|
125
124
|
(`release run`/`resume`/`retry`/`undo`/`deprecate`/`yank`/`scrub`/`reconcile`, `claim-name`,
|
|
126
|
-
`deploy`, `monorepo release run`/`mirror`/`absorb`/`extract
|
|
125
|
+
`deploy`, `monorepo release run`/`mirror`/`absorb`/`extract`) and asks
|
|
127
126
|
for confirmation before running; pass `--approve-consequential` in non-interactive contexts
|
|
128
127
|
(CI, AI agents), where the prompt is a hard error instead. Every other command runs without
|
|
129
128
|
asking.
|
|
@@ -137,9 +136,10 @@ Pre-release versions (e.g. `1.0.0-beta.1`) are supported.
|
|
|
137
136
|
## Scaffold
|
|
138
137
|
|
|
139
138
|
```
|
|
140
|
-
rlsbl scaffold
|
|
141
|
-
rlsbl scaffold --
|
|
142
|
-
rlsbl scaffold --no-auto-commit
|
|
139
|
+
rlsbl scaffold # create or update CI/CD for all detected registries
|
|
140
|
+
rlsbl scaffold --target plain # also cover a registry auto-detection cannot find
|
|
141
|
+
rlsbl scaffold --no-auto-commit # skip auto-commit of scaffolded files
|
|
142
|
+
rlsbl scaffold --no-auto-tag # skip the rlsbl GitHub topic tag on this run
|
|
143
143
|
```
|
|
144
144
|
|
|
145
145
|
Created files are committed automatically by default.
|
|
@@ -161,7 +161,7 @@ Created files are committed automatically by default.
|
|
|
161
161
|
|
|
162
162
|
**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.
|
|
163
163
|
|
|
164
|
-
**User-owned files** (CHANGELOG.md, LICENSE, hooks) are never overwritten
|
|
164
|
+
**User-owned files** (CHANGELOG.md, LICENSE, `.rlsbl/hooks/pre-checks.sh`, `.rlsbl/changes/unreleased.jsonl`) are never overwritten by a re-scaffold: there is no flag that makes scaffold clobber them.
|
|
165
165
|
|
|
166
166
|
**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:
|
|
167
167
|
|
|
@@ -174,17 +174,24 @@ See [docs/ci-customization.md](docs/ci-customization.md) for an example.
|
|
|
174
174
|
|
|
175
175
|
## Check system
|
|
176
176
|
|
|
177
|
-
rlsbl includes
|
|
177
|
+
rlsbl includes 83 checks across 9 tags.
|
|
178
178
|
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
|
182
|
-
|
|
|
183
|
-
| `
|
|
184
|
-
| `
|
|
185
|
-
| `
|
|
186
|
-
| `
|
|
187
|
-
|
|
|
179
|
+
Checks are grouped by tag -- `--tag` runs one family, `--name` runs a single check, and `--all` runs everything, including the checks that carry no tag:
|
|
180
|
+
|
|
181
|
+
| Tag | Checks |
|
|
182
|
+
| --- | --- |
|
|
183
|
+
| `project` | 25 |
|
|
184
|
+
| `preflight` | 20 |
|
|
185
|
+
| `workspace` | 19 |
|
|
186
|
+
| `quality` | 16 |
|
|
187
|
+
| `changelog` | 11 |
|
|
188
|
+
| `preflight-changelog` | 9 |
|
|
189
|
+
| `prepush` | 6 |
|
|
190
|
+
| `release` | 6 |
|
|
191
|
+
| `maven` | 1 |
|
|
192
|
+
| (untagged) | 4 |
|
|
193
|
+
|
|
194
|
+
What each tag's checks actually verify, one row per check with its severity, is in [docs/checks.md](docs/checks.md), which also says which tags the release pipeline runs on its own.
|
|
188
195
|
|
|
189
196
|
```
|
|
190
197
|
rlsbl check --all # run all checks
|
|
@@ -208,6 +215,31 @@ Reverts the last release:
|
|
|
208
215
|
|
|
209
216
|
On partial failure, prints a structured summary table with remediation commands for each failed step.
|
|
210
217
|
|
|
218
|
+
## Who writes which ref namespace
|
|
219
|
+
|
|
220
|
+
Each namespace has one routine writer -- the flow that puts refs there while
|
|
221
|
+
shipping -- and a named set of repair and retraction surfaces for correcting or
|
|
222
|
+
withdrawing what already shipped:
|
|
223
|
+
|
|
224
|
+
| Namespace | Routine writer |
|
|
225
|
+
|-----------|------------|
|
|
226
|
+
| `origin` branch heads | Releases. `rlsbl release run` pushes the untagged candidate and, after CI, the finalization commits; there is no dev-branch push path. |
|
|
227
|
+
| `origin` tags and their GitHub Releases | The release's tag step, repaired by `rlsbl release reconcile` when a rewrite or a partial release left them wrong -- both composing the Release through one module, so the notes and the `rlsbl-ci-sha` marker match either way. |
|
|
228
|
+
| A subtree mirror's `main` | The mirror reconciler's converge (`rlsbl monorepo mirror`, and the release's mirror step, which calls the same code). Force-with-lease is its routine write; a commit it cannot account for is a contract violation it refuses. |
|
|
229
|
+
| A subtree mirror's tags and their GitHub Releases | The mirror publication module, driven by the release's mirror step or by `rlsbl monorepo mirror` materializing a version the mirror is missing. A mirror's scaffold renders no publish workflow and every convergence sweeps one that arrived another way, so the mirror never releases itself. |
|
|
230
|
+
| Rewritten history on any of the above | `rlsbl release scrub`, the one sanctioned rewrite: it force-pushes, remaps the changelog hashes, re-points the tags and rewrites each tag's Release document in a single pass -- in place, never delete-then-create. |
|
|
231
|
+
|
|
232
|
+
The repair and retraction surfaces, in full: `rlsbl release undo` (deletes the
|
|
233
|
+
Release and the tag, reverts the version-bump commit and pushes the branch),
|
|
234
|
+
`rlsbl release reconcile` (re-pushes moved tags, writes their Release documents
|
|
235
|
+
in place and creates only the absent ones),
|
|
236
|
+
`rlsbl release scrub` (the rewrite), `rlsbl release edit` (re-syncs one
|
|
237
|
+
Release's notes), `rlsbl release deprecate` and `rlsbl release yank` (rewrite a
|
|
238
|
+
Release body and set its pre-release flag; `yank` also performs the registry's
|
|
239
|
+
removal), `rlsbl changelog amend` and `rlsbl changelog edit` (re-sync a released
|
|
240
|
+
version's Release notes), and `rlsbl monorepo rename-releasable` (pushes one
|
|
241
|
+
boundary alias tag). A write from anywhere else is not rlsbl's.
|
|
242
|
+
|
|
211
243
|
## Pre-push hook
|
|
212
244
|
|
|
213
245
|
The `.git/hooks/pre-push` hook captures push refs from git and runs `rlsbl check --tag prepush`, which enforces:
|
|
@@ -231,7 +263,7 @@ To disable:
|
|
|
231
263
|
|
|
232
264
|
| Method | Scope |
|
|
233
265
|
|--------|-------|
|
|
234
|
-
| `--no-tag` flag | Single invocation |
|
|
266
|
+
| `--no-auto-tag` flag | Single invocation |
|
|
235
267
|
| `{"tag": false}` in `.rlsbl/config.json` | This project |
|
|
236
268
|
| `{"tag": false}` in `~/.rlsbl/config.json` | All projects |
|
|
237
269
|
|