compliance-close.yml 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. name: compliance-close
  2. on:
  3. schedule:
  4. # Run every 30 minutes to check for expired compliance windows
  5. - cron: "*/30 * * * *"
  6. workflow_dispatch:
  7. permissions:
  8. contents: read
  9. issues: write
  10. pull-requests: write
  11. jobs:
  12. close-non-compliant:
  13. runs-on: ubuntu-latest
  14. steps:
  15. - name: Close non-compliant issues and PRs after 2 hours
  16. uses: actions/github-script@v7
  17. with:
  18. script: |
  19. const { data: items } = await github.rest.issues.listForRepo({
  20. owner: context.repo.owner,
  21. repo: context.repo.repo,
  22. labels: 'needs:compliance',
  23. state: 'open',
  24. per_page: 100,
  25. });
  26. if (items.length === 0) {
  27. core.info('No open issues/PRs with needs:compliance label');
  28. return;
  29. }
  30. const now = Date.now();
  31. const twoHours = 2 * 60 * 60 * 1000;
  32. for (const item of items) {
  33. const isPR = !!item.pull_request;
  34. const kind = isPR ? 'PR' : 'issue';
  35. const { data: comments } = await github.rest.issues.listComments({
  36. owner: context.repo.owner,
  37. repo: context.repo.repo,
  38. issue_number: item.number,
  39. });
  40. const complianceComment = comments.find(c => c.body.includes('<!-- issue-compliance -->'));
  41. if (!complianceComment) continue;
  42. const commentAge = now - new Date(complianceComment.created_at).getTime();
  43. if (commentAge < twoHours) {
  44. core.info(`${kind} #${item.number} still within 2-hour window (${Math.round(commentAge / 60000)}m elapsed)`);
  45. continue;
  46. }
  47. const closeMessage = isPR
  48. ? 'This pull request has been automatically closed because it was not updated to meet our [contributing guidelines](../blob/dev/CONTRIBUTING.md) within the 2-hour window.\n\nFeel free to open a new pull request that follows our guidelines.'
  49. : 'This issue has been automatically closed because it was not updated to meet our [contributing guidelines](../blob/dev/CONTRIBUTING.md) within the 2-hour window.\n\nFeel free to open a new issue that follows our issue templates.';
  50. await github.rest.issues.createComment({
  51. owner: context.repo.owner,
  52. repo: context.repo.repo,
  53. issue_number: item.number,
  54. body: closeMessage,
  55. });
  56. if (isPR) {
  57. await github.rest.pulls.update({
  58. owner: context.repo.owner,
  59. repo: context.repo.repo,
  60. pull_number: item.number,
  61. state: 'closed',
  62. });
  63. } else {
  64. await github.rest.issues.update({
  65. owner: context.repo.owner,
  66. repo: context.repo.repo,
  67. issue_number: item.number,
  68. state: 'closed',
  69. state_reason: 'not_planned',
  70. });
  71. }
  72. core.info(`Closed non-compliant ${kind} #${item.number} after 2-hour window`);
  73. }