Skip to content

feat(cli): snapshot/canary releases for PR previews without git tags #495

Description

@BryanFRD

Problem

No way to publish a non-mergeable preview version of a package from an arbitrary PR branch. Today the prerelease channel mechanism requires the branch to match a configured `workspace.branches` entry — fine for `beta` / `rc` long-lived branches, not for "PR #123 build a one-off `1.2.3-pr-123-abc1234` artifact".

Comparison

  • changesets: `pnpm changeset version --snapshot pr-123` produces `0.0.0-pr-123-` with no git ops
  • semantic-release: `--dry-run` + custom `channel` and `tagFormat`
  • Many monorepos use this for "preview my PR live": each PR pushes `@scope/cli@0.0.0-pr-123-…` to npm, devs install with `npm i @scope/cli@pr-123`.

Proposal

New command: `ferrflow snapshot --tag [--no-git]`

  • Computes next version per package using the normal commit-walk
  • Suffix-rewrites: `1.2.3` → `1.2.3-.` (or `0.0.0-.` if `--from-zero`)
  • Writes versioned files
  • Optionally publishes (runs publish hooks) without committing/tagging/pushing
  • Output: JSON listing every package and its snapshot version, ready to feed into `npm publish --tag` or `cargo publish` from CI

`--no-git` skips the workdir mutation pre-flight so it works on already-modified PR checkouts.

Implementation hints

  • Reuse `monorepo/run/mod.rs` orchestrator; add a `SnapshotOpts` struct that gates the git ops in `release` mode.
  • The version-bumping logic in `src/versioning/strategies.rs` already handles prerelease suffixes — just need to splice the user-provided `` cleanly.
  • `hooks::HookPoint::PrePublish` and `PostPublish` should still fire so npm/cargo publish flows hook in.

Test plan

  • Snapshot run produces correct version string per package
  • `--no-git` runs against a dirty workdir without failing
  • JSON output schema stable for CI consumers

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementImprovement to existing feature

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions