Skip to content

Commit e6e72c5

Browse files
authored
Add auto triage issue workflow for monthly tracking
This workflow automatically creates a monthly GitHub triage issue and closes the previous month's issue. It includes steps to compute the current and previous month, check for existing issues, and create a new issue if necessary.
1 parent b2dcfd2 commit e6e72c5

File tree

1 file changed

+97
-0
lines changed

1 file changed

+97
-0
lines changed
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
name: Auto Create Monthly GitHub Triage Issue (Create + Close Previous)
2+
3+
on:
4+
schedule:
5+
- cron: '5 7 1 * *' # 07:05 UTC on the 1st day of each month
6+
workflow_dispatch:
7+
8+
permissions:
9+
issues: write
10+
contents: read
11+
12+
jobs:
13+
ensure-triage-issue:
14+
runs-on: ubuntu-latest
15+
steps:
16+
- name: Compute date context
17+
id: dates
18+
run: |
19+
YEAR_MONTH=$(date -u +'%Y-%m')
20+
PREV_YEAR_MONTH=$(date -u -d "$(date -u +%Y-%m-01) -1 month" +'%Y-%m')
21+
echo "year_month=$YEAR_MONTH" >> $GITHUB_OUTPUT
22+
echo "prev_year_month=$PREV_YEAR_MONTH" >> $GITHUB_OUTPUT
23+
24+
- name: Create current triage & close previous
25+
uses: actions/github-script@v7
26+
with:
27+
script: |
28+
const current = core.getInput('current') || '${{ steps.dates.outputs.year_month }}';
29+
const previous = core.getInput('previous') || '${{ steps.dates.outputs.prev_year_month }}';
30+
const currentTitle = `GitHub Triage: ${current}`;
31+
const previousTitle = `GitHub Triage: ${previous}`;
32+
33+
async function findIssueByExactTitle(title) {
34+
const perPage = 100;
35+
for (let page = 1; page < 50; page++) {
36+
const { data } = await github.rest.issues.listForRepo({
37+
owner: context.repo.owner,
38+
repo: context.repo.repo,
39+
state: 'all',
40+
per_page: perPage,
41+
page
42+
});
43+
if (!data.length) break;
44+
const hit = data.find(i => i.title === title);
45+
if (hit) return hit;
46+
if (data.length < perPage) break;
47+
}
48+
return null;
49+
}
50+
51+
// Close previous month issue if open
52+
const prevIssue = await findIssueByExactTitle(previousTitle);
53+
if (prevIssue && prevIssue.state === 'open') {
54+
await github.rest.issues.update({
55+
owner: context.repo.owner,
56+
repo: context.repo.repo,
57+
issue_number: prevIssue.number,
58+
state: 'closed'
59+
});
60+
core.notice(`Closed previous triage issue #${prevIssue.number} (${previousTitle}).`);
61+
} else {
62+
core.info(`No open previous triage issue to close (title: ${previousTitle}).`);
63+
}
64+
65+
// Ensure current month issue
66+
const currIssue = await findIssueByExactTitle(currentTitle);
67+
if (currIssue) {
68+
core.info(`Current triage issue already exists: #${currIssue.number}`);
69+
return;
70+
}
71+
72+
const body = `
73+
### Monthly GitHub Triage – ${current}
74+
75+
Automatically generated tracking issue for ${current}.
76+
77+
#### Purpose
78+
- Collect newly opened issues for classification.
79+
- Track placeholders (titles containing \`[REPLACE_WITH_MODULE_TITLE]\`).
80+
- Identify consolidation / closure candidates.
81+
82+
#### Actions
83+
- Apply governance labels.
84+
- Escalate support or experience issues.
85+
- Prepare weekly summaries (see companion workflow).
86+
87+
:octocat: :copilot: Created automatically.
88+
`.trim();
89+
90+
const created = await github.rest.issues.create({
91+
owner: context.repo.owner,
92+
repo: context.repo.repo,
93+
title: currentTitle,
94+
body,
95+
labels: ['triage']
96+
});
97+
core.notice(`Created new triage issue #${created.data.number} (${currentTitle}).`);

0 commit comments

Comments
 (0)