rlsbl v0.92.0 /Configuration reference
On this page

Configuration reference for rlsbl: config.json settings, workspace.toml for monorepos, and selfdoc.json for documentation.

#Configuration reference

#.rlsbl/config.json

Project-level configuration file created by rlsbl config init or rlsbl scaffold. This JSON file controls release behavior such as which targets to use (chosen from 18 supported registries) and whether ecosystem tagging is enabled. Settings here override user-level defaults in ~/.rlsbl/config.json but are themselves overridden by CLI flags passed at release time, forming a 3-layer precedence chain (CLI > project > user).

.rlsbl/config.json
KeyTypeValue
privatebooleanfalse
env_filestring"~/Projects/.env"
push_timeoutinteger120
batch_limitsobject{...} (1 keys)
targetsarray[...] (2 items)
pipelinesobject{...} (3 keys)

#Key reference

Key reference
KeyTypeDescription
targetsarrayList of target names to use for versioning (overrides auto-detection)
pipelinesobjectPublish pipelines keyed by user-chosen name (see Pipeline config below)
tagboolEnable/disable ecosystem tagging (default: true)
privatebool (required)Safety guardrail: when true, blocks publishing to public registries
release_branchesarrayBranch names that trigger the manual-release-push warning. Default: ["main", "master"] when absent. An empty list is a hard error -- either omit the key entirely or list at least one branch.
changelog_formatstringControls the format of generated CHANGELOG.md. Default: "grouped". Currently the only supported value, which produces version sections with ### Breaking, ### Features, ### Fixes sub-headers.
batch_limitsobjectLimits and exclusions for changelog batch-size validation checks. See batch_limits below.

Configuration precedence for tagging: CLI flag (--no-tag) > project config > user config (~/.rlsbl/config.json) > default (true).

#batch_limits

The batch_limits object controls the batch_size_commits and batch_size_entries changelog validation checks, which prevent excessively large changelog entries that obscure individual change attribution. Both checks produce blocking errors when they fail, and violations must be resolved before releasing. Default limits allow a maximum of 5 commits per entry and 5 entries per commit.

batch_limits
FieldTypeDefaultDescription
max_commits_per_entryint5Maximum number of commit hashes allowed in a single JSONL entry. Entries exceeding this limit fail the batch_size_commits check.
max_entries_per_commitint5Maximum number of JSONL entries that may reference the same commit hash. Commits exceeding this limit fail the batch_size_entries check.
exclusionsarray[]Per-violation silencers for known exceptions (see below).

Each entry in exclusions is a dict with:

batch_limits
FieldTypeRequiredDescription
reasonstringYesMandatory audit trail explaining why this exclusion exists.
commitsarrayAt least one of commits or entriesCommit hashes to exclude from the batch_size_entries check.
entriesarrayAt least one of commits or entriesEntry identifiers (commit lists) to exclude from the batch_size_commits check.

Example:

{} json
{
  "batch_limits": {
    "max_commits_per_entry": 5,
    "max_entries_per_commit": 5,
    "exclusions": [
      {
        "reason": "Large refactor commit touches many changelog areas",
        "commits": ["a1b2c3d"]
      }
    ]
  }
}

#Pipeline config

The pipelines key configures how releases are published. It replaces the old publish key, which is now rejected during rlsbl release run. Pipelines are separate from targets: targets handle version bumps (which files to update), while pipelines handle publishing (where and how to distribute the release).

Each entry in pipelines is keyed by a user-chosen name and must have:

Pipeline config
FieldTypeRequiredDescription
typestringYesOne of the 9 built-in pipeline types (see below)
localboolYesWhether to publish from the developer machine. When false, CI handles publishing.
token_varstringNoEnv var name for the publish token. Each type has a default (e.g. NPM_TOKEN for npm).
username_varstringNoEnv var name for username auth (used by docker).
password_varstringNoEnv var name for password auth (used by docker).
assetsboolNoEnable building and uploading target-specific artifacts to GitHub Releases.
max_asset_size_mbintWhen assets or custom_assets is setMaximum artifact size in MB. Releases fail if exceeded.
custom_assetsarrayNoList of custom build artifacts (see below).

Built-in pipeline types: npm, pypi, go, cargo, deno, hex, maven, docker, cloudflare-pages

Pipeline types use different auth patterns:

  • Token-based (npm, pypi, go, cargo, deno, hex, maven): authenticate via a single env var specified by token_var
  • Credential-based (docker): authenticate via username_var and password_var
  • Other (cloudflare-pages): type-specific auth configured per pipeline

#Per-pipeline-type reference

