From 39e5cfa99c29288d391be0ea8a747545468e5dda Mon Sep 17 00:00:00 2001 From: Claude Code Date: Mon, 18 May 2026 23:54:22 -0500 Subject: [PATCH] ci(docs): soft-fail badge localization on transient fetch errors MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The Docs Testing workflow has been the top CI flake source on master (61 failures in the last 2 weeks), and almost every one fails with the same signature: Cause: [remark-localize-badges] Failed to download badge: https://img.shields.io/badge/slack-join-orange.svg Error: fetch failed Build cannot continue with broken badges. `remark-localize-badges` already retries 3× with backoff and a 30s timeout. When shields.io rate-limits the CI runner anyway (very common from GitHub Actions IP ranges), the plugin currently throws and the entire docs build dies — even though the badge URL is fine and the docs would render correctly via the remote URL. Change the terminal failure path to log a warning and fall back to the original remote URL. The rendered docs still show the badge (just unlocalized for this build); the docs build keeps going. Add a `REMARK_BADGES_STRICT=true` env var as an opt-in for the old fail-the-build behavior, in case a release pipeline wants to catch genuinely broken badge URLs. --- docs/plugins/remark-localize-badges.mjs | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/docs/plugins/remark-localize-badges.mjs b/docs/plugins/remark-localize-badges.mjs index 757b400b350..ac3dc03a582 100644 --- a/docs/plugins/remark-localize-badges.mjs +++ b/docs/plugins/remark-localize-badges.mjs @@ -206,12 +206,26 @@ async function downloadBadge(url, staticDir) { badgeCache.set(url, webPath); return webPath; } catch (error) { - // Fail the build on badge download failure - throw new Error( - `[remark-localize-badges] Failed to download badge: ${url}\n` + - `Error: ${error.message}\n` + - `Build cannot continue with broken badges. Please fix the badge URL or remove it.`, + // Soft fallback: keep the original remote URL in the rendered output + // so the badge still appears for readers, and the docs build continues. + // External badge services (notably img.shields.io) rate-limit CI IPs + // aggressively, and a transient fetch failure shouldn't take the whole + // docs build down with it. Set REMARK_BADGES_STRICT=true to opt back + // into hard-fail-the-build behavior (e.g. for release builds where you + // want to catch genuinely broken badge URLs). + if (process.env.REMARK_BADGES_STRICT === 'true') { + throw new Error( + `[remark-localize-badges] Failed to download badge: ${url}\n` + + `Error: ${error.message}\n` + + `Build cannot continue with broken badges (REMARK_BADGES_STRICT=true).`, + ); + } + console.warn( + `[remark-localize-badges] Could not localize ${url} ` + + `(${error.message}); falling back to remote URL.`, ); + badgeCache.set(url, url); + return url; } finally { // Clean up the in-flight tracker inFlightDownloads.delete(url);