@@ -174,27 +174,20 @@ jobs:
174174 echo "No summary file found." >> $GITHUB_STEP_SUMMARY
175175 fi
176176
177- # Full-suite Linux runs are sharded across 4 parallel jobs by suite group.
178- # `e2e-run-all-flows.sh --suite=<csv>` accepts a comma-separated list, so
179- # each shard runs roughly a quarter of the ~80 specs. With Swatinem
180- # rust-cache + the CEF cache restored on every job, the per-shard build
181- # step is fast (~1-3 min). Longest shard dominates wall clock — expect
182- # ~20-25 min vs the ~60-min serial baseline.
183- e2e-linux-full :
177+ # Full-suite Linux is now build-once-then-fanout: one `build-linux-full`
178+ # job produces the binary + frontend dist + CEF runtime as a single
179+ # workflow artifact, and the 4 shard test jobs `needs:` that build and
180+ # download the artifact. This eliminates the parallel-shard cache race
181+ # (only the first shard would otherwise populate the binary/CEF caches,
182+ # the others would lose the race and rebuild) and guarantees the binary
183+ # and its libcef.so are always packaged together.
184+ build-linux-full :
184185 if : inputs.run_linux && inputs.full
185- name : E2E (Linux full / ${{ matrix.shard.name }} )
186+ name : Build (Linux full)
186187 runs-on : ubuntu-22.04
187188 container :
188189 image : ghcr.io/tinyhumansai/openhuman_ci:latest
189- timeout-minutes : 60
190- strategy :
191- fail-fast : false
192- matrix :
193- shard :
194- - { name: foundation, suites: "auth,navigation,system" }
195- - { name: chat, suites: "chat,skills,journeys" }
196- - { name: integrations, suites: "providers,webhooks,notifications" }
197- - { name: commerce, suites: "payments,settings" }
190+ timeout-minutes : 45
198191 steps :
199192 - name : Checkout code
200193 uses : actions/checkout@v5
@@ -218,25 +211,86 @@ jobs:
218211 . -> target
219212 app/src-tauri -> target
220213 cache-on-failure : true
221- # Shared key across shards so the first shard to populate the cache
222- # warms it for the others within the same run.
223214 key : e2e-linux-unified
224215
225216 - name : Cache CEF binary distribution
226- id : cef-cache
227217 uses : actions/cache@v5
228218 with :
229- # e2e-build.sh + ensure-tauri-cli.sh always export
230- # CEF_PATH=$HOME/Library/Caches/tauri-cef regardless of OS, so the
231- # cef-dll-sys download lands there on Linux/Windows too. Cache the
232- # actual download location so the cache hits when the binary-cache
233- # short-circuit skips the build step.
219+ # cef-dll-sys downloads into $CEF_PATH; ensure-tauri-cli.sh +
220+ # e2e-build.sh pin that to $HOME/Library/Caches/tauri-cef on
221+ # every OS, so the cache key/path live there too.
234222 path : |
235223 ~/Library/Caches/tauri-cef
236224 key : cef-x86_64-unknown-linux-gnu-v2-${{ hashFiles('app/src-tauri/Cargo.toml') }}
237225 restore-keys : |
238226 cef-x86_64-unknown-linux-gnu-v2-
239227
228+ - name : Install JS dependencies
229+ run : pnpm install --frozen-lockfile
230+
231+ - name : Ensure .env exists for E2E build
232+ run : |
233+ touch .env
234+ touch app/.env
235+
236+ - name : Build E2E app
237+ run : pnpm --filter openhuman-app test:e2e:build
238+
239+ - name : Package build artifact
240+ run : |
241+ # Stage everything the test shards need at the layout they expect
242+ # under a single directory, so the consumer can extract straight
243+ # into the workspace + $HOME.
244+ STAGE="$(mktemp -d)"
245+ mkdir -p "$STAGE/repo/app/src-tauri/target/debug"
246+ mkdir -p "$STAGE/repo/app/dist"
247+ mkdir -p "$STAGE/home/Library/Caches"
248+ cp -a app/src-tauri/target/debug/OpenHuman "$STAGE/repo/app/src-tauri/target/debug/"
249+ cp -a app/dist/. "$STAGE/repo/app/dist/"
250+ cp -a "$HOME/Library/Caches/tauri-cef" "$STAGE/home/Library/Caches/tauri-cef"
251+ tar --zstd -cf e2e-build-linux.tar.zst -C "$STAGE" repo home
252+ ls -lh e2e-build-linux.tar.zst
253+
254+ - name : Upload build artifact
255+ uses : actions/upload-artifact@v5
256+ with :
257+ name : e2e-build-linux-${{ github.run_id }}
258+ path : e2e-build-linux.tar.zst
259+ retention-days : 1
260+ if-no-files-found : error
261+
262+ e2e-linux-full :
263+ if : inputs.run_linux && inputs.full
264+ needs : build-linux-full
265+ name : E2E (Linux full / ${{ matrix.shard.name }})
266+ runs-on : ubuntu-22.04
267+ container :
268+ image : ghcr.io/tinyhumansai/openhuman_ci:latest
269+ timeout-minutes : 60
270+ strategy :
271+ fail-fast : false
272+ matrix :
273+ shard :
274+ - { name: foundation, suites: "auth,navigation,system" }
275+ - { name: chat, suites: "chat,skills,journeys" }
276+ - { name: integrations, suites: "providers,webhooks,notifications" }
277+ - { name: commerce, suites: "payments,settings" }
278+ steps :
279+ - name : Checkout code
280+ uses : actions/checkout@v5
281+ with :
282+ ref : ${{ inputs.ref }}
283+ fetch-depth : 1
284+ submodules : recursive
285+
286+ - name : Cache pnpm store
287+ uses : actions/cache@v5
288+ with :
289+ path : ~/.local/share/pnpm/store
290+ key : pnpm-store-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
291+ restore-keys : |
292+ pnpm-store-${{ runner.os }}-
293+
240294 - name : Cache Appium global install
241295 uses : actions/cache@v5
242296 with :
@@ -245,51 +299,40 @@ jobs:
245299 /usr/local/lib/node_modules/appium
246300 key : appium3-chromium-${{ runner.os }}-v1
247301
248- - name : Install JS dependencies
302+ - name : Install JS dependencies (for test harness only)
249303 run : pnpm install --frozen-lockfile
250304
251- - name : Ensure .env exists for E2E build
252- run : |
253- touch .env
254- touch app/.env
255-
256305 - name : Install Appium and chromium driver
257306 run : |
258307 if ! command -v appium >/dev/null 2>&1; then
259308 npm install -g appium@3
260309 fi
261310 appium driver install --source=npm appium-chromium-driver >/dev/null 2>&1 || true
262311
263- # Cache the built debug binary + bundled frontend dist across runs.
264- # Most iteration on this branch is CI/spec/orchestrator changes that do
265- # NOT touch the Rust core or the React app — so the key below is stable
266- # across those iterations and the next run hits the cache, skipping the
267- # 10-15 min `cargo tauri build` step.
268- - name : Cache built E2E binary (Linux)
269- id : e2e-binary-cache
270- uses : actions/cache@v5
312+ - name : Download build artifact
313+ uses : actions/download-artifact@v5
271314 with :
272- path : |
273- app/src-tauri/target/debug/OpenHuman
274- app/dist
275- key : e2e-binary-${{ runner.os }}-${{ hashFiles('src/**/*.rs', 'app/src-tauri/src/**', 'app/src-tauri/build.rs', 'app/src-tauri/tauri.conf.json', 'Cargo.lock', 'app/src-tauri/Cargo.lock', 'app/src-tauri/vendor/tauri-cef/Cargo.lock', 'rust-toolchain.toml', 'app/src/**', 'app/index.html', 'app/vite.config.*', 'app/tailwind.config.*', 'app/postcss.config.*', 'app/package.json', 'pnpm-lock.yaml', 'app/scripts/e2e-build.sh') }}
315+ name : e2e-build-linux-${{ github.run_id }}
316+ path : .
276317
277- # Skip the (slow) build only when BOTH the binary AND the CEF runtime
278- # caches hit — having the binary without libcef makes the runner fail
279- # with 'libcef.so: cannot open shared object file' at launch.
280- - name : Build E2E app
281- if : steps.e2e-binary-cache.outputs.cache-hit != 'true' || steps.cef-cache.outputs.cache-hit != 'true'
282- run : pnpm --filter openhuman-app test:e2e:build
318+ - name : Restore build artifact into workspace + $HOME
319+ run : |
320+ tar --zstd -xf e2e-build-linux.tar.zst
321+ # The artifact contains: repo/{app/src-tauri/target/debug/OpenHuman, app/dist/...}
322+ # and home/Library/Caches/tauri-cef/...
323+ mkdir -p app/src-tauri/target/debug app/dist "$HOME/Library/Caches"
324+ cp -a repo/app/src-tauri/target/debug/OpenHuman app/src-tauri/target/debug/
325+ cp -a repo/app/dist/. app/dist/
326+ cp -a home/Library/Caches/tauri-cef "$HOME/Library/Caches/"
327+ rm -rf repo home e2e-build-linux.tar.zst
328+ chmod +x app/src-tauri/target/debug/OpenHuman
329+ ls -la app/src-tauri/target/debug/OpenHuman app/dist | head
330+ ls -la "$HOME/Library/Caches/tauri-cef" | head
283331
284332 - name : Run E2E shard (${{ matrix.shard.name }} — suites=${{ matrix.shard.suites }})
285333 env :
286334 E2E_BAIL_ON_FAILURE : ${{ vars.E2E_BAIL_ON_FAILURE || '' }}
287335 run : |
288- # Pin CEF_PATH to the actual download location used by
289- # ensure-tauri-cli.sh + e2e-build.sh. The default in
290- # e2e-run-session.sh already points here on macOS but Linux
291- # needs the explicit export when the binary-cache short-circuit
292- # skips the build step (which would otherwise have exported it).
293336 export CEF_PATH="$HOME/Library/Caches/tauri-cef"
294337 BAIL_FLAG=""
295338 if [[ "${E2E_BAIL_ON_FAILURE:-}" == "1" ]]; then
0 commit comments