Verifies that git status is clean for all pathspecs that ship in the Hex
tarball plus test/**.
Runs as the first step of every publish path (canonical release-please flow, manual-recovery workflow, and per-push CI) so a release cannot ship files that were not reviewed and merged.
This gate exists because an earlier release cycle shipped a partial tarball
when uncommitted files did not travel to the release tag. See
docs/releasing.md § Historical context for why parity and workspace gates
matter on publish paths.
Usage
mix verify.workspace_cleanThe task takes no arguments. There is deliberately no escape-hatch flag or environment variable — the friction is the feature. Real emergencies require commenting out the workflow step in a PR.
Summary
Functions
Returns the pathspec list used by run/1 — derived from
mix.exs package.files plus "test".
Pure classifier for git status --porcelain output.
Functions
@spec build_pathspecs() :: [String.t()]
Returns the pathspec list used by run/1 — derived from
mix.exs package.files plus "test".
Exposed publicly for testability.
@spec classify(String.t(), integer(), non_neg_integer()) :: {:ok, String.t()} | {:dirty, String.t()} | {:git_error, String.t()}
Pure classifier for git status --porcelain output.
Split out of run/1 so tests can exercise each branch without a real git
subprocess (mirrors the Mix.Tasks.Verify.ReleaseParity.compute/2 seam).
Returns one of:
{:ok, message}— clean tree (empty output, exit 0){:dirty, paths}— uncommitted or untracked files present (non-empty output, exit 0){:git_error, err}—git statusitself failed (non-zero exit)