ci: sign Android releases, and build iOS against the SDK it now needs - #16
Merged
Conversation
The Android deploy writes `fastlane/keystore.jks` from a secret and passes SIGNING_STORE_PASSWORD, SIGNING_KEY_ALIAS and SIGNING_KEY_PASSWORD to fastlane — but nothing ever read any of it. There was no `signingConfigs` block at all, so `bundleDevRelease` produced an unsigned bundle, which the Play Store will not take. This is latexcards-app's block, which has been deploying that way for a year, with one change: the config only applies when the keystore is actually there. Taken verbatim, a release built anywhere but CI fails on a missing file, and `assembleProductionRelease` is worth keeping usable locally. Without the keystore the build now comes out unsigned instead of failing. Verified by building a release with the keystore and the three variables present: the APK comes out signed with the upload certificate.
With the certificate renewed, `deploy-ios` finally reached compilation — and
failed at the link:
Undefined symbols for architecture arm64
"_OBJC_CLASS_$_UIViewLayoutRegion", referenced from: …
`UIViewLayoutRegion` is iOS 26. Compose Multiplatform 1.11.1 references it in
its UIKit layer, so the framework needs the iOS 26 SDK. `macos-15` ships
Xcode 16 and `iPhoneOS18.5.sdk`, which is why this only showed up on CI:
locally the same code builds against `iPhoneOS26.5.sdk`.
This is a consequence of the migration raising Compose Multiplatform from
1.8.2 to 1.11.1. Nothing could see it while the job was still stopping earlier,
first on the SSH key and then on the expired certificate.
`macos-latest` currently resolves to macOS 26 arm64. Worth knowing that this
repository once had to pin *away* from it — `ci: using macos-15 (because
macos-latest is macos-14)` — so if GitHub's default ever lags the SDK the app
needs again, pinning to `macos-26` is the answer.
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.
deploy-androidnow builds — the Ruby fix got it as far asBUILD SUCCESSFULand a bundle — butwhat it produces is unsigned, so the Play Store will refuse it.
The workflow writes
fastlane/keystore.jksfromSIGNING_KEY_JKSand passesSIGNING_STORE_PASSWORD,SIGNING_KEY_ALIASandSIGNING_KEY_PASSWORDto fastlane. Nothing readany of it:
androidApp/build.gradle.ktshad nosigningConfigsblock at all.This is latexcards-app's block, which has been deploying that way for a year, with one deliberate
change: the config only applies when the keystore is actually present.
Taken verbatim,
storeFile = file("fastlane/keystore.jks")makes any release built outside CI failon a missing file — including
assembleProductionRelease, which is worth keeping usable forchecking what ships. With the guard, a build without the keystore comes out unsigned rather than
failing. Say the word if you would rather it match latexcards exactly.
Verified
A release built with the keystore present and the three variables set comes out signed with the
upload certificate (
CN=Fallet Nathan, OU=ZabriCraft) — which is the CI's exact situation.Still needed outside this PR
groupeminaste/matchhas expired(
V6866DQQ65.cer). The SSH side is fixed — match clones and decrypts fine now — but it stops onthe expired certificate. Removing the four distribution files from the match repo and re-running
fastlane match appstoreregenerates it without revoking anything.GOOGLE_SERVICE_ACCOUNT_KEYwas empty, which is whyupload_to_play_storesaid'fastlane/key.json' doesn't seem to be a JSON file. IfSIGNING_KEY_JKSand the three signingsecrets were never set either, this PR will get the build to the same place and stop there — the
bundle will be unsigned again, because the keystore file will be empty.
Also: iOS builds on
macos-latestPushed here rather than in its own PR, to save a merge and a run.
With the certificate renewed,
deploy-iosfinally reached compilation and failed at the link:UIViewLayoutRegionis iOS 26. Compose Multiplatform 1.11.1 references it in its UIKit layer, sothe framework needs the iOS 26 SDK.
macos-15ships Xcode 16 andiPhoneOS18.5.sdk; locally thesame code builds against
iPhoneOS26.5.sdk, which is why this never showed up before.It is a consequence of the migration raising Compose Multiplatform from 1.8.2 to 1.11.1 — invisible
until now, because the job kept stopping earlier: first on the SSH key, then on the expired
certificate.
macos-latestcurrently resolves to macOS 26 arm64. Worth remembering that this repository oncehad to pin away from it (
ci: using macos-15 (because macos-latest is macos-14)), so if GitHub'sdefault ever lags the SDK the app needs,
macos-26is the explicit alternative.