rlsbl v0.113.0 /rlsbl.release_file
On this page

Release file reader and validator for file-based releases, parsing .rlsbl/releases/unreleased.toml for bump type and release metadata.

#rlsbl.release_file

#rlsbl.release_file

Release file reader and validator for file-based releases, parsing .rlsbl/releases/unreleased.toml for bump type and release metadata.

Instead of passing bump type on the CLI, the user creates .rlsbl/releases/unreleased.toml describing the release. This module reads and validates that file's internal consistency.

#ReleaseConfig

ReleaseConfig
FieldTypeDefault
bumpstr
includelist[str]
excludelist[str]
targetsdict[str, dict]field(default_factory=dict)
descriptionstr''
contextstr''
preidstr''
blogboolFalse

#get_releases_dir

python
def get_releases_dir(project_dir: str='.', *, releasable_dir: str | None=None) -> str

Return the directory holding release files (unreleased.toml family).

releasable_dir is the releasable's state directory (.rlsbl-monorepo/releasables/<name>/); when given, release files live in its releases/ subdirectory — the same home as in-progress.json/scrub-result.json — instead of the project's .rlsbl/releases/. This is the single derivation for the releases dir; the release state module delegates here.

#get_release_file_path

python
def get_release_file_path(project_dir: str='.', *, releasable_dir: str | None=None) -> str

Return the path to the release file (unreleased.toml).

Standalone projects and implicit-monorepo packages: <project_dir>/.rlsbl/releases/unreleased.toml. Releasable releases (explicit monorepo mode): pass releasable_dir — the file lives at .rlsbl-monorepo/releasables/<name>/releases/unreleased.toml.

#_field_is_blank

python
def _field_is_blank(value) -> bool

True if a release-file field is absent or an empty/whitespace string.

The scaffolder writes bump = "" and description = ""; an operator "fills in" the file by setting a real value. Anything non-string and non-None (e.g. a number) counts as filled.

#is_pristine_release_file

python
def is_pristine_release_file(content: str) -> bool

True if content is a still-pristine single-project release scaffold.

Pristine means the operator has not filled in the release: either the file is empty/whitespace-only, or it parses as TOML with a blank bump and a blank description. Any filled bump/description -- or content that fails to parse as TOML -- is treated as operator data and reported non-pristine so release init refuses to clobber it.

#is_pristine_batch_release_file

python
def is_pristine_batch_release_file(content: str) -> bool

True if content is a still-pristine batch (monorepo) release scaffold.

Pristine means every [packages.<name>] / [releasables.<name>] section has a blank bump and blank description (the scaffold state). Empty/whitespace-only content is pristine. Any filled section, a non-table section entry, or unparseable content is non-pristine so monorepo release init refuses to clobber it.

#check_legacy_release_file

python
def check_legacy_release_file(project_dir: str, releasable_dir: str | None) -> None

Hard-error if a release file sits at the legacy member location.

Releasable release files used to live under the representative member's .rlsbl/releases/. A file found there in releasable mode must never be silently ignored (it would be skipped by the relocated read path and left behind as per-package residue).

Raises ReleaseFileError with a migration hint. No-op when releasable_dir is None (standalone / implicit mode).

#_validate_release_config

python
def _validate_release_config(data: dict, prefix: str='') -> ReleaseConfig

Validate release config fields from a parsed TOML dict.

Shared validation for both single-project and batch (per-package) release configs. The prefix is prepended to all error messages -- empty string for single-project, "[packages.] " for batch.

Raises ReleaseFileError for schema/validation failures. Returns a ReleaseConfig on success.

#_render_release_diags

python
def _render_release_diags(diags) -> str

Render strictspec diagnostics in rlsbl's release-file error style.

Each diagnostic contributes its rendered path, message, and stable code so the operator sees exactly which field failed and why.

#_strictspec_validate_release_document

python
def _strictspec_validate_release_document(raw: bytes) -> None

Validate the raw release-file document shape via the generated validator.

