CI
Run warden e2e in GitHub Actions on a macOS runner, install warden with the install action or npm, and gate a pull request on the affected specs.
Use this page to run warden e2e on a macOS GitHub Actions runner; it covers installing warden, the run command, headless behavior and cleanup.
jobs:
e2e:
runs-on: macos-15
steps:
- uses: actions/checkout@v4
with: { fetch-depth: 0 }
- uses: oven-sh/setup-bun@v2
- run: bun install
- uses: delacournz/warden/.github/actions/install-warden@main
- run: warden e2e mobile --base origin/main --count 2 --report e2e-report.jsonfetch-depth: 0 gives warden the history it needs for the merge-base against --base. The same command runs locally or in a pre-push hook.
Install warden
Two routes:
- npm:
npm i -g @delacour/warden, orbunx @delacour/warden. It is a node shim plus one prebuilt binary per platform (macOS and Linux,arm64andx64); an install with--omit=optionalleaves the shim without a binary. - Install action:
delacournz/warden/.github/actions/install-wardendownloads the release binary for the runner (warden-darwin-arm64…), checks it againstchecksums.txt, installs it to~/.local/bin/wardenand puts that onPATH. Inputs:token(default: the workflow'sgithub.token, which can read the public releases),version(a tag such asv0.1.0; defaultlatest) andrepo(defaultdelacournz/warden).
A private fork in repo needs a token with Contents: read on that repo.
@delacour/warden-e2e is a dev dependency of your app at the same version as warden; bun install brings it in. A mismatch makes the preload exit 2.
What the runner needs
- macOS for iOS simulators, with Xcode and the iOS runtime installed; Android needs the SDK. There is no Windows support.
- bun 1.3 or newer on
PATH(orWARDEN_BUN). - No prior state. The
--profileis created on claim, cloned from a golden image that is built on first use (about a minute or two); cache~/Library/Developer/CoreSimulator/Devicesbetween runs to keep it (Golden images). If cloning fails it falls back tosimctl create.
Gate a pull request
warden e2e <suite> --base origin/main runs only the specs the diff needs (Affected). It exits 0 when every required spec passed or nothing was affected (no device claimed), and 1 when a required one failed. Parsed imports are cached under $WARDEN_HOME/affected. The compiled warden binary carries no TypeScript compiler, so add typescript 5.0 or later as a dev dependency of the app.
Keep the evidence when a run fails:
- uses: actions/upload-artifact@v4
if: failure()
with:
name: warden-e2e
path: |
e2e-report.json
~/.warden/batchesHeadless and cleanup
Simulators boot without a window. On a CI runner nothing else is open, so no flag is needed; --headless guarantees it when Simulator.app is running (Headless). Under CI, a passed gate shuts down the simulators and emulators warden created for the run, and a failed run leaves them booted. --no-shutdown keeps them up. A leftover test.only fails the run under CI.