fix(devtag-guard): snapshot explicit VERSION at source time (#194 finding)

The guard read $VERSION, but app bodies set VERSION to the derived default
before calling it, so accidental local --publish without an explicit version
or v* tag still pushed. Capture PARITY_VERSION_EXPLICIT at source time and
gate on that instead.
This commit is contained in:
Oleks
2026-06-02 05:08:05 +03:00
parent 6d4fec3f71
commit 9107923c5a
2 changed files with 19 additions and 1 deletions
+7
View File
@@ -7,6 +7,13 @@ semantic versioning; the version is a conceptual tag (no git tag is created).
## Unreleased
- **Fix (safety): dev-tag guard was ineffective.** Every publish app body runs
`VERSION="$(parity_derive_version <default>)"` before `parity_devtag_guard`, so
by the time the guard checked `$VERSION` it was always non-empty (the derived
default) and an accidental local `--publish` with no explicit version and no
`v*` tag still pushed (cluster #194 finding). The guard now reads a source-time
snapshot `PARITY_VERSION_EXPLICIT` captured before any clobber, so it correctly
blocks unless the caller set `$VERSION` or `$CI_COMMIT_TAG` matches `^v[0-9]`.
- `pipeline-doctor` (cluster #191 security sweep): added a scoped per-file check
asserting **no `set -x` in token-bearing `ci/*.sh` scripts** going forward — a
script that references a registry token (`REGISTRY_TOKEN` / `CI_REGISTRY_TOKEN`
+12 -1
View File
@@ -22,6 +22,15 @@ PARITY_REGISTRY_OWNER="${PARITY_REGISTRY_OWNER:-oleks}"
# Local on-disk stage. BUILD-parity artifacts land here; push-staged replays them.
PARITY_STAGE_DIR="${PARITY_STAGE_DIR:-${PWD}/.parity-stage}"
# Snapshot whether the caller set $VERSION EXPLICITLY, captured at source time —
# BEFORE any app body overwrites VERSION with the derived default version
# (VERSION="$(parity_derive_version <default>)"). parity_devtag_guard reads this
# snapshot, not the live $VERSION, so an accidental local `--publish` with no
# explicit version and no v* tag is still blocked instead of silently shipping
# the flake's default version. Set-once: re-sourcing won't clobber the capture.
: "${PARITY_VERSION_EXPLICIT=${VERSION:-}}"
export PARITY_VERSION_EXPLICIT
# ---------------------------------------------------------------------------
# Token resolution: $REGISTRY_TOKEN -> `pass` fallback -> named hard fail.
# Prints the token on stdout so a caller can `tok="$(parity_resolve_token)"`.
@@ -75,7 +84,9 @@ parity_derive_version() {
# the flake's default development version.
# ---------------------------------------------------------------------------
parity_devtag_guard() {
if [ -n "${VERSION:-}" ]; then
# Read the source-time snapshot, NOT the live $VERSION (which the app body
# has already set to the derived default by the time this runs).
if [ -n "${PARITY_VERSION_EXPLICIT:-}" ]; then
return 0
fi
if printf '%s' "${CI_COMMIT_TAG:-}" | grep -Eq '^v[0-9]'; then