Skip to content

The Release PR

The release PR is the heart of the brel workflow: a single, long-lived pull request that always represents “the next release”. Every time commits land on your default branch, brel release-pr refreshes it — new version, updated files, regenerated changelog. Merging it is how you ship.

On each brel release-pr run with releasable commits:

  1. Computes the next version (how versioning works).
  2. Updates the files configured in version_updates.
  3. Stages the changelog output_file when changelog generation is enabled and the file exists.
  4. Commits and pushes the release branch, then creates or updates the PR/MR.
Thing Value
Release branch brel/release/v{{version}} (configurable via release_branch_pattern; only the {{version}} token is supported)
Commit message chore(release): <rendered-tag>
PR/MR title Release <rendered-tag>
Commit author brel[bot] <brel[bot]@users.noreply.github.com> (configurable via [release_pr.commit_author])
Push strategy git push --force-with-lease to origin

brel identifies its own PRs by a hidden HTML comment in the PR body:

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

On each run, brel looks for an open managed release PR (via gh pr list on GitHub, or the REST API on GitLab/Forgejo):

  • Found on the current release branch — the PR is updated in place.
  • Found on a stale branch (the version changed since it was opened, so the rendered branch name changed) — brel first creates or updates the PR for the current branch, then closes the stale PR and best-effort deletes its remote branch.
  • Not found — a new PR is created.

The result is that you only ever have one open release PR, and it always reflects the current state of your default branch.

Because the branch is pushed with --force-with-lease on every run, manual commits to the release branch will be overwritten by the next run. Treat the release PR as generated output: change its inputs (commits on the default branch, config, templates) rather than the PR itself.