strictspec owns the DOCUMENT SHAPE: the format_version gate, field types, the bump/preid/mode enums, required fields, unknown-key rejection, include/exclude disjointness, the [targets.<name>]include reference, and the preid/bump couplings. Raises ReleaseFileError (rlsbl's native error style) when any diagnostic fires.

Consumer-native refinements that strictspec cannot express (whitespace-only description, the Flutter required-mode gate) stay in :func:_bind_release_config. There is no dual validation: any property strictspec owns is not re-checked natively on this path.

#_bind_release_config

python
def _bind_release_config(data: dict) -> ReleaseConfig

Build a ReleaseConfig from a shape-validated release document.

Assumes :func:_strictspec_validate_release_document already validated the document shape, so this applies only the consumer-native refinements and the field normalization (.strip()) before constructing the dataclass.

#read_release_file

python
def read_release_file(path: str) -> ReleaseConfig

Read and validate a single-project release TOML file.

The raw document shape is validated by the strictspec-generated validator (which requires a format_version gate) BEFORE tomlkit parsing; consumer-native refinements and dataclass construction happen after. Batch (monorepo) release files keep the native :func:_validate_release_config path -- their document shape is different and not yet strictspec-modeled.

Raises FileNotFoundError if the file doesn't exist. Raises ReleaseFileError for schema/validation failures.

#write_archived_release_file

python
def write_archived_release_file(releases_dir: str, version: str, *, bump: str, include, exclude=(), description: str, context: str='', preid: str='', blog: bool=False) -> str

Write v{version}.toml for a release that had no unreleased.toml.

A standalone release finalizes by RENAMING its release file to v{version}.toml, and every later changelog regeneration reads the version's description, context and bump type back out of that archive.

A batch release has no per-member release file -- its members' metadata lives in the workspace-level batch TOML, archived under a different name -- so nothing was ever written here, and regeneration silently stripped the description and context from the version's .md and its CHANGELOG.md section. Materializing the archive puts the metadata exactly where every reader already looks, rather than teaching each reader a second source.

The result is a complete, schema-valid release document (read_release_file accepts it, which matters because rlsbl release undo restores it as unreleased.toml), and read-only like every other archived release file.

Returns the path written.

#unfinalize_release_file

python
def unfinalize_release_file(releases_dir: str, version: str) -> list[str]

Reverse a release-file finalization: restore vX.Y.Z.toml to unreleased.toml.

Inverse of the finalization step in release run, which renames unreleased.toml to vX.Y.Z.toml and chmods it read-only (0o444).

  1. No-op (returns []) if the versioned file doesn't exist.
  2. If unreleased.toml exists with content that differs from the versioned

file, warns on stderr and skips -- nothing is deleted.

  1. Otherwise removes any stale unreleased.toml, makes the versioned file

writable, and renames it back to unreleased.toml.

Returns the list of changed file paths (for committing).

#BatchReleaseConfig

Configuration from a batch release TOML file (monorepo).

packages maps either package names (implicit mode / backward compat) or releasable names (explicit mode) to their release configs. section_type indicates which top-level key was used: "packages" or "releasables".

#get_batch_release_file_path

python
def get_batch_release_file_path(workspace_root: str='.') -> str

Return the path to .rlsbl-monorepo/releases/unreleased.toml.

#read_batch_release_file

python
def read_batch_release_file(path: str) -> BatchReleaseConfig

Read and validate a batch release TOML file.

Accepts either [packages.<name>] sections (implicit mode, backward compat) or [releasables.<name>] sections (explicit mode). Having both is a hard error.

Each section has the same fields as a single ReleaseConfig (bump, include, exclude, optional targets, description, context).

Raises FileNotFoundError if the file doesn't exist. Raises ReleaseFileError for schema/validation failures.

#RetryConfig

Configuration from a retry TOML file (.rlsbl/releases/retry.toml).

#discard_invalid_retry_file

python
def discard_invalid_retry_file(retry_path: str) -> None

Delete a retry file that failed to parse.

An unparseable retry.toml is not recoverable state: leaving it on disk dirties the working tree and blocks the next rlsbl release run. Lives beside the retry-file readers (and out of the command registration module, which must stay free of effect calls for the effects-bypass lint).

#get_retry_file_path

python
def get_retry_file_path(project_dir: str='.', *, releasable_dir: str | None=None) -> str

Return the path to retry.toml (same releases-dir home as unreleased.toml).

Releasable releases (explicit monorepo mode): pass releasable_dir so the file lives under the releasable's own releases dir instead of the member's .rlsbl/releases/.

#read_retry_file

python
def read_retry_file(path: str) -> RetryConfig

Read and validate a retry TOML file.

Raises FileNotFoundError if the file doesn't exist. Raises ReleaseFileError for schema/validation failures.

Search