Centralize release naming (tag, asset filenames, checksum file, target
list, arch/os tokens) so producers derive from one source instead of
duplicating literals across build, checksum, and workflow files.
- cli/package.json: add difyctl.release block (tagPrefix, binName,
checksumsSuffix, targets[id/bunTarget/exe]) as the naming data source.
- cli/scripts/release-naming.mjs: new format source + validator; subcommands
tag/asset/checksums/tag-prefix/targets/validate.
- release-build.sh, release-write-checksums.sh: derive target list and asset
names from release-naming.mjs; drop hardcoded maps and literals.
- release-validate-manifest.sh: run release-naming.mjs validate, rejecting a
malformed difyctl.release before any build derives from it.
- cli-release.yml: emit tagPrefix from the manifest step; tag guard,
idempotency check, tag_name, and files glob all derive from it.
- install-cli.sh, install.ps1: standalone installers stay hardcoded by
convention; add a comment pointing at the source.
- cli-release.yml: workflow_dispatch/workflow_call/repository_dispatch/tag
triggers; version sourced from cli/package.json (not the trigger). Split into
validate + release jobs with an idempotency guard (gh release view) and a
tag-vs-manifest match guard so a difyctl-v* tag push must equal the manifest
version (prevents a dangling/mismatched tag). Releases may be cut from any
branch. Concurrency serialized (fixed group, cancel-in-progress: false) so
releases never double-publish.
- install-cli.sh: tokenless resolution via git/matching-refs, channel-aware
(stable/rc) selection, fail-closed sha256 verification; distinguishes a fetch
failure (network / API rate limit) from "no release found".
- install.ps1: Windows installer at parity with install-cli.sh.
- install-cli.test.ts: resolver unit tests (rc ordering, channel filter).
- .bun-version: pin Bun 1.3.11 for reproducible --compile builds.