Skip to content

ci: unblock pinned-actions gate and pr title check - #10

Closed
will-wang-opus wants to merge 3 commits into
mainfrom
willw-0814--pin-check-reusable
Closed

ci: unblock pinned-actions gate and pr title check#10
will-wang-opus wants to merge 3 commits into
mainfrom
willw-0814--pin-check-reusable

Conversation

@will-wang-opus

@will-wang-opus will-wang-opus commented Aug 14, 2026

Copy link
Copy Markdown
Contributor

What & why

Two CI gates in this repo were broken. Both are fixed here.

1. check (actions-pinned-check) — the required gate was failing because its inline implementation declared runs-on: opus-runner-standard, a self-hosted runner with no available capacity. The job never ran a step: it queued for 24h and was killed ("exceeded the maximum execution time while awaiting a runner"). It now consumes the shared iac gate through its composite action (SEC-254), which also closes a correctness gap — the inline grep had no exemption for first-party opus-pro/*@main refs, so it would have wrongly flagged this very change. The job stays on opus-runner-standard because only that runner's allow-listed IP can resolve the private opus-pro/iac action.

2. check-pr-basics — failing on every PR since the org IP allow list was enabled:

Couldn't retrieve or parse the config file specified - HttpError: ... the `opus-pro`
organization has an IP allow list enabled, and your IP address is not permitted to
access this resource.

thehanimo/pr-title-checker was reading pull_request_title.json through the GitHub contents API, and GitHub-hosted runner IPs are not on the allow list. Switching configuration_pathlocal_configuration_path reads the same file from the checkout that already runs in the job. With LABEL.name empty in the config, the label/check calls short-circuit, so the config fetch was the action's only API call — the gate is now entirely API-free and unaffected by the allow list. The sibling repos (agent-opus, clip-apps) were never hit because they pull the config from the public raw.githubusercontent.com URL and run on self-hosted runners.

Note: opened as a fresh PR because the original PR #9 was already squash-merged and its branch billyen-sec-254 deleted, so a commit could not be added to it. Direct pushes to master/main are prohibited.

AI coding brief

  • Original request: Fix the failing CI check gate on PR ci: pin github actions to commit shas #9 (SEC-254, "pin GitHub Actions to commit SHAs"). Goal: get the shared pinned-actions gate working on this repo. Follow-up: fix the check-pr-basics failure on this PR.
  • Manual interventions: None. The check-pr-basics diagnosis came from the run log, not from the check's own error message, which only said the config file could not be parsed.
  • Retro:
    • State up front whether the target PR may already be merged/closed, so the agent picks "add a commit to the branch" vs "open a fresh PR" without discovering it mid-task.
    • Name the annotation when one exists ("awaiting a runner") — the first failure was runner starvation, not an unpinned ref, and the annotation says so directly.
    • "Fix the failing check" prompts are best served by reading the raw job log first: both failures here presented as a generic red X whose surface message pointed at the wrong layer (config parse error, not org IP allow list).

will-wang-opus and others added 2 commits August 14, 2026 15:33
The inline gate declared `runs-on: opus-runner-standard`, a self-hosted
runner that never became available — the job on PR #9 starved in the queue
and was killed after 24h ("exceeded the maximum execution time while
awaiting a runner"), failing the required `check`.

Replace the hand-rolled jobs section with a one-line call to the shared
reusable gate at opus-pro/iac. This also fixes correctness: the inline grep
had no exemption for first-party `opus-pro/*@main` refs, so it would have
wrongly rejected this very change; the reusable gate parses YAML and exempts
opus-pro/*, local ./ and docker@sha256.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The workflow_call caller form couldn't resolve/reach the private opus-pro/iac
reusable workflow from this repo. Use the iac composite action instead, on a
job that keeps runs-on: opus-runner-standard — only that runner's allow-listed
IP can fetch the private iac action. Same shared gate logic (check.py), same
`check` job name for the required status check.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The org IP allow list rejects contents-API calls from GitHub-hosted
runners, so pr-title-checker failed to fetch pull_request_title.json and
the gate failed on every PR. local_configuration_path reads the same file
from the checkout; with an empty LABEL.name it was the only API call the
action made.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@will-wang-opus will-wang-opus changed the title ci: run actions-pinned-check via reusable workflow ci: unblock pinned-actions gate and pr title check Aug 17, 2026
@will-wang-opus
will-wang-opus deleted the willw-0814--pin-check-reusable branch August 17, 2026 17:41
will-wang-opus added a commit that referenced this pull request Aug 17, 2026
## What & why

This repo is public. Two of its gates were broken by assumptions that
only hold for our private repos.

**1. `actions-pinned-check` never ran.** The job declared `runs-on:
opus-runner-standard`, a self-hosted runner. It has never once been
assigned a runner in this repo — every run sat queued with
`runner_name=""` until GitHub auto-cancelled it at the 24h ceiling ([run
31613024589](https://github.com/opus-pro/.github/actions/runs/31613024589),
[run
31847701356](https://github.com/opus-pro/.github/actions/runs/31847701356)).
The identical gate finished in 8 seconds when it ran on `ubuntu-latest`
([run
31595196968](https://github.com/opus-pro/.github/actions/runs/31595196968)).

Beyond the hang, a public repo should not target self-hosted runners at
all: a pull request from a fork runs untrusted code, and a self-hosted
runner would execute it on our own infrastructure with whatever state
the previous job left behind. This is [GitHub's documented
guidance](https://docs.github.com/en/actions/how-tos/manage-runners/self-hosted-runners/manage-access#self-hosted-runner-security-with-public-repositories).
The gate is shell-only — a `grep` over `.github/**` — so it needs
nothing a hosted runner lacks.

**2. `check-pr-basics` failed on every PR.**
`thehanimo/pr-title-checker` was fetching `pull_request_title.json`
through the GitHub contents API, which this job cannot reach. The file
lives in this repo and the job already checks it out, so
`local_configuration_path` reads the same config straight off the
working tree. `LABEL.name` is empty in the config, which short-circuits
the action's label calls, so that fetch was its only API call — the gate
is now self-contained.

Verified locally against this branch: the pinned-actions grep reports
all `uses:` refs SHA-pinned, and `test_pr_title.py` passes.

## AI coding brief

- **Original request:** Get the `check` gate running on this repo — it
had been queuing for 24h and dying without executing a step — and keep
the public repo off self-hosted runners.
- **Manual interventions:** An earlier attempt routed the gate through a
shared composite action while keeping the self-hosted runner; that was
reverted (#10 closed) once it was clear the runner, not the gate's
implementation, was the problem.
- **Retro:** "The check is failing" and "the check never started" look
identical in the PR UI but have nothing in common — reading
`runner_name` and the queued→cancelled timestamps off the jobs API
separates them in one call and would have skipped the first attempt
entirely. Worth stating a repo's visibility up front too: public vs
private is what made both of these defaults wrong.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
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.

2 participants