ci(staging): decouple deployment from main
Staging Backend Quality Gate / validate (push) Successful in 14m50s
Staging Backend Quality Gate / publish (push) Failing after 7m58s

This commit is contained in:
Jesse_Chen
2026-08-13 11:57:24 +08:00
parent cf7598b337
commit 013c15a9e9
6 changed files with 127 additions and 82 deletions
@@ -584,27 +584,35 @@ test("Gitea staging mutations resolve bundles from actual gate-run artifacts", (
}
});
test("Gitea deployment follows only a successful staging push gate and keeps rollback manual", () => {
test("Gitea staging deployment is dispatched from staging after the exact push gate", () => {
const quality = read(giteaQualityWorkflow);
const workflow = read(giteaDeployWorkflow);
assert.match(workflow, /workflow_run:\n\s+workflows: \["Staging Backend Quality Gate"\]/);
assert.match(workflow, /workflow_dispatch:/);
assert.match(workflow, /workflow_run\.conclusion == 'success'/);
assert.match(workflow, /workflow_run\.event == 'push'/);
assert.match(workflow, /workflow_run\.head_branch == 'staging'/);
assert.match(workflow, /^on:\n\s+workflow_dispatch:/m);
assert.doesNotMatch(workflow, /workflow_run:|read_ref_sha main|refs\/heads\/main|reviewed main/);
assert.match(workflow, /gate_run_id:/);
assert.match(workflow, /REQUESTED_GATE_RUN_ID: \$\{\{ inputs\.gate_run_id \}\}/);
assert.match(workflow, /actions\/runs\/\$gate_run_id/);
assert.match(workflow, /timed out waiting for source staging quality gate success/);
assert.match(workflow, /concurrency:\n\s+group: staging-mutation\n\s+cancel-in-progress: false\n\s+queue: max/);
assert.match(workflow, /rollback authorization is manual-only/);
assert.match(workflow, /stale staging revision refused/);
assert.match(workflow, /rollback revision is not in current staging history/);
assert.match(workflow, /ALLOW_ROLLBACK: \$\{\{ steps\.revision\.outputs\.allow_rollback \}\}/);
assert.match(workflow, /reviewed main and staging controller heads differ/);
assert.match(workflow, /rollback revision is not in reviewed main history/);
assert.match(workflow, /controller_gate_run_id/);
assert.match(workflow, /def reaches\(\$sha; \$seen\)/);
assert.match(workflow, /\.total_commits == \(\$commits \| length\)/);
assert.match(workflow, /staging advanced during deployment; refusing stale mutation/);
assert.match(workflow, /automatic staging rollback or divergent deploy refused/);
assert.match(workflow, /API_IMAGE: \$\{\{ steps\.images\.outputs\.api_image \}\}/);
assert.match(workflow, /WEB_IMAGE: \$\{\{ steps\.images\.outputs\.web_image \}\}/);
assert.match(quality, /Dispatch exact-SHA staging deployment/);
assert.match(quality, /staging advanced before deployment dispatch; refusing stale release/);
assert.match(quality, /actions\/workflows\/deploy-staging\.yml\/dispatches\?return_run_details=true/);
assert.match(quality, /--arg ref "refs\/heads\/staging"/);
assert.match(quality, /gate_run_id="\$\{GITHUB_RUN_ID:-\}"/);
assert.match(quality, /--arg gate_run_id "\$gate_run_id"/);
assert.match(quality, /allow_rollback:"false"/);
assert.match(quality, /\.workflow_run_id \| select\(type == "number" and \. > 0\)/);
});
test("Gitea migration remains manual and consumes only the gate-pinned web image", () => {
@@ -614,7 +622,7 @@ test("Gitea migration remains manual and consumes only the gate-pinned web image
assert.doesNotMatch(workflow, /workflow_run:|\n\s+push:/);
assert.match(workflow, /concurrency:\n\s+group: staging-mutation\n\s+cancel-in-progress: false\n\s+queue: max/);
assert.match(workflow, /migration requires current staging head/);
assert.match(workflow, /staging migration revision must equal reviewed main head/);
assert.doesNotMatch(workflow, /read_ref_sha main|refs\/heads\/main|reviewed main/);
assert.doesNotMatch(workflow, /--deepen=/);
assert.match(workflow, /staging advanced during migration; refusing stale mutation/);
assert.match(workflow, /WEB_IMAGE: \$\{\{ steps\.image\.outputs\.web_image \}\}/);