mix verify.release_parity (scrypath v0.3.5)

Copy Markdown View Source

Verifies that the file list inside the published Hex tarball for X.Y.Z matches the file list inside lib/ + guides/ + docs/ at git tag scrypath-vX.Y.Z.

Usage

mix verify.release_parity 0.3.0
mix verify.release_parity 0.3.0 --json

Exit codes

  • 0 — parity (no drift)
  • 2 — drift detected (POSIX "intentional failure")
  • 1 — runtime error (network failure, missing tag, tarball fetch failure)

Retry behavior

Inherits SCRYPATH_RELEASE_VERIFY_ATTEMPTS (default 10) and SCRYPATH_RELEASE_VERIFY_SLEEP_MS (default 15_000) from verify.release_publish so daily cron runs do not false-fail during CDN propagation of a freshly-cut release.

Implementation notes

Path-set equality only. Content-digest comparison is deliberately deferred — git archive at a tag and mix hex.build from the same commit produce byte-equal contents because they read the same locked git tree, so content drift would require post-tag file mutation (orthogonal to the v1.2 incident class).

The module is split into a pure compute/2 + a thin run/1 so the drift-exit-code semantics (via System.halt(2)) can be unit-tested without killing the ExUnit runner (Pitfall 11).

Summary

Functions

Pure path-set comparison. Returns :parity when the two MapSets are equal, otherwise a {:drift, only_in_git_sorted, only_in_hex_sorted} tuple.

Validates the one-and-only user-supplied argument against a canonical semver regex before it reaches any subprocess (Security V5 / Pitfall 7).

Renders the --json output shape documented in docs/releasing.md.

Retry loop copied from verify.release_publish.ex:58-75 — same env-var names, same semantics — so maintainers learn one retry model.

Functions

compute(git_paths, hex_paths)

@spec compute(MapSet.t(String.t()), MapSet.t(String.t())) ::
  :parity | {:drift, [String.t()], [String.t()]}

Pure path-set comparison. Returns :parity when the two MapSets are equal, otherwise a {:drift, only_in_git_sorted, only_in_hex_sorted} tuple.

Exposed publicly for Pitfall 11 unit testability.

parse_version!(arg1)

@spec parse_version!([String.t()]) :: String.t() | no_return()

Validates the one-and-only user-supplied argument against a canonical semver regex before it reaches any subprocess (Security V5 / Pitfall 7).

render_json(version, status, only_in_git, only_in_hex)

@spec render_json(String.t(), :parity | :drift, [String.t()], [String.t()]) ::
  String.t()

Renders the --json output shape documented in docs/releasing.md.

:parity status renders as "ok" in the JSON envelope.

retry_until!(label, attempts, sleep_ms, fun)

@spec retry_until!(String.t(), pos_integer(), non_neg_integer(), (-> :ok
                                                               | {:error,
                                                                  term()})) ::
  :ok | no_return()

Retry loop copied from verify.release_publish.ex:58-75 — same env-var names, same semantics — so maintainers learn one retry model.

Exposed publicly for Pitfall 1 unit testability (stub the fun with a counter-backed Agent).