action-release-issues.yml 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465
  1. name: Release Issues
  2. on:
  3. pull_request_target:
  4. types:
  5. - opened
  6. - reopened
  7. - synchronize
  8. - ready_for_review
  9. - closed
  10. branches:
  11. - master
  12. permissions:
  13. issues: write
  14. pull-requests: write
  15. concurrency:
  16. group: release-issues-${{ github.event.pull_request.number }}
  17. jobs:
  18. release-issues:
  19. if: github.repository_owner == 'GameServerManagers' && startsWith(github.event.pull_request.head.ref, 'release/') && github.event.pull_request.head.repo.full_name == github.repository
  20. runs-on: ubuntu-latest
  21. steps:
  22. - name: List fixed issues in the release PR and close them on merge
  23. uses: actions/github-script@v9
  24. with:
  25. script: |
  26. const { owner, repo } = context.repo;
  27. const pr = context.payload.pull_request;
  28. const fixedLabel = 'status: fixed in develop';
  29. const start = '<!-- release-issues:start -->';
  30. const end = '<!-- release-issues:end -->';
  31. const labelled = (await github.paginate(github.rest.issues.listForRepo, { owner, repo, state: 'all', labels: fixedLabel, per_page: 100 }))
  32. .filter((issue) => !issue.pull_request)
  33. .sort((a, b) => a.number - b.number);
  34. if (context.payload.action === 'closed') {
  35. if (!pr.merged) {
  36. return;
  37. }
  38. const version = pr.head.ref.replace(/^release\//, '');
  39. for (const issue of labelled) {
  40. if (issue.state === 'open') {
  41. await github.rest.issues.createComment({ owner, repo, issue_number: issue.number, body: `Released in ${version} (#${pr.number}).` });
  42. await github.rest.issues.update({ owner, repo, issue_number: issue.number, state: 'closed', state_reason: 'completed' });
  43. core.info(`Closed #${issue.number}.`);
  44. }
  45. await github.rest.issues.removeLabel({ owner, repo, issue_number: issue.number, name: fixedLabel }).catch(() => {});
  46. }
  47. return;
  48. }
  49. const open = labelled.filter((issue) => issue.state === 'open');
  50. const lines = open.length > 0 ? open.map((issue) => `Fixes #${issue.number}`) : [`No open issues are labelled "${fixedLabel}".`];
  51. const block = [start, '## Issues fixed in this release', '', ...lines, end].join('\n');
  52. const current = pr.body || '';
  53. const pattern = new RegExp(`${start}[\\s\\S]*?${end}`);
  54. const updated = pattern.test(current) ? current.replace(pattern, block) : `${current.trim() ? `${current.trimEnd()}\n\n` : ''}${block}\n`;
  55. if (updated !== current) {
  56. await github.rest.pulls.update({ owner, repo, pull_number: pr.number, body: updated });
  57. core.info(`Listed ${open.length} issue(s) in #${pr.number}.`);
  58. }