(msg: Api.Message, args: string[])
| 298 | private async handleMergeAll(msg: Api.Message, args: string[]) { |
| 299 | if (args.length < 1) { |
| 300 | throw new Error("参数不足,需要提供仓库名"); |
| 301 | } |
| 302 | const repoName = args[0]; |
| 303 | await msg.edit({ text: `🔄 正在准备批量合并 <code>${htmlEscape(repoName)}</code> 的PR...`, parseMode: "html" }); |
| 304 | |
| 305 | const parts = repoName.split("/"); |
| 306 | if (parts.length !== 2) { |
| 307 | throw new Error("仓库名格式应为 owner/repo,例如 octocat/Hello-World"); |
| 308 | } |
| 309 | const [owner, repo] = parts; |
| 310 | |
| 311 | const api = await getApi(); |
| 312 | |
| 313 | // 1. 获取所有PR的详细信息 |
| 314 | const prsResponse = await api.get(`/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls`, { |
| 315 | params: { state: "open", per_page: 100 } |
| 316 | }); |
| 317 | |
| 318 | const prsList: any[] = prsResponse.data || []; |
| 319 | if (!prsList.length) { |
| 320 | await msg.edit({ text: `ℹ️ 仓库 <code>${htmlEscape(repoName)}</code> 中没有待处理的PR。`, parseMode: "html" }); |
| 321 | return; |
| 322 | } |
| 323 | |
| 324 | // 2. 筛选可合并的PR |
| 325 | const mergeablePRs = []; |
| 326 | for (const item of prsList) { |
| 327 | try { |
| 328 | const pr = await api.get(`/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls/${item.number}`); |
| 329 | if (pr.data?.mergeable) { |
| 330 | mergeablePRs.push(item); |
| 331 | } |
| 332 | } catch (e) { |
| 333 | // 忽略获取详情失败的PR |
| 334 | } |
| 335 | } |
| 336 | |
| 337 | if (mergeablePRs.length === 0) { |
| 338 | await msg.edit({ text: `ℹ️ 仓库 <code>${htmlEscape(repoName)}</code> 中没有可自动合并的PR。`, parseMode: "html" }); |
| 339 | return; |
| 340 | } |
| 341 | |
| 342 | // 按PR编号升序排序 |
| 343 | mergeablePRs.sort((a, b) => a.number - b.number); |
| 344 | |
| 345 | // 3. 依次合并 |
| 346 | let report = `🔀 <b>批量合并报告 for <code>${htmlEscape(repoName)}</code>:</b>\n\n`; |
| 347 | let successCount = 0; |
| 348 | let failCount = 0; |
| 349 | |
| 350 | for (const pr of mergeablePRs) { |
| 351 | try { |
| 352 | await api.put(`/repos/${encodeURIComponent(owner)}/${encodeURIComponent(repo)}/pulls/${pr.number}/merge`); |
| 353 | report += `✅ <b>#${pr.number}</b>: ${htmlEscape(pr.title)} - <b>成功</b>\n`; |
| 354 | successCount++; |
| 355 | } catch (error: any) { |
| 356 | const errorMsg = error.response?.data?.message || error.message; |
| 357 | report += `❌ <b>#${pr.number}</b>: ${htmlEscape(pr.title)} - <b>失败:</b> ${htmlEscape(errorMsg)}\n`; |
no test coverage detected