fix(release): verify the private Pro source pair before creating a draft

A 6.x release creates its draft release object before stage_private_pro_runtime dispatches the private Pro build, which resolves the payload by the exact frozen public commit (docs/release-source-pairs/<sha>.json). When that declaration is absent or names a different pulse_sha, the private build refuses and the run leaves an orphaned draft (v6.4.5-beta.2, v6.4.5-beta.3). Verify the declaration in prepare, before any draft exists, and fail with the exact path to create. This is an unconditional fact check independent of the opt-in harness gate in pulse-dev-infra #443/#444; the release steward still owns choosing the pair. Source issue: pulse-dev-infra #441.

Change-source: pulse-maintainer
This commit is contained in:
pulse-triage[bot]
2026-09-20 14:24:41 +01:00
parent b344b45304
commit f43a7a3e62
+38
View File
@@ -140,6 +140,44 @@ jobs:
fi
echo "[OK] Release dispatch is bound to ${EXPECTED_SOURCE_SHA}"
- name: Verify the private Pro source pair is declared
# A 6.x release stages a private Pro payload that the private build
# resolves by the exact frozen public commit. Verify that declaration
# before any draft release object exists, so a missing or mismatched
# pair cannot orphan another draft. This is a fact check: the release
# steward still owns choosing the pair.
if: ${{ startsWith(github.event.inputs.version, '6.') && github.event.inputs.historical_asset_backfill_only != 'true' && github.event.inputs.draft_only != 'true' }}
env:
GH_TOKEN: ${{ secrets.WORKFLOW_PAT }}
EXPECTED_SOURCE_SHA: ${{ inputs.expected_source_sha }}
PRIVATE_PAIR_REPOSITORY: rcourtman/pulse-enterprise
run: |
set -euo pipefail
if [[ -z "${GH_TOKEN:-}" ]]; then
echo "::error::WORKFLOW_PAT is required to verify the private Pro source pair before dispatch."
exit 1
fi
pair_path="docs/release-source-pairs/${EXPECTED_SOURCE_SHA}.json"
pair_err="$(mktemp)"
if ! pair_content="$(gh api \
-H 'Accept: application/vnd.github+json' \
-H 'X-GitHub-Api-Version: 2026-03-10' \
"repos/${PRIVATE_PAIR_REPOSITORY}/contents/${pair_path}" \
--jq '.content' 2>"${pair_err}")"; then
if grep -qE 'HTTP 404|Not Found' "${pair_err}"; then
echo "::error::${PRIVATE_PAIR_REPOSITORY} has no ${pair_path} for the frozen public commit ${EXPECTED_SOURCE_SHA}. Record that pair, then dispatch again; refusing to create an orphaned draft."
else
echo "::error::Could not verify ${pair_path} in ${PRIVATE_PAIR_REPOSITORY}: $(tr '\n' ' ' <"${pair_err}")"
fi
exit 1
fi
declared_pulse_sha="$(printf '%s' "${pair_content}" | base64 -d | python3 -c 'import json, sys; print(json.load(sys.stdin).get("pulse_sha", ""))')"
if [[ "${declared_pulse_sha}" != "${EXPECTED_SOURCE_SHA}" ]]; then
echo "::error::${pair_path} declares pulse_sha '${declared_pulse_sha}', not the frozen public commit ${EXPECTED_SOURCE_SHA}."
exit 1
fi
echo "[OK] Private Pro source pair ${pair_path} declares pulse_sha ${declared_pulse_sha}."
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with: