Repository navigation
ci: land main through quest land - #137
Conversation
Quest-Claim: 4ab8057807151749
The Land workflow batches PRs queued with `quest merge --land`, checks the chain with Check's steps once, and fast-forwards main to the passing prefix. It pushes with a land App's token from the `land` environment; a test keeps every other job out of that environment. Check drops its merge_group and push-to-main triggers. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
Security findingsAdvisory findings (1)ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
kixelated
left a comment
There was a problem hiding this comment.
Automated review by review (OpenAI)
Reviewed commit: 494f104485dc32545127ca42d9415f38a531c9c8.
No actionable bugs found in the changed workflow, guard, and contributor instructions. The resolve/check/push separation is a reasonable direction: queued code runs without the landing credential, while the existing pinned quest CLI supplies batching rather than duplicating that logic here.
Verification limits: static GitHub review only; I did not run Nix, lint, tests, or a live landing. The App/environment/ruleset setup and end-to-end enforcement remain unverified, as documented in the remaining quest. The text-based environment guard is a regression check for the repository's current YAML conventions, not a general security boundary.
There was a problem hiding this comment.
🛡️ Codex Security Review · Automatically triggered
Here are some automated security review suggestions for this pull request.
Reviewed commit: 494f104485
ℹ️ About Codex security reviews in GitHub
This is an experimental Codex feature. Security reviews are triggered when:
- You comment "@codex security review"
- A regular code review gets triggered (for example, "@codex review" or when a PR is opened), and you’re opted in so security review runs alongside code review
Once complete, Codex will leave suggestions, or a comment if no findings are found.
The line scan read only `*.yml` and could miss an environment spelled through an expression, a flow mapping, or another repository's reusable workflow. Parse every `*.yml` and `*.yaml` workflow and allow no environment and no remote reusable workflow outside land.yml's land job. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
kixelated
left a comment
There was a problem hiding this comment.
Automated review by review (OpenAI)
Reviewed commit: 1349259388552cac8034c3652dd9bdfd759b8a02, compared with my previous review of 494f104485dc32545127ca42d9415f38a531c9c8.
Fixed: the independent security finding is addressed in .github/land.test.ts:11–15,30–34: both workflow extensions are scanned and parsed, any environment reference is rejected outside the designated job, and remote reusable workflows are included in the guard. The new fixtures exercise the scalar, mapping, flow and expression cases. This is a fix to an existing finding, not a new one.
No new actionable bugs found. Replacing line matching with the existing Bun runtime's YAML parser is a simpler, more reliable direction than extending the awk grammar; just test now invokes that guard.
Verification: static review of this update, its fixtures and test wiring only; I did not execute Bun/Nix, the suite or a live landing. External App/environment/ruleset configuration remains unverified. This guard still does not replace review of changes to the guard itself or the privileged landing job.
|
Landing a8c7966 (squash, pinned to the reviewed head).
(Written by Claude Opus 5.5) |
Problem
Today each PR merges once it is green against the
mainit last saw, so two PRs that pass alone can breakmaintogether. #176 and #177 did: together they leftlang'sdyns.tssnapshot stale, andmainwent red at 1af6db6a. Landing should test the combination beforemainmoves.quest/m1/land.md:
mainshould land PRs only throughquest land, as one tested batch, so the merge button cannot land around it. Todaymainhas no ruleset or branch protection, andcheck.ymlstill carries amerge_grouptrigger for a merge queue this personal repository cannot use.Approach
.github/workflows/land.yml: the three jobs from kixelated/quest's README, set up like kixelated/quest#236:questfrom main's flake pin, outside the checkout, so a queued PR cannot change it.just check && just testin the dev shell) on the chain, on the sameubuntu-24.04-armrunner. It holds only a read token and no persisted credentials. Its timeout is 90 minutes, enough for a few bisection runs of the ~12 minute suite.landenvironment (vars.LAND_APP_CLIENT_ID,secrets.LAND_APP_PRIVATE_KEY). Then it re-dispatches itself when the queue changed..github/land.test.ts, run byjust testwith Bun: parses every*.ymland*.yamlworkflow and fails if any job other thanland.yml'slandnames an environment (any environment, since an expression can spelllandwithout the word) or calls another repository's reusable workflow, which could name it.check.ymldropsmerge_group. It also dropspush: main: main only fast-forwards to a tree the gate already checked. It gainsworkflow_dispatchso an admin can check main after an emergency bypass push.CONTRIBUTING.md: PRs land only throughquest land, and the admin bypass is for emergencies. The squash body is the PR's commit messages (the gate builds GitHub's squash format), not the PR description.quest/m1/land.mdis rewritten to what remains: the maintainer's setup and a live landing.Change from the quest's plan
The plan (2026-10-26) named GitHub Actions as the ruleset's bypass actor, guarded by a test refusing
contents: writeoutside the land job. That no longer works. On 2026-10-27 GitHub refused GitHub Actions (Integration15368) as a bypass actor on a personal repository (kixelated/quest) and on an organization repository, both with "must be part of the ruleset source or owner organization". Even where GitHub allows it,GITHUB_TOKENcannot getworkflowspermission, so it could not land a PR that changes.github/workflows. This PR follows kixelated/quest's newer setup instead: an App bypass, with a test that guards the environment holding the App's key.Impact
quest merge <pr> <token> --land <sha>(/quest-mergedoes this).Alternatives
mainstill shows on every PR's Check, which runs on the PR merged withmain.Decisions
Settled without the maintainer, since none changes this diff:
land.ymlonmainfirst. Until the setup below exists,land.ymlstops atresolve(it refuses a base that does not requirequest land), so nothing lands through it early.land.yml: either way it readsLAND_APP_CLIENT_IDandLAND_APP_PRIVATE_KEY..github/run byjust test, since rust2 has no TypeScript test harness at the root. Unlike kixelated/quest's line-basedtest/workflows.test.ts, it parses the YAML, per Codex's security finding.Maintainer setup after merge
landon kixelated/rust2 with deployment branches restricted tomain, the variableLAND_APP_CLIENT_ID, and the secretLAND_APP_PRIVATE_KEY. Do this before the ruleset: kixelated/quest's first live run failed at the App token step because itslandenvironment had no client ID yet.mainthat restricts deletions, blocks force pushes, and requires two status checks:Checkfrom GitHub Actions (so the gate ejects a red PR before batching it), andquest landpinned to the land App, which never reports it. Bypass actors: the land App and the Repository admin role. Add no other rule types:quest land resolvefails on any it does not uphold, and these are all the gate needs.quest/m1/land.mdlands through the gate as the live check.Checks
just checkandjust testpassed locally on the merged head 494f104; after the guard rewrite, CI runs them.quest check --base origin/main --branch quest/m1/landandactionlintare clean..yamlworkflow naming an expression environment.Follow-ups
test/workflows.test.tshas the same gaps (expressions, flow mappings, remote reusable workflows); worth the same parse there.(Written by Claude Opus 5.5)
🤖 Generated with Claude Code