action-pr-body-check.yml 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. name: PR Body Check
  2. on:
  3. pull_request:
  4. types:
  5. - opened
  6. - edited
  7. - reopened
  8. - synchronize
  9. branches:
  10. - develop
  11. permissions:
  12. contents: read
  13. jobs:
  14. pr-body-check:
  15. if: github.repository_owner == 'GameServerManagers' && github.event.pull_request.user.type != 'Bot'
  16. runs-on: ubuntu-latest
  17. steps:
  18. - name: Check pull request body follows the template
  19. uses: actions/github-script@v9
  20. with:
  21. script: |
  22. const body = (context.payload.pull_request.body || '').replace(/<!--[\s\S]*?-->/g, '');
  23. const requiredHeadings = ['# Description', '## Type of change', '## Testing', '## Checklist'];
  24. const missing = requiredHeadings.filter((h) => !body.split(/\r?\n/).some((line) => line.trim() === h));
  25. const errors = [];
  26. if (missing.length > 0) {
  27. errors.push(`Missing template sections: ${missing.join(', ')}. Use .github/pull_request_template.md as the pull request body.`);
  28. }
  29. if (/^\s*fixes #\[issue\]\s*$/im.test(body)) {
  30. errors.push('Replace the "Fixes #[issue]" placeholder with the issue number, for example "Fixes #123".');
  31. }
  32. const closingKeyword = /\b(close[sd]?|fix(e[sd])?|resolve[sd]?):?\s+([\w.-]+\/[\w.-]+)?#\d+/i;
  33. const relatedIssue = /\brelated to:?\s+([\w.-]+\/[\w.-]+)?#\d+/i;
  34. if (!closingKeyword.test(body) && !relatedIssue.test(body)) {
  35. core.warning('No closing keyword found. Add "Fixes #123" to link the issue, or "Related to #123" if this pull request does not fully resolve it.');
  36. }
  37. if (errors.length > 0) {
  38. core.setFailed(errors.join('\n'));
  39. }