mix verify.release_parity (relyra v1.5.4)

Copy Markdown View Source

Verifies that the file list inside the published Hex tarball for X.Y.Z matches the file list at git tag vX.Y.Z over Relyra's full package.files scope (lib/, priv/, docs/, guides/, and root artifacts).

Usage

mix verify.release_parity 1.4.0
mix verify.release_parity 1.4.0 --json

Exit codes

  • 0 — parity (no drift)
  • 2 — drift detected or test_support path in published tarball
  • 1 — runtime error (network failure, missing tag, tarball fetch failure)

Retry behavior

RELYRA_RELEASE_VERIFY_ATTEMPTS (default 10) and RELYRA_RELEASE_VERIFY_SLEEP_MS (default 15_000) allow CDN propagation retries after a freshly-cut release.

Implementation notes

Path-set equality is the primary gate — outer .tar SHA256 may differ while extracted contents match. Any published path containing test_support fails closed before the path-set diff (TD-02 defense-in-depth).

Summary

Functions

Hard-fails with exit 2 when published paths include test_support.

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

Returns sorted path prefixes and root files matching mix.exs package.files.

Filters relative paths to the package.files scope and excludes test_support.

Validates the version argument against canonical semver before any subprocess.

Returns true when any path contains test_support.

Renders the --json output envelope. Parity renders as "ok".

Retry loop with env-configurable attempts and sleep between transient failures.

Functions

assert_no_test_support!(paths)

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

Hard-fails with exit 2 when published paths include test_support.

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 {:drift, only_in_git_sorted, only_in_hex_sorted}.

expected_relative_paths()

@spec expected_relative_paths() :: [String.t()]

Returns sorted path prefixes and root files matching mix.exs package.files.

filter_package_paths(paths)

@spec filter_package_paths([String.t()]) :: [String.t()]

Filters relative paths to the package.files scope and excludes test_support.

parse_version!(arg1)

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

Validates the version argument against canonical semver before any subprocess.

paths_contain_test_support?(paths)

@spec paths_contain_test_support?([String.t()]) :: boolean()

Returns true when any path contains test_support.

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 envelope. Parity renders as "ok".

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 with env-configurable attempts and sleep between transient failures.