Per-pipeline-type reference
TypeDefault token_varAuth patternPublish action
npmNPM_TOKENTokenRuns npm publish (or pnpm/yarn equivalent based on lockfile detection)
pypiPYPI_TOKEN (or TWINE_PASSWORD)Token / OIDCOIDC Trusted Publishing preferred; falls back to token-based upload via twine
goNoneNoneNotifies Go module proxy (GOPROXY=proxy.golang.org); no authentication required
cargoCARGO_REGISTRY_TOKENTokenRuns cargo publish to crates.io
denoDENO_TOKEN (or JSR_TOKEN)TokenRuns deno publish to JSR
hexHEX_API_KEYTokenRuns mix hex.publish to hex.pm
mavenMAVEN_TOKEN (or GITHUB_TOKEN)TokenRuns gradle or maven publish task to configured repository
dockerN/AUsername + PasswordAuthenticates via DOCKER_USERNAME + DOCKER_PASSWORD, then runs docker push
cloudflare-pagesNoneSelfdoc CLIUses the selfdoc CLI for deploy; no token needed locally (CF credentials sourced from env)

#custom_assets

The custom_assets field is a list of dicts, each with:

custom_assets
FieldTypeRequiredDescription
namestringYesOutput filename (must appear in $RLSBL_DIST_DIR after the build command runs)
buildstringYesShell command to execute. Receives $RLSBL_DIST_DIR env var pointing to the distribution directory.

The build command runs with $RLSBL_DIST_DIR set to a temporary distribution directory. The command must produce a file named name in that directory. After building, rlsbl verifies the file exists and checks its size against max_asset_size_mb. All custom asset files are then uploaded to the GitHub Release.

Example config:

{} json
{
  "pipelines": {
    "npm-publish": {
      "type": "npm",
      "local": false
    },
    "docker-push": {
      "type": "docker",
      "local": true,
      "username_var": "DOCKER_USER",
      "password_var": "DOCKER_PASS"
    },
    "binaries": {
      "type": "go",
      "local": false,
      "custom_assets": [
        {"name": "myapp-linux-amd64.tar.gz", "build": "make dist-linux"},
        {"name": "myapp-darwin-arm64.tar.gz", "build": "make dist-darwin"}
      ],
      "max_asset_size_mb": 50
    }
  }
}

#rlsbl.config

Project configuration loading with layered precedence.

Layers (highest to lowest priority):

  1. Per-package config.json
  2. Releasable config.json

CLI flags override project-level .rlsbl/config.json which overrides user-level defaults.

#merge_config

python
def merge_config(base, overlay)

Merge two config dicts with shallow-replace, deep-merge for nested dicts.

Top-level keys in overlay replace those in base, except when both values are dicts -- in that case the nested dict is merged recursively (overlay nested keys merge into base nested keys).

Keys present in base but absent in overlay are preserved.

Returns a new dict; neither input is mutated.

#load_env_file

python
def load_env_file(path)

Load KEY=VALUE pairs from a file into os.environ.

