Skip to content

Commit 492946e

Browse files
committed
fix(maker): slow down clone transient retries
- Increase Maker clone/fetch retry budget from 2 to 3 retries. - Change default retry base delay from 1500ms to 10000ms. - Give Maker repositories more time to finish server-side preparation. - Cover retry count and default delay with clone binding tests. - Update Maker docs for the new retry behavior and env override default. Verification: - npm test -- --runTestsByPath src/__tests__/makerCloneBinding.test.ts --runInBand - npm run lint - npm run format:check - npm run build - npm test -- --runInBand
1 parent ffda08a commit 492946e

3 files changed

Lines changed: 14 additions & 8 deletions

File tree

docs/MAKER.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ Maker app 列表关键字段:
364364
`git init` + `git fetch --depth=1 origin`,再 checkout 远端默认分支,避免大项目在慢网环境下载完整历史。
365365
- 首次 clone/fetch 前会明确提示用户:Maker server 可能正在准备仓库,首次拉代码 20 秒以上是正常现象,请保持当前命令运行。
366366
- `taptap-maker init` 会根据 Git stderr 判断是否自动重试:HTTP 5xx503、超时、连接重置、HTTP2/RPC 中断、early EOF 等远端临时错误会在 fetch 阶段重试;认证失败、权限不足、仓库不存在、远端拒绝、非空目录冲突、本地权限错误不会重试。
367-
- 首次 clone/fetch 默认最多自动重试 2;连续重试后仍失败时,错误会保留 `retryable``retry_reason` 和已重试次数,方便 Agent 判断是让用户稍后直接重试,还是先处理 PAT、权限或本地目录问题。
367+
- 首次 clone/fetch 默认最多自动重试 3 次,基础等待间隔为 10;连续重试后仍失败时,错误会保留 `retryable``retry_reason` 和已重试次数,方便 Agent 判断是让用户稍后直接重试,还是先处理 PAT、权限或本地目录问题。
368368
- `maker_build_current_directory` 会在本地 commit、push 和远端 build 阶段输出状态,并解析 Git push stderr 中的百分比进度。
369369
- `maker_build_current_directory` 的 push 阶段也会对远端临时错误自动重试;push 最终失败时不会继续远端 build。
370370
- `maker_build_current_directory` 会转发远端 build tool 的 progress notification。
@@ -583,7 +583,7 @@ push
583583
| `TAPTAP_MAKER_REMOTE_MCP_SERVER_URL` | 可选:覆盖当前环境的远端 Maker MCP server URL |
584584
| `TAPTAP_MAKER_WEB_URL` | 可选:覆盖当前环境的 Maker 网页地址 |
585585
| `TAPTAP_MAKER_GIT_BIN` | 可选:覆盖 Git 可执行文件路径 |
586-
| `TAPTAP_MAKER_GIT_RETRY_DELAY_MS` | 可选:覆盖 Git 临时错误重试基础延迟,默认 1500ms |
586+
| `TAPTAP_MAKER_GIT_RETRY_DELAY_MS` | 可选:覆盖 Git 临时错误重试基础延迟,默认 10000ms |
587587
| `SCE_MCP_URL` | 云端 SCE MCP endpoint 默认值 |
588588

589589
Maker 后端默认地址集中在 `src/maker/config.ts`。兼容旧变量名:`MAKER_API_BASE`

src/__tests__/makerCloneBinding.test.ts

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import fs from 'node:fs';
66
import os from 'node:os';
77
import path from 'node:path';
88
import { createDevKitGitignoreBlock, DEV_KIT_GITIGNORE_STAGING_FILE } from '../maker/cli/devKit';
9-
import { cloneMakerProject } from '../maker/cli/projects';
9+
import { cloneMakerProject, getMakerGitRetryDelayMs } from '../maker/cli/projects';
1010
import { saveProjectConfig } from '../maker/storage';
1111

1212
describe('maker clone binding safety', () => {
@@ -236,11 +236,17 @@ describe('maker clone binding safety', () => {
236236
expect(progressMessages.join('\n')).toContain('20+ seconds');
237237
expect(progressMessages.join('\n')).toContain('transient 503/5xx errors are retried');
238238
expect(progressMessages.join('\n')).toContain('Maker server may still be preparing');
239-
expect(progressMessages.join('\n')).toContain('retrying 1/2');
239+
expect(progressMessages.join('\n')).toContain('retrying 1/3');
240240
const commands = fs.readFileSync(gitLog, 'utf8');
241241
expect(commands.match(/^fetch --progress --depth=1 origin$/gm)).toHaveLength(2);
242242
});
243243

244+
test('uses a 10 second default delay for transient Maker git retries', () => {
245+
delete process.env.TAPTAP_MAKER_GIT_RETRY_DELAY_MS;
246+
247+
expect(getMakerGitRetryDelayMs()).toBe(10_000);
248+
});
249+
244250
test('continues from a recorded project config after earlier clone failure', async () => {
245251
const gitLog = path.join(tempDir, '.test-tools', 'git.log');
246252
const fakeGit = createFakeGit(gitLog);

src/maker/cli/projects.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1759,7 +1759,7 @@ async function runWithTransientRetry(
17591759
}
17601760
): Promise<number> {
17611761
let retries = 0;
1762-
const maxRetries = 2;
1762+
const maxRetries = 3;
17631763

17641764
for (;;) {
17651765
try {
@@ -1780,7 +1780,7 @@ async function runWithTransientRetry(
17801780
phase: options.stage,
17811781
message: formatGitRetryProgressMessage(options.stage, decision, retries, maxRetries),
17821782
});
1783-
await sleep(getGitRetryDelayMs() * retries);
1783+
await sleep(getMakerGitRetryDelayMs() * retries);
17841784
}
17851785
}
17861786
}
@@ -1845,9 +1845,9 @@ function appendRetryExhausted(
18451845
);
18461846
}
18471847

1848-
function getGitRetryDelayMs(): number {
1848+
export function getMakerGitRetryDelayMs(): number {
18491849
const value = Number.parseInt(process.env.TAPTAP_MAKER_GIT_RETRY_DELAY_MS || '', 10);
1850-
return Number.isFinite(value) && value >= 0 ? value : 1500;
1850+
return Number.isFinite(value) && value >= 0 ? value : 10_000;
18511851
}
18521852

18531853
function sleep(ms: number): Promise<void> {

0 commit comments

Comments
 (0)