feat(dependabot-auto-merge): convert to reusable workflow, add #64 guardrails - #96
Merged
Merged
Conversation
…ardrails Extracts dependabot-auto-merge.yml into a workflow_call reusable, matching the pattern already used by claude-blocking-review and claude-assistant. Preserves the currently-deployed working logic exactly (env: GH_TOKEN, env: PR_URL, id: metadata) plus two hardening changes: - Both gh pr review --approve and gh pr merge --auto now degrade to a visible ::warning:: instead of a hard failure (closes the structural half of #87 — a hard failure on either call left an unactionable red check with no visible cause). - A "Verify caller permissions" preflight, mirroring claude-blocking-review.yml's pattern, fails loudly if the caller didn't grant contents:write / pull-requests:write. Tagged with a prefixed namespace (dependabot-auto-merge-v1, not v1) since bare v1/v2/v3 tags in this repo are already live and consumed by claude-assistant.yml@v1. Adds the #64 no-checkout guardrail in two places: a new plain-shell guard-no-checkout job in self-review.yml (separate from the claude-review job, which is a reusable-workflow call and can't have its own steps; also deliberately not an LLM-based check, so it isn't subject to the workflow-self-modification skip that would otherwise exempt exactly the PRs that need checking), and a read-only fleet-wide check in claude-review-audit.sh that flags any caller stub containing actions/checkout or secrets: inherit. Documents the "callers MUST NOT use secrets: inherit" rule in both the workflow's header comment and README.md. Note for reviewers: zizmor flags dependabot-auto-merge.yml's `if: github.actor == 'dependabot[bot]'` as a spoofable bot-conditions finding (its general recommendation is github.event.pull_request.user.login instead). This condition is preserved verbatim per the plan and issue #64's own audit, which argues it's safe here specifically because the workflow only ever makes API calls (fetch-metadata, gh pr review/merge) and never executes PR code — the code-execution-via-spoofed-actor bypass zizmor describes doesn't apply without a checkout step. Flagging explicitly rather than silently suppressing or redesigning the condition. Claude-Session: https://claude.ai/code/session_0143Nf4sXqnTp2Kx3LNbMvBA
…ment The guardrail's bare `grep -q "actions/checkout"` matched the header comment in dependabot-auto-merge.yml that explains why actions/checkout must never be added there, failing the job on the very PR meant to add that comment. Strip comment lines and match the real `uses:` invocation form instead of a bare substring. Also fixes two pre-existing zizmor findings on the guardrail's own checkout step: missing persist-credentials: false, and a version comment that said v4 instead of the actually-pinned v4.3.1.
twistedmelonman
added a commit
to smartwatermelon/.github
that referenced
this pull request
Aug 7, 2026
…perties (#11) * feat(workflow-templates): add dependabot-auto-merge caller stub + properties Replaces the self-contained dependabot-auto-merge.yml body with a caller stub pointing at the new reusable workflow in smartwatermelon/github-workflows (Part A2 of the reusable-workflows plan; see smartwatermelon/github-workflows#96). Adds the missing dependabot-auto-merge.properties.json so the workflow-templates picker actually offers this template — it was confirmed silently absent from the picker during planning validation. Temporarily pinned to a commit SHA rather than the dependabot-auto-merge-v1 tag, since that tag doesn't exist until github-workflows#96 merges and the tag is cut (~1 minute after merge, per this fleet's established convention). Follow-up PR needed once the tag exists. Claude-Session: https://claude.ai/code/session_0143Nf4sXqnTp2Kx3LNbMvBA * chore(workflow-templates): repoint dependabot-auto-merge caller stub to cut tag The reusable workflow's dependabot-auto-merge-v1.0.0 tag (and floating dependabot-auto-merge-v1) are now cut in smartwatermelon/github-workflows following #96's merge. Replace the temporary branch-tip SHA pin with the real tag. * chore(workflow-templates): repoint dependabot-auto-merge stub to cut tag The reusable workflow's dependabot-auto-merge-v1.0.0 tag (and floating dependabot-auto-merge-v1) are now cut in smartwatermelon/github-workflows following #96's merge. Replace the temporary branch-tip SHA pin with the real floating tag, and document explicitly that floating (versus a stricter pin) is an accepted tradeoff for this template, not an oversight -- matching the precedent already set by claude-blocking-review.yml@v3. * docs(workflow-templates): note actor-gate and defaults live in the reusable Address two non-blocking review findings on the prior commit: the actor gate (dependabot[bot] only) and merge-scope defaults are entirely inside the reusable workflow now, invisible from this caller stub since it passes no with: inputs. Point auditors at the reusable workflow file directly. --------- Co-authored-by: Claude Code Bot <claude-code@smartwatermelon.github>
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements Part A2 of the reusable-workflows plan: extracts
dependabot-auto-merge.ymlfrom a copy-pasted-per-repo file into aworkflow_callreusable workflow, matching the pattern already used byclaude-blocking-reviewandclaude-assistant.Closes #87 (structural half — approve/merge calls now degrade to
::warning::instead of hard-failing) and #64 (no-checkout guardrail, enforced two ways).What changed
.github/workflows/dependabot-auto-merge.yml— the reusable workflow. Preserves the currently-deployed working logic exactly (env: GH_TOKEN,env: PR_URL,id: metadata), plus:claude-blocking-review.yml's pattern) that fails loudly if the caller didn't grantcontents: write/pull-requests: write.gh pr review --approveandgh pr merge --autonow degrade to::warning::on failure (the original only fixed the approve call — see dependabot-auto-merge is inert in 29/51 fleet repos: can_approve_pull_request_reviews unset by installer #87).secrets: inherit" rule with the reasoning (splitting this file out of every caller repo creates a new incentive to reach forsecrets: inheriton an auth failure, which would leak every repo secret to code evaluating externally-authored PR content underpull_request_target).dependabot/fetch-metadatapinned to its v2 commit SHA (matching this repo's convention foractions/checkout)..github/workflows/self-review.yml: newguard-no-checkoutjob — plain shell, no LLM call, so it isn't subject to the workflow-self-modification skip. Fails if this repo's owndependabot-auto-merge.ymlever containsactions/checkout. (Moved the top-levelpermissions:block down onto theclaude-reviewjob since the new job needs a much smaller set — zizmor'sexcessive-permissionscheck was right that the old top-level grant was overly broad for the new job mix.)claude-review-audit.sh: new read-only, audit-only check — for every repo it scans, flags any caller stub referencingdependabot-auto-merge.ymlthat containsactions/checkoutorsecrets: inherit. Doesn't block or gate anything, consistent with the rest of the script.README.md: new## dependabot-auto-mergesection documenting setup, thesecrets: inheritprohibition, the no-checkout invariant, tag versioning, and rollout discipline. (Also picked up a markdownlint table-formatting fix on adjacent pre-existing tables — pre-existing en-dash unicode character was breakingMD060alignment checks; switched to plain hyphens.)Versioning
Tagged with a prefixed namespace —
dependabot-auto-merge-v1,dependabot-auto-merge-v1.0.0— not barev1. Git tags are repo-scoped;v1already exists in this repo and is live, consumed byclaude-assistant.yml@v1. Tag/release creation is deferred until after merge, per this repo's established convention (confirmed in the recent A1 PR).Known findings, tracked as follow-ups (not blocking this PR)
gh api repos/.../pulls/${PR_NUMBER}check has a false-positive ifPR_NUMBERis empty (non-pull_request-family caller trigger) — degrades to a silent no-op rather than a loud diagnostic. Bounded blast radius (caller misconfiguration only; the documented caller stub uses the correct trigger).actions/checkout/secrets: inheritgrep doesn't strip comments first, so a caller stub with an explanatory comment mentioning either string would false-positive in the audit report. Audit-only (no blocking/gating), so blast radius is report noise.if: github.actor == 'dependabot[bot]'as a spoofablebot-conditionsfinding (general recommendation:github.event.pull_request.user.login). Preserved verbatim per the plan and issue Add guardrail preventing actions/checkout in dependabot-auto-merge.yml #64's own audit — the code-execution-via-spoofed-actor bypass zizmor describes requires a checkout step, which this workflow structurally never has. Noted in the commit message rather than silently suppressed or redesigned.Follow-up work outside this PR
smartwatermelon/.github,nightowlstudiollc/.github) need theirworkflow-templates/dependabot-auto-merge.ymlreplaced with a caller stub once this PR merges and thedependabot-auto-merge-v1tag is cut — separate PRs, in progress.dependabot-auto-merge-v1,dependabot-auto-merge-v1.0.0) is deferred until after this PR merges.Test plan
shellcheck -S info claude-review-audit.shcleanyamllintclean (only pre-existing-style line-length warnings)markdownlintcleanactions/checkoutto a scratch-branch copy ofdependabot-auto-merge.ymland confirmguard-no-checkoutfailsClaude-Session: https://claude.ai/code/session_0143Nf4sXqnTp2Kx3LNbMvBA