auto-close-default-branch-prs.yml 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. name: Close PR From Fork Default Branch
  2. on:
  3. # pull_request_target is required so we have permission to comment and close PRs from forks.
  4. pull_request_target:
  5. types: [opened, reopened]
  6. permissions:
  7. pull-requests: write
  8. issues: write
  9. jobs:
  10. close:
  11. name: Close PR opened from fork's default branch
  12. runs-on: ubuntu-latest
  13. if: >-
  14. github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
  15. && github.event.pull_request.head.ref == github.event.repository.default_branch
  16. steps:
  17. - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
  18. with:
  19. script: |
  20. const { owner, repo } = context.repo;
  21. const prNumber = context.payload.pull_request.number;
  22. const author = context.payload.pull_request.user.login;
  23. const defaultBranch = context.payload.repository.default_branch;
  24. const headRepo = context.payload.pull_request.head.repo.full_name;
  25. const body = [
  26. `Hi @${author}, thanks for opening a pull request! :tada:`,
  27. ``,
  28. `It looks like this PR was opened from the \`${defaultBranch}\` branch of your fork (\`${headRepo}\`), which is the same name as this repository's default branch. Working directly on \`${defaultBranch}\` in your fork causes a few problems:`,
  29. ``,
  30. `- Your fork's \`${defaultBranch}\` branch will permanently diverge from \`${owner}/${repo}:${defaultBranch}\`, making it hard to keep your fork up to date.`,
  31. `- Any additional commits you push to \`${defaultBranch}\` will be added to this PR, so you can't easily work on multiple changes at once.`,
  32. `- Pushing maintainer fixes to your branch is awkward, since it means committing directly to your fork's default branch.`,
  33. `- It makes local collaboration painful — \`${defaultBranch}\` in a checkout becomes ambiguous between upstream and your fork, and maintainers end up with naming collisions when fetching your branch.`,
  34. ``,
  35. `Please re-open this as a new PR from a dedicated feature branch. The usual flow looks like:`,
  36. ``,
  37. `\`\`\`bash`,
  38. `# Make sure your fork's ${defaultBranch} is up to date with upstream`,
  39. `git remote add upstream https://github.com/${owner}/${repo}.git # if you haven't already`,
  40. `git fetch upstream`,
  41. `git checkout ${defaultBranch}`,
  42. `git reset --hard upstream/${defaultBranch}`,
  43. `git push --force-with-lease origin ${defaultBranch}`,
  44. ``,
  45. `# Create a new branch for your change and cherry-pick / re-apply your commits there`,
  46. `git checkout -b my-feature-branch upstream/${defaultBranch}`,
  47. `# ...re-apply your changes, then:`,
  48. `git push origin my-feature-branch`,
  49. `\`\`\``,
  50. ``,
  51. `Then open a new pull request from \`my-feature-branch\` into \`${owner}/${repo}:${defaultBranch}\`.`,
  52. ``,
  53. `Closing this PR for now — sorry for the friction, and thanks again for contributing! :heart:`,
  54. ].join('\n');
  55. await github.rest.issues.createComment({
  56. owner,
  57. repo,
  58. issue_number: prNumber,
  59. body,
  60. });
  61. await github.rest.pulls.update({
  62. owner,
  63. repo,
  64. pull_number: prNumber,
  65. state: 'closed',
  66. });