Skip to content
FerrFlow

Reference / CLI commands

CLI commands

Run the full release pipeline: bump versions, update changelogs, commit, tag, push, and create a release.

Terminal window
ferrflow release [OPTIONS]
FlagDescription
--dry-runPreview all changes without writing, committing, or pushing
--forceAllow floating tags to move backward to a lower version
--force-version <VERSION>Force a specific version, skipping commit analysis. Format: VERSION (single repo) or NAME@VERSION (monorepo)
--verbose, -vShow detailed output including commit hashes and file diffs

What it does:

  1. Scans commits since the last tag for each package
  2. Determines the version bump from Conventional Commits
  3. Updates all versionedFiles with the new version
  4. Appends the new section to CHANGELOG.md
  5. Creates a git commit, opens a PR, or skips (depending on releaseCommitMode)
  6. Creates and pushes the git tag
  7. Creates a GitHub/GitLab release with the changelog as notes

Starting with FerrFlow v3, the baseline for every bump is the highest semver-valid tag for the package (e.g. my-pkg@v2.4.1 or v2.4.1), not the value in the versioned file.

The versioned file stays the canonical write target so downstream consumers (cargo publish, Docker builds, etc.) always see a coherent version, but it is no longer the source of truth for the bump computation. This prevents two classes of silent failure:

  • Parallel release workflows: two pull requests merging back-to-back used to spawn two release jobs that both read the pre-release version from the file. Both computed the same next version — the second push either collided or was silently skipped. Today the second workflow sees the first workflow’s freshly-pushed tag and computes the correct next version on top of it.
  • File/tag drift: a revert, a merge from an old branch, or a manual edit could leave the file behind the tags. Bumping from a stale file produced tags that collided with history and the release got silently skipped with tag X already exists, skipping. The tag now wins; the file only wins when it is genuinely ahead (human pre-bump).

Resolution order, per package:

TagFileBaseline used
presentpresentmax(tag, file) by semver
presentabsenttag
absentpresentfile
absentabsentstrategy bootstrap (see below)

When no tag exists yet and the format has no version to read (notably go.mod, which stores the version in tags alone), FerrFlow bootstraps from the versioning strategy’s zero value:

StrategyBootstrap baseline
semver, zerover0.0.0
sequential0
calver-seq0.0
calver, calver-shortignored — bump derives from today’s date

From there the first feat: commit bumps to 0.1.0 / 1 / today’s date / … and the release flow creates the tag itself — no git tag foo@v0.0.0 ceremony required before the first run.


Preview what ferrflow release would do without making any changes. Equivalent to ferrflow release --dry-run.

Terminal window
ferrflow check

Generate or update CHANGELOG.md only, without bumping versions or creating tags.

Terminal window
ferrflow changelog [OPTIONS]
FlagDescription
--dry-runPrint the changelog entry without writing to disk

Scaffold a config file for the current repository. Detects existing version files (Cargo.toml, package.json, etc.) and generates the appropriate config.

Terminal window
ferrflow init [OPTIONS]
FlagDescription
--format <FORMAT>Config file format: json, json5, or toml

Show the current version of each package and whether a release would be triggered.

Terminal window
ferrflow status [OPTIONS]
FlagDescription
--output <FORMAT>Output format: text (default) or json

Example output:

api 1.2.3 minor bump pending (1 feat commit)
site 0.4.1 no release (only chore commits)

Print the current version of one or all packages. Useful in CI scripts.

Terminal window
ferrflow version [PACKAGE] [OPTIONS]
FlagDescription
--jsonOutput as JSON

Returns the version from the latest git tag matching the package’s tag template.


Print the latest tag for one or all packages.

Terminal window
ferrflow tag [PACKAGE] [OPTIONS]
FlagDescription
--jsonOutput as JSON

These flags work with all commands:

FlagDescription
--config <PATH>Path to a custom config file (default: auto-detected). Also accepts FERRFLOW_CONFIG env variable.
--versionPrint the FerrFlow version and exit
--help, -hPrint help