compliance-close #7
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: compliance-close | |
| on: | |
| schedule: | |
| # Run every 30 minutes to check for expired compliance windows | |
| - cron: "*/30 * * * *" | |
| workflow_dispatch: | |
| permissions: | |
| contents: read | |
| issues: write | |
| pull-requests: write | |
| jobs: | |
| close-non-compliant: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Close non-compliant issues and PRs after 2 hours | |
| uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const { data: items } = await github.rest.issues.listForRepo({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| labels: 'needs:compliance', | |
| state: 'open', | |
| per_page: 100, | |
| }); | |
| if (items.length === 0) { | |
| core.info('No open issues/PRs with needs:compliance label'); | |
| return; | |
| } | |
| const now = Date.now(); | |
| const twoHours = 2 * 60 * 60 * 1000; | |
| for (const item of items) { | |
| const isPR = !!item.pull_request; | |
| const kind = isPR ? 'PR' : 'issue'; | |
| const { data: comments } = await github.rest.issues.listComments({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: item.number, | |
| }); | |
| const complianceComment = comments.find(c => c.body.includes('<!-- issue-compliance -->')); | |
| if (!complianceComment) continue; | |
| const commentAge = now - new Date(complianceComment.created_at).getTime(); | |
| if (commentAge < twoHours) { | |
| core.info(`${kind} #${item.number} still within 2-hour window (${Math.round(commentAge / 60000)}m elapsed)`); | |
| continue; | |
| } | |
| const closeMessage = isPR | |
| ? '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.' | |
| : '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.'; | |
| await github.rest.issues.createComment({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: item.number, | |
| body: closeMessage, | |
| }); | |
| if (isPR) { | |
| await github.rest.pulls.update({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| pull_number: item.number, | |
| state: 'closed', | |
| }); | |
| } else { | |
| await github.rest.issues.update({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| issue_number: item.number, | |
| state: 'closed', | |
| state_reason: 'not_planned', | |
| }); | |
| } | |
| core.info(`Closed non-compliant ${kind} #${item.number} after 2-hour window`); | |
| } |