|
| 1 | +name: Handle AwaitingUserResponse |
| 2 | + |
| 3 | +on: |
| 4 | + issues: |
| 5 | + types: [labeled] |
| 6 | + issue_comment: |
| 7 | + types: [created] |
| 8 | + schedule: |
| 9 | + - cron: '*/15 * * * *' # TODO(glider): change to '0 0 * * *' once we finish testing. |
| 10 | + |
| 11 | +jobs: |
| 12 | + handle-awaiting-user-response: |
| 13 | + runs-on: ubuntu-latest |
| 14 | + |
| 15 | + steps: |
| 16 | + - name: Checkout code |
| 17 | + uses: actions/checkout@v3 |
| 18 | + |
| 19 | + - name: Handle Issues and Comments |
| 20 | + if: github.event_name == 'issues' && github.event.action == 'labeled' || github.event_name == 'issue_comment' |
| 21 | + uses: actions/github-script@v6 |
| 22 | + with: |
| 23 | + github-token: ${{ secrets.GITHUB_TOKEN }} |
| 24 | + script: | |
| 25 | + const { owner, repo, number } = context.issue; |
| 26 | + |
| 27 | + if (context.event_name === 'issues' && context.payload.action === 'labeled') { |
| 28 | + const labelName = context.payload.label.name; |
| 29 | + |
| 30 | + if (labelName === 'AwaitingUserResponse') { |
| 31 | + // Add a comment notifying the user. |
| 32 | + await github.rest.issues.createComment({ |
| 33 | + owner, |
| 34 | + repo, |
| 35 | + issue_number: number, |
| 36 | + body: 'We are awaiting your response. If we do not hear back from you within 90 days, this issue will be automatically closed.' |
| 37 | + }); |
| 38 | + } |
| 39 | + } else if (context.event_name === 'issue_comment') { |
| 40 | + const issue = context.payload.issue; |
| 41 | + |
| 42 | + // Check if the "AwaitingUserResponse" label is present. |
| 43 | + const labels = issue.labels.map(label => label.name); |
| 44 | + if (labels.includes('AwaitingUserResponse')) { |
| 45 | + // Remove the label. |
| 46 | + await github.rest.issues.removeLabel({ |
| 47 | + owner, |
| 48 | + repo, |
| 49 | + issue_number: number, |
| 50 | + name: 'AwaitingUserResponse' |
| 51 | + }); |
| 52 | + } |
| 53 | + } |
| 54 | + |
| 55 | + - name: Handle Scheduled Cleanup |
| 56 | + if: github.event_name == 'schedule' |
| 57 | + uses: actions/github-script@v6 |
| 58 | + with: |
| 59 | + github-token: ${{ secrets.GITHUB_TOKEN }} |
| 60 | + script: | |
| 61 | + const { owner, repo } = context.repo; |
| 62 | + |
| 63 | + // Fetch all open issues with the "AwaitingUserResponse" label. |
| 64 | + const issues = await github.paginate(github.rest.issues.listForRepo, { |
| 65 | + owner, |
| 66 | + repo, |
| 67 | + state: 'open', |
| 68 | + labels: 'AwaitingUserResponse', |
| 69 | + per_page: 100 |
| 70 | + }); |
| 71 | + |
| 72 | + const now = new Date(); |
| 73 | + |
| 74 | + for (const issue of issues) { |
| 75 | + const timelineEvents = await github.paginate(github.rest.issues.listEventsForTimeline, { |
| 76 | + owner, |
| 77 | + repo, |
| 78 | + issue_number: issue.number, |
| 79 | + per_page: 100 |
| 80 | + }); |
| 81 | + |
| 82 | + // Find the latest labeled event for "AwaitingUserResponse". |
| 83 | + const labeledEvents = timelineEvents.filter(event => |
| 84 | + event.event === 'labeled' && event.label.name === 'AwaitingUserResponse' |
| 85 | + ); |
| 86 | + |
| 87 | + if (labeledEvents.length > 0) { |
| 88 | + const latestLabelEvent = labeledEvents.reduce((latest, event) => |
| 89 | + new Date(event.created_at) > new Date(latest.created_at) ? event : latest |
| 90 | + ); |
| 91 | + |
| 92 | + const labelAppliedAt = new Date(latestLabelEvent.created_at); |
| 93 | + // TODO(glider): use diffDays instead of diffHours once we finish testing. |
| 94 | + // const diffDays = (now - labelAppliedAt) / (1000 * 60 * 60 * 24); |
| 95 | + const diffHours = (now - labelAppliedAt) / (1000 * 60 * 60); |
| 96 | + |
| 97 | + //if (diffDays > 90) { |
| 98 | + if (diffHours > 2) { |
| 99 | + // Close the issue. |
| 100 | + await github.rest.issues.update({ |
| 101 | + owner, |
| 102 | + repo, |
| 103 | + issue_number: issue.number, |
| 104 | + state: 'closed' |
| 105 | + }); |
| 106 | + |
| 107 | + // Add a comment notifying the user. |
| 108 | + await github.rest.issues.createComment({ |
| 109 | + owner, |
| 110 | + repo, |
| 111 | + issue_number: issue.number, |
| 112 | + body: 'This issue has been automatically closed as it has been marked "AwaitingUserResponse" for more than 90 days with no activity.' |
| 113 | + }); |
| 114 | + } |
| 115 | + } |
| 116 | + } |
| 117 | + |
0 commit comments