Skip to content

feat(versioning): add versionCommand, a command that decides the release version - #1331

Merged
BryanFRD merged 1 commit into
mainfrom
feat/version-command
Oct 20, 2026
Merged

BryanFRD merged 1 commit into
mainfrom
feat/version-command

Conversation

@BryanFRD

Copy link
Copy Markdown
Contributor

Closes #1021

Adds versionCommand (workspace, with a per-package override). Its stdout is the version a release ships.

  • Runs only in release (dry run included), after the bump is decided and before any version file, tag or changelog heading is written. Also runs for packages bumped by the dependency cascade.
  • check, preview, why and impact never run it. check --json reports next_version and tag as null, text output says the version is set by the command.
  • Output is trimmed, a leading v dropped, and rejected if empty, not semver (semver/zerover), not past the current version, or if the tag already exists. Printing the current version skips the package.
  • Rejected on packages in linked/fixed groups. --force-version wins over it.

next_version and tag in check --json are now nullable, which only shows when a versionCommand is configured.

Schemas, en/fr config docs and the release-algorithm diagram are updated.

@ferrfleet-interne ferrfleet-interne Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nothing blocking. The resolved version reaches the tag, the changelog, the manifests and bumped_versions on both the direct path and the cascade path. check, preview, why and graph never execute the command. Nits are inline: the non-semver output is not checked to go past the current version although the docs say it is, and the prerelease channel is not checked.

Comment on lines +110 to +117
_ => {
let valid = version
.chars()
.all(|c| c.is_ascii_alphanumeric() || matches!(c, '.' | '-' | '+' | '_'));
if !valid {
bail!("versionCommand must print a bare version, got {output:?} from: {command}");
}
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: for calver, sequential and the other non-semver strategies, nothing checks that the output goes past current, but the docs and schema say "must be a version that goes past the current one". If a calver command prints 2025.1.1 while the current version is 2026.1.1, and that tag no longer exists, the release goes backwards without an error. I'd add a strategy-aware comparison (numeric, dot-separated segments works for every calver and sequential format). The alternative is to limit the doc sentence to semver and zerover.

Also on this function: on a prerelease channel, a stable output such as 2.0.0 is accepted, and the package then ships with is_prerelease: true and a stable version. Either reject that or document it.

Comment thread src/monorepo/run/cascade.rs Outdated
@@ -30,16 +31,19 @@ pub(super) struct CascadeSink<'a> {

#[allow(clippy::too_many_arguments)]

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: the function takes 5 arguments now, so this allow no longer suppresses anything and can go.

@BryanFRD
BryanFRD force-pushed the feat/version-command branch from 974eadc to a038365 Compare October 20, 2026 10:06

@ferrfleet-interne ferrfleet-interne Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-checked after the rebase onto the refactored run pipeline. Nothing blocking. The resolved version still reaches the tag, the changelog, the manifests and bumped_versions through PackageRun and CascadedRelease, and the read-only commands still pass false. shadow-release now runs the command too, which matches how it runs hooks.

@BryanFRD
BryanFRD merged commit fcf98b5 into main Oct 20, 2026
34 checks passed
@BryanFRD
BryanFRD deleted the feat/version-command branch October 20, 2026 10:33
ferrflow Bot added a commit that referenced this pull request Oct 20, 2026
## [7.32.0] - 2026-10-20

### Features

- feat(versioning): add versionCommand, a command that decides the release version (#1331)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

RFC: let a hook decide the version number, without making read-only commands run user code

1 participant