From 7c65574803212a3b38d7dd9073ef27a38a67fd11 Mon Sep 17 00:00:00 2001 From: Florent Tapponnier Date: Fri, 10 Jul 2026 16:14:18 +0200 Subject: [PATCH] prod-deploy: smoke retries cold sitemap renders (60s x3), rollback gets the mobula-labs scope (403'd without it) --- .github/workflows/prod-deploy.yml | 2 +- scripts/sitemap-smoke.mjs | 21 ++++++++++++++++++++- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/.github/workflows/prod-deploy.yml b/.github/workflows/prod-deploy.yml index 763d3310..ba08b7b0 100644 --- a/.github/workflows/prod-deploy.yml +++ b/.github/workflows/prod-deploy.yml @@ -101,7 +101,7 @@ jobs: if: steps.smoke.outcome == 'failure' run: | echo "::error::Sitemap smoke failed. Rolling back prod alias to the previous deploy." - vercel rollback --token=${{ secrets.VERCEL_TOKEN }} --yes + vercel rollback --token=${{ secrets.VERCEL_TOKEN }} --scope=mobula-labs --yes # Re-fail the job so the rollback is visible in the workflow # status (a red X on the commit + an email). exit 1 diff --git a/scripts/sitemap-smoke.mjs b/scripts/sitemap-smoke.mjs index 4de6753f..983758dd 100644 --- a/scripts/sitemap-smoke.mjs +++ b/scripts/sitemap-smoke.mjs @@ -51,7 +51,26 @@ async function getText(url, timeoutMs = TIMEOUT_MS) { } } -const sitemapRes = await getText(sitemapUrl); +// The first sitemap render after a fresh deploy is cold (full catalog +// load) and can exceed a single request timeout. Retry with backoff so +// a cold cache never fails the smoke and triggers a rollback of a +// perfectly healthy deploy (observed 2026-07-10: AbortError at 20s, +// sitemap healthy 30s later). +async function getTextWithRetry(url, attempts = 3, timeoutMs = 60000) { + let lastErr; + for (let i = 1; i <= attempts; i++) { + try { + return await getText(url, timeoutMs); + } catch (err) { + lastErr = err; + console.warn(`[smoke] attempt ${i}/${attempts} failed: ${err}`); + if (i < attempts) await new Promise((r) => setTimeout(r, 10000 * i)); + } + } + throw lastErr; +} + +const sitemapRes = await getTextWithRetry(sitemapUrl); if (sitemapRes.res.status !== 200) { console.error( `[smoke] sitemap fetch failed: status=${sitemapRes.res.status}`,