summaryrefslogtreecommitdiffhomepage
path: root/.github/workflows/compliance-close.yml
blob: c3bcf9f686f437260dd0c59030136245fa88fefc (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
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,
              });

              try {
                await github.rest.issues.removeLabel({
                  owner: context.repo.owner,
                  repo: context.repo.repo,
                  issue_number: item.number,
                  name: 'needs:compliance',
                });
              } catch (e) {}

              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`);
            }