mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-28 13:32:23 +00:00
411 lines
14 KiB
YAML
411 lines
14 KiB
YAML
---
|
|
# Reusable E2E workflow — single source of truth for the desktop E2E recipe.
|
|
#
|
|
# Callers:
|
|
# - `.github/workflows/e2e.yml` — PR/push, Linux-only smoke (blocking).
|
|
# - `.github/workflows/release-staging.yml` — pretest gate, all 3 OS, full suite.
|
|
# - `.github/workflows/release-production.yml` — pretest gate, all 3 OS, full suite.
|
|
#
|
|
# Recipe per OS (identical across platforms — see e2e-run-session.sh):
|
|
# 1. Build the CEF app via `pnpm --filter openhuman-app test:e2e:build`.
|
|
# 2. Install Appium 3.x + the `chromium` driver.
|
|
# 3. Run `app/scripts/e2e-run-session.sh` which:
|
|
# - launches the built binary,
|
|
# - waits for CDP on :19222,
|
|
# - prunes the prewarm `about:blank` target,
|
|
# - downloads a chromedriver matching CEF's Chromium version,
|
|
# - starts Appium and runs WDIO against `wdio.conf.ts`.
|
|
#
|
|
# Linux runs inside the project CI container under Xvfb (no native display).
|
|
# macOS / Windows run on GitHub-hosted runners.
|
|
#
|
|
# Caching: pnpm store, Swatinem rust-cache, and CEF runtime download
|
|
# (~400MB) are cached on every job. The CEF cache key matches what
|
|
# build-desktop.yml uses so cross-workflow hits are possible.
|
|
name: E2E (reusable)
|
|
|
|
on:
|
|
workflow_call:
|
|
inputs:
|
|
ref:
|
|
description:
|
|
Git ref (tag or SHA) to test. Release workflows pass the
|
|
freshly-pushed staging/production tag here so pretest validates
|
|
the exact commit the build matrix will check out, not main HEAD
|
|
at workflow_dispatch time. Defaults to empty (checkout uses its
|
|
own default, i.e. the workflow's triggering ref).
|
|
type: string
|
|
default: ""
|
|
run_linux:
|
|
description: Run the Linux (Xvfb / container) E2E job.
|
|
type: boolean
|
|
default: true
|
|
run_macos:
|
|
description: Run the macOS E2E job.
|
|
type: boolean
|
|
default: false
|
|
run_windows:
|
|
description: Run the Windows E2E job.
|
|
type: boolean
|
|
default: false
|
|
full:
|
|
description:
|
|
When true, run the entire spec suite via `e2e-run-session.sh` (no
|
|
spec arg). When false, run the smoke spec + mega-flow (mega-flow
|
|
non-blocking). Releases set this to true; PR runs leave it false.
|
|
type: boolean
|
|
default: false
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
jobs:
|
|
e2e-linux:
|
|
if: inputs.run_linux
|
|
name: E2E (Linux / Appium Chromium)
|
|
runs-on: ubuntu-22.04
|
|
container:
|
|
image: ghcr.io/tinyhumansai/openhuman_ci:latest
|
|
timeout-minutes: 90
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v5
|
|
with:
|
|
ref: ${{ inputs.ref }}
|
|
fetch-depth: 1
|
|
submodules: recursive
|
|
|
|
- name: Cache pnpm store
|
|
uses: actions/cache@v5
|
|
with:
|
|
path: ~/.local/share/pnpm/store
|
|
key: pnpm-store-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
|
|
restore-keys: |
|
|
pnpm-store-${{ runner.os }}-
|
|
|
|
- name: Cache Rust build artifacts
|
|
uses: Swatinem/rust-cache@v2
|
|
with:
|
|
workspaces: |
|
|
. -> target
|
|
app/src-tauri -> target
|
|
cache-on-failure: true
|
|
key: e2e-linux-unified
|
|
|
|
# CEF runtime download cache — matches the key shape used by
|
|
# build-desktop.yml so a release build and an E2E run on the same
|
|
# commit can share a single download.
|
|
- name: Cache CEF binary distribution
|
|
uses: actions/cache@v5
|
|
with:
|
|
path: |
|
|
~/.cache/tauri-cef
|
|
key: cef-x86_64-unknown-linux-gnu-${{ hashFiles('app/src-tauri/Cargo.toml') }}
|
|
restore-keys: |
|
|
cef-x86_64-unknown-linux-gnu-
|
|
|
|
- name: Cache Appium global install
|
|
uses: actions/cache@v5
|
|
with:
|
|
path: |
|
|
~/.appium
|
|
/usr/local/lib/node_modules/appium
|
|
key: appium3-chromium-${{ runner.os }}-v1
|
|
|
|
- name: Install JS dependencies
|
|
run: pnpm install --frozen-lockfile
|
|
|
|
- name: Ensure .env exists for E2E build
|
|
run: |
|
|
touch .env
|
|
touch app/.env
|
|
|
|
- name: Install Appium and chromium driver
|
|
run: |
|
|
if ! command -v appium >/dev/null 2>&1; then
|
|
npm install -g appium@3
|
|
fi
|
|
# `appium driver list --installed` can miss cached installs on some
|
|
# Appium builds; install idempotently and ignore "already installed".
|
|
appium driver install --source=npm appium-chromium-driver >/dev/null 2>&1 || true
|
|
|
|
- name: Build E2E app
|
|
run: pnpm --filter openhuman-app test:e2e:build
|
|
|
|
- name: Run E2E (smoke)
|
|
if: ${{ !inputs.full }}
|
|
run: |
|
|
xvfb-run -a --server-args="-screen 0 1280x960x24" \
|
|
bash app/scripts/e2e-run-session.sh test/e2e/specs/smoke.spec.ts smoke
|
|
|
|
# Mega-flow exercises the OAuth-success-deep-link and Composio
|
|
# trigger-lifecycle paths. Both currently hit a pre-existing race
|
|
# in the deep-link → custom-event propagation on the Linux CI
|
|
# image (smoke.spec.ts has a related skipped `it()` with the
|
|
# same root cause). Keep mega-flow visible in CI as a signal but
|
|
# non-blocking, mirroring the pre-refactor behavior — once the
|
|
# auth/oauth deep-link race lands a fix, drop the
|
|
# `continue-on-error` and consolidate the two steps.
|
|
- name: Run E2E (mega-flow, non-blocking)
|
|
if: ${{ !inputs.full }}
|
|
continue-on-error: true
|
|
run: |
|
|
xvfb-run -a --server-args="-screen 0 1280x960x24" \
|
|
bash app/scripts/e2e-run-session.sh test/e2e/specs/mega-flow.spec.ts mega-flow
|
|
|
|
- name: Run E2E (full suite)
|
|
if: ${{ inputs.full }}
|
|
run: |
|
|
xvfb-run -a --server-args="-screen 0 1280x960x24" \
|
|
bash app/scripts/e2e-run-session.sh
|
|
|
|
# Artifact uploads intentionally omitted — this reusable workflow
|
|
# is invoked from release-staging.yml and release-production.yml,
|
|
# and uploaded logs can carry mock-backend payloads, env-var
|
|
# echoes, and CDP transcripts that we don't want pinned to a
|
|
# release artifact. Local repro: rerun the spec via Docker and
|
|
# the same logs land in /tmp.
|
|
|
|
# Rust-side E2E counterpart to the Tauri runs above. Same Linux-only
|
|
# scope (CI does not run this on macOS or Windows — the Rust core is
|
|
# platform-independent, so one OS is enough signal). Boots the same
|
|
# `scripts/mock-api-server.mjs` the Tauri specs hit, then runs every
|
|
# `tests/*_e2e.rs` suite against it.
|
|
rust-e2e-linux:
|
|
if: inputs.run_linux
|
|
name: E2E (Linux / Rust integration suite)
|
|
runs-on: ubuntu-22.04
|
|
container:
|
|
image: ghcr.io/tinyhumansai/openhuman_ci:latest
|
|
timeout-minutes: 60
|
|
env:
|
|
CARGO_INCREMENTAL: '0'
|
|
RUST_BACKTRACE: '1'
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v5
|
|
with:
|
|
ref: ${{ inputs.ref }}
|
|
fetch-depth: 1
|
|
submodules: recursive
|
|
|
|
- name: Cache pnpm store
|
|
uses: actions/cache@v5
|
|
with:
|
|
path: ~/.local/share/pnpm/store
|
|
key: pnpm-store-${{ runner.os }}-${{ hashFiles('pnpm-lock.yaml') }}
|
|
restore-keys: |
|
|
pnpm-store-${{ runner.os }}-
|
|
|
|
- name: Cache Rust build artifacts
|
|
uses: Swatinem/rust-cache@v2
|
|
with:
|
|
workspaces: . -> target
|
|
cache-on-failure: true
|
|
key: rust-e2e-linux
|
|
|
|
- name: Install JS dependencies
|
|
run: pnpm install --frozen-lockfile
|
|
|
|
- name: Ensure .env exists for tests
|
|
run: |
|
|
touch .env
|
|
touch app/.env
|
|
|
|
- name: Run Rust E2E suite (tests/*_e2e.rs vs mock backend)
|
|
run: pnpm test:rust:e2e
|
|
|
|
# No artifact uploads here either — same release-workflow reuse
|
|
# concern as the Tauri job above. Mock-backend log lives at
|
|
# /tmp/openhuman-rust-e2e-mock.log for local docker repro.
|
|
|
|
e2e-macos:
|
|
if: inputs.run_macos
|
|
name: E2E (macOS / Appium Chromium)
|
|
runs-on: macos-latest
|
|
timeout-minutes: 90
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v5
|
|
with:
|
|
ref: ${{ inputs.ref }}
|
|
fetch-depth: 1
|
|
submodules: recursive
|
|
|
|
- name: Install pnpm
|
|
uses: pnpm/action-setup@v4
|
|
|
|
- name: Setup Node.js 24.x
|
|
uses: actions/setup-node@v5
|
|
with:
|
|
node-version: 24.x
|
|
cache: pnpm
|
|
|
|
- name: Install Rust (rust-toolchain.toml)
|
|
uses: dtolnay/rust-toolchain@1.93.0
|
|
with:
|
|
# macos-latest is arm64, but the vendored tauri-cli's build.rs
|
|
# compiles a CEF helper for x86_64-apple-darwin (universal binary),
|
|
# so the x86_64 libstd must be installed too.
|
|
targets: x86_64-apple-darwin
|
|
|
|
- name: Verify cargo resolves to real toolchain
|
|
run: |
|
|
rustup default 1.93.0 || true
|
|
which cargo
|
|
cargo --version
|
|
|
|
- name: Cache Rust build artifacts
|
|
uses: Swatinem/rust-cache@v2
|
|
with:
|
|
workspaces: |
|
|
. -> target
|
|
app/src-tauri -> target
|
|
cache-on-failure: true
|
|
key: e2e-macos-unified-v2
|
|
|
|
- name: Cache CEF binary distribution
|
|
uses: actions/cache@v5
|
|
with:
|
|
path: |
|
|
~/Library/Caches/tauri-cef
|
|
key: cef-aarch64-apple-darwin-${{ hashFiles('app/src-tauri/Cargo.toml') }}
|
|
restore-keys: |
|
|
cef-aarch64-apple-darwin-
|
|
|
|
- name: Cache Appium global install
|
|
uses: actions/cache@v5
|
|
with:
|
|
path: |
|
|
~/.appium
|
|
key: appium3-chromium-${{ runner.os }}-v1
|
|
|
|
- name: Install JS dependencies
|
|
run: pnpm install --frozen-lockfile
|
|
|
|
- name: Ensure .env exists for E2E build
|
|
run: |
|
|
touch .env
|
|
touch app/.env
|
|
|
|
- name: Install Appium and chromium driver
|
|
run: |
|
|
if ! command -v appium >/dev/null 2>&1; then
|
|
npm install -g appium@3
|
|
fi
|
|
# `appium driver list --installed` can miss cached installs on some
|
|
# Appium builds; install idempotently and ignore "already installed".
|
|
appium driver install --source=npm appium-chromium-driver >/dev/null 2>&1 || true
|
|
|
|
- name: Build E2E app
|
|
run: pnpm --filter openhuman-app test:e2e:build
|
|
|
|
# macOS rejects dynamic-framework loads from unsigned bundles — adhoc
|
|
# signing satisfies the loader without a real developer-ID cert.
|
|
- name: Adhoc-sign the .app bundle
|
|
run: |
|
|
codesign --force --deep --sign - \
|
|
app/src-tauri/target/debug/bundle/macos/OpenHuman.app
|
|
codesign --verify --deep --verbose=2 \
|
|
app/src-tauri/target/debug/bundle/macos/OpenHuman.app
|
|
|
|
- name: Run E2E (smoke + mega-flow)
|
|
if: ${{ !inputs.full }}
|
|
run: |
|
|
bash app/scripts/e2e-run-session.sh test/e2e/specs/smoke.spec.ts smoke
|
|
bash app/scripts/e2e-run-session.sh test/e2e/specs/mega-flow.spec.ts mega-flow
|
|
|
|
- name: Run E2E (full suite)
|
|
if: ${{ inputs.full }}
|
|
run: bash app/scripts/e2e-run-session.sh
|
|
|
|
# Artifact uploads intentionally omitted — see e2e-linux for the
|
|
# reusable-workflow-is-also-used-by-releases rationale.
|
|
|
|
e2e-windows:
|
|
if: inputs.run_windows
|
|
name: E2E (Windows / Appium Chromium)
|
|
runs-on: windows-latest
|
|
timeout-minutes: 90
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v5
|
|
with:
|
|
ref: ${{ inputs.ref }}
|
|
fetch-depth: 1
|
|
submodules: recursive
|
|
|
|
- name: Install pnpm
|
|
uses: pnpm/action-setup@v4
|
|
|
|
- name: Setup Node.js 24.x
|
|
uses: actions/setup-node@v5
|
|
with:
|
|
node-version: 24.x
|
|
cache: pnpm
|
|
|
|
- name: Install Rust (rust-toolchain.toml)
|
|
uses: dtolnay/rust-toolchain@1.93.0
|
|
|
|
- name: Cache Rust build artifacts
|
|
uses: Swatinem/rust-cache@v2
|
|
with:
|
|
workspaces: |
|
|
. -> target
|
|
app/src-tauri -> target
|
|
cache-on-failure: true
|
|
key: e2e-windows-unified
|
|
|
|
- name: Cache CEF binary distribution
|
|
uses: actions/cache@v5
|
|
with:
|
|
path: |
|
|
~/AppData/Local/tauri-cef
|
|
key: cef-x86_64-pc-windows-msvc-${{ hashFiles('app/src-tauri/Cargo.toml') }}
|
|
restore-keys: |
|
|
cef-x86_64-pc-windows-msvc-
|
|
|
|
- name: Cache Appium global install
|
|
uses: actions/cache@v5
|
|
with:
|
|
path: |
|
|
~/.appium
|
|
key: appium3-chromium-${{ runner.os }}-v1
|
|
|
|
- name: Install JS dependencies
|
|
run: pnpm install --frozen-lockfile
|
|
|
|
- name: Ensure .env exists for E2E build
|
|
shell: bash
|
|
run: |
|
|
touch .env
|
|
touch app/.env
|
|
|
|
- name: Install Appium and chromium driver
|
|
shell: bash
|
|
run: |
|
|
if ! command -v appium >/dev/null 2>&1; then
|
|
npm install -g appium@3
|
|
fi
|
|
# `appium driver list --installed` can miss cached installs on some
|
|
# Appium builds; install idempotently and ignore "already installed".
|
|
appium driver install --source=npm appium-chromium-driver >/dev/null 2>&1 || true
|
|
|
|
- name: Build E2E app
|
|
run: pnpm --filter openhuman-app test:e2e:build
|
|
|
|
- name: Run E2E (smoke + mega-flow)
|
|
if: ${{ !inputs.full }}
|
|
shell: bash
|
|
run: |
|
|
bash app/scripts/e2e-run-session.sh test/e2e/specs/smoke.spec.ts smoke
|
|
bash app/scripts/e2e-run-session.sh test/e2e/specs/mega-flow.spec.ts mega-flow
|
|
|
|
- name: Run E2E (full suite)
|
|
if: ${{ inputs.full }}
|
|
shell: bash
|
|
run: bash app/scripts/e2e-run-session.sh
|
|
|
|
# Artifact uploads intentionally omitted — see e2e-linux for the
|
|
# reusable-workflow-is-also-used-by-releases rationale.
|