Skip to content

Auto-close stale sync PRs when source file reverts to match target #189

Description

@joshjohanning

Problem

When a synced file (e.g., dependabot.yml, .gitignore, workflow files) is changed and the action runs, it creates PRs in target repos. If the source file is then reverted (so source matches target again), the next run correctly reports "no changes" — but the previously-created PRs remain open as orphans.

Example: User changed dependabot.yml, action created PRs (joshjohanning/text-to-emoji-action#5, joshjohanning/revoke-github-ssh-key-sso-authorization#5, etc.). User reverted the change. Next run says no changes, but the stale PRs are still open.

Proposed Solution

When the action determines that a synced file has no changes (source matches target), check if there are any open PRs created by the action for that file and close them with a comment explaining the source was reverted.

Approach

  1. Before skipping a file sync due to "no changes", search for open PRs matching the configured PR title for that sync type
  2. If found, close the PR with a comment like: Closing: the source file has been reverted to match the current target. This PR is no longer needed.
  3. This should apply to all file-sync types: dependabot-yml, gitignore, pull-request-template, workflow-files, copilot-instructions-md, codeowners, package-json-file

Implementation Notes

  • PR identification: Match by branch name pattern (each sync type uses a predictable branch name) rather than title alone — more reliable
  • Author matching: Only close PRs created by the same token/app to avoid closing unrelated PRs
  • Safety check: If the PR has additional commits beyond the original action-created one, warn instead of closing (user may have added manual work)
  • Multiple workflow files: Each workflow file creates its own PR — need to handle per-file
  • Dry-run: Log which PRs would be closed without actually closing them
  • Rate limiting: Adds a search API call per file-sync type per repo when there are no changes. Only search when source matches target (no diff) to minimize extra calls
  • Consider a shared helper: Since 7 sync types need this, extract a closeStaleActionPrs(octokit, repo, branchPattern, prTitle, dryRun) helper to avoid duplicating the logic at each call site
  • Subresults: Report closed/would-close PRs as subResults so they appear in the job summary
  • On by default: Orphaned PRs are confusing — this should be default behavior, not opt-in

Metadata

Metadata

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions