This is an automated email from the ASF dual-hosted git repository.

github-merge-queue[bot] pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/texera.git


The following commit(s) were added to refs/heads/main by this push:
     new 90d0404f1b fix(ci, test, frontend): stop the frontend matrix 
manufacturing false reds (#7623)
90d0404f1b is described below

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(),

Reply via email to