Add a KMP runner, and let it gate the merge it is checking - #57
Draft
vaishnav-0 wants to merge 1 commit into
Draft
Add a KMP runner, and let it gate the merge it is checking#57vaishnav-0 wants to merge 1 commit into
vaishnav-0 wants to merge 1 commit into
Conversation
geoanimator is Kotlin Multiplatform, so neither existing Android nor iOS runner fits: one build graph produces the Android APK, the Apple framework and the JVM test binaries, and bending two single-platform pipelines together would mean configuring Gradle twice. Three things here differ from the Android and iOS runners deliberately. It posts a commit status back to the source repository. travel-animator-android's own CLAUDE.md records why that matters: the dispatcher in the app repo goes green in under fifteen seconds while the real build runs here, where GitHub cannot make it a required check, so a broken change can be merged past a red pipeline. The runner already mints a repo-scoped installation token to check the source out, so it can post ci/kmp-gate with the same token. The trigger sends the head SHA for this reason. Its tests block. The iOS runner runs none; geoanimator has 184 test files, and the Apple job is not optional because RenG publishes no jvm target — FramePlanAdapter's bake-key assertions live in :render's commonTest and are reachable from no JVM suite. It is also unrationed: this repository is public, so macOS minutes are free. It reads no local.properties from Infisical. Runners preset ANDROID_HOME, and RenG resolves anonymously, so the only secrets are the debug keystore and a chat id. Their Infisical names match the environment variables the Gradle build reads, so there is no remapping step — the Android runner needs one only because its names disagree with its build's. The gate excludes :ui:iosSimulatorArm64Test for a measured reason, stated inline: that task fails to compile, not to pass. Co-Authored-By: Claude Opus 5 (1M context) <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.
Adds a Kotlin Multiplatform runner, for
Lascade-Co/geoanimator. Designed in that repository'sADR 0028,
which carries the full reasoning; this describes what lands here.
What's here
.github/workflows/kmp-build-debug.yml.github/workflows/kmp-device-tests.ymltriggers/kmp-pr.yml,triggers/kmp-dev-push.yml,triggers/kmp-device-tests.ymlCLAUDE.md.Event types are
kmp-debugandkmp-device-tests— distinct frombuild-debug-apkanddebug-ios, so nothing collides with the existing handlers.Three deliberate departures from the Android and iOS runners
1. It posts a commit status back, so it can gate a merge.
travel-animator-android/CLAUDE.mdalready records the problem: the dispatcher in the app repo goes green in under fifteen seconds
while the real build runs here, where GitHub can't surface it as a required check — so a broken
change can be merged past a red pipeline. This runner posts
ci/kmp-gate(pending → success/failure)onto the head SHA using the installation token it already mints to check the source out. That status
is requirable in branch protection.
This is why the triggers send
sha, which the existing triggers don't.2. Its tests block. The iOS runner runs none; geoanimator has 184 test files. The Apple job is
not optional either — RenG publishes no
jvmtarget, so:renderhas none, andFramePlanAdapterTest's bake-key assertions are reachable from no JVM suite. It's also unrationed,because this repository is public and macOS minutes are free. (The disabled workflow it replaces
gated its iOS job behind a label for exactly the cost reason that doesn't apply here.)
3. No
local.propertiesfrom Infisical. Runners presetANDROID_HOME, and RenG resolvesanonymously from
maven.rohittp.com, so the build needs no repository credentials. Infisical/Build(staging) carries four keystore values plusTELEGRAM_CHAT_ID, and their names match theenvironment variables the Gradle build reads — so there's no remapping step. The Android runner
needs one only because its Infisical names disagree with its build's.
Verification
The workflows can't be tested from a PR —
repository_dispatchfires only on the default branch —so both jobs were rehearsed locally against the source repo instead. All 8 gate steps pass:
qualityCheck,-p build-logic spotlessCheck, the desktop and Android host suites,assembleDebug, the iOS framework link, the Apple-native tests, and an unsignediosAppXcodebuild.
actionlintis clean apart from two known false positives (its bundled metadata still thinkscreate-github-app-token'sclient-idis invalid — it's actually the current input andapp-idisthe deprecated one; and SC2129 style notes on
$GITHUB_OUTPUTredirects).The rehearsal caught two things the first real run would otherwise have: the Android host-test task
is
testAndroidHostTest, notandroidHostTest; and:ui:iosSimulatorArm64Testfails to compilebecause
PictureRateTestcalls the JVM-onlyString.format. The latter is excluded with thatmeasured reason stated inline, and recorded in geoanimator's known gaps rather than worked around.
Before this does anything
CENTRAL_DISPATCH_TOKENinLascade-Co/geoanimator, and the triggers copied there (done on thatside already).
geoanimator, envstaging, path/Build.statuses: writeonLascade-Co/geoanimator, or the post-back 403sand the whole point of item 1 is lost. This is the one thing I couldn't verify from outside.
Merging makes it live for anything dispatching
kmp-debug; today that's geoanimator alone. Worthrehearsing once via
workflow_dispatchonmainafter merge, since that's the only rehearsal thedispatch model allows.
🤖 Generated with Claude Code