|
69 | 69 |
|
70 | 70 | jobs: |
71 | 71 | issue-regex-labeler: |
72 | | - if: github.repository_owner == 'GameServerManagers' && github.event_name == 'issues' && (github.event.action == 'opened' || github.event.action == 'edited') |
| 72 | + if: github.repository_owner == 'GameServerManagers' && github.event_name == 'issues' && github.event.issue.state == 'open' && (github.event.action == 'opened' || github.event.action == 'edited') |
73 | 73 | runs-on: ubuntu-latest |
74 | 74 | steps: |
75 | 75 | - name: Issue Labeler |
|
82 | 82 | sync-labels: 0 |
83 | 83 |
|
84 | 84 | issue-ai-maintenance: |
85 | | - if: github.repository_owner == 'GameServerManagers' && (github.event_name == 'issues' || github.event_name == 'issue_comment') |
| 85 | + if: github.repository_owner == 'GameServerManagers' && (github.event_name == 'issues' || github.event_name == 'issue_comment') && github.event.issue.state == 'open' |
86 | 86 | runs-on: ubuntu-latest |
87 | 87 | steps: |
88 | 88 | - name: Reconcile issue labels and AI triage |
@@ -819,8 +819,37 @@ jobs: |
819 | 819 | } |
820 | 820 |
|
821 | 821 | // Avoid pointless API calls. |
822 | | - const finalAdds = [...labelsToAdd].filter((label) => !existingLabels.has(label)); |
823 | | - const finalRemoves = [...labelsToRemove].filter((label) => existingLabels.has(label)); |
| 822 | + let finalAdds = [...labelsToAdd].filter((label) => !existingLabels.has(label)); |
| 823 | + let finalRemoves = [...labelsToRemove].filter((label) => existingLabels.has(label)); |
| 824 | +
|
| 825 | + const isGameOrEngineLabel = (label) => label.startsWith('game: ') || label.startsWith('engine: '); |
| 826 | + if ([...finalAdds, ...finalRemoves].some(isGameOrEngineLabel)) { |
| 827 | + try { |
| 828 | + const issueEvents = await github.paginate(github.rest.issues.listEvents, { |
| 829 | + owner, |
| 830 | + repo, |
| 831 | + issue_number: issueNumber, |
| 832 | + per_page: 100, |
| 833 | + }); |
| 834 | + const lastManualLabelEvent = new Map(); |
| 835 | + for (const e of issueEvents) { |
| 836 | + if (!['labeled', 'unlabeled'].includes(e.event) || !e.label?.name) continue; |
| 837 | + lastManualLabelEvent.set(e.label.name, e.actor?.type === 'Bot' ? null : e.event); |
| 838 | + } |
| 839 | + finalAdds = finalAdds.filter((label) => { |
| 840 | + if (!isGameOrEngineLabel(label) || lastManualLabelEvent.get(label) !== 'unlabeled') return true; |
| 841 | + console.log(`Label "${label}" was removed manually; not adding it back.`); |
| 842 | + return false; |
| 843 | + }); |
| 844 | + finalRemoves = finalRemoves.filter((label) => { |
| 845 | + if (!isGameOrEngineLabel(label) || lastManualLabelEvent.get(label) !== 'labeled') return true; |
| 846 | + console.log(`Label "${label}" was added manually; keeping it.`); |
| 847 | + return false; |
| 848 | + }); |
| 849 | + } catch (err) { |
| 850 | + console.log(`Could not read issue events: ${err.message}`); |
| 851 | + } |
| 852 | + } |
824 | 853 |
|
825 | 854 | for (const label of finalRemoves) { |
826 | 855 | try { |
@@ -2199,8 +2228,38 @@ jobs: |
2199 | 2228 | } |
2200 | 2229 |
|
2201 | 2230 | // Apply changes |
2202 | | - const finalAdds = [...labelsToAdd].filter((label) => !existingLabels.has(label)); |
2203 | | - const finalRemoves = [...labelsToRemove].filter((label) => existingLabels.has(label)); |
| 2231 | + let finalAdds = [...labelsToAdd].filter((label) => !existingLabels.has(label)); |
| 2232 | + let finalRemoves = [...labelsToRemove].filter((label) => existingLabels.has(label)); |
| 2233 | +
|
| 2234 | + const isGameOrEngineLabel = (label) => label.startsWith('game: ') || label.startsWith('engine: '); |
| 2235 | + if ([...finalAdds, ...finalRemoves].some(isGameOrEngineLabel)) { |
| 2236 | + try { |
| 2237 | + const issueEvents = await github.paginate(github.rest.issues.listEvents, { |
| 2238 | + owner, |
| 2239 | + repo, |
| 2240 | + issue_number: rawIssue.number, |
| 2241 | + per_page: 100, |
| 2242 | + }); |
| 2243 | + const lastManualLabelEvent = new Map(); |
| 2244 | + for (const e of issueEvents) { |
| 2245 | + if (!['labeled', 'unlabeled'].includes(e.event) || !e.label?.name) continue; |
| 2246 | + lastManualLabelEvent.set(e.label.name, e.actor?.type === 'Bot' ? null : e.event); |
| 2247 | + } |
| 2248 | + finalAdds = finalAdds.filter((label) => { |
| 2249 | + if (!isGameOrEngineLabel(label) || lastManualLabelEvent.get(label) !== 'unlabeled') return true; |
| 2250 | + console.log(`#${rawIssue.number}: "${label}" was removed manually; not adding it back`); |
| 2251 | + return false; |
| 2252 | + }); |
| 2253 | + finalRemoves = finalRemoves.filter((label) => { |
| 2254 | + if (!isGameOrEngineLabel(label) || lastManualLabelEvent.get(label) !== 'labeled') return true; |
| 2255 | + console.log(`#${rawIssue.number}: "${label}" was added manually; keeping it`); |
| 2256 | + return false; |
| 2257 | + }); |
| 2258 | + } catch (err) { |
| 2259 | + if (isApiRateLimitError(err)) throw err; |
| 2260 | + console.log(`#${rawIssue.number}: could not read issue events: ${err.message}`); |
| 2261 | + } |
| 2262 | + } |
2204 | 2263 |
|
2205 | 2264 | let labelAdded = 0; |
2206 | 2265 | let labelRemoved = 0; |
|
0 commit comments