Files
DeepSeek-Reasonix/scripts/verify-release-push-ci.sh
SivanCola ab24371d98 fix(release): bind stable tags to reviewed candidate
Problem:
The stable helper could consume immutable version tags if main-v2 advanced while exact-SHA CI or the protected relay was starting. Manual CLI and Desktop recovery also still accepted RC tags despite the official-only release contract.

Root cause:
The helper sampled main-v2 once, pushed only tag refs, and the orchestrator required the tags to equal the later branch tip. The candidate was not proven to be the commit that changed the target reviewed Notes record.

Fix:
Bind normal candidates to their reviewed Notes change, revalidate exact push CI from the protected control plane, include main-v2 as a guarded ref in the atomic tag transaction, and accept the immutable candidate after later protected branch advances. Restrict manual CLI and Desktop recovery to official versions while retaining historical reusable-workflow parsing.

Verification:
- bash scripts/release-stable.test.sh
- bash scripts/release-workflows.test.sh
- node --test scripts/release-notes.test.mjs
- actionlint on all active release workflows
- site contract tests, SignPath contract tests, Desktop control-plane test, cache guard, and git diff --check
2026-08-03 01:05:09 +08:00

50 lines
1.7 KiB
Bash
Executable File

#!/usr/bin/env bash
# Wait for successful push CI on one immutable main-v2 candidate.
set -euo pipefail
if [ "$#" -ne 1 ] || [[ ! "$1" =~ ^[0-9a-f]{40}$ ]]; then
echo "usage: verify-release-push-ci.sh FULL_COMMIT_SHA" >&2
exit 2
fi
candidate="$1"
repository="${RELEASE_REPOSITORY:-esengine/DeepSeek-Reasonix}"
wait_seconds="${RELEASE_CI_WAIT_SECONDS:-1800}"
poll_seconds="${RELEASE_CI_POLL_SECONDS:-10}"
if [[ ! "$wait_seconds" =~ ^[0-9]+$ ]] || [[ ! "$poll_seconds" =~ ^[1-9][0-9]*$ ]]; then
echo "RELEASE_CI_WAIT_SECONDS must be non-negative and RELEASE_CI_POLL_SECONDS must be positive" >&2
exit 2
fi
for command in gh jq; do
command -v "$command" >/dev/null || {
echo "required command is unavailable: $command" >&2
exit 2
}
done
deadline=$((SECONDS + wait_seconds))
while :; do
runs="$(gh run list --repo "$repository" --workflow ci.yml --commit "$candidate" \
--event push --limit 20 --json headSha,status,conclusion 2>/dev/null || true)"
run_status="$(jq -r --arg sha "$candidate" \
'[.[] | select(.headSha == $sha)][0].status // ""' <<<"$runs" 2>/dev/null || true)"
conclusion="$(jq -r --arg sha "$candidate" \
'[.[] | select(.headSha == $sha and .status == "completed")][0].conclusion // ""' <<<"$runs" 2>/dev/null || true)"
case "$conclusion" in
success)
echo "successful main-v2 push CI verified: $candidate"
exit 0
;;
failure | cancelled | timed_out | action_required | startup_failure)
echo "CI for $candidate concluded $conclusion" >&2
exit 1
;;
esac
if [ "$SECONDS" -ge "$deadline" ]; then
echo "timed out waiting for successful main-v2 CI on $candidate (last status: ${run_status:-missing})" >&2
exit 1
fi
sleep "$poll_seconds"
done