Repository navigation
test(backfill-images): kill slug-filter CI forks-pool flake - #2812
Merged
Merged
Conversation
Bump deploy version 1.38.0 -> 1.39.0 (.deploy/mta.yaml) for the DEV->main promotion and refresh the user-facing What's New digest (hugo/data/whats_new.json) with 24 summarized PRs merged since 1.38.0. Headline: URL Health subsystem for tutorials/missions/groups (#2787) — nightly + on-demand broken/slow link detection and membership-integrity reporting in a new Admin UI screen. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Release 1.39.0 (DEV → main)
…pendent
The new URL Health admin tile (app/admin/health) failed to render with a
runtime ModuleError: "failed to load sap/ui/model/odata/v4/library.js ...
script load error". Three defects compounded:
1. manifest + (intended) ui5.yaml listed `sap.ui.model.odata.v4` under
dependency libs. That is NOT a SAPUI5 framework library — the OData V4
model ships inside `sap.ui.core`. `ui5 build` can't resolve it
("Could not find library"), so copy-components.js silently fell back from
the preload build to a raw copy that ships NO Component-preload.js.
UI5 then lazy-loaded each declared lib from the CDN at runtime, and the
bogus odata/v4 path 404'd → the ModuleError.
2. app/admin/health had no ui5.yaml AND no package.json. `ui5 build` needs
both; without them it walked up to app/admin (tutorials-admin-fiori,
ui5:null) and failed project resolution — another path to the same raw-copy
fallback.
Fix: add app/admin/health/{ui5.yaml,package.json} matching the sibling apps,
and drop the non-existent sap.ui.model.odata.v4 lib from both the manifest and
ui5.yaml (sap.m + sap.ui.core only). Result: 52/52 admin components now
preload-build (was 51/52, health raw-copied); health ships a real
Component-preload.js and no longer hits the CDN.
Guard so this class can't ship silently again: discoverComponents() now throws
at build time when a non-excluded admin component lacks its ui5.yaml, with a
message pointing at the raw-copy/CDN failure mode and the PRELOAD_EXCLUDE
opt-out. preload-components.cjs threads PRELOAD_EXCLUDE through so excluded
tiles stay exempt. Unit tests cover the real tree, a throwing fixture, and the
exempt path.
Bump deploy version 1.39.0 -> 1.39.1 (.deploy/mta.yaml) for the DEV->main promotion and refresh the What's New digest (hugo/data/whats_new.json). Patch release: carries #2796 — make the URL Health admin tile preload-buildable (bundled into the admin UI, not CDN-dependent), a follow-up to the URL Health subsystem shipped in 1.39.0 (not yet deployed to PROD; this is the version that will deploy). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Release 1.39.1 (DEV → main)
…s-pool flake The 'restricts enumeration to the target slug' test intermittently failed in CI (expected [] to deeply equal ['beta']) even with retry:1, while passing every time locally and in isolation. Root cause: a per-file beforeAll fixture plus the workspace-first async-import shim in srv/lib/image-warm-utils.js left the fixture and the lazily-resolved extractImgCdnUrls binding exposed to cross-attempt/worker timing under the Vitest-4 forks pool. The code path is correct (both the workspace module and the deploy bundle extract identically). - Move fixtures to beforeEach/afterEach so every attempt (incl. retry) is fully self-contained; drop the shared closure state that was the flake surface. - Add a beforeEach sanity guard: assert the fixture contains /img-cdn?u= and that collectImageUrls resolved to a function, so any future silent empty-map (broken shim resolution) fails loudly and diagnosably instead of flaking. No production code touched; the 116-file import-shim convention is unchanged.
This was referenced Oct 16, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
The lone CI unit-test failure (
backfill-images-slug-filter.test.ts > restricts enumeration to the target slug,expected [] to deeply equal ['beta']) was a pre-existing non-hermetic flake, not a regression from #2808/#2809 — both the test andscripts/backfill-images.tsare 5 weeks old (last touched in #2288) and untouched by the recent merges.Root cause
retry:1already fired.collectImageUrlsreachesextractImgCdnUrlsvia the workspace-first async-import shim insrv/lib/image-warm-utils.js(try await import('@tutorials/content/...') catch await import(bundle)). A per-filebeforeAllfixture + that lazily-resolved binding left shared state exposed to cross-attempt/worker timing.content.bundle.mjs, built byscripts/bundle-shared.cjsin CI) return identical output on the test input.Fix (test-only)
beforeEach/afterEachso every attempt — including the retry — is fully self-contained; removes the shared-closure flake surface.beforeEachsanity guard asserting the fixture contains/img-cdn?u=andcollectImageUrlsresolved to a function. Any future silent empty-map now fails loudly and diagnosably instead of flaking — directly addressing the 'why do we tolerate flaky red?' concern.Verification
CI=1forks pool.expected '…/BROKEN…' to contain '/img-cdn?u='), confirming the guard is not a no-op.🤖 Generated with Claude Code