fix(ci): let staging migration resolve the latest gated SHA
Independent Staging Quality Gate / validate (push) Successful in 9m38s
Independent Staging Quality Gate / publish (push) Successful in 2m7s

Leave Migrate Staging Database deploy_sha empty (or type latest) to use the newest successful backend-quality-gate push. Filled 40-hex still takes the original path. Production workflows stay required.
This commit is contained in:
jesse-ux
2026-09-15 23:19:44 +08:00
parent 9bf13df023
commit 1a73f64ecd
5 changed files with 111 additions and 6 deletions
@@ -719,6 +719,37 @@ test("Gitea migration remains manual and consumes only the gate-pinned web image
]);
});
test("manual staging migration can leave deploy_sha empty and still requires a successful gate", () => {
const workflow = read(giteaMigrationWorkflow);
const productionDeploy = read(giteaProductionWorkflow);
const productionMigrate = read(giteaProductionMigrationWorkflow);
// 原值: deploy_sha required: true
// 新值: required: false;留空或 latest 自动解析最新成功门禁 SHA,填了仍走原校验
// 原因: TASK-staging-dispatch-autofill-sha-20260915 产品授权;手抄 40 位与机器能算的值相同
assert.match(
workflow,
/deploy_sha:\n\s+description: 留空=自动用最新一个通过门禁的 staging 提交;填写=迁移到指定的 40 位 SHA(回滚用)\n\s+required: false\n\s+type: string/,
);
assert.match(workflow, /if \[\[ -z "\$\{DEPLOY_SHA:-\}" \|\| "\$DEPLOY_SHA" == "latest" \]\]/);
assert.match(workflow, /actions\/runs\?branch=staging&event=push&status=success&limit=100/);
assert.match(workflow, /resolved deploy_sha=\$DEPLOY_SHA \(latest gated staging commit\)/);
assert.match(workflow, /staging 上还没有任何通过门禁的提交,先等门禁跑完再迁移/);
assert.match(workflow, /查不到 staging 的门禁运行记录,Gitea API 请求失败/);
assert.match(workflow, /\[\[ "\$DEPLOY_SHA" =~ \^\[0-9a-f\]\{40\}\$ \]\] \|\| \{ echo "deploy_sha must be a lowercase full commit SHA"/);
assert.match(workflow, /actions\/runs\?head_sha=\$DEPLOY_SHA&branch=staging&event=push&status=success&limit=100/);
assert.match(workflow, /no successful exact-SHA staging quality gate run found/);
assertOrder(workflow, [
'if [[ -z "${DEPLOY_SHA:-}" || "$DEPLOY_SHA" == "latest" ]]; then',
"resolved deploy_sha=$DEPLOY_SHA (latest gated staging commit)",
'[[ "$DEPLOY_SHA" =~ ^[0-9a-f]{40}$ ]] || { echo "deploy_sha must be a lowercase full commit SHA"',
"actions/runs?head_sha=$DEPLOY_SHA&branch=staging&event=push&status=success&limit=100",
"no successful exact-SHA staging quality gate run found",
]);
assert.match(productionDeploy, /deploy_sha:[\s\S]*required: true/);
assert.match(productionMigrate, /deploy_sha:[\s\S]*required: true/);
});
test("Gitea staging mutations use deploy-owned temporary paths", () => {
for (const workflow of [read(giteaDeployWorkflow), read(giteaMigrationWorkflow)]) {
assert.match(workflow, /mktemp -d \/tmp\/jyotisha-staging\.XXXXXXXXXX/);