rlsbl v0.113.0 /rlsbl.commands.changelog_cmd
On this page

Changelog subcommands for adding new entries, amending released versions, and generating Markdown changelogs from JSONL sources.

#rlsbl.commands.changelog_cmd

#rlsbl.commands.changelog_cmd

Changelog subcommands for adding new entries, amending released versions, and generating Markdown changelogs from JSONL sources.

#_ResolvedContext

Carries project, releasable, and workspace info for changelog commands.

#is_releasable

python
def is_releasable(self)

#name

python
def name(self)

#get

python
def get(self, key, default=None)

#_resolve_workspace_project

python
def _resolve_workspace_project(project_root)

Resolve the WorkspaceProject for project_root, or None in standalone mode.

Also checks and exits if the project is non-releasable. Returns a _ResolvedContext with releasable info when in explicit mode.

#_check_project_scope

python
def _check_project_scope(resolved_commits, ws_context)

Verify all commits touch files belonging to the project or releasable.

Hard error if any commit does not touch the project's files. In explicit releasable mode, checks against all member projects. Skipped when ws_context is None (standalone mode).

#_entry_ref

python
def _entry_ref(entry, ordinal)

Human-readable reference to an existing entry.

Prefers the entry's stable ULID id (survives unrelated edits to the file). Legacy entries without an id fall back to a 1-based ordinal, noted explicitly so the reader knows it is positional and unstable.

#_check_duplicate_commits

python
def _check_duplicate_commits(existing_entries, new_entry)

Check if any commits in new_entry already appear in existing entries.

Hard error (nothing is written, the process exits) when a commit appears in an existing entry with the SAME user_facing value and type. Allowed (the new entry IS written) when the type/user_facing differ: one commit may legitimately carry, say, both a feature and a fix -- validation bounds this via max_entries_per_commit.

Existing entries are named by their stable ULID id (see _entry_ref) so the message stays valid across unrelated edits to the file.

#_build_entry

python
def _build_entry(flags, resolved_commits)

Build and validate a ChangelogEntry from CLI flags and resolved commits.

Reads user_facing, description, type, and release_type from flags. Validates that user-facing entries have description and type. Returns a validated ChangelogEntry.

#_regenerate_changelog_outputs

python
def _regenerate_changelog_outputs(ws_context, project_root, changes_dir)

Regenerate CHANGELOG.md via the single home resolver.

In explicit releasable mode, writes the canonical CHANGELOG.md into the releasable dir and regenerates the combined root CHANGELOG.md; otherwise writes the project-root CHANGELOG.md. Returns the list of output paths (for auto-commit).

#_resolve_changes_dir

python
def _resolve_changes_dir(ws_context, project_root)

Return the appropriate changes directory based on context.

In explicit releasable mode, returns the releasable's changes dir. Otherwise, returns the per-project changes dir.

#_derive_packages_from_commits

python
def _derive_packages_from_commits(resolved_commits, member_projects)

Derive the list of affected package names from commit file paths.

For each commit, checks which member projects have files touched. Returns a sorted, deduplicated list of project names, or None if there are no member projects to check against.

#_populate_packages_field

python
def _populate_packages_field(entry, resolved_commits, ws_context)

Auto-populate entry.packages in explicit releasable mode.

Releasable-scoped: only the current releasable's members are considered, so a commit touching sub-projects of another releasable does not leak those packages into this releasable's changelog entry. No-op outside explicit releasable mode (non-releasable context or no member projects).

#cmd_add

python
def cmd_add(flags, project_root)

Add a changelog entry.

Appends to unreleased.jsonl. Required flags: --commits, --description, --type (the latter two unless --no-user-facing).

Under --dry-run, all validation runs but nothing is written.

#_cmd_add_commit

python
def _cmd_add_commit(flags, project_root, ws_context, config, dry_run)

Add a changelog entry to unreleased.jsonl.

#cmd_generate

python
def cmd_generate(flags, project_root)

Generate CHANGELOG.md from JSONL changelog files.

#cmd_amend

python
def cmd_amend(flags, project_root)

Amend a released version's JSONL changelog by appending a new entry.

Unlocks the read-only versioned JSONL file, appends the entry, re-locks it, regenerates CHANGELOG.md, and optionally syncs GitHub Release notes.

Required flags:

  • --version: which released version to amend (e.g., "0.39.0")
  • --commits: comma-separated commit hashes

Optional flags:

  • --description and --type: required unless --no-user-facing is set
  • --no-user-facing: mark entry as non-user-facing
  • --no-validate-hashes: skip hash validation (for old/amended commits)

Under --dry-run, all validation runs but nothing is written: no JSONL append, no CHANGELOG.md regeneration, no GitHub Release sync, no commit.

#cmd_edit

python
def cmd_edit(flags, project_root)

Edit an existing changelog entry in unreleased or released JSONL files.

Finds the entry by commit hash, applies field changes, and rewrites the file atomically. For released files, temporarily unlocks the read-only file, regenerates CHANGELOG.md, and syncs GitHub Release notes.

Required flags:

  • --commits: comma-separated commit hashes identifying the target entry

At least one edit flag required:

  • --type: new type value (feature, fix, breaking)
  • --description: new description text
  • --user-facing / --no-user-facing: set user_facing status

Under --dry-run, all validation and entry matching runs but nothing is written: no file rewrite, no CHANGELOG.md regeneration, no GitHub Release sync, no commit.

#_parse_sha_map_lines

python
def _parse_sha_map_lines(lines)

Parse old_sha new_sha lines into a dict.

Accepts the format git's post-rewrite hook emits: each line is <old-sha> <new-sha> (optionally followed by extra fields which are ignored). Blank lines and lines starting with # are skipped. Returns {old_sha: new_sha}.

Hardened against being fed a raw git-filter-repo commit-map directly:

  • The literal old new header row git-filter-repo writes is skipped

rather than ingested as a junk {"old": "new"} mapping.

  • Rows whose target is the all-zeros null SHA (git-filter-repo's marker

for a pruned commit) are dropped with a warning. Keeping them would let a real hash be rewritten to nothing, corrupting the changelog entry.

#cmd_remap

python
def cmd_remap(flags, project_root)

Remap stale commit hashes in all JSONL changelog files.

Reads a mapping of old-SHA to new-SHA from one of three sources (--map-file, --from-journal, --stdin) and applies it to every JSONL file in the project's (or monorepo's) changelog dirs.

At least one source is required; no source is a hard error. Auto-commits with Autogenerated: true trailer.

#_sync_github_release

python
def _sync_github_release(version: str) -> None

Sync GitHub Release notes for a version (best-effort, warns on failure).

#_filter_dirty_files

python
def _filter_dirty_files(paths: list[str], repo_root: str) -> list[str]

Return the subset of paths that git reports as modified/untracked.

Paths are returned as absolute paths. Used by releasable-mode changelog generation where the generated files live outside the member project.

#_get_generated_files

python
def _get_generated_files(project_path: str) -> list[str]

Return paths of files modified or created by generate_changelog.

Checks git status for CHANGELOG.md and .rlsbl/changes/*.md files.

Search