Skip to content

feat(workflows): add pr-automerge-dependabot reusable - #676

Merged
kyle-sexton merged 5 commits into
mainfrom
feat/pr-automerge-dependabot
Oct 4, 2026
Merged

kyle-sexton merged 5 commits into
mainfrom
feat/pr-automerge-dependabot

Conversation

@kyle-sexton

@kyle-sexton kyle-sexton commented Oct 4, 2026 •

Copy link
Copy Markdown
Contributor

No related issue: Phase 5 plan step (shared Dependabot auto-merge reusable R); tracked in the actions-conventions plan, not an issue.

Summary

Adds .github/workflows/pr-automerge-dependabot.yml, a workflow_call reusable that arms GitHub squash auto-merge on low-risk Dependabot PRs. GitHub then merges once ci-status and every other required check pass. It implements standards components/dependabot-policy/policy.json autoMerge (github-actions; actions/*, github/*, anthropics/*; no semver-major; ci-status).

Fix

  • Gates, all required: event is pull_request; PR author id 49699333 (dependabot[bot]); event sender (github.event.sender.id, the pusher) is 49699333; fetch-metadata succeeded, and failed, empty or invalid metadata is a skip; every update's ecosystem is github_actions; every dependency name matches the case-sensitive allowlist glob; every update is semver patch or minor (grouped PRs included; an uncomputable type skips); every PR commit, head included, has author 49699333, committer 19864447 (web-flow) and a signature verified with reason valid. That commit shape matches live Dependabot commits on medley#2094 and ci-workflows build: bump anthropics/claude-code-action from 1.0.235 to 1.0.239 #651, build: bump anthropics/claude-code-action from 1.0.235 to 1.0.240 #655 and build: bump github/codeql-action/upload-sarif from 4.38.1 to 4.38.2 in the vendor-actions group across 1 directory #674.
  • fetch-metadata is continue-on-error, and the gate step runs on !cancelled(). A force-push that makes fetch-metadata fail therefore still reaches the disarm.
  • Arms with enablePullRequestAutoMerge(mergeMethod: SQUASH, expectedHeadOid: <verified head>). No direct-merge fallback, so nothing merges around ci-status.
  • A skipped PR that was armed on an earlier head is disarmed (GitHub keeps auto-merge on after a push by a write-access user).
  • No checkout; PR-derived values reach the script via env: only. Job permissions: contents: write, pull-requests: write. Input: runner (default ubuntu-24.04).
  • The gate runs inline in actions/github-script because a reusable has no ci-workflows checkout. .github/scripts/pr-automerge-dependabot.test.cjs extracts the script and runs it against fixtures, picked up by test-contracts (node --test .github/scripts/*.test.cjs).
  • README entry with the canonical caller.

Verification

  • node --test .github/scripts/*.test.cjs: 219 pass, 0 fail (27 in the new file: vendor patch armed, vendor major, community patch, mixed group, vendor group with one major, non-Dependabot author, non-Dependabot sender, foreign head commit, forged author with a non-web-flow committer, unsigned commit, non-valid reason, moved head, non-actions ecosystem, lookalike owner, Actions/checkout case variant, empty and invalid metadata, failed metadata fetch disarmed, disarm).
  • Mutation spot-checks (unanchored glob, head-moved check, disarm, signature, committer, reason, sender, metadata outcome, continue-on-error) each turn a test red.
  • actionlint 1.7.12 and zizmor 1.30.0 clean on the new workflow; markdownlint and typos clean.
  • naming-lint --mode enforcing exits 0 after merging origin/main (refactor(actions): move the synced comment and machine-path composites to their convention names #675).

Related

  • Phase 5 plan Phase 3 (R). Next: Fable review, a minor release, then the standards approvedReusableWorkflowContracts entry and the allowlist lockstep test (separate PRs).
  • Ports medley .github/workflows/dependabot-automerge.yml.

🤖 Generated with Claude Code

kyle-sexton and others added 3 commits October 4, 2026 10:04
Arms squash auto-merge on Dependabot PRs that bump only allowlisted
GitHub Actions publishers (actions/*, github/*, anthropics/*) by a semver
patch or minor, so GitHub merges once ci-status passes. Gates on author
id 49699333, the github_actions ecosystem, every dependency name, every
update type, and verified Dependabot authorship of every commit. Disarms
a skipped PR armed on an earlier head. Never merges directly.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
…abot

Run the gate even when fetch-metadata fails, so a force-pushed PR that was
armed earlier gets disarmed. Treat failed, empty or invalid metadata as a
skip. Require the event sender to be Dependabot. Require every commit to be
committed by web-flow with a signature verified as "valid", because an
author id alone can be forged.

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@kyle-sexton
kyle-sexton marked this pull request as ready for review October 4, 2026 14:21
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-04T14:24:10.514378Z 220a6a3 Draft marked ready
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@claude

claude Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 3m 46s —— View job


Code review — PR #676

  • Gather context (diff, CLAUDE.md/REVIEW.md, changed files)
  • Review .github/workflows/pr-automerge-dependabot.yml
  • Review .github/scripts/pr-automerge-dependabot.test.cjs
  • Review README.md additions
  • Post findings

Scope: /review:code-review (code-review lane). This repo has no security lane (pr-review-security/claude-security-review), so per REVIEW.md security findings would also belong here — I didn't find any.

Findings

1 inline finding posted on .github/workflows/pr-automerge-dependabot.yml#L83: this PR introduces dependabot/fetch-metadata as the repo's first use of that action, whose publisher isn't on the autoMerge allowlist the workflow itself enforces. REVIEW.md's "Always check" rule for GitHub Actions dependency additions asks the PR to state why no vendor action/gh/script step serves instead — the PR body doesn't carry that rationale. Also noted: this pin can never auto-merge through this same lane, so its own future bumps will always need a human.

What I verified vs. author-claimed

I statically traced the gate logic in pr-automerge-dependabot.yml (author/sender/metadata-outcome/ecosystem/allowlist/update-type/commit-shape checks, the expectedHeadOid arm, and the disarm-on-skip path) against the test file and found the logic internally consistent — no bugs surfaced. I was not able to execute node --test .github/scripts/*.test.cjs, actionlint, or zizmor myself (the sandbox blocked running node --test ..., requiring approval I don't have in this context), so the PR's "219 pass, 0 fail", actionlint, and zizmor claims are author-claimed and unverified by me. If you want me to actually run these, the --allowedTools for this lane would need to permit the node --test invocation.

No other correctness, test-coverage, or maintainability issues met the high-signal bar for this lane.

@claude

claude Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 3m 39s —— View job


Security review — /review:security-review

  • Gather context (PR diff, changed files)
  • Review .github/workflows/pr-automerge-dependabot.yml for trust-boundary / logic flaws
  • Review .github/scripts/pr-automerge-dependabot.test.cjs for test-only concerns
  • Check instruction-surface deletions (none — PR only adds files/content)
  • Post findings

No security issues found.

Scope: this lane covers logic, trust-boundary, and data-flow reasoning static analysis misses. Actions hardening (trigger choice, permission widening, pin/supply-chain risk) is zizmor's advisory lane and out of scope here; the PR already reports a clean zizmor 1.30.0 run.

What I checked in pr-automerge-dependabot.yml:

  • Trust boundary into the script: SENDER_ID, METADATA_OUTCOME, and UPDATED_DEPENDENCIES_JSON all reach the actions/github-script body via env: (L88-L92), never interpolated into the script text as ${{ }}, which is the usual github-script injection vector. The test file independently asserts this (gateScript contains no ${{).
  • Identity checks can't be spoofed by payload shape alone: author id (L112) and sender id (L113) are numeric GitHub account ids from event data GitHub itself generates, not attacker-controlled strings — a look-alike login can't match an id.
  • Metadata forgery is closed by the commit-signature check, not just trusted: even if dependabot/fetch-metadata's parsed update-type could theoretically be influenced by editing PR text, every commit — including the one carrying that metadata — must have author.id === 49699333, committer.id === 19864447 (web-flow), and verification.reason === "valid" (L136-L146). A GPG/SSH signature covers the full commit object including its message, so a tampered metadata trailer would break verification rather than silently pass.
  • Head-move / TOCTOU race is covered twice: the live listCommits result is checked against the triggering event's pr.head.sha (L133-L135) before arming, and the arm mutation itself passes expectedHeadOid (L166-L171), so a push landing in the remaining gap fails the mutation instead of silently covering a new, unverified head.
  • Glob allowlist: anchored (^...$), case-sensitive, and tested against a same-prefix look-alike owner (evil-actions/checkout) and a case variant (Actions/checkout) — both correctly rejected. No ReDoS surface given the bounded, anchored pattern.
  • Permissions are minimal for what the job does (contents: write + pull-requests: write, no secrets referenced), and the job-level if restricts this to pull_request events only, so there's no pull_request_target-style exposure to review here.
  • No merge bypass path: the workflow only ever calls enablePullRequestAutoMerge / disablePullRequestAutoMerge — no direct merge mutation — so it cannot itself land a PR around ci-status or any other required check.

The 27 new test cases in pr-automerge-dependabot.test.cjs exercise the forgery-relevant edge cases directly (forged author with non-web-flow committer, unsigned commit, verified-but-wrong-reason, foreign head commit, moved head), which lines up with what I'd want adversarial coverage on for this trust boundary.

Nothing here rises to CRITICAL/IMPORTANT/SUGGESTION — the gate composes multiple independent, non-bypassable checks (id-based identity, cryptographic commit verification, and an atomic expected-head-oid mutation) rather than relying on any single trusted signal.

Note: I wasn't able to resolve this run's Actions URL from within the sandbox (env/gh access required approval I don't have in this session), so I'm omitting the [View job run] link rather than guessing one. Branch: feat/pr-automerge-dependabot.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 220a6a3b60

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread .github/workflows/pr-automerge-dependabot.yml
Comment thread .github/workflows/pr-automerge-dependabot.yml
@github-actions

github-actions Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

claude-security-review has reviewed this pull request through 1256592; a later push is reviewed from there.

@github-actions

github-actions Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

claude-review has reviewed this pull request through 1256592; a later push is reviewed from there.

… used

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@claude

claude Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 31s —— View job


Security review — PR #676 (incremental, 220a6a3 → 92e30ec)

  • Read .claude-lane/incremental.diff (scope: only what changed since 220a6a3)
  • Review changes to .github/scripts/pr-automerge-dependabot.test.cjs
  • Review changes to .github/workflows/pr-automerge-dependabot.yml
  • Apply skip gate / instruction-surface lens
  • Post findings

No security issues found.

What changed since the last review

  • .github/scripts/pr-automerge-dependabot.test.cjs: whitespace-only reformat (2-space indent → tabs across the file). No assertions, fixtures, or logic changed — same test cases, same gate-script extraction, same runGate/assertSkipped helpers.
  • .github/workflows/pr-automerge-dependabot.yml: a 3-line comment added above the dependabot/fetch-metadata step (L93-L95) stating why that non-allowlisted-publisher action is used (GitHub's own verified org, documented parser for Dependabot metadata, reimplementation cost) and noting its own bumps stay manual. This directly answers the Codex and Claude code-review findings from the prior round — it's documentation only, no behavioral change to the gate, the trust boundary, or permissions.

Why this is a skip

Per the skip gate, this incremental diff has no security-relevant surface: one hunk is a pure formatting change (tabs vs. spaces) with zero semantic delta, and the other is an added # comment with no effect on if:, permissions:, env:, the gate script, or the arm/disarm GraphQL calls. No instruction file, guardrail, allowlist, or hook block-list was touched, so the instruction-surface-deletion lens doesn't apply either. The trust-boundary and commit-verification logic reviewed on 220a6a3 (env-only data flow, id-based identity checks, signature verification, expectedHeadOid arm) is byte-for-byte unchanged.
· Branch: feat/pr-automerge-dependabot

@claude

claude Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 3m 45s —— View job


Code review — PR #676 (incremental, since 220a6a3)

  • Read .claude-lane/incremental.diff (scoped to what changed since 220a6a3)
  • Review .github/workflows/pr-automerge-dependabot.yml diff (new rationale comment for dependabot/fetch-metadata)
  • Review .github/scripts/pr-automerge-dependabot.test.cjs diff (reformat)
  • Cross-check against this repo's own formatting policy/CI (.editorconfig, biome.json, pr-require-checks.yml)
  • Post findings

Scope: /review:code-review (code-review lane), reviewing only the incremental change since this lane's last review of 220a6a3 — i.e. commit 92e30ec ("format the gate tests and state why fetch-metadata is used"). Security concerns are out of scope here; pr-review-security already reviewed this PR separately.

What changed in this increment

  1. pr-automerge-dependabot.yml: added a 3-line rationale comment above the dependabot/fetch-metadata step explaining why that non-allowlisted-publisher action is used (GitHub-owned org, documented parser, avoids reimplementing version/update-type logic). This directly addresses the earlier Codex and Claude lane findings on 220a6a3 asking for that justification. Good fix, no issues.
  2. pr-automerge-dependabot.test.cjs: reformatted — otherwise no logic changes (verified the hunks line-by-line; the only non-whitespace edit is dropping a redundant double-paren in JSON.parse((stepEnv(...))) → JSON.parse(stepEnv(...)), a no-op).

Findings

1 inline finding posted on .github/scripts/pr-automerge-dependabot.test.cjs#L10: the reformat in commit 92e30ec switched this file from 2-space to tab indentation, which conflicts with this repo's own enforced Biome formatter policy (fixtures/typescript/good/biome.json: indentStyle: "space", indentWidth: 2) and .editorconfig. The biome job in pr-require-checks.yml runs biome ci (format-check) against .github/scripts and gates ci-status. This file is now the only .cjs under .github/scripts using tabs — every sibling file uses 2-space.

What I verified vs. unverified

I statically confirmed: the diff's indentation change (read directly), the .editorconfig and biome.json policy text, the biome job's scope and its place in ci-status's needs list, and that this file is the sole tab-indented .cjs in the directory (via grep -rl '^\t' .github/scripts/*.cjs). I was not able to execute npx @biomejs/biome ci ..., node --test .github/scripts/*.test.cjs, or any node -e snippet myself — the sandbox for this lane required an approval I don't have for those invocations — so whether the biome CI job actually fails on this head, and the PR's re-asserted "219 pass, 0 fail" test claim, are author-claimed and unverified by me. Recommend confirming against the actual biome job run for 92e30ec before merge.

No other correctness, test-coverage, or maintainability issues met the high-signal bar for this lane in the incremental diff.

Branch: feat/pr-automerge-dependabot

Comment thread .github/scripts/pr-automerge-dependabot.test.cjs Outdated
…warnings in the gate tests

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
@claude

claude Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 2m 49s —— View job


Code review — PR #676 (incremental, since 92e30ec)

  • Read .claude-lane/incremental.diff, scoped to .github/scripts/pr-automerge-dependabot.test.cjs
  • Confirm the reformat matches the repo's enforced Biome/.editorconfig policy
  • Spot-check the non-whitespace edits in the diff for behavior changes
  • Attempt to run node --test / Biome to verify the claims
  • Post findings

Scope: /review:code-review (code-review lane), reviewing only the incremental change since this lane's last review of 92e30ec — i.e. commit 1256592 ("restore 2-space indentation and clear the biome lint warnings in the gate tests"). Security concerns are out of scope here (separate security lane).

No findings.

What changed in this increment

  1. Indentation revert: the entire file goes from tab indentation (introduced by the prior commit, 92e30ec) back to 2-space, matching fixtures/typescript/good/biome.json (indentStyle: "space", indentWidth: 2) and resolving the inline finding this lane posted on 92e30ec about the file being the sole tab-indented .cjs under .github/scripts. Confirmed no tabs remain in the file (grep -P '\t' → 0 matches).
  2. workflowLines.findIndex((line) => line === " enable-auto-merge:") → workflowLines.indexOf(" enable-auto-merge:") (L160): a pure simplification, no semantic change. Verified against the workflow file that the exact 2-space-indented line still matches.
  3. Plain strings → escaped template literals for GitHub-expression assertions (L169-170, L351): e.g. "${{ github.event.sender.id }}" → `\${{ github.event.sender.id }}`. I initially suspected this might trade one Biome lint warning (noTemplateCurlyInString, which flags a plain string that looks like an unescaped template placeholder) for another (noUnusedTemplateLiteral, which flags a template literal with no real substitution). I checked how every other .github/scripts/*.test.cjs file in this repo asserts against a ${{ }} string (claude-lane-scope.test.cjs, checks-outcome.test.cjs, claude-review-plugin-path.test.cjs, claude-lane-compose-args.test.cjs, etc.) — they all already use this exact escaped-backtick pattern. So this change brings the file in line with the repo's established, working convention rather than introducing something new; no issue.

What I verified vs. unverified

I statically confirmed the diff is whitespace-only plus the two edits above (read the full post-commit file and the relevant workflow lines directly) and cross-checked the template-literal pattern against sibling test files in the same directory. I was not able to execute node --test .github/scripts/pr-automerge-dependabot.test.cjs or npx @biomejs/biome ci ... myself — the sandbox for this lane requires an approval I don't have for node/npx invocations — so the re-asserted "219 pass, 0 fail" test count and a clean Biome run on this head are author-claimed and unverified by me, same limitation as the prior rounds on this PR.

Branch: feat/pr-automerge-dependabot

@claude

claude Bot commented Oct 4, 2026 •

Copy link
Copy Markdown

Claude finished @kyle-sexton's task in 38s —— View job


Security review — PR #676 (incremental, 92e30ec → 1256592)

  • Read .claude-lane/incremental.diff (scope: only what changed since 92e30ec)
  • Review changes to .github/scripts/pr-automerge-dependabot.test.cjs
  • Apply skip gate / instruction-surface lens
  • Post findings

No security issues found.

What changed since the last review

.github/scripts/pr-automerge-dependabot.test.cjs is reformatted back from tab to 2-space indentation (reverting the regression this lane flagged on 92e30ec, where the biome/editorconfig format-check conflict was raised). Diffing with whitespace ignored (git diff 92e30ec..1256592 -b) confirms the only non-whitespace edits are:

  • workflowLines.findIndex((line) => line === " enable-auto-merge:") → workflowLines.indexOf(" enable-auto-merge:") — equivalent lookup, no behavior change.
  • Two string literals ("${{ github.event.sender.id }}", "if: ${{ !cancelled() }}") rewritten as template literals with an escaped ${{ — same string value, same assertion target.

No fixture, assertion, gate-script extraction, or runGate/assertSkipped helper logic changed. This is a test-only file; it has no production trust boundary, no env:/${{ }} data flow, and doesn't touch the workflow being tested.

Why this is a skip

This diff has no security-relevant surface: it's a whitespace/style normalization of a test harness plus two no-op refactors. No if:, permissions:, env:, gate logic, or GraphQL arm/disarm call was touched. No instruction file, guardrail, allowlist, or hook block-list was modified, so the instruction-surface-deletion lens doesn't apply. The trust-boundary and commit-verification logic reviewed on prior heads (env-only data flow, id-based identity checks, signature verification, expectedHeadOid arm) is unchanged by this commit.

Branch: feat/pr-automerge-dependabot

@kyle-sexton
kyle-sexton merged commit 69e506b into main Oct 4, 2026
27 checks passed
@kyle-sexton
kyle-sexton deleted the feat/pr-automerge-dependabot branch October 4, 2026 14:42
kyle-sexton added a commit to melodic-software/standards that referenced this pull request Oct 4, 2026
…tract (#687)

No related issue: follow-up registration for the ci-workflows v0.35.0
reusable reviewed on melodic-software/ci-workflows#676

## Summary

Approves the new ci-workflows `pr-automerge-dependabot.yml` reusable at
v0.35.0 in `runner-policy` and adds a lockstep check so its
`PUBLISHER_ALLOWLIST` constant cannot drift from `dependabot-policy`
`autoMerge.publisherAllowlist`.

Contract for hand review (`components/runner-policy/policy.json`,
`approvedReusableWorkflowContracts`):

```json
"melodic-software/ci-workflows/.github/workflows/pr-automerge-dependabot.yml@69e506b7c119517ef1dfc421479232b386b93a52": {
  "routing": "runner-input",
  "runnerInput": "runner",
  "allowedInputs": ["runner"],
  "allowedSecrets": {},
  "allowedCallerPermissions": {
    "contents": "write",
    "pull-requests": "write"
  }
}
```

`allowedCallerPermissions` rather than `minimumCallerPermissions`:
`runner-policy.mjs` rejects a write scope in `minimumCallerPermissions`
(GitHub downgrades caller write grants on Dependabot PRs), and the job
declares exactly these two write scopes.

## Fix

- `components/runner-policy/policy.json`: the entry above, spliced as
text (diff is additions only).
- `components/runner-policy/README.md`: ledger note covering what the
reusable does, its gating, permissions, inputs and secrets, pinned
actions (`dependabot/fetch-metadata` v3.1.0
`25dd0e34f4fe68f24cc83900b1fe3fe149efef98`, `actions/github-script`
v9.0.0 `3a2844b7e9c422d3c10d287c895573f7108da1b3`), and the
ci-workflows#676 security review.
- `components/dependabot-policy/automerge-lockstep.mjs`: reads the
reusable's SHA from its single runner-policy contract key, fetches the
reusable at that SHA over the contents API with three attempts (same
transport and token handling as
`pr-convention-policy/lockstep-drift.mjs`), finds the single
`PUBLISHER_ALLOWLIST` step env, and fails on any difference from
`policy.json`.
- `components/dependabot-policy/README.md` and `THREAT-MODEL.md`: the
reusable is live (no longer "planned"), and the lockstep is in scope
with its own threat row.
- Enforcement rollout (docs/component-lifecycle.md#enforcement-rollout):
the lockstep blocks from admission with no report-only period. It
compares two files at fixed revisions, so there is no fleet baseline to
observe; the observation run against the live pinned reusable matched
(`PUBLISHER_ALLOWLIST at 69e506b matches policy.json`).
- `package.json`: `lint:dependabot-automerge-lockstep`.
- `.github/workflows/ci.yml`: a step in the existing `dependabot-policy`
job. The fetch targets an immutable SHA in a public repository, so a
separate job would add a `needs` edge to `ci-status` with no isolation
gain.

## Verification

- `npm run lint:runner-policy`: Runner policy passed.
- `node --test components/runner-policy/runner-policy.test.mjs`: 296/296
pass.
- `npm run lint:dependabot-automerge-lockstep`: PUBLISHER_ALLOWLIST at
69e506b matches policy.json.
- `npm run test:dependabot-policy`: 36/36 pass; `npm run
lint:dependabot-policy` passed.
- `npm run lint:md`: 0 issues; biome clean; lefthook pre-commit green.

## Related

- melodic-software/ci-workflows#676 (security review of the reusable)
- ci-workflows release v0.35.0
(`69e506b7c119517ef1dfc421479232b386b93a52`)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
kyle-sexton added a commit that referenced this pull request Oct 5, 2026
No related issue: found by the actions-conventions Phase 8 sanity check
(16 of 17 repos passed; ci-workflows lacked an auto-merge caller).

## Summary

ci-workflows is the only repository without a caller of the shared
`pr-automerge-dependabot` reusable, so its own vendor Dependabot bumps
(e.g. #674) never arm auto-merge, contrary to the org Dependabot lanes
policy (standards#684). A separate caller file cannot exist here because
`pr-automerge-dependabot.yml` is the reusable itself, so this adds a
thin dogfood caller job to `pr-require-checks.yml`, the pattern the
Claude lanes already use.

## Fix

- New job `pr-automerge-dependabot` in
`.github/workflows/pr-require-checks.yml`: `pull_request` events only,
the same action predicate as `pr-review`. It has job-scoped `contents:
write` and `pull-requests: write`; workflow-level permissions are
unchanged.
- It is pinned to the released reusable (`@fb56986… # v0.36.0`), not
`./`, so a pull request, a Dependabot bump of an action inside the
reusable included, cannot redefine the code that holds the write token.
- `ci-status` does not depend on the job, because arming waits on
`ci-status`. `ci-fanout-consolidation.test.cjs` now lists it among the
jobs that stay out of `ci-status`.

## Verification

- `actionlint .github/workflows/pr-require-checks.yml`: exit 0.
- `node --test .github/scripts/*.test.cjs`: all pass.
- The Claude review lanes skip pull requests that edit their caller
workflow (`pr-require-checks.yml`); a local review stands in for them.
- To confirm after merge: the next vendor-actions Dependabot PR in this
repo shows a passing `pr-automerge-dependabot / …` check and auto-merge
armed.

## Related

- standards#684 (Dependabot lanes policy)
- #674 (vendor bump merged by hand for lack of this caller)
- #676 (the reusable)

🤖 Generated with [Claude Code](https://claude.com/claude-code)

---------

Co-authored-by: Claude Opus 5.5 <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.

1 participant