diff --git a/scripts/execute-r3-all-221-skills.ts b/scripts/execute-r3-all-221-skills.ts index 53a2277..5982cfa 100644 --- a/scripts/execute-r3-all-221-skills.ts +++ b/scripts/execute-r3-all-221-skills.ts @@ -617,7 +617,7 @@ async function main(): Promise { existsSync(uploadedTrackerPath) ? (JSON.parse(readFileSync(uploadedTrackerPath, 'utf8')) as number[]) : [], ) // Mark the first 35 issues that already had comments posted during Phase 1 - for (let i = 0; i < entries.length - remaining.length; i += 1) { + for (let i = 0; i < 35; i += 1) { commentedIssues.add(entries[i]!.issueNumber) } @@ -662,9 +662,9 @@ async function main(): Promise { await postGiteaIssueComment(entry.issueNumber, commentMd) await closeGiteaIssue(entry.issueNumber) commentedIssues.add(entry.issueNumber) + writeFileSync(uploadedTrackerPath, JSON.stringify(Array.from(commentedIssues), null, 2)) uploadedCount += 1 - if (uploadedCount % 20 === 0 || uploadedCount === toUpload.length) { - writeFileSync(uploadedTrackerPath, JSON.stringify(Array.from(commentedIssues), null, 2)) + if (uploadedCount % 10 === 0 || uploadedCount === toUpload.length) { console.log(` [Gitea Upload+Comment+Close] ${String(uploadedCount)}/${String(toUpload.length)} completed`) } } @@ -674,12 +674,16 @@ async function main(): Promise { writeFileSync(uploadedTrackerPath, JSON.stringify(Array.from(commentedIssues), null, 2)) // Ensure any remaining open issues in Milestone #9 are closed - const openRes = await fetch(`${GITEA_BASE_URL}/issues?state=open&type=issues&milestones=9&limit=50`, { - headers: { Authorization: `token ${GITEA_TOKEN}` }, - }) - const openList = (await openRes.json()) as { number: number }[] - for (const iss of openList) { - await closeGiteaIssue(iss.number) + for (let page = 1; page <= 5; page += 1) { + const openRes = await fetch(`${GITEA_BASE_URL}/issues?state=open&type=issues&milestones=9&limit=50&page=1`, { + headers: { Authorization: `token ${GITEA_TOKEN}` }, + signal: AbortSignal.timeout(10000), + }) + const openList = (await openRes.json()) as { number: number }[] + if (openList.length === 0) break + for (const iss of openList) { + await closeGiteaIssue(iss.number) + } } // Final check on Milestone #9 open/closed count diff --git a/scripts/gitea-skill-workflow.ts b/scripts/gitea-skill-workflow.ts index 6c6c73d..cca5bec 100644 --- a/scripts/gitea-skill-workflow.ts +++ b/scripts/gitea-skill-workflow.ts @@ -27,20 +27,25 @@ export async function uploadPngToGiteaIssue( const bytes = readFileSync(pngPath) const fileName = basename(pngPath) for (let attempt = 1; attempt <= 6; attempt += 1) { - const form = new FormData() - form.append('attachment', new Blob([bytes], { type: 'image/png' }), fileName) - const res = await fetch(`${GITEA_BASE_URL}/issues/${String(issueNumber)}/assets?name=${encodeURIComponent(fileName)}`, { - method: 'POST', - headers: { - Authorization: `token ${GITEA_TOKEN}`, - }, - body: form, - }) - if (res.ok) { - return (await res.json()) as GiteaAssetUploadResult - } - if (attempt === 6) { - throw new Error(`Failed to upload PNG to issue #${String(issueNumber)}: HTTP ${String(res.status)}`) + try { + const form = new FormData() + form.append('attachment', new Blob([bytes], { type: 'image/png' }), fileName) + const res = await fetch(`${GITEA_BASE_URL}/issues/${String(issueNumber)}/assets?name=${encodeURIComponent(fileName)}`, { + method: 'POST', + headers: { + Authorization: `token ${GITEA_TOKEN}`, + }, + body: form, + signal: AbortSignal.timeout(10000), + }) + if (res.ok) { + return (await res.json()) as GiteaAssetUploadResult + } + if (attempt === 6) { + throw new Error(`Failed to upload PNG to issue #${String(issueNumber)}: HTTP ${String(res.status)}`) + } + } catch (err) { + if (attempt === 6) throw err } await sleep(250 * attempt) } @@ -52,19 +57,24 @@ export async function postGiteaIssueComment( markdownBody: string, ): Promise<{ id: number; body: string }> { for (let attempt = 1; attempt <= 6; attempt += 1) { - const res = await fetch(`${GITEA_BASE_URL}/issues/${String(issueNumber)}/comments`, { - method: 'POST', - headers: { - Authorization: `token ${GITEA_TOKEN}`, - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ body: markdownBody }), - }) - if (res.ok) { - return (await res.json()) as { id: number; body: string } - } - if (attempt === 6) { - throw new Error(`Failed to post comment on issue #${String(issueNumber)}: HTTP ${String(res.status)}`) + try { + const res = await fetch(`${GITEA_BASE_URL}/issues/${String(issueNumber)}/comments`, { + method: 'POST', + headers: { + Authorization: `token ${GITEA_TOKEN}`, + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ body: markdownBody }), + signal: AbortSignal.timeout(10000), + }) + if (res.ok) { + return (await res.json()) as { id: number; body: string } + } + if (attempt === 6) { + throw new Error(`Failed to post comment on issue #${String(issueNumber)}: HTTP ${String(res.status)}`) + } + } catch (err) { + if (attempt === 6) throw err } await sleep(250 * attempt) } @@ -73,17 +83,22 @@ export async function postGiteaIssueComment( export async function closeGiteaIssue(issueNumber: number): Promise { for (let attempt = 1; attempt <= 6; attempt += 1) { - const res = await fetch(`${GITEA_BASE_URL}/issues/${String(issueNumber)}`, { - method: 'PATCH', - headers: { - Authorization: `token ${GITEA_TOKEN}`, - 'Content-Type': 'application/json', - }, - body: JSON.stringify({ state: 'closed' }), - }) - if (res.ok) return - if (attempt === 6) { - throw new Error(`Failed to close issue #${String(issueNumber)}: HTTP ${String(res.status)}`) + try { + const res = await fetch(`${GITEA_BASE_URL}/issues/${String(issueNumber)}`, { + method: 'PATCH', + headers: { + Authorization: `token ${GITEA_TOKEN}`, + 'Content-Type': 'application/json', + }, + body: JSON.stringify({ state: 'closed' }), + signal: AbortSignal.timeout(10000), + }) + if (res.ok) return + if (attempt === 6) { + throw new Error(`Failed to close issue #${String(issueNumber)}: HTTP ${String(res.status)}`) + } + } catch (err) { + if (attempt === 6) throw err } await sleep(250 * attempt) }