Files
simplex-chat/scripts/ci
spacedandy-agents-simplex e7e8b0abf3 ci: the iOS simulator tests set private routing to unknown servers only, so the app can reach the test names server
Master's 3126d9b54 made the iOS app's default private routing "always". Name lookups then go through a preset server, which can't reach the test SMP server on the runner's localhost, so every iOS case that resolves a SimpleX name would fail. The desktop and Android tests already set "unknown" before the first launch; the iOS smoke test now writes the same into the app group's defaults after installing the app, and the app applies it when its chat starts.
2026-10-21 18:31:15 +00:00
..
2026-10-19 22:36:12 +01:00

App tests on GitHub's runners

Three workflows build the apps from a branch's own code and test them, only when asked: ios-sim (the iOS app in a simulator on a macOS runner), desktop-linux (the desktop app on a Linux runner) and android-emu (the Android app in an emulator on a Linux runner). Each runs a scripted smoke test and, on request, a Claude session that follows a test plan, and a test backend (relay, directory, names server, peers). Details: iOS, desktop, Android.

Starting a run

Pushes start nothing: a run is started by hand, on any branch, with inputs that are off by default and combine.

Input iOS Desktop Android
no input scripted test scripted test scripted test
claude scripted test, then Claude scripted test, then Claude scripted test, then Claude
backend also the test backend also the test backend also the test backend
release — also the latest release's onboarding, to tell a branch's failure from the runner's also the latest release's onboarding, to tell a branch's failure from the runner's

In the Actions tab: ios-sim, desktop-linux or android-emu → Run workflow, choose the branch and tick the inputs. With the GitHub CLI, each input is a field:

gh workflow run ios-sim.yml --ref <branch>
gh workflow run ios-sim.yml --ref <branch> -f claude=true
gh workflow run desktop-linux.yml --ref <branch> -f claude=true -f backend=true -f release=true
gh workflow run android-emu.yml --ref <branch> -f claude=true

A newer run of a workflow on the same branch cancels the older one.

How long a run takes

Run iOS Desktop Android
Scripted test, builds reused about 25 min, plus the wait for a macOS runner, which the team's builds share (minutes to an hour) about 10 min about 15 min
The core rebuilt, after Haskell changes 30–45 min more about 25 min more about 27 min more
With the test backend 20–45 min more when it is rebuilt, then about 10 min to start about 30 min more when it is rebuilt, then a few minutes to start as desktop, whose backend it shares
With Claude on the smoke plan 10–15 min more about 4 min more about 5 min more

The Claude job

It needs the GitHub environment app-sim-claude with the secret CLAUDE_CODE_OAUTH_TOKEN, a Claude subscription token. The environment's branch rule alone decides which branches may use it: on a branch it doesn't allow, a run that asks for Claude fails at the Claude job's environment check, and the scripted test runs as usual. Each run spends the subscription's usage limits; the job summary gives its tokens and cost estimated at API prices.

A Claude job that starts the app job's test backend again (iOS and desktop, when claude-scope says backend: yes) also needs the environment's secret BACKEND_STATE_KEY, the private key of backend-state.crt, to decrypt that backend's keys and databases (backend-state.sh). A new pair replaces both:

openssl req -x509 -newkey rsa:4096 -nodes -days 3650 -subj /CN=simplex-chat-ci-backend-state -keyout key.pem -out scripts/ci/backend-state.crt
gh secret set BACKEND_STATE_KEY --env app-sim-claude --repo simplex-chat/simplex-chat < key.pem
rm key.pem