Skip to content

ci(publish): fail loudly when no runner can accept the job - #28

Merged
ken-jo merged 1 commit into
mainfrom
ci/publish-timeout-and-ref-policy
Aug 23, 2026
Merged

ci(publish): fail loudly when no runner can accept the job#28
ken-jo merged 1 commit into
mainfrom
ci/publish-timeout-and-ref-policy

Conversation

@ken-jo

@ken-jo ken-jo commented Aug 23, 2026

Copy link
Copy Markdown
Contributor

The failure this closes

The publish job runs on a single workflow-restricted host. When it becomes unschedulable — host down, or the group's allow-list naming a ref the caller no longer writes — GitHub does not raise an error. The job queues until the 24-hour limit expires, with the runner reported online and busy: false and no annotation anywhere.

That is exactly what happened in 2026-08: every plugin repo's publish stopped working for days, and there was no red check to point at. The pins were repointed, CI went green, and publishing was still silently stuck because moving the caller's ref moved it out of the runner group's allow-list.

timeout-minutes: 15 on the publish job turns that into a red check on the first release after a break. timeout-minutes: 30 on the GitHub-hosted candidate build for the same reason. The publish job uploads a zip in well under a minute, so neither bound is near legitimate work.

Ref policy, brought in line with the callers

All seven plugin repos now reference this workflow as @main rather than a commit SHA, and the org allow-list is ...@refs/heads/main — one entry that never has to move again. The header comment claimed the opposite, so it is rewritten rather than left to be "fixed" back into the trap.

A SHA in the caller was never a second lock. The runner group matches its allow-list against the exact ref the caller writes, so a SHA meant the same decision lived twice — once in a reviewed workflow file, once in an org setting no pull request sees — and drift between the two is the outage above.

What actually guards the credential is unchanged, and now stated where the next reader will look:

  • main in this repo is branch-protected — a revision reaches the pipeline only through a reviewed merge here.
  • The caller is repository_dispatch-only, so it is always loaded from its own protected default branch and a tag can never supply the workflow that receives the key.
  • The runner group still admits only this workflow onto the publisher host.
  • The tag proofs still run before the key is in scope: annotated tag, peeled commit equal to the checked-out HEAD and reachable from origin/main, version matching plugin.json, slug matching plugin.json.id.

Verified

lvis-plugin-local-indexer published 0.5.35 through this path after the allow-list was corrected (plugin_id 9, ed25519, signer_key_id prod-v1) — the first successful publish since 2026-08-21.

🤖 Generated with Claude Code

https://claude.ai/code/session_01W9K9WE1ATSqYFStZGtLpNk

The publish job runs on a single workflow-restricted host, so the ways it can
become unschedulable are real and silent: the host down, or the allow-list
naming a ref the caller no longer writes. Neither raises an error. The job sits
queued until the 24-hour limit expires, runner reported online and idle, with no
red check anywhere — which is how every plugin stopped publishing for days in
2026-08 without a single failed run to point at. A timeout turns that into a red
check on the first release after the break, which is the only signal anyone was
ever going to look at.

Fifteen minutes for a job that uploads a zip in under a minute; thirty for the
GitHub-hosted candidate build.

The header's ref policy is rewritten to match what the callers now do. A SHA in
the caller was not a second lock: the runner group matches its allow-list
against that exact ref, so the same decision lived twice — once in a reviewed
workflow file, once in an org setting no pull request sees — and drift between
the two is precisely the outage above. What guards the credential is unchanged
and stated where the next reader will look: protected main here, a dispatch-only
caller, one workflow admitted to the publisher host, and the tag proofs that run
before the key is in scope.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01W9K9WE1ATSqYFStZGtLpNk
@ken-jo
ken-jo merged commit 313e56d into main Aug 23, 2026
1 check passed
@ken-jo
ken-jo deleted the ci/publish-timeout-and-ref-policy branch August 23, 2026 16:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant