Skip to content

Commit edc8e9a

Browse files
mikepitreclaude
andcommitted
docs(expo): say what the CI device job keeps, where it runs, and that drafts skip it
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1 parent f2dd962 commit edc8e9a

2 files changed

Lines changed: 14 additions & 3 deletions

File tree

‎.claude/skills/verify-clerk-expo/SKILL.md‎

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -253,9 +253,9 @@ For a remote device, `down` ends the runner job and waits for it to finish, and
253253

254254
- `bin/control-clerk-expo` is the CLI. It is executable, and every verb is shown above.
255255
- `npm test --prefix .claude/skills/verify-clerk-expo` runs the CLI's unit tests, with no network, key, or device. `npm run typecheck --prefix .claude/skills/verify-clerk-expo` runs `tsc`. The `Verify Skill Tests` job in `.github/workflows/ci.yml` runs both on Linux when a pull request changes the skill, the fixture, or a package the fixture links.
256-
- `src/core/`, `src/platform/ios/`, `src/platform/android/`, `specs/fixtures.ts`, `testing/`, and every test but `test/host.test.ts`, `test/remote-host.test.ts`, and `test/freshness.test.ts` are shared with the clerk-ios and clerk-android verification skills. Change them there first, then copy them here, and never edit them here. `doctor`'s `core-drift` check fails when a file under `src/core/` differs from `src/core/MANIFEST`. Do not rewrite the manifest here to make it pass.
257-
- `src/host.ts`, `src/fixture.ts`, and `src/freshness.ts` are this repository's own: the screens, the build of the fixture, the Metro ports, and the check that Metro serves current JS. `specs/native.ts` holds the per-platform locators for the native views.
258-
- `.github/workflows/verify-device-specs.yml` runs `up --backend local`, `run --all`, and `down` on a runner for each platform, so the device is on the runner itself and no remote session starts. It sets `VERIFY_LOCAL_BUILD=standalone`, which makes a local lease build the Release app with the JS embedded and start no Metro. The Platform API key comes from the `MOBILE_VERIFICATION_PLATFORM_API_KEY` repository secret, and the repository variables `VERIFY_CI_RUNNER_IOS` and `VERIFY_CI_RUNNER_ANDROID` name other runner labels. It uploads each run's `run.json`, video, screenshots, and `e2e` summary and failure pages for three days, and only when the run is sealed with no secret found in it.
256+
- `src/core/`, `src/platform/ios/`, `src/platform/android/`, `specs/fixtures.ts`, `testing/`, and every test but `test/host.test.ts`, `test/remote-host.test.ts`, `test/freshness.test.ts`, and `test/native-build.test.ts` are shared with the clerk-ios and clerk-android verification skills. Change them there first, then copy them here, and never edit them here. `doctor`'s `core-drift` check fails when a file under `src/core/` differs from `src/core/MANIFEST`. Do not rewrite the manifest here to make it pass.
257+
- `src/host.ts`, `src/fixture.ts`, `src/native-build.ts`, and `src/freshness.ts` are this repository's own: the screens, the build of the fixture, the native build that CI keeps between runs, the Metro ports, and the check that Metro serves current JS. `specs/native.ts` holds the per-platform locators for the native views.
258+
- `.github/workflows/verify-device-specs.yml` runs `up --backend local`, `run --all`, and `down` on a runner for each platform, so the device is on the runner itself and no remote session starts. It runs for a pull request that is not a draft, and a draft gets a notice instead. The runners are GitHub-hosted, `macos-26` and `ubuntu-24.04`, and the repository variables `VERIFY_CI_RUNNER_IOS` and `VERIFY_CI_RUNNER_ANDROID` name other labels. It sets `VERIFY_LOCAL_BUILD=standalone`, which makes a local lease build the Release app with the JS embedded and start no Metro, and `VERIFY_NATIVE_CACHE`, which keeps the native build between runs ([freshness.md](references/freshness.md)). The Platform API key comes from the `MOBILE_VERIFICATION_PLATFORM_API_KEY` repository secret. It uploads each run's `run.json`, video, screenshots, and `e2e` summary and failure pages for three days, and only when the run is sealed with no secret found in it.
259259
- `src/platform/session-device.ts` holds the steps that a remote session runs on its device, `.github/workflows/verify-remote.yml` is the workflow that the session runs in, and `src/core/remote/` is the code on both ends of it. The runner installs this skill with `npm ci` and uses the same `node_modules/.bin/agent-device` as a Mac does.
260260
- To call `agent-device` yourself, use `node_modules/.bin/agent-device` in the skill directory with `AGENT_DEVICE_STATE_DIR=.claude/skills/verify-clerk-expo/.verify/agent-device`. Each worktree runs its own daemon from there, and `down` stops it. Never print `.verify/agent-device/daemon.json`, because it holds the daemon's auth token.
261261
- `features/` is the feature map. Start with `features/README.md`, and update a feature file in the same PR as a change to the behavior it maps.