Supports ~ expansion. Ignores comments (#) and blank lines. Strips surrounding quotes from values.

#_project_config

python
def _project_config(project_root)

Resolve project config path at call time.

Returns an absolute path based on project_root.

#read_json_config

python
def read_json_config(path)

Safely read a JSON file, returning {} on missing.

#should_tag

python
def should_tag(flags, config)

Returns True if tagging is enabled, checking flag > project > user > default.

config is the project config dict (already loaded). User-level config is still read from disk.

#read_project_config

python
def read_project_config(project_root, releasable_config_dir=None)

Read project config with optional releasable-level inheritance.

When releasable_config_dir is provided (path to a releasable's state directory, e.g. .rlsbl-monorepo/releasables/www/), config is loaded with 2-level precedence:

  1. Per-package config.json (highest)
  2. Releasable config.json (lowest)

When releasable_config_dir is None, loads only the per-package level.

#read_deploy_config

python
def read_deploy_config(config)

Read and validate deploy targets from project config dict. Returns (targets, errors).

#get_changelog_validation_config

python
def get_changelog_validation_config(config)

Read changelog validation config from a project config dict.

Returns the batch_limits section as a dict like {"max_commits_per_entry": 5, "max_entries_per_commit": 2, "exclusions": [{"reason": "...", "commits": [...], "entries": [{"version": "...", "line": N}]}]}.

Each exclusion object has a required "reason" string for audit purposes; "commits" and "entries" are optional lists silencing the corresponding batch_size_commits and batch_size_entries violations.

Returns an empty dict if no config or malformed.

#get_release_mode

python
def get_release_mode(config)

Return the release mode from config, defaulting to "imperative".

Reads config["release"]["mode"] if present, otherwise returns "imperative". Does NOT validate -- call validate_release_mode for that.

#validate_release_mode

python
def validate_release_mode(config)

Validate the release.mode config key if present.

Valid values: "imperative" (default) and "pr". Raises ConfigError if the value is invalid or the structure is wrong.

#validate_pipelines_config

python
def validate_pipelines_config(config)

Validate the pipelines section of a project config.

Raises ConfigError if:

  • pipelines is present but not a dict
  • An entry is not a dict
  • An entry is missing type (str) or local (bool)
  • type is not a registered pipeline type
  • assets is true but max_asset_size_mb is missing or not a positive int
  • custom_assets is present but max_asset_size_mb is missing or not a positive int
  • custom_assets entries are malformed (missing name or build)

#_read_unreleased_commits

python
def _read_unreleased_commits(config_path)

Read commit hashes from unreleased.jsonl adjacent to config_path.

Returns a set of commit hash strings found in the "commits" arrays of all entries in unreleased.jsonl. Returns an empty set if the file does not exist or is empty.

#clean_stale_exclusions

python
def clean_stale_exclusions(config_path)

Remove stale batch_limits exclusions after release finalization.

Two kinds of exclusions become stale:

  1. Entry-level (have "entries" with version="unreleased"):

after finalization renames unreleased.jsonl to X.Y.Z.jsonl, these are dead references.

  1. Commit-level (have "commits" but no "entries"): stale when

ALL referenced commits are no longer in unreleased.jsonl (they were moved to a versioned file during finalization).

Returns the number of exclusions removed. Returns 0 and does not write to disk if nothing changed.

#update_last_build_release

python
def update_last_build_release(project_dir, version)

Store last_build_release version in .rlsbl/config.json for OTA validation.

#write_project_config

python
def write_project_config(key, value, project_root)

Write or update a key in .rlsbl/config.json (creates dir if needed).

Returns the updated config dict after writing to disk.

#User-level configuration

The user-level configuration file at ~/.rlsbl/config.json provides personal defaults that apply across all rlsbl-managed projects on the machine. It uses the same JSON schema as the project-level config, but with lower precedence -- project-level settings always override user-level ones, and CLI flags override both.

Location: ~/.rlsbl/config.json

This optional file uses the same JSON format as the project-level .rlsbl/config.json. It provides personal defaults that apply to all rlsbl-managed projects when a given key is not set at the project level.

Precedence (highest to lowest):

  1. CLI flags (e.g., --no-tag)
  2. Project config (.rlsbl/config.json)
  3. User config (~/.rlsbl/config.json)
  4. Built-in defaults

The file is optional — a missing ~/.rlsbl/config.json is not an error. When absent, built-in defaults apply for any key not set at the project level.

Currently supported keys:

User-level configuration
KeyTypeDefaultDescription
tagbooltrueControls whether ecosystem tags (e.g., npm dist-tags) are created during release.

Example ~/.rlsbl/config.json:

{} json
{
  "tag": false
}

#CLI flag overrides

Some CLI flags override config.json keys for a single invocation, providing temporary behavior changes without modifying the persistent configuration. Most global flags like --dry-run, --yes, and --quiet are runtime-only and have no persistent config equivalent, affecting only the current command execution.

CLI flag overrides
FlagConfig keyScopeEffect
--no-tagtagproject + userDisables ecosystem tagging for this invocation
--allow-dirty(none)release onlySkips clean working tree check
--watch/--no-watch(none)release onlyControls CI monitoring after push
RLSBL_PUSH_TIMEOUT envpush_timeoutprojectPush timeout in seconds (default 120)

Global flags --dry-run, --yes, and --quiet are runtime-only and have no config.json equivalent. They affect the current invocation but are never persisted to configuration.

#.rlsbl-monorepo/workspace.toml

Monorepo workspace definition that lists all sub-projects, their relative paths, and optional names. rlsbl walks up from the current directory to find this file, so you can run release commands from within any sub-project. See the monorepo guide for setup instructions, workspace commands, and subtree publishing.

The file uses TOML format with a [[projects]] array. Each entry has a path key (relative to the monorepo root) and an optional name key. If name is omitted, the directory basename is used.

#selfdoc.json

When present in the project root, this file configures documentation builds via selfdoc. It specifies the source directories to scan, the output path for generated pages, the base URL for the published site, and an optional deploy provider such as Cloudflare Pages. Documentation deployment is handled via a cloudflare-pages pipeline in .rlsbl/config.json, not as a release target. See the selfdoc documentation for the full schema.

selfdoc.json
KeyTypeValue
base_urlstring"https://rlsbl.smmh.dev"
sourcearray[...] (1 items)
docsstring"docs/"
outputstring"docs/_build/"
localesarray[...] (1 items)
deployobject{...} (2 keys)
genobject{...} (1 keys)
root_filesarray[...] (2 items)
directivesobject{...} (5 keys)
topologyobject{...} (5 keys)
assemblyobject{...} (1 keys)