Skip to content

Commit 6a07241

Browse files
committed
refactor(release-sandbox): remove redundant commit message check from workflow
Updated the GitHub Actions workflow for the studio-sandbox release by removing the conditional check that skipped republishing for commits with a '[release]:' prefix. This simplifies the workflow logic. feat(sandbox): implement retry logic for transient network errors during cloning Enhanced the cloning process in the sandbox daemon by adding retry logic for transient network errors. The new implementation allows up to three retries with a delay between attempts, improving robustness against temporary network issues.
1 parent 1af3c5c commit 6a07241

2 files changed

Lines changed: 51 additions & 10 deletions

File tree

.github/workflows/release-studio-sandbox.yaml

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,6 @@ jobs:
1515
build-push:
1616
name: Build & Push studio-sandbox image
1717
runs-on: ubuntu-latest
18-
# `[release]:` commits come from the auto-bump bot and don't actually
19-
# change the sandbox source — skip them to avoid republishing the same
20-
# version on every release tag bump.
21-
if: ${{ !startsWith(github.event.head_commit.message, '[release]:') }}
2218
permissions:
2319
contents: read
2420
packages: write

packages/sandbox/daemon/setup/clone.ts

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,48 @@ function runStep(cmd: string, deps: CloneDeps): Promise<number> {
2929
return spawnSetupStep(cmd, deps.onChunk, deps.dropPrivileges);
3030
}
3131

32+
const TRANSIENT_ERRORS = [
33+
"Could not resolve host",
34+
"early EOF",
35+
"unexpected disconnect",
36+
"Connection reset by peer",
37+
"Connection timed out",
38+
];
39+
const CLONE_MAX_RETRIES = 3;
40+
const CLONE_RETRY_DELAY_MS = 3000;
41+
42+
function isTransient(output: string): boolean {
43+
return TRANSIENT_ERRORS.some((e) => output.includes(e));
44+
}
45+
46+
function sleep(ms: number): Promise<void> {
47+
return new Promise((resolve) => setTimeout(resolve, ms));
48+
}
49+
50+
async function runNetworkStep(cmd: string, deps: CloneDeps): Promise<number> {
51+
for (let attempt = 0; attempt <= CLONE_MAX_RETRIES; attempt++) {
52+
if (attempt > 0) {
53+
deps.onChunk(
54+
"setup",
55+
`\r\n[clone] transient network error, retrying in ${CLONE_RETRY_DELAY_MS / 1000}s (attempt ${attempt + 1}/${CLONE_MAX_RETRIES + 1})...\r\n`,
56+
);
57+
await sleep(CLONE_RETRY_DELAY_MS);
58+
}
59+
let output = "";
60+
const tee: CloneDeps = {
61+
...deps,
62+
onChunk: (src, data) => {
63+
output += data;
64+
deps.onChunk(src, data);
65+
},
66+
};
67+
const code = await runStep(cmd, tee);
68+
if (code === 0) return 0;
69+
if (!isTransient(output) || attempt >= CLONE_MAX_RETRIES) return code;
70+
}
71+
return 1;
72+
}
73+
3274
/** Resolves to exit code (0 on success). Emits chunks via `onChunk`. */
3375
export async function spawnClone(deps: CloneDeps): Promise<number> {
3476
const { config } = deps;
@@ -52,18 +94,21 @@ export async function spawnClone(deps: CloneDeps): Promise<number> {
5294
// and is not an empty directory". Use init+fetch+checkout instead — it
5395
// operates in-place and tolerates existing content.
5496
if (isNonEmptyWithoutGit(dir)) {
55-
const steps = [
97+
const localSteps = [
5698
`${gc} -C ${dir} init`,
5799
`${gc} -C ${dir} remote add origin ${cloneUrl}`,
58-
`${gc} -C ${dir} fetch --depth 1 origin HEAD`,
59-
`${gc} -C ${dir} checkout FETCH_HEAD`,
60100
];
61-
for (const step of steps) {
101+
for (const step of localSteps) {
62102
const code = await runStep(step, deps);
63103
if (code !== 0) return code;
64104
}
65-
return 0;
105+
const fetchCode = await runNetworkStep(
106+
`${gc} -C ${dir} fetch --depth 1 origin HEAD`,
107+
deps,
108+
);
109+
if (fetchCode !== 0) return fetchCode;
110+
return runStep(`${gc} -C ${dir} checkout FETCH_HEAD`, deps);
66111
}
67112

68-
return runStep(`${gc} clone --depth 1 ${cloneUrl} ${dir}`, deps);
113+
return runNetworkStep(`${gc} clone --depth 1 ${cloneUrl} ${dir}`, deps);
69114
}

0 commit comments

Comments
 (0)