‎.claude/skills/verify-clerk-expo/references/freshness.md‎

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,17 @@ A remote lease runs a standalone Release build with the JS embedded, so there is
3939

4040
`VERIFY_LOCAL_BUILD=standalone` makes a local lease build that same standalone app in the working tree. `up` and `run` then start no watch build and no Metro, and the build key covers the JS inputs. Every JS edit then changes the key, so the next `up` or `run` generates the native project again and rebuilds the app, and that build stops this worktree's Metro and watch build if a dev client left them running. The `Verify device specs` workflow sets it, so its runners build the same kind of app as a remote session and serve no JS. Unset, or set to `dev-client`, a local lease gets the dev client.
4141

42+
`VERIFY_NATIVE_CACHE=<directory>` keeps the app of a standalone build in `<directory>/<platform>-<fingerprint>/`. The fingerprint covers that platform's native inputs, the fixture's `pnpm-lock.yaml` as its install wrote it, the Xcode version on iOS, and `src/fixture.ts` and `src/native-build.ts`. A JS edit does not change it. A later standalone build with the same fingerprint runs no `expo prebuild`, `xcodebuild`, or Gradle. It builds the workspace packages, exports the bundle from the working tree with `expo export:embed`, compiles it with the fixture's `hermesc`, and puts it in a copy of the kept app:
43+
44+
```console
45+
build native <platform>-<fingerprint> an app built from these native inputs is kept, so no native build runs
46+
build bundle <bundle> exported from this checkout and embedded in that app
47+
```
48+
49+
The build fails unless the app then holds exactly the bundle it compiled, so a kept app never reaches a device with the JS it was built with. It builds natively instead, and prints `not reused:` with the reason, when the kept app holds no Hermes bundle, when it runs another Hermes bytecode version, when an Android bundle has image assets, which an APK takes only from a resource build, or when the Android SDK has no build-tools 35 or newer to align the APK again. On Android the app is signed with the generated project's debug keystore when the working tree has one and with a new key otherwise, so a device that already holds the app under another key needs it uninstalled first.
50+
51+
The `Verify device specs` workflow sets the variable. A job that had to build natively stores the app as a run artifact named `verify-expo-native-<platform>-<fingerprint>` for seven days, and a later job takes it only from a run of the same branch of this repository. When there is none, the job takes the app that the `Expo` workflow built for the same commit (`expo-native-build-<platform>-<commit>`), waiting up to ten minutes while that workflow is still running, and it builds natively only when that is missing too. It does not store an app that the `Expo` workflow built. Unset, nothing is kept and every standalone build is a native build. A remote session does not set it.
52+
4253
## Troubleshooting
4354

4455
- A machine behind an HTTPS debugging proxy such as Proxyman needs the proxy's CA trusted by `Clerk Verify Template iOS` before lanes are cloned from it. `doctor` reports it as `proxy-trust` and prints the fix.

0 commit comments

Comments
 (0)