Skip to content

Auto Close Old Issues (1y) #111

Auto Close Old Issues (1y)

Auto Close Old Issues (1y) #111

name: Auto Close Old Issues (1y)
on:
schedule:
# Daily at 02:20 UTC
- cron: '20 2 * * *'
workflow_dispatch:
permissions:
issues: write
jobs:
close_old_issues:
runs-on: ubuntu-latest
steps:
- name: Close issues older than 1 year
uses: actions/github-script@v7
with:
script: |
const owner = context.repo.owner;
const repo = context.repo.repo;
const now = new Date();
const cutoff = new Date(now.getTime() - 365 * 24 * 60 * 60 * 1000);
const closeComment = `该 Issue 已超过 1 年未活跃,为便于维护当前问题队列,先做关闭处理。\n\n如该问题在最新版本仍存在,欢迎直接 **Reopen** 本 Issue(或新建 Issue 并关联本单),并补充:\n1. 版本与部署方式\n2. 最小复现步骤\n3. 关键日志/截图(请脱敏)\n\n我们会优先跟进。`;
let page = 1;
let processed = 0;
while (true) {
const { data: issues } = await github.rest.issues.listForRepo({
owner,
repo,
state: 'open',
per_page: 100,
page,
sort: 'created',
direction: 'asc'
});
if (!issues.length) break;
for (const issue of issues) {
// skip pull requests
if (issue.pull_request) continue;
const createdAt = new Date(issue.created_at);
if (createdAt > cutoff) {
// list is sorted asc by created time; remaining items are newer
core.info('Reached issues newer than cutoff, stop scanning.');
return;
}
try {
await github.rest.issues.createComment({
owner,
repo,
issue_number: issue.number,
body: closeComment,
});
await github.rest.issues.update({
owner,
repo,
issue_number: issue.number,
state: 'closed',
});
processed += 1;
core.info(`Closed #${issue.number}`);
} catch (e) {
core.warning(`Failed to close #${issue.number}: ${e.message}`);
}
}
page += 1;
}
core.info(`Done. Closed ${processed} old issues.`);