Repository navigation
feat(verify): borrow an emulator on a CI runner when the machine cannot run one - #1069
Merged
Merged
Conversation
Contributor
This was referenced Oct 8, 2026
mikepitre
force-pushed
the
mike/verify-borrowed-device-android
branch
from
October 8, 2026 04:36
a93327c to
f36fa01
Compare
mikepitre
force-pushed
the
mike/verify-borrowed-device-android
branch
from
October 8, 2026 12:02
f36fa01 to
3adb90e
Compare
mikepitre
force-pushed
the
mike/verify-borrowed-device-android
branch
from
October 8, 2026 14:19
3adb90e to
b426eed
Compare
mikepitre
force-pushed
the
mike/verify-borrowed-device-android
branch
from
October 8, 2026 20:40
b426eed to
55b313f
Compare
…home A launch with verify extras takes its publishable key, auth mode, initial identifier, sign-in ticket, storage scope, and log level from them, and opens on a home that shows whether a user is signed in. The home opens AuthView in a sheet or full screen, and a custom sign-in form. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
mikepitre
force-pushed
the
mike/verify-borrowed-device-android
branch
from
October 8, 2026 20:45
55b313f to
e54b8b5
Compare
mikepitre
force-pushed
the
mike/verify-borrowed-device-android
branch
from
October 8, 2026 20:49
e54b8b5 to
a0da184
Compare
mikepitre
added this pull request to stack #1053
October 8, 2026 22:12
main gained the e2e app's parity work with the iOS harness (#1057), which rewrote the Trailblaze screens in MainActivity.kt. This branch had moved those screens to TrailApp.kt and made MainActivity choose between them and the verify host. - TrailApp.kt is now main's version of the Trailblaze screens, with the activity class removed and the entry point named TrailApp. - MainActivity.kt stays as on this branch. - E2ETags keeps main's flat tags and this branch's nested groups. - e2e/build.gradle.kts keeps both test dependencies. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
mikepitre
force-pushed
the
mike/verify-borrowed-device-android
branch
from
October 9, 2026 01:04
a0da184 to
5558f6b
Compare
mikepitre
force-pushed
the
mike/verify-borrowed-device-android
branch
2 times, most recently
from
October 9, 2026 03:57
f699ca9 to
026ffb2
Compare
mikepitre
force-pushed
the
mike/verify-borrowed-device-android
branch
from
October 9, 2026 05:23
026ffb2 to
ce42c02
Compare
…@24 through npx The CLI fetched node@24 with npx without asking and reran itself with the full environment, Platform API key included. It now stops with the existing fix message. src/core/launch.mjs is shared byte for byte with clerk-ios and clerk/javascript; copy it there too.
…g an app open The retry reused the single-use ticket of the first try, so a first open that reached the app left the retry with a spent ticket. Each try now gets its own ticket, storage scope, and launch id. specs/support/launch.ts is shared byte for byte with clerk-ios and clerk/javascript; copy it there too.
…her updates stay off
…d' into fix/verify-ci-device-specs-android # Conflicts: # e2e/src/main/java/com/clerk/e2e/E2ECleanupReceiver.kt
…oid' into fix/verify-borrowed-device-android # Conflicts: # e2e-tests/src/core/MANIFEST # e2e-tests/src/core/launch.mjs # e2e-tests/src/host.ts
…sitory uses The dispatcher named the session job's runner label, and the job holds it for up to 370 minutes. The plan job now fails for any label other than ubuntu-24.04 (the default), ubuntu-latest (doctor --live), and blacksmith-4vcpu-ubuntu-2404 (the documented paid label).
Collaborator
|
Pushed fixes for the review findings above:
The comment near the end of verify-remote.yml was already gone after your f4eaf89. |
… Node This puts src/core/launch.mjs back to what it was before 719b680, which made the CLI stop on an unsupported Node. The file is shared byte for byte with clerk-ios and clerk/javascript, and they keep the rerun. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…device-specs-android
…device-specs-android
…orrowed-device-android # Conflicts: # e2e-tests/src/core/launch.mjs
… the limit over a finished build The limit only stopped a command that was running. When it passed between two commands, or while the device module was being asked for the build commands, nothing was stopped and the next command started. A command that exited 0 after the limit also left the build as built. The sequence now ends once the limit has passed, and a build that ran into its limit is timed-out whatever its last command returned. src/core/remote/session-agent.ts is shared byte for byte with clerk-ios and clerk/javascript. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
GNU tail rejects `tail -20` with two files, so the step printed no log on ubuntu-24.04. `tail -n 20` works on GNU and BSD tail. The new test runs the step's own lines with a stand-in pgrep. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A run's addresses were 60 characters, such as verify_r20261013_141954_62f0_ab12cd34+clerk_test@example.com, and the tests type every one of them into the app. An address is now the time of day and the four characters of the run id, then four random characters: 14195462f0ab12+clerk_test@example.com. That is three typing commands where there were four. The first ten characters still say which run made the address, so the stand-in still limits a run to its own users and run still finds the users a form signed up. The prefix comes from a parse of the run id that fails on an id of another shape. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…an app of your own AGENTS.md named the verification skill as the way to prove a change. The proof is what matters: run the change on an emulator and put the screenshots or video on the pull request. The skill is one way to do that, and a throwaway app that exercises the change is as good. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…device-specs-android
…orrowed-device-android # Conflicts: # AGENTS.md
Four hex characters gave a run 65,536 addresses, so a run that makes about 25 of them made the same one twice about once in 200 runs, and the second createUser then failed its test. The four characters now come from 36 symbols, which is 1,679,616 addresses for a run. The address stays 37 characters and its first ten still name the run. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…device-specs-android
…orrowed-device-android
…-specs-android main now holds the pull request below this one as a squash commit. This branch already contains all of main, so the conflict takes this branch's side and the tree is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…orrowed-device-android
…device-android main now holds the pull request below this one as a squash commit. This branch already contains all of main, so the conflict takes this branch's side and the tree is unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What & why
upstarts a session on a GitHub Actions runner, and the CLI drives the emulator there through a tunnel, with the same verbs, tests, and evidence.e2e-tests/, and theverify-clerk-androidskill is the instructions that point an agent at it.--backend remoteondoctor,up, andrunforces the remote backend. With no flag the CLI picks the local backend where the machine can run the emulator and the remote one anywhere else, and its first line says which and why..github/workflows/verify-remote.ymlruns one session. It builds the pushed commit, never the working tree, boots the emulator, records the video, and ends ondown, after 15 idle minutes, or at 60 minutes.--runner <label>names the runner for a new session. The default isubuntu-24.04.doctorchecks that git can fetch and push the branch, that GitHub has HEAD, and that this machine reaches GitHub, the tunnel host, and Clerk. It starts nothing without--live.doctor --livestarts one short session and stops it.downends the runner job, anddown --stalealso ends a session that a crashed run of the same checkout left running.ghcannot attach files,attachhands the video and screenshots to the session's runner through the tunnel, and the runner keeps them as the artifactverify-evidence.references/remote.mdis new andSKILL.mddescribes the remote backend. Outside it ande2e-tests/, the PR addsverify-remote.ymland one line inandroid-test.yml, and it changes one sentence inAGENTS.md.To try it, on any machine with Node 24.8 or newer, the team's Clerk Platform API key, and a GitHub token that can push to this repository and start a workflow in it:
On a machine that cannot run the emulator, leave out
--backend remote. Allow about ten minutes for the firstup, most of it the first Gradle build.What to focus on
Five commits in dependency order, then six commits added after review.
attachwrite a run's video and screenshots into the pull request description, in one block that a laterattachreplaces. In #1046 it posts a comment.https:proxy on port 443 when its URL names no port, with the same rule the doctor's check uses. Added after review.attachbeforedowninAGENTS.md, the order a remote session needs.Commit 1 has its own unit tests. The unit tests for commits 2 and 3 arrive in commit 4.
Everything under
e2e-tests/src/core/ande2e-tests/specs/support/, and most of the unit tests, are the same files, byte for byte, in clerk/clerk-ios#661 and clerk/javascript#10131.src/core/MANIFESTlists every shared file with its hash, and a unit test fails when one drifts. Review them once.Not proven:
doctor --live, the idle stop, and the 60-minute cap, at this head.What limits the risk:
workflow_dispatchonly, so it takes write access to start one and a fork cannot. The workflow has nopushorpull_requesttrigger and uses no repository or environment secret. Its onepermissionsblock iscontents: read, and no job has a write permission. The step that reads the request uses the job's own read-only token to check the requested commit. A session starts only for the commit the run was dispatched on, or for a later commit of that branch.e2e-tests/.verify/remote/on the machine that started the session. The workflow gets only its SHA-256.downdeletes the throwaway Clerk application.ubuntu-24.04label. A Blacksmith label is billed by the minute.attach, the new code runs only when the CLI picks the remote backend. The release gate in ci: run the end-to-end tests in the release workflow, and remove the Trailblaze suite #1052 does not use it.npm test --prefix e2e-testspasses 672 of 672 at this head with no network, key, or emulator, andnpm run typecheck --prefix e2e-testsreports nothing.Screenshots / video
None attached.
🤖 Generated with Claude Code
Summary by CodeRabbit