Skip to content

[SWR-VERSION-BUILD-STAMPING] Enforce placeholder versions: fail the build when any source version field isn't 0.0.0-dev #25

@MelbourneDeveloper

Description

@MelbourneDeveloper

The bug

Repos store real version numbers in their source manifests (package.json, pubspec.yaml, *.csproj, Cargo.toml, shipwright.json). Every release then bumps those fields and commits/PRs the bump back — producing version churn on tracked source on every single release.

The correct, universal behaviour:

  • Every package carries a placeholder version (0.0.0-dev) in source so it runs/builds locally.
  • On deployment, the git tag is the single source of truth for the version — it is stamped into the artifacts at build time, in the runner working tree only, and is never committed back.

This is not monorepo- or registry-specific. It applies to every Shipwright repo and every language.

Status of the spec

[SWR-VERSION-BUILD-STAMPING] already states this rule correctly and universally — "All version fields in source (Cargo.toml, package.json, *.csproj, pubspec.yaml, shipwright.json) MUST be 0.0.0-dev on every branch at all times" and "Release jobs MUST NOT commit, push, or move source-control refs after the tag exists."

So the rule is clear. What's missing is enforcement — nothing fails when a repo drifts off the placeholder, so the churn keeps happening in practice.

Ask

Add an acceptance gate ([SWR-GATE-*]) that:

  1. Scans every version carrier in the repo (package.json, pubspec.yaml, *.csproj, Cargo.toml, shipwright.json, …).
  2. Fails the build if any of them is not the 0.0.0-dev placeholder (on PRs and on main), with a message pointing at the offending file/line.
  3. Is wired into the standard CI gate so a real version can never be committed to source.

That turns the existing rule from documentation into something that is actually enforced, which is what prevents the churn.

Real-world trigger

MelbourneDeveloper/dart_node (Dart → pub.dev) had real versions (0.11.0-beta, and one package hard-coded at the release version 0.13.0-beta) sitting in pubspec.yaml, and its release flow committed/PR'd the bumps back to main. Fixed by resetting every version: to 0.0.0-dev and stamping the tag version in the runner at publish time (zero source churn) — but only after the drift had already shipped, because no gate caught it.

(Edited: this issue originally and incorrectly framed the problem as a monorepo/registry gap. The placeholder rule is universal and already specified; the real gap is enforcement.)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    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