This is an automated email from the ASF dual-hosted git repository. github-merge-queue[bot] pushed a commit to branch gh-readonly-queue/main/pr-7623-2173ec57fcc237b9716caf80d4990ba3df479d99 in repository https://gitbox.apache.org/repos/asf/texera.git
commit 90d0404f1bbcef98edd7c62d13f35b5287663c64 Author: Xinyuan Lin <[email protected]> AuthorDate: Sat Aug 29 06:03:26 2026 +0000 fix(ci, test, frontend): stop the frontend matrix manufacturing false reds (#7623) ### What changes were proposed in this PR? **Rescoped after #7717 landed.** That PR merged the jsdom half of this one — `testTimeout: 20000` / `hookTimeout: 30000` in `frontend/vitest.config.ts` — which is what put this branch in conflict. This branch had 30s/30s, so the merge would have reverted a value another author had just landed. Resolved by taking main's verbatim: **`vitest.config.ts` now has no diff against main at all.** What remains is the part of #6073 that #7717 does not cover, plus a timeout the job was still missing: | Change | File | Rationale | | --- | --- | --- | | `fail-fast: false` | `.github/workflows/build.yml` | one flaky OS leg cancels the other two, destroying the evidence that says flake vs. real break | | `timeout-minutes: 45` | `.github/workflows/build.yml` | the job had no cap, so a true hang ran to GitHub's implicit 6h, holding one of the 50 concurrent macOS jobs the whole `apache` org shares | | `testTimeout` 15s → 30s | `frontend/vitest.browser.config.ts` | 15s is now the tightest per-test ceiling in the job, on its slower runtime | | Timeouts row, scoped per config | `frontend/TESTING.md` | documents #7717's values and this one's, separately | #### `fail-fast: false` — the flake destroys its own evidence The `build / frontend` macOS leg goes red on a different unit test every few days: always a timeout, never an assertion, always green on rerun. It is a runner stall landing on whichever test happens to be executing — same commit, same matrix, run [31665399757](https://github.com/apache/texera/actions/runs/31665399757/job/94338769943): | Measure | ubuntu-latest | macos-latest | | --- | --- | --- | | the spec file that failed (10 tests) | 240 ms | **11 727 ms** | | suite wall clock | 89.85 s | 252.88 s | | runner size | 4 cores / 16 GB | 3 cores / 7 GB | Today the default fail-fast then cancels ubuntu and windows, so the run no longer says whether the failure reproduces off macOS — exactly the fact needed to classify it. ``` Before: macOS stalls -> that test fails -> ubuntu + windows cancelled After: macOS stalls -> that leg fails alone; a real break still fails all three ``` The opt-out set becomes `frontend`, `platform`, `platform-integration`, `agent-service`, `infra`. `amber-integration` (2 OS legs) and `pyamber` (3 Python versions) are multi-leg without it; left alone to keep this PR to the frontend job. #### `timeout-minutes: 45` — based on green legs, not typical ones This is a correction to what this PR carried through the last review round. The earlier `timeout-minutes: 30` was based on run `31869822969` alone (legs at 8.6 / 10.0 / 10.7 min) and the comment called 30 "~3x the slowest". Pulling every frontend leg from the last eight `Required Checks` runs says otherwise: | Leg | green legs observed | worst green | | --- | --- | --- | | ubuntu-latest | 8.4 – 9.6 min | 9.6 min | | windows-latest | 7.1 – 11.4 min | 11.4 min | | macos-latest | 10.0 – 21.1 min | **21.1 min** | The 21.1-minute leg is run [32219352076](https://github.com/apache/texera/actions/runs/32219352076) — this branch's own merge push, **passing**. #7713 corroborates the range independently at 16m52s. So 30 was 1.4x the worst observed *green* leg, not 3x, and could have ended a run that was merely slow — the same false red `fail-fast: false` is here to stop manufacturing. 45 is ~2x that leg and still cuts a true hang from 6h. The per-step breakdown also relocates the variance: on macOS it is the Angular production build, not the tests. | Run | macOS leg | `Prod build` | `Run frontend unit tests` | | --- | --- | --- | --- | | `32219432444` | 12.4 min | 4.5 min | 4.4 min | | `32117825499` | (failed) | 7.8 min | — | | `32219352076` | 21.1 min | **11.1 min** | 5.3 min | #### Browser mode — 15s is now the tightest ceiling in the job `gui:test-browser` runs on all three OSes, on the same runners. Vitest keys its defaults off `browser.enabled` — read out of the pinned `[email protected]`, `dist/chunks/coverage.DM_a_rWm.js:538-539`: ```js resolved.testTimeout ??= resolved.browser.enabled ? 15e3 : 5e3; resolved.hookTimeout ??= resolved.browser.enabled ? 3e4 : 1e4; ``` So after #7717 the per-test ceilings are jsdom 20s vs. browser 15s — the tighter limit sitting on the *slower* runtime, since driving real Chromium through playwright costs more than jsdom. Raised to 30s. `hookTimeout` stays absent: `browser.enabled` already resolves it to the 30s `vitest.config.ts` sets explicitly. **Left out:** capping `maxWorkers` on the macOS leg to cut memory pressure — it trades wall clock for stability and can't be measured from a non-macOS box. ### Any related issues, documentation, discussions? Closes #6073 `#6073` lists two follow-ups: raise the Vitest timeout, and set `fail-fast: false` on the frontend matrix. #7717 delivered the first for jsdom; this PR delivers it for browser mode and delivers the second. ### How was this PR tested? No production code is touched — the changes are CI config, a test-runner config, and a doc row. | Check | Result | | --- | --- | | conflict resolution | `git diff origin/main -- frontend/vitest.config.ts` is empty, so #7717's merged values stand unmodified | | `build.yml` parses | `yaml.safe_load` → `jobs.frontend['timeout-minutes'] === 45`, `strategy['fail-fast'] === false`; the same pass over every job confirms the opt-out set is exactly the five named above | | runner cost | `macos-latest` is a standard runner and this repo is public, so [GitHub's runner policy](https://docs.github.com/en/actions/reference/runners/github-hosted-runners) puts the usage at free and unlimited — the 10x multiplier is a billed-minutes rate for private repos. `orgs/apache` reports the `enterprise` plan, whose [limit](https://docs.github.com/en/actions/reference/limits) is 500 concurrent jobs but only 50 concurrent macOS, org-wide — that is the bound the comment names instead | | leg durations | measured from the Actions jobs API across the last eight `Required Checks` runs and per-step for the three macOS legs — not read off the run summary | | browser-mode defaults | read out of the pinned `[email protected]` in `node_modules`, not from the docs | | formatting | `prettier --check frontend/vitest.browser.config.ts` clean. `TESTING.md` is outside `format:ci`'s `src/**` glob and already fails `prettier --check` on main, so it is left as-is | The flake itself can't be reproduced on demand — that is what a runner stall is. What this PR asserts is verifiable: the browser leg's per-test ceiling doubles (15s → 30s), a failing leg no longer cancels its siblings, and a genuine hang ends at 45 minutes instead of 6 hours without threatening a green 21-minute macOS leg. ### Was this PR authored or co-authored using generative AI tooling? Generated-by: Claude Code (Opus 5) --- .github/workflows/build.yml | 18 ++++++++++++++++++ frontend/TESTING.md | 1 + frontend/vitest.browser.config.ts | 10 ++++++++++ 3 files changed, 29 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6a2a6cff2c..35e921a3d2 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -86,7 +86,25 @@ jobs: frontend: if: ${{ inputs.run_frontend }} runs-on: ${{ matrix.os }} + # Only the "Install dependency" step below is bounded, so a spec that + # truly hangs would otherwise run to GitHub's implicit 6h cap, holding one + # of the 50 concurrent macOS jobs the whole `apache` org shares for that + # window. The timeout is based on observed *green* legs rather than a + # typical one, because the macOS leg swings hard: 21.1 minutes at its + # slowest while still passing, and the variance sits in "Prod build" + # (4.5-11.1 min there) more than in the tests (4.4-5.3 min). 45 is ~2x + # that worst green leg, so it bounds a runaway without turning a merely + # slow macOS runner into a false red — which is the same failure this + # job's `fail-fast: false` is here to stop manufacturing. + timeout-minutes: 45 strategy: + # An OS-specific failure should not cancel the other two legs: with the + # default fail-fast the surviving jobs report "The operation was + # canceled" and the run no longer says whether the failure reproduces + # off that OS — exactly the evidence needed to tell a runner flake from + # a real break. `platform`, `platform-integration`, `agent-service` and + # `infra` opt out for the same reason. + fail-fast: false matrix: os: [ubuntu-latest, windows-latest, macos-latest] include: diff --git a/frontend/TESTING.md b/frontend/TESTING.md index 7372fc4b29..7adea47e4b 100644 --- a/frontend/TESTING.md +++ b/frontend/TESTING.md @@ -47,6 +47,7 @@ For repo-wide testing philosophy (TDD, characterization tests, "every test must | Coverage | `@vitest/coverage-v8` | | Test setup | `src/test-zone-setup.ts` wraps `it`/`test` in an Angular ProxyZone (Vitest does not provide one and Angular's `fakeAsync` requires it) | | Globals | `globals: true` in `vitest.config.ts`, so `describe / it / expect / vi / beforeEach` come from the runtime — no per-file imports | +| Timeouts | Raised over Vitest's defaults because macOS CI runners stall for seconds at a time (#6073, #7713). jsdom: 20s per test / 30s per hook (`vitest.config.ts`, defaults 5s/10s). Browser mode: 30s per test (`vitest.browser.config.ts`), hooks left at the 30s default that `browser.enabled` already resolves — its per-test default is 15s | `src/main.test.ts` is intentionally a near-empty `export {}`. The `unit-test` builder uses `buildTarget`'s `main` to seed the bundle graph; if it pointed at the real `main.ts`, every component declared in `AppModule` would be type-checked for every spec, surfacing template errors for components no active spec touches. Keeping `main.test.ts` empty narrows the graph to what each spec actually imports. diff --git a/frontend/vitest.browser.config.ts b/frontend/vitest.browser.config.ts index 3fe2c41039..9500247000 100644 --- a/frontend/vitest.browser.config.ts +++ b/frontend/vitest.browser.config.ts @@ -64,6 +64,16 @@ export default defineConfig({ // browser-mode the runtime has neither, so we install the `buffer` npm // package as a shim). setupFiles: ["src/browser-buffer-polyfill.ts", "src/test-zone-setup.ts"], + // Browser mode resolves larger defaults than jsdom off `browser.enabled` + // (15s per test, 30s per hook), but since #7717 raised the jsdom config to + // 20s per test, 15s is the tightest per-test ceiling left in the frontend + // job — on the slower of the two runtimes, since driving a real Chromium + // through playwright costs more than jsdom. Both legs run on the same + // macOS runners, whose stalls are what the jsdom raise was for, so this + // one gets at least as much headroom. `hookTimeout` is left alone — its + // browser-mode default is already the 30s the jsdom config sets. See + // apache/texera#6073. + testTimeout: 30_000, browser: { enabled: true, provider: playwright(),
