bug: with_connection global write lock + unclosed notify channel freezes bot when ACP process goes stale #40
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: Issue pending-maintainer flip | |
| on: | |
| schedule: | |
| - cron: '0 * * * *' # hourly safety net | |
| issue_comment: | |
| types: [created] | |
| workflow_dispatch: | |
| jobs: | |
| check-pending: | |
| if: >- | |
| github.event_name == 'workflow_dispatch' | |
| || github.event_name == 'schedule' | |
| || (github.event_name == 'issue_comment' && !github.event.issue.pull_request) | |
| runs-on: ubuntu-latest | |
| permissions: | |
| issues: write | |
| steps: | |
| - uses: actions/github-script@v7 | |
| with: | |
| script: | | |
| const MAINTAINER = 'pending-maintainer'; | |
| const CONTRIBUTOR = 'pending-contributor'; | |
| let issueNumbers = []; | |
| if (context.eventName === 'workflow_dispatch' || context.eventName === 'schedule') { | |
| const issues = await github.rest.issues.listForRepo({ | |
| ...context.repo, | |
| state: 'open', | |
| per_page: 100 | |
| }); | |
| issueNumbers = issues.data | |
| .filter(i => !i.pull_request) | |
| .map(i => i.number); | |
| } else if (context.eventName === 'issue_comment') { | |
| issueNumbers = [context.payload.issue.number]; | |
| } | |
| for (const issueNumber of issueNumbers) { | |
| const { data: issue } = await github.rest.issues.get({ | |
| ...context.repo, | |
| issue_number: issueNumber | |
| }); | |
| const labels = issue.labels.map(l => l.name); | |
| // Skip if closing-soon or wontfix/not-planned | |
| if (labels.includes('closing-soon')) continue; | |
| if (labels.includes('wontfix') || labels.includes('not-planned')) continue; | |
| // Check last human comment is from issue author | |
| const { data: allComments } = await github.rest.issues.listComments({ | |
| ...context.repo, | |
| issue_number: issueNumber, | |
| per_page: 100 | |
| }); | |
| const humanComments = allComments.filter(c => c.user.type !== 'Bot'); | |
| if (humanComments.length === 0) continue; | |
| const lastCommenter = humanComments[humanComments.length - 1].user.login; | |
| if (lastCommenter !== issue.user.login) continue; | |
| // Flip: +pending-maintainer, -pending-contributor | |
| if (!labels.includes(MAINTAINER)) { | |
| await github.rest.issues.addLabels({ | |
| ...context.repo, | |
| issue_number: issueNumber, | |
| labels: [MAINTAINER] | |
| }); | |
| } | |
| if (labels.includes(CONTRIBUTOR)) { | |
| await github.rest.issues.removeLabel({ | |
| ...context.repo, | |
| issue_number: issueNumber, | |
| name: CONTRIBUTOR | |
| }).catch(() => {}); | |
| } | |
| console.log(`#${issueNumber} — author replied, set ${MAINTAINER}`); | |
| } |