Uh oh!
There was an error while loading. Please reload this page.
Add companion-check workflow: docs PRs auto-merge once their companion code PR lands - #629
Add companion-check workflow: docs PRs auto-merge once their companion code PR lands#629kriszyp wants to merge 6 commits into
Conversation
…repos Adds a workflow posting a companion-check commit status driven by Depends-on: markers in PR bodies, so a docs PR can be approved and armed for auto-merge, then merge automatically once the feature PR it documents lands. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Fail closed on unparseable markers, support repo#N shorthand, bound and dedupe refs, isolate per-dep/per-PR errors, restrict the cross-repo token to same-org refs, guard sweep/event races, and skip no-marker PRs in the cron sweep. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Round-2 review fixes: any non-ref residue on a Depends-on line fails the check; empty markers fail closed; token-confirmed 404s fail as not-found instead of pending on a token hint; the sweep reconciles every open PR (backfill + dropped-webhook healing); dep lookups are memoized per run; path-traversal segments rejected; API base from context.apiUrl. Adds a self-contained node test harness covering the embedded script. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
A missing or unreadable-without-secret companion now blocks with an honest red failure instead of pending on a token hint that misdiagnoses typos; transport/auth errors keep the pending Cannot-read form. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Code Review
This pull request adds a test harness (scripts/companion-check.test.mjs) and registers it under package.json to validate the embedded GitHub script in the companion-check workflow. The reviewer pointed out that the current YAML script extraction logic is fragile and suggested replacing it with a stateful parser to robustly extract only the script block.
Uh oh!
There was an error while loading. Please reload this page.
🚀 Preview DeploymentYour preview deployment is ready! 🔗 Preview URL:https://preview.harper-documentation.harperfabric.com/pr-629 This preview will update automatically when you push new commits. |
…on (review feedback) Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
🚀 Preview DeploymentYour preview deployment is ready! 🔗 Preview URL:https://preview.harper-documentation.harperfabric.com/pr-629 This preview will update automatically when you push new commits. |
Adds a
companion-checkcommit status driven byDepends-on:markers in PR bodies, so a docs PR documenting an unmerged code change can be approved and armed for auto-merge, then land automatically once its companion PR (e.g. harper#2147) merges. PRs without a marker get an immediatesuccess, so oncecompanion-checkbecomes a required check it never blocks ordinary docs PRs.For the human reviewer
Depends-on: noneopt-out) reaches every author's habits. To cover the typo risk this creates, everything else fails closed: empty markers, unparseable refs, and any non-ref residue on a marker line all postfailure. Reversible in-script.HarperFast/.githubis the moment to deduplicate; the committed test harness makes drift detectable.github-script, tested by extraction. The ~150-line script stays in the YAML (no build step, no action packaging);scripts/companion-check.test.mjsextracts it by its 12-space indent and runs 25+ scenario assertions, wired into the Validate matrix asWorkflow Tests. The extraction is a stateful parse of thescript: |block (until dedent) and asserts loudly if it comes back empty.pull_request_targetwith a secret in scope, on a public repo. Mitigations: the workflow never checks out PR code, the body is only ever data insidegithub-script, and the optionalCOMPANION_CHECK_TOKENis used exclusively for same-org refs on non-fork PRs — a fork PR referencing a private repo blocks with an explanatory failure rather than probing with the secret. A maintenance rule at the top of the file states the invariant.failure"not found or inaccessible" rather than an eternalpendingblaming a token. Both states block; the failure is more honest about needing human attention.pending, which blocks); markers inside fenced code blocks are parsed as live (quote the word, not the marker form, when writing about it); statuses (not check runs) were chosen for required-check simplicity, so there is no re-run button — the 15-minute sweep or aworkflow_dispatchis the retry path.Not in this PR (needs repo admin, after merge): enable the
companion-checkrequired status check in branch protection, run oneworkflow_dispatchbackfill sweep, and optionally addCOMPANION_CHECK_TOKEN(fine-grained PAT or app token with PR read on harper-pro) for docs PRs that depend on private-repo PRs. Repo auto-merge (allow_auto_merge) is already enabled.Verification
npm run test:workflows(added to the Validate matrix) passes: 25+ assertions over the extracted production script covering marker parsing (all three documented forms, shorthand, dedupe, cap, empty/partial/traversal markers failing closed), state reduction (merged/open/closed/missing/unreadable precedence), sweep semantics (no-repost dedup, no-marker backfill, dropped-webhook healing, race-guard skip on changed PRs), error isolation (HTTP 500 degrades to pending; a thrown refresh posts pending rather than preserving stale success), and secret guards (withheld for foreign orgs and fork PRs).npm run format:checkclean. The workflow itself cannot run end-to-end from this branch (schedulefires on the default branch only, and the status context becomes selectable in branch protection only after a firstmainrun) — post-merge verification is a manualworkflow_dispatchsweep plus arming #623 as the live trial.Review coverage
Authored by Claude Fable 5. Cross-model review across 4 rounds (full @ f2c4478, deltas @ 2fd988e / e6093a1, final @ 71750b6 = HEAD): codex graded leg ✓ (gpt-5.6-sol @ HEAD), gemini via agy (default model) ✓ every round, Harper-domain adjudication ✓ (claude-opus-5, last @ e6093a1; pruned on the final narrow delta), cursor-grok ✗ (output-format failure), cursor-composer ✗ (pruned round 1, format failure @ e6093a1). Verdict trail CHANGES → CHANGES → CHANGES → COMMENTS; the remaining findings are the accepted residuals in the ledger above.
Human-Review-Need: 4 @ b3681a1