Split out of #91 §4, which was filed as a note rather than an action and stayed unaddressed when #468 closed the rest of that issue. Recording it so it is not lost.
What it is now
.github/workflows/npm-publish.yml gates the publish on ci.yml being green for the exact SHA it is about to ship. It does that by polling:
- name: Wait for ci.yml to succeed on ${{ github.sha }}
run: |
for i in $(seq 1 60); do
run=$(gh api "repos/$REPO/actions/workflows/ci.yml/runs?head_sha=$SHA&per_page=1" --jq '.workflow_runs[0] // empty')
...
sleep 30
done
Sixty attempts, thirty seconds apart — a thirty-minute ceiling.
Why it is worth changing
It works, and it has not failed. The objections are about shape rather than correctness:
- A runner sits idle for the duration. Thirty minutes of billed time doing nothing but
gh api calls every half minute.
- The ceiling is arbitrary. A CI run slower than thirty minutes — a cold cache, a queued runner, a re-run — times out and fails a release that was going to be fine. There is no signal distinguishing "CI failed" from "CI was slow today".
- It re-implements something the platform provides.
workflow_run fires when a workflow completes, with the conclusion attached.
Why it is not trivial
The obvious rewrite does not work as-is, which is presumably why it was left as a note:
workflow_run runs against the default branch's copy of the workflow file, and its github.sha is the default branch head, not the SHA that triggered the upstream run. The publish job would have to read github.event.workflow_run.head_sha and check that commit out explicitly.
- The publish is also reachable by
release: published and by workflow_dispatch, so workflow_run would be a third trigger rather than a replacement, and all three would need to converge on the same guard.
- The merged-history assert (
compare/main...$SHA) and the "already published / older than latest" check must keep running on whichever path fires.
So this is a real piece of work on the release path, not a cleanup. It should be done on its own, with the understanding that a mistake here is only visible at the next release.
Acceptance
- The publish no longer holds a runner idle waiting for CI.
- A CI run that takes longer than thirty minutes still publishes.
- A CI run that fails still blocks the publish, on every trigger path.
- The merged-history assert and the version checks still run.
Priority: P3 — the current loop is correct, this is cost and robustness.
Split out of #91 §4, which was filed as a note rather than an action and stayed unaddressed when #468 closed the rest of that issue. Recording it so it is not lost.
What it is now
.github/workflows/npm-publish.ymlgates the publish onci.ymlbeing green for the exact SHA it is about to ship. It does that by polling:Sixty attempts, thirty seconds apart — a thirty-minute ceiling.
Why it is worth changing
It works, and it has not failed. The objections are about shape rather than correctness:
gh apicalls every half minute.workflow_runfires when a workflow completes, with the conclusion attached.Why it is not trivial
The obvious rewrite does not work as-is, which is presumably why it was left as a note:
workflow_runruns against the default branch's copy of the workflow file, and itsgithub.shais the default branch head, not the SHA that triggered the upstream run. The publish job would have to readgithub.event.workflow_run.head_shaand check that commit out explicitly.release: publishedand byworkflow_dispatch, soworkflow_runwould be a third trigger rather than a replacement, and all three would need to converge on the same guard.compare/main...$SHA) and the "already published / older than latest" check must keep running on whichever path fires.So this is a real piece of work on the release path, not a cleanup. It should be done on its own, with the understanding that a mistake here is only visible at the next release.
Acceptance
Priority: P3 — the current loop is correct, this is cost and robustness.