brel 0.6.0

better-releases cli tool
brel-0.6.0 is not a library.

brel

brel is a CLI that scaffolds and runs the better-releases workflow.

Commands

  • brel init generates a managed GitHub Actions workflow.
  • brel release-pr computes the next version, updates configured files, commits, pushes, and creates/updates a release PR.
  • brel next-version computes the next releasable version and prints it as plain SemVer.
  • brel validate validates a config file and prints warnings for ignored keys.

release-pr Prerequisites

  • git must be available.
  • gh (GitHub CLI) must be available.
  • A GitHub token must be present in GH_TOKEN or GITHUB_TOKEN.
    • The workflow generated by brel init sets GH_TOKEN: ${{ github.token }} automatically.

Config File

brel discovers config in this order:

  1. --config <path> (when provided)
  2. brel.toml
  3. .brel.toml

Use brel validate to check that an existing config file parses and satisfies the current schema before running other commands.

Minimal release-pr config

provider = "github"
default_branch = "main"

[release_pr.version_updates]
"package.json" = ["version"]

Full release_pr config

[release_pr.version_updates]
"package.json" = ["version"]
"Cargo.toml" = ["package.version"]

[release_pr.format_overrides]
"Cargo.toml" = "toml"

[release_pr]
release_branch_pattern = "brel/release/v{{version}}"
pr_template_file = ".github/brel/release-pr-body.hbs"

[release_pr.changelog]
enabled = true
output_file = "CHANGELOG.md"

[release_pr.tagging]
enabled = false
tag_template = "v{version}"

[release_pr.commit_author]
name = "brel[bot]"
email = "brel[bot]@users.noreply.github.com"

How Versioning Works

When you run brel release-pr:

  1. It finds the highest stable SemVer tag that matches release_pr.tagging.tag_template (default v{version}).
  2. If no valid tag exists, it uses 0.0.0.
  3. It scans commits since that tag (or all commits when no tag exists).
  4. It picks one bump level from Conventional Commit signals:
    • major: BREAKING CHANGE in body/footer, or ! in the type/scope prefix.
    • minor: feat: ...
    • patch: fix: ...
  5. If no releasable commits are found, it exits successfully with no changes.

brel next-version uses the same versioning rules:

  • when releasable commits exist, it prints the next version (for example 1.2.3)
  • when none exist, it prints nothing and exits successfully

How File Updates Work

  • release_pr.version_updates maps exact repo-relative file paths to selector paths.
  • Selector syntax:
    • key: version
    • nested key: package.version
    • index selector: packages[0].version
    • filter selector: package[name=brel].version
  • Supported file formats:
    • inferred from extension (.json, .toml)
    • or forced via release_pr.format_overrides
  • Updates are fail-fast. The command errors if:
    • a file is missing,
    • format cannot be determined,
    • parse fails,
    • a selector is invalid,
    • a selector matches no values,
    • a selector uses index/filter on a non-array segment,
    • a matched value is not a string.
  • Match behavior:
    • all values matched by a selector are updated
    • selectors do not create missing keys/paths

Example selectors:

  • JSON: "package.json" = ["version", "tooling.release.version"]
  • JSON with filter: "package.json" = ["package[name=brel].version"]
  • TOML: "Cargo.toml" = ["package.version"]
  • Cargo.lock (explicit format override required):
[release_pr.version_updates]
"Cargo.lock" = ["package[name=brel].version"]

[release_pr.format_overrides]
"Cargo.lock" = "toml"

Changelog Generation (git-cliff)

  • brel init generates a workflow that runs orhun/git-cliff-action@v4 by default.
  • Configure changelog behavior with [release_pr.changelog]:
    • enabled (default true)
    • output_file (default "CHANGELOG.md")
  • Generated workflow behavior:
    • computes next-version first via brel next-version
    • runs git-cliff only when a next version exists
    • passes --unreleased --tag <rendered-tag-template> so the newest changelog section is versioned instead of [unreleased]
  • If changelog generation is enabled, brel release-pr stages output_file in the release commit when that file exists.
  • Disable changelog generation:
[release_pr.changelog]
enabled = false
  • brel init does not create or manage cliff.toml; keep that file in your repository if you want custom git-cliff rules.

Branch / Commit / PR Behavior

  • Default branch pattern: brel/release/v{{version}}
    • Only {{version}} is supported as a token.
  • release_pr.tagging.tag_template controls rendered release tags (default v{version}).
    • tag_template accepts {version} and legacy {{version}} (normalized to {version}).
    • tag_template must include exactly one version token.
  • Commit message: chore(release): <rendered-tag>
  • PR title: Release <rendered-tag>
  • Commit author defaults to:
    • name = "brel[bot]"
    • email = "brel[bot]@users.noreply.github.com"
  • Push strategy: --force-with-lease to origin.

For PRs:

  • brel uses gh pr list to find an open managed release PR.
  • If found, it updates that PR (continuity wins over recomputing branch name).
  • If not found, it creates a new PR.

Tagging on Merge

  • Optional config: [release_pr.tagging] enabled = true (default false).
  • Tag format config: [release_pr.tagging] tag_template = "v{version}" (default shown).
  • When enabled, the generated workflow listens for merged pull requests into the configured default branch.
  • If the merged PR is managed by brel and titled Release <rendered-tag>, the workflow validates it against tag_template, then creates and pushes that tag when it does not already exist.
  • Create repository secret BREL_TAG_PUSH_TOKEN before using tagging-on-merge.
    • Use a PAT that can push tags to the repository (fine-grained PAT with Contents: Read and write).
    • This is required because pushes done with GITHUB_TOKEN do not trigger downstream tag-push workflows.
  • brel init prints this secret requirement whenever tagging is enabled.

PR Body Templates

If release_pr.pr_template_file is set, brel renders that Handlebars template.

Available variables:

  • version
  • tag
  • base_branch
  • release_branch
  • commits (array of { sha_short, subject })

Important: include this marker in your template so future runs can detect and update the same PR:

<!-- managed-by: brel -->

If rendering fails, brel release-pr exits with an error.

Typical Usage

Generate workflow once:

brel init --yes

Run release locally:

GH_TOKEN=... brel release-pr

Run with explicit config:

brel release-pr --config ./configs/release.toml

Validate config:

brel validate

Preview the next release version:

brel next-version