1- name : Sync Issues to CSV
1+ name : Sync Issue to CSV
22
33on :
4+ issues :
5+ types : [opened, edited]
6+ issue_comment :
7+ types : [created]
48 schedule :
59 - cron : " */10 * * * *" # 每10分钟兜底
610 workflow_dispatch :
@@ -14,44 +18,29 @@ jobs:
1418 runs-on : ubuntu-latest
1519
1620 steps :
17- - name : Checkout repo
18- uses : actions/checkout@v4
21+ - uses : actions/checkout@v4
1922
20- - name : Setup Node.js
21- uses : actions/setup-node@v3
22- with :
23- node-version : " 20"
24-
25- - name : Sync all issues to CSV
23+ - name : Sync Issue to CSV
2624 uses : actions/github-script@v7
2725 with :
2826 script : |
2927 const fs = require('fs');
3028 const owner = context.repo.owner;
3129 const repo = context.repo.repo;
3230
33- // ===== 读取 CSV 或初始化 =====
34- let csv = fs.existsSync('tasks.csv') ? fs. readFileSync('tasks.csv', 'utf8') : "Project,Repo,Issue,Owner,PR,Status,Source\n" ;
31+ // ===== 读取 CSV =====
32+ let csv = fs.readFileSync('tasks.csv', 'utf8');
3533 let lines = csv.split('\n').filter(line => line.trim() !== '');
3634 const header = lines[0];
3735 let rows = lines.slice(1);
3836
39- // ===== 获取所有 open Issue =====
37+ // ===== 当前触发的 issue =====
4038 let issues = [];
41- const perPage = 100;
42- let page = 1;
43- while (true) {
44- const { data } = await github.rest.issues.listForRepo({
45- owner,
46- repo,
47- state: 'open',
48- per_page: perPage,
49- page
50- });
51- if (!data.length) break;
52- issues = issues.concat(data);
53- if (data.length < perPage) break;
54- page++;
39+ if (context.payload.issue) {
40+ issues = [context.payload.issue];
41+ } else {
42+ console.log("Skip full sync due to permission limits");
43+ return;
5544 }
5645
5746 for (const issue of issues) {
@@ -60,38 +49,44 @@ jobs:
6049 const issueNumber = issue.number;
6150 const issueUrl = `https://github.com/${owner}/${repo}/issues/${issueNumber}`;
6251
63- // ===== Repo URL =====
52+ // ===== Repo =====
6453 const repoMatch = body.match(/https:\/\/github\.com\/[^\s]+/);
6554 const repoUrl = repoMatch ? repoMatch[0] : "";
66- if (!repoUrl) continue;
55+ if (!repoUrl) continue; // 必须有 repo
6756
6857 // ===== Owner =====
6958 const ownerMatch = body.match(/Owner:\s*@([^\s]+)/);
7059 const taskOwner = ownerMatch ? ownerMatch[1] : "";
7160
72- // ===== PR URL =====
61+ // ===== PR =====
7362 const prMatch = body.match(/PR:\s*(https:\/\/[^\s]+)/);
7463 const prUrl = prMatch ? prMatch[1] : "";
7564
7665 // ===== Status =====
7766 let status = "";
7867 if (prUrl) {
68+ // 默认 open,如果 merged/closed 信息在 body 可解析,这里简单占位
7969 const mergedMatch = body.match(/Status:\s*(merged|closed|open)/i);
8070 status = mergedMatch ? mergedMatch[1].toLowerCase() : "open";
71+ } else {
72+ status = "";
8173 }
8274
8375 let found = false;
76+
8477 rows = rows.map(row => {
8578 let parts = row.split(',');
8679 while (parts.length < 7) parts.push('');
8780
81+ // Project,Repo,Issue,Owner,PR,Status,Source
8882 if (parts[2] === issueUrl || (parts[2] === "" && parts[1] === repoUrl)) {
8983 parts[2] = issueUrl;
9084 parts[3] = taskOwner;
9185 parts[4] = prUrl;
9286 parts[5] = status;
9387 found = true;
9488 }
89+
9590 return parts.join(',');
9691 });
9792
@@ -111,15 +106,12 @@ jobs:
111106 }
112107 }
113108
114- // ===== 写回 CSV =====
109+ // ===== 写回 CSV(临时环境) =====
115110 const newCsv = [header, ...rows].join('\n');
116111 fs.writeFileSync('tasks.csv', newCsv);
117112
118- - name : Upload CSV artifact (for manual download/merge)
119- uses : actions/upload-artifact@v3
120- with :
121- name : tasks-csv
122- path : tasks.csv
123-
124113 - name : Show CSV (Debug)
125114 run : cat tasks.csv
115+
116+ - name : Skip push
117+ run : echo "No write permission, CSV changes are local to runner"
0 commit comments