feat(automerge): add safe-paths reusable for docs/tests-only PRs#22
Merged
Conversation
Auto-enables `gh pr merge --auto --squash` on any PR (any author)
whose diff touches ONLY paths matching the safe list:
- docs/**
- tests/**
- test_*.py / *_test.{py,go,js,ts} (Python + Go + JS test conventions)
- *.test.{js,ts,jsx,tsx} / *.spec.{js,ts,jsx,tsx}
- **/__tests__/**
The gate is all-or-nothing: if even one changed file is outside the
safe list, this workflow no-ops and downstream gating workflows
(claude-author-automerge, manual click) decide.
Rationale: docs have zero runtime impact and tests can't break
runtime — failing tests don't ship, passing tests don't change
behavior. Maintainers click-merging typo fixes and test additions
is alarm-fatigue-by-design; the path classification IS the safety
argument.
Auto-merge enablement uses GitHub native `gh pr merge --auto`, so
required-status-checks on the caller repo's branch protection still
apply. This workflow does not bypass them.
Caller repos opt in by adding a thin wrapper that calls this
reusable on `pull_request` events. Optional `extra_safe_globs`
input lets callers extend the list with repo-specific safe paths
(e.g. `^changelogs/.*`, `^.devcontainer/.*`).
Smoke-tested classification locally with seven path mixes:
docs-only / tests-only / mixed-test-layouts / mixed-with-src /
src-only / workflow-file / nested-src-test_*.py — all expected
outcomes.
|
No issues found. Logic is sound, failure modes are safe (loud fail, never silent bypass), and the known path-classification trade-off for Python test naming is clearly documented. |
topcoder1
added a commit
that referenced
this pull request
May 3, 2026
## Summary The `safe-paths-automerge.yml` reusable from #22 runs `gh pr diff "\$PR" --name-only` without a local checkout. gh falls back to spawning git locally and fails: ``` failed to run git: fatal: not a git repository (or any of the parent directories): .git ##[error]Process completed with exit code 1. ``` Pass `--repo "\$GITHUB_REPOSITORY"` so gh hits the API directly. No checkout step needed. ## How it surfaced The very first install of the caller (`topcoder1/webcrawl#130`) triggered the workflow on the install PR itself. The workflow's diff was the workflow file — not a safe path — so it should have logged "deferring" and exited 0. Instead it crashed at the `gh pr diff` line. Net effect on #130: the workflow shows red but doesn't block merge (it's not a required check); the PR can still merge manually. Self-test caught it before the user merged the install — exactly what the self-test step was for. ## Auto-merge rationale Workflow file → manual click-merge per CLAUDE.md. Same caveat as #22 — fleet-wide blast radius if the regex change is wrong, even though this is a 1-line `--repo` addition. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Jonathan Zhang <[email protected]> Co-authored-by: Claude Opus 4.7 (1M context) <[email protected]>
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
A new reusable workflow that auto-enables
gh pr merge --auto --squashon any PR (any author) whose diff touches only paths matching the safe list:docs/**tests/**test_*.py/*_test.{py,go,js,ts}*.test.{jsx,tsx,js,ts}/*.spec.{jsx,tsx,js,ts}**/__tests__/**All-or-nothing: if even one changed file is outside the safe list, this workflow no-ops and downstream gating (claude-author-automerge, manual click) decides.
Rationale
Docs have zero runtime impact and tests can't break runtime — failing tests don't ship; passing tests don't change behavior. Maintainers click-merging typo fixes and test additions is alarm-fatigue-by-design. The path classification IS the safety argument.
This is a deliberate carve-out from the existing "human-authored PRs default to manual click-merge" policy. Sensitive surfaces (auth, secrets, migrations, workflows, infra) are still excluded — they don't match any of the safe globs, so this workflow leaves them to the existing gates.
Caller integration
Optional
extra_safe_globsinput lets callers extend the list per-repo (e.g.^changelogs/.*,^.devcontainer/.*).Verification
python3 yaml.safe_loadparses;actionlintclean.src/.../test_*.py→ SAFE (intentional — Python test convention)Notes
gh pr merge --auto, so required-status-checks on the caller's branch-protection ruleset still apply. This workflow does not bypass branch protection.test_*.py(e.g.src/webcrawl/test_helpers.py). The Python convention is thattest_*.pyis always test code, but the workflow can't enforce that. Mitigation: existing CI build/lint/Claude-review still runs on every PR, so any production code accidentally classified as a test would still get reviewed.Auto-merge rationale
Workflow file → manual click-merge per CLAUDE.md.
🤖 Generated with Claude Code