Merge pull request 'feat/plan-analyze-timing/main' (#63) from feat/plan-analyze-timing/main into master

Reviewed-on: #63
Reviewed-by: 系統管理員 <1+admin@noreply.localhost>
This commit was merged in pull request #63.
This commit is contained in:
2026-09-18 00:52:27 +00:00
15 changed files with 756 additions and 84 deletions
+34
View File
@@ -1036,6 +1036,40 @@ export function stopwatchOnIssue(watches, repo, index) {
);
}
/**
* 「這顆議題上沒有碼錶在跑」的回法不只一種:看過 500,也看過 409。
* 狀態碼隨站台版本而異,所以認的是「狀態碼在這一組裡 **且** 訊息說的是碼錶」——
* 只看訊息會把真的伺服器錯誤一起吞掉,只看狀態碼會把別的衝突也當成沒錶。
*/
const NO_STOPWATCH_STATUS = [409, 500];
/**
* 停錶。停在指定議題上,只停那一顆——端點本身就是議題範圍的,
* 停錶不會波及別顆議題上的錶,那正是領取鎖那條規則要守住的事。
*
* 錶沒在跑不算失敗:停錶多半排在別的事情做完之後(開完 PR、回報完),
* 把「本來就沒在跑」報成失敗,只會讓人以為前面那件事沒做成而重跑一次。
*
* @param {{base: string, token: string}} login
* @param {string} repo owner/name
* @param {number} index
* @returns {Promise<boolean>} 這次真的停了一支錶才是 true
*/
export async function stopStopwatch(login, repo, index) {
const path = `/repos/${repo}/issues/${index}/stopwatch/stop`;
const response = await giteaRequest(login, 'POST', path, { body: {} });
if (response.status >= 200 && response.status < 300) return true;
if (
NO_STOPWATCH_STATUS.includes(response.status) &&
/stopwatch/i.test(response.body?.message ?? '')
) {
return false;
}
expectOk(response, `POST ${path}`);
return false;
}
// ── 標籤 ───────────────────────────────────────────────────────────
/**