Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Commands

Releasaurus operates entirely through forge platform APIs — no local clone required — so every command can run from any machine with network access to your forge. An optional hybrid mode uses a local clone for git operations.

The core workflow is two commands:

# 1. Prepare: analyze commits, bump versions, write changelog, open a PR
releasaurus release-pr --repo "https://github.com/owner/repo"

# 2. Review and merge the PR in your forge's UI, then publish:
releasaurus release --repo "https://github.com/owner/repo"

release-direct replaces both steps for repos that don’t want a review PR. start-next and get are optional helpers covered below.

release-pr

Analyzes commits since the last release, determines the version bump (patch/minor/major) from conventional commits, updates version files (if a release_type is configured), generates the changelog, and creates or updates a release pull request.

# All packages
releasaurus release-pr --repo "https://github.com/owner/repo"

# A single package in a monorepo
releasaurus release-pr --package my-pkg \
  --repo "https://github.com/owner/repo"

Supports prereleases, dry-run, and the overrides below.

release

Run after the release PR is merged. Validates the release commit, creates and pushes the git tag, and publishes the release on your forge. Reads the release notes directly from the merged PR body (see Editing Release Notes).

# All packages with merged release PRs
releasaurus release --repo "https://github.com/owner/repo"

# A single package
releasaurus release --package my-pkg \
  --repo "https://github.com/owner/repo"

release-direct

Does everything release-pr and release do together, in a single pass and with no pull request: analyzes commits, bumps versions, writes the changelog, commits directly to the base branch, tags that commit, and publishes the release.

# All packages
releasaurus release-direct --repo "https://github.com/owner/repo"

# A single package in a monorepo
releasaurus release-direct --package my-pkg \
  --repo "https://github.com/owner/repo"

Use it for trunk-based or fully automated releases where a review step adds nothing — internal tools, nightly builds, or CI that already gates on the merge into the base branch. Prefer release-pr + release whenever you want the version bump and changelog reviewed before they land.

In a monorepo, every package released in a run shares a single release commit, and each package’s tag points at that commit. Setting separate_pull_requests gives you one commit per package instead, matching how that setting splits release PRs.

Confirmation

Because there is no PR to review and no way to finish a partially failed run by repeating it, release-direct stops and asks you to type yes before it changes anything:

release-direct will make changes that re-running it cannot undo.

  repository: https://github.com/owner/repo
  branch:     main

It commits the version bumps and changelog to that branch, creates and
pushes the release tag(s), and publishes the release(s) on your forge.
No pull request is created and there is no review step.

Type 'yes' to continue:

Pass --auto-approve to skip it. CI must pass --auto-approve — when stdin is not a terminal the command refuses to run rather than hang or guess, and tells you to add the flag.

--dry-run never prompts, since it writes nothing.

Warning: This is a separate, out-of-band flow — it never creates a release PR. Do not mix it with the release-pr / release workflow on the same packages: the tag release-direct creates will collide with the one release later tries to create for the merged PR. As a safety net, release-direct refuses to run if a package it is about to release still has a merged release PR waiting to be tagged, but it cannot detect every ordering.

Note: Like start-next, this commits directly to your base branch, so your branch protection rules must permit it. Unlike release, it is not driven by auto_start_next and will not trigger a follow-up patch bump.

Supports dry-run and the overrides below. Run it with --dry-run first to see exactly what it would commit, tag, and publish.

start-next

Bumps the patch version for each previously-tagged package and commits the manifest changes directly to the base branch as a chore commit. It does not open PRs or create tags, and skips packages that have never been tagged. Use it right after a release to keep manifest versions ahead of the last release.

# All previously-tagged packages
releasaurus start-next --repo "https://github.com/owner/repo"

# Specific packages only
releasaurus start-next --repo "https://github.com/owner/repo" \
  --packages pkg-a,pkg-b

Note: This commits directly to your base branch. Ensure your branch protection rules permit it. It can also run automatically after release — see auto_start_next.

get

Queries release information as JSON without making any changes — useful for debugging version detection and for building custom notifications. (show is kept as an alias.)

get next-release

Projects the next release for each package as JSON.

releasaurus get next-release --repo "https://github.com/owner/repo"

# Single package, or write to a file
releasaurus get next-release --package my-pkg --out-file releases.json \
  --repo "https://github.com/owner/repo"

get current-release

Returns the most recent release for each package (packages without a release are omitted).

releasaurus get current-release --repo "https://github.com/owner/repo"

get release

Returns the data for an existing tag — tag, sha, and notes.

releasaurus get release --tag v1.0.0 \
  --repo "https://github.com/owner/repo"

get notes

Re-renders release notes from a get next-release JSON file using your configured Tera template. This lets you transform the data (for example, replacing author names with Slack IDs) before producing final notes. (recompiled-notes is kept as an alias.)

# 1. Capture release data
releasaurus get next-release --out-file releases.json \
  --repo "https://github.com/owner/repo"

# 2. Transform it however you like (custom script), then re-render:
releasaurus get notes --file releases.json \
  --repo "https://github.com/owner/repo"

Output is a JSON array of { name, notes } objects.

Global Options & Forge Selection

These apply to every command:

FlagEnv fallbackDescription
--repo <url>RELEASAURUS_REPORepository URL
--forge <forge>RELEASAURUS_FORGEForge type (see below)
--token <token>RELEASAURUS_<FORGE>_TOKEN, <FORGE>_TOKENAuth token
--local-path <path>RELEASAURUS_LOCAL_PATHLocal clone for hybrid mode
--base-branch <branch>Override the base branch
--debugRELEASAURUS_DEBUGVerbose logging
--configRELEASAURUS_CONFIGCustom file path location

Available forge types: github, gitlab, gitea, forgejo, azure-devops (experimental), and local (testing). For the full list of token variables and required scopes, see the Configuration Reference.

Automatic forge inference

When --repo points at a recognized cloud host, --forge can be omitted:

HostInferred forge
github.comgithub
gitlab.comgitlab
gitea.comgitea
codeberg.orgforgejo
dev.azure.comazure-devops

Self-hosted instances (e.g. https://gitlab.company.com/...) and --forge local always require the flag, since the host alone can’t identify the forge software.

Testing Modes

Three ways to run safely or against a local checkout.

Dry-Run Mode

Performs all analysis and validation and logs exactly what would happen, but makes no changes — no branches, PRs, tags, or releases. Dry-run automatically enables debug logging (output is prefixed dry_run:).

releasaurus release-pr --dry-run --repo "https://github.com/owner/repo"

# Or via environment variable
export RELEASAURUS_DRY_RUN=true

Local Repository Mode

--forge local reads commits, tags, and files from your working directory and never contacts a remote forge — ideal for validating a releasaurus.toml change before pushing. No token required.

releasaurus release-pr --forge local --repo "."

# Or from a specific path
releasaurus release-pr --forge local --repo "/path/to/repo"

Hybrid Mode (Local Git + Remote Forge)

--local-path performs git operations (reading commits/tags/files, creating branches, committing, pushing) against a local clone, while still creating real PRs and releases via the forge API. Use it when you already have a checkout and want to avoid repeated API calls for data gathering. A forge token is still required.

releasaurus release-pr \
  --repo "https://github.com/owner/repo" \
  --token "$GITHUB_TOKEN" \
  --local-path /path/to/checkout

CI fetch depth: in hybrid mode the local checkout must include full history and all tags back to the previous release. Most CI systems shallow-clone by default — set fetch-depth: 0 (GitHub/Gitea Actions) or GIT_DEPTH: 0 (GitLab CI), or run git fetch --unshallow. See CI/CD Integration for per-platform setup.

Configuration Overrides

Override config from the command line without editing releasaurus.toml — handy for testing, one-off releases, and per-branch CI settings.

FlagEffect
--base-branch <branch>Override the base branch
--tag-prefix <prefix>Global tag prefix for all packages
--version-type <value>Global version type for all packages
--prerelease-suffix <suffix>Global prerelease suffix (empty "" disables)
--prerelease-strategy <versioned|static>Global prerelease strategy
--skip-sha <sha>Skip a commit by SHA prefix (repeatable)
--reword <sha>=<message>Rewrite a commit message (repeatable)
--set-package <pkg>.<property>=<value>Per-package override (repeatable)

--set-package takes precedence over all other overrides and config. Supported properties: tag_prefix, versioning.version_type, versioning.prerelease.suffix, versioning.prerelease.strategy. Setting an unsupported property prints an error listing valid values.

Precedence (highest to lowest): --set-package → global CLI overrides → [[package]] config → [defaults] config → built-in defaults.

# Override base branch and global prerelease suffix
releasaurus release-pr --base-branch develop --prerelease-suffix beta \
  --repo "https://github.com/owner/repo"

# Per-package override (e.g. only the frontend gets a beta suffix)
releasaurus release-pr \
  --set-package frontend.versioning.prerelease.suffix=beta \
  --repo "https://github.com/owner/repo"

# Date-based versioning for just the nightly package
releasaurus release-pr \
  --set-package nightly.versioning.version_type=year.month.day \
  --repo "https://github.com/owner/repo"

# Skip one commit and reword another
releasaurus release-pr --skip-sha abc123d \
  --reword "def456e=feat: improved authentication" \
  --repo "https://github.com/owner/repo"

See Configuration for what these settings mean.

Known Limitations

Gitea < v1.26 / Forgejo < v16: Force Push Not Supported

Releasaurus force-pushes the release branch on each run so repeated runs update the existing release PR in place rather than piling up new ones. On Gitea and Forgejo this relies on a force-overwrite option on the /contents API route that was only added in Gitea v1.26 and Forgejo v16.

Fix (recommended): upgrade your Gitea/Forgejo instance to v1.26 / v16 or later. Alternative: use hybrid mode (--local-path), which pushes the release branch over git and avoids the API limitation entirely.

Gitea and Forgejo Actions: Injected Token Shadows Your PAT

Gitea and Forgejo Actions runners (including Codeberg) automatically inject an ephemeral, limited per-job token into the job environment under the names GITHUB_TOKEN, GITEA_TOKEN, and FORGEJO_TOKEN. If you supply your own token through one of those environment variables — for example env: FORGEJO_TOKEN: ${{ secrets.RELEASE_TOKEN }} — the runner’s injected value can take precedence inside the action, and Releasaurus authenticates with the limited token instead of your PAT.

That injected token can usually read the repository, so startup succeeds, but it cannot create a pull request on a private repo. Gitea/Forgejo return 404 Not Found for the unauthorized write against the .../pulls endpoint, which is easy to misread as a missing repository. Public repos hide the problem because reads are anonymous.

Fix (recommended): supply your token through the RELEASAURUS_-prefixed environment variable — e.g. RELEASAURUS_FORGEJO_TOKEN for Forgejo, RELEASAURUS_GITEA_TOKEN for Gitea. Releasaurus reads it before the bare *_TOKEN name, and the runner does not inject the prefixed name, so it can’t be shadowed:

env:
  RELEASAURUS_FORGEJO_TOKEN: ${{ secrets.RELEASE_TOKEN }}

Alternative: pass the token on the command line with --token, which takes precedence over every environment variable. Note that command arguments are more likely to appear in CI logs than env vars:

command_args: >-
  --forge forgejo
  --repo ${{ github.server_url }}/${{ github.repository }}
  --token ${{ secrets.RELEASE_TOKEN }}

Azure DevOps: Release Branch Requires “Allow rewriting history”

When updating a release PR, Releasaurus resets the release branch to the tip of the base branch and replays the changelog commit. If the existing release branch has diverged, this is a non-fast-forward update that Azure DevOps rejects unless Allow rewriting history is granted on the release branch (typically releasaurus-release-*).

Grant it under Project Settings → Repositories → {repo} → Security → Branches → {release branch}, setting Allow rewriting history to Allow for the identity holding the PAT. Azure DevOps release also only pushes the git tag — there is no native release object, so no release notes page is published.

Azure DevOps: Merge Commits Are Not Detected

Azure DevOps omits the parents field from its commit list API — only the single-commit endpoint returns it. Releasaurus reads history in bulk, so recovering parents would cost one extra API request per commit. Every Azure commit is therefore reported as a non-merge commit.

Two settings quietly have no effect as a result:

  • skip_merge_commits (default true) filters nothing out.
  • The default body template’s filter(attribute="merge_commit", value=false) clause excludes nothing.

This only matters for completion strategies that create a merge commit. If you complete PRs with Merge (no fast forward) or Semi-linear merge, Azure adds a commit titled Merged PR <n>: <PR title> on top of the source branch’s own commits. That commit becomes its own changelog entry, so the PR’s change is represented twice — once by the merge commit, once by the commits it brought in.

Fix (recommended): complete PRs with Squash commit. Azure then adds a single commit per PR, so there is nothing to filter and no duplication. Rebase and fast-forward is likewise unaffected, since it creates no merge commit.

Alternative: drop individual merge commits with skip_shas (see Skipping or Rewording Commits). That setting applies to the next release only, so it has to be repeated each cycle.

Getting Help

releasaurus --help          # general help
releasaurus <cmd> --help    # command-specific help
releasaurus --version       # version information