The release script tests could only observe behaviour through a process
exit code, because die() called process.exit from inside otherwise-pure
functions. That forced every test to spawn a subprocess, which forced
its input to come from cli/package.json, which is why editing that file
kept breaking tests — most recently #39658, and next the difyctl version
bump that cli-release.yml requires on every release.
Move the decisions into lib/release-rules.mjs and lib/edge-manifest.mjs,
which take every input as an argument and return values instead of
exiting. release-naming.mjs and release-r2-edge.mjs keep argv parsing,
manifest reading, stdout and exit codes, and nothing else.
Tests now split by what they ask. Logic is unit-tested against literal
inputs, the shells are tested for plumbing only, and release-config.test.ts
is the single place that reads the real manifest — asserting it is
internally consistent, never what it currently contains. Editing
cli/package.json no longer breaks a logic test; a malformed config still
fails. Verified by mutating each field in both directions.
Three intentional behaviour changes:
- compat-check compares the numeric A.B.C core only, ignoring prerelease
and build suffixes, so Dify 1.16.0-rc1 now satisfies a 1.16.0 window.
This matches the shipped runtime check in src/version/compat.ts, which
already stripped suffixes; the release gate was the one disagreeing.
Removes the hand-rolled prerelease ordering entirely.
- validate now rejects a missing or inverted compat window. It previously
passed such a config while github-env emitted minDify=undefined.
- release-r2-edge reports a bad channel version under its own name rather
than release-naming's, since it no longer borrows that script's die().
release-config.test.ts also pins the install scripts to the naming config.
They hardcode artifact names by necessity — they run standalone on a user
machine with no repo and no node — so changing tagPrefix or checksumsSuffix
now fails until all four installers are updated to match, instead of
silently publishing names no installer looks for.