From 97f82dd4645d7ac985e3a25560ab220fec3905bc Mon Sep 17 00:00:00 2001 From: Kamil Krzywda Date: Sat, 19 Sep 2026 07:55:29 +0000 Subject: [PATCH] =?UTF-8?q?ci:=20self-hosted=20map=20assets=20for=20e2e=20?= =?UTF-8?q?=E2=80=94=20download=20+=20cache=20pack,=20mount=20./public?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitea/workflows/ci.yml | 30 ++++++++++++++++++++++++++++++ CHANGELOG.md | 1 + docker-compose.ci.yml | 4 ++++ 3 files changed, 35 insertions(+) diff --git a/.gitea/workflows/ci.yml b/.gitea/workflows/ci.yml index b0bbce6..f05202c 100644 --- a/.gitea/workflows/ci.yml +++ b/.gitea/workflows/ci.yml @@ -86,6 +86,36 @@ jobs: # No explicit save step: caches marked by the restore steps are uploaded automatically at job end. + # Map e2e tests abort ALL *.openfreemap.org traffic (page.route → route.abort()), assuming + # styles/fonts/sprites are SELF-HOSTED from /styles, /fonts, /sprites — locally that pack is + # produced by `npm run assets:download` and reaches the app via the compose volume mount. + # CI must reproduce it or lib/mapStyles.ts probes /map-assets-manifest.json, finds nothing, + # falls back to remote OFM styles — which the tests abort → style never loads (the + # deterministic map.spec.ts wheel-zoom + style-switcher failures). The script needs no env + # vars/args and writes into ./public (git-ignored, docker-excluded; the app container gets + # it via the volume mount in docker-compose.ci.yml). + - name: Restore map assets cache + uses: actions/cache@v4 + continue-on-error: true + with: + path: public/ + key: ${{ runner.os }}-map-assets-${{ hashFiles('scripts/download-map-assets.mjs') }} + + # Retried: the runner's uplink is flaky (same transient EAI_AGAIN pattern as dep install). + # The job-end cache upload seeds public/ for future runs; a partial pack without + # map-assets-manifest.json is harmless — the app probes that manifest and falls back to + # remote styles when it's missing. + - name: Download map assets (retries) + run: | + set -u + ok=0 + for i in 1 2 3 4 5 6; do + if npm run assets:download; then ok=1; break; fi + echo "::warning::map assets download attempt $i/6 failed (likely transient network) — retrying in 5s" >&2 + sleep 5 + done + [ "$ok" = "1" ] || { echo "::error::map assets download failed after 6 attempts" >&2; exit 1; } + - name: Build run: npm run build diff --git a/CHANGELOG.md b/CHANGELOG.md index e4d4782..6e32279 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ - **CI caches Playwright browser binaries across runs** (`$HOME/.cache/ms-playwright` via actions/cache): the flaky runner uplink makes the ~187 MiB Chrome-for-Testing download unreliable (runs #20/#21 died mid-download at "Install browsers"); also removed the no-op "Save deps cache" step — on this runner caches marked by a restore step are uploaded automatically at job end, so an explicit save never did anything - **CI browser install runs in a bounded 6-attempt loop** — cdn.playwright.dev is flaky from the runner and Playwright's internal retry window (~40–90s) was often insufficient (runs #21–#23), while longer windows get through (runs #12/#18); already-installed browsers are skipped so progress accumulates across attempts - Verified: unit suite 234 green locally; e2e not run locally by design (would deploy to production) — first real pass happens in the PR's CI run +- **CI e2e now runs in self-hosted map-assets mode** — the workflow downloads the OpenFreeMap asset pack (`npm run assets:download` → styles/fonts/sprites into git-ignored `./public`, bounded 6-attempt retry like the other flaky-network steps) and caches it via actions/cache keyed on the download script (job-end upload seeds future runs; a partial pack without manifest is harmless — app falls back to remote); `docker-compose.ci.yml` mounts `./public:/app/public` mirroring docker-compose.yml, so map tests that abort all *.openfreemap.org traffic get self-hosted styles/fonts/sprites like local dev (fixes the deterministic map.spec.ts wheel-zoom + style-switcher failures) ## v0.12.2 — 2026-09-18 14:06 - **Bugfix (ISS-003): route leg lines were drawn as straight two-point chords instead of following the curved great-circle path planes actually fly.** Root cause in `lib/mapData.ts`: `routesGeoJson` built each flying plane's leg LineString from only its origin and destination airport coordinates, so on long routes the drawn line cut across the chord (up to ~40 km off the true arc for a ~1400 km leg) while the plane marker moved along the curved path. Fix: new pure `greatCircleArc(from, to)` samples the same slerp used by the sim (`positionAt` in `lib/sim/movement.ts`) at t = i/24 for i = 0..24 — **25 coordinates** (exact endpoints + 23 intermediate points, `ROUTE_ARC_SEGMENTS = 24`) — so the drawn line matches the curved flight path; `routesGeoJson` now uses it instead of the two-point chord diff --git a/docker-compose.ci.yml b/docker-compose.ci.yml index 12615ab..3e89c74 100644 --- a/docker-compose.ci.yml +++ b/docker-compose.ci.yml @@ -15,6 +15,10 @@ services: environment: FLIGHT_TEST_HOOKS: "1" volumes: + # Self-hosted map-asset pack (styles/fonts/sprites): the workflow downloads it into ./public + # before build; absent/empty → app falls back to remote OFM styles. Mirrors docker-compose.yml's + # mount so e2e runs in self-hosted mode like local dev (map tests abort openfreemap.org traffic). + - "./public:/app/public" - flight-db:/app/db networks: flight-ci-e2e: