fix(留言分頁): 改用 timeline 分頁讀取留言

Gitea 議題留言端點無法可靠處理分頁;改由 timeline 逐頁篩選 comment 事件並去重,讓抽取、整併與 PR 留言流程取得完整集合。
This commit is contained in:
2026-09-22 14:37:38 +08:00
parent a5699d1798
commit a944141109
5 changed files with 19 additions and 19 deletions
+2 -3
View File
@@ -31,16 +31,15 @@ main(async () => {
const repo = parseRepo(flags.repo);
const index = parseIndex(flags.index);
const issuePath = `/repos/${repo}/issues/${index}`;
const commentsPath = `${issuePath}/comments`;
const timelinePath = `${issuePath}/timeline`;
if (flags['dry-run']) {
return {
dryRun: true,
repo,
index,
requests: [
{ method: 'GET', path: issuePath },
{ method: 'GET', path: commentsPath },
{ method: 'GET', path: timelinePath },
],
note: UNMERGED_COMMENT_NOTE,
};
+11 -5
View File
@@ -974,16 +974,22 @@ export async function countUnmergedComments(login, repo, index, me) {
/**
* 逐頁走過一顆議題(或 PR)的一般留言。
* 三支腳本都要做這件事:數未整併的則數、列出留言內容、核對 --merged 的 id。
* Gitea 的 comments 端點固定只回第一批,完整清單改從 timeline 取得。
* @returns {AsyncGenerator<object>} 一則一則交出去
*/
export async function* listIssueComments(login, repo, index) {
const path = `/repos/${repo}/issues/${index}/comments`;
const path = `/repos/${repo}/issues/${index}/timeline`;
const seen = new Set();
for await (const comments of pages(login, path, {
limitCode: 'COMMENT_LIMIT',
limitHint: `${path} 的留言太多,讀不完整份清單`,
for await (const entries of pages(login, path, {
limitCode: 'TIMELINE_LIMIT',
limitHint: `${path} 的 timeline 太多,讀不完整份留言清單`,
})) {
for (const comment of comments) yield comment;
for (const entry of entries) {
if (entry.type !== 'comment' || seen.has(entry.id)) continue;
seen.add(entry.id);
yield entry;
}
}
}
+3 -8
View File
@@ -24,6 +24,7 @@ import {
ScriptError,
expectOk,
giteaRequest,
listIssueComments,
main,
pages,
parseFlags,
@@ -205,14 +206,8 @@ async function findInline(login, repo, index, commentId) {
}
async function findGeneral(login, repo, index, commentId) {
const path = `/repos/${repo}/issues/${index}/comments`;
for await (const comments of pages(login, path, {
limitCode: 'COMMENT_LIMIT',
limitHint: `${path} 的留言太多,找不完`,
})) {
const hit = comments.find((comment) => comment.id === commentId);
if (hit) return hit;
for await (const comment of listIssueComments(login, repo, index)) {
if (comment.id === commentId) return comment;
}
throw notFound(index, '一般留言', commentId);
}
+2 -2
View File
@@ -49,7 +49,7 @@ export function plannedRequests(repo, index) {
return [
{ method: 'GET', path: '/user' },
{ method: 'GET', path: pullPath },
{ method: 'GET', path: `/repos/${repo}/issues/${index}/comments` },
{ method: 'GET', path: `/repos/${repo}/issues/${index}/timeline` },
{ method: 'GET', path: `${pullPath}/reviews` },
{ method: 'GET', path: `/repos/${repo}/issues/${index}/timeline` },
];
@@ -65,7 +65,7 @@ export function plannedRequests(repo, index) {
export function commonRequests(repo, index) {
return [
{ method: 'GET', path: `/repos/${repo}/issues/${index}` },
{ method: 'GET', path: `/repos/${repo}/issues/${index}/comments` },
{ method: 'GET', path: `/repos/${repo}/issues/${index}/timeline` },
];
}
+1 -1
View File
@@ -54,7 +54,7 @@ main(async () => {
{ method: 'GET', path: issuePath },
{ method: 'GET', path: `${issuePath}/dependencies` },
{ method: 'GET', path: `${issuePath}/blocks` },
{ method: 'GET', path: `${issuePath}/comments` },
{ method: 'GET', path: `${issuePath}/timeline` },
],
note: UNMERGED_COMMENT_NOTE,
};