Muse Release Process: Building Android (APK/AAB) and iOS Binaries
The Muse release process triggers automated Android builds via GitHub Actions when you publish a new release, while iOS requires running a local shell script for simulator testing or manual Xcode commands to generate production IPAs.
The kkoshin/muse repository is a Kotlin Multiplatform project that packages a Compose Multiplatform app for both Android and iOS distribution. Whether you are shipping a signed APK to Google Play or testing an iOS build locally, the release pipeline relies on distinct workflows for each platform.
Android Release Workflow (APK and AAB)
The Android release process is fully automated through GitHub Actions and produces signed, production-ready artifacts.
Automated CI/CD Pipeline
The workflow defined in .github/workflows/package.yml listens for release events and executes six distinct stages:
-
Trigger: Creating a new GitHub release automatically starts the workflow via the
on: releaseevent trigger. -
Build: The runner executes
./gradlew assembleReleaseto compile thecomposeAppmodule. This generates an unsigned APK in release mode. For an Android App Bundle (AAB) instead, the command would be./gradlew bundleRelease. -
Sign: The
ilharp/sign-android-releaseGitHub Action signs the artifact using keystore credentials stored in repository secrets:KEY_STORE_BASE64(Base64-encoded keystore)KEY_STORE_PASSWORDALIASKEY_PASSWORD
-
Rename: The workflow strips the
-signedsuffix from the filename and moves the signed artifact to asigned/subdirectory. -
Publish: The signed APK (or AAB) and the ProGuard mapping file are uploaded as a workflow artifact named
release-artifacts, available for download from the Actions run page. -
Metadata: The
fastlane/metadata/androiddirectory contains Play Store screenshots, changelogs, and listing metadata that you manually update before distribution.
The release build configuration itself is defined in composeApp/build.gradle.kts, which specifies the signing configuration and release build type parameters.
Local Android Builds
For local development or manual releases, you can generate unsigned artifacts directly:
# Build APK
./gradlew assembleRelease
# Build Android App Bundle (AAB)
./gradlew bundleRelease
These commands output to composeApp/build/outputs/apk/release/ and composeApp/build/outputs/bundle/release/ respectively. You must then sign the artifact using jarsigner or Android Studio’s Generate Signed Bundle/APK wizard, ensuring you use the same keystore referenced in the CI secrets.
iOS Release Workflow
Unlike Android, the Muse repository does not include a fully automated CI workflow for iOS distribution. Instead, it provides a convenience script for development builds and requires manual Xcode commands for release archiving.
Development Builds with run_ios.sh
The run_ios.sh script automates building, installing, and launching the app on an iOS simulator:
-
Simulator Selection: The script searches for a currently booted simulator; if none exists, it automatically boots an
iPhone 15 Pro. -
Build: It invokes
xcodebuildusing theswiftApp/swiftApp.xcworkspaceworkspace andswiftAppscheme inDebugconfiguration, directing derived data tobuild/ios_derived_data. -
Installation: The script locates the compiled
.appbundle inDerivedData/Build/Products/Debug-iphonesimulator, extracts the bundle identifier fromswiftApp/swiftApp/Info.plistusingPlistBuddy, and installs the app viaxcrun simctl. -
Launch: Finally, it launches the installed app on the selected simulator using
xcrun simctl launch.
Production IPA Generation
To create a distributable IPA for TestFlight or the App Store, you must run manual xcodebuild commands. The repository does not currently automate this step in CI, though you could adapt the following commands into a GitHub Actions workflow:
# Step 1: Create archive
xcodebuild -workspace swiftApp/swiftApp.xcworkspace \
-scheme swiftApp \
-configuration Release \
-archivePath build/ios.xcarchive \
archive
# Step 2: Export IPA (requires ExportOptions.plist)
xcodebuild -exportArchive \
-archivePath build/ios.xcarchive \
-exportPath build/ios_ipa \
-exportOptionsPlist ExportOptions.plist
The resulting .ipa file in build/ios_ipa/ can then be uploaded to App Store Connect using the Transporter app or xcrun altool.
Key Configuration Files
Understanding the Muse release process requires familiarity with these specific files:
| File Path | Platform | Purpose |
|---|---|---|
.github/workflows/package.yml |
Android | CI workflow that triggers on releases, builds, signs, and publishes artifacts |
composeApp/build.gradle.kts |
Android | Gradle configuration defining the release build type and version codes |
fastlane/metadata/android/** |
Android | Store listing assets including screenshots and changelogs |
run_ios.sh |
iOS | Local development script for simulator builds and testing |
swiftApp/swiftApp.xcworkspace |
iOS | Xcode workspace file used by xcodebuild |
swiftApp/swiftApp/Info.plist |
iOS | Contains bundle identifier used during simulator installation |
Summary
- Android releases are fully automated through GitHub Actions when you publish a new release, producing signed APKs or AABs using secrets stored in the repository.
- iOS development builds rely on the
run_ios.shconvenience script to compile and run the app on a local simulator. - iOS production releases currently require manual
xcodebuildarchiving and exporting, though the commands can be adapted for CI/CD. - The
fastlane/metadata/androiddirectory manages Play Store listing content separately from the binary build process.
Frequently Asked Questions
How do I trigger an Android release build in Muse?
Create a new GitHub release (or push a new tag) to automatically trigger the package.yml workflow. The workflow listens for release events and handles the entire build, sign, and publish cycle without manual intervention.
What secrets are required for Android signing?
You must configure four GitHub Secrets: KEY_STORE_BASE64 (your keystore file encoded as Base64), KEY_STORE_PASSWORD, ALIAS (the keystore alias), and KEY_PASSWORD. These are consumed by the ilharp/sign-android-release action during the CI workflow.
Can I build iOS release binaries automatically in CI?
The current repository does not include an automated iOS release workflow. While run_ios.sh handles debug simulator builds, you must manually run xcodebuild archive and xcodebuild -exportArchive commands locally to generate IPAs. You can adapt these commands into a GitHub Actions workflow using macOS runners if needed.
What is the difference between APK and AAB in Muse builds?
The Muse CI workflow generates an APK by default using ./gradlew assembleRelease. To produce an Android App Bundle (AAB) required for Google Play Store distribution, you would modify the workflow to run ./gradlew bundleRelease instead, or execute this command locally. Both artifacts are signed using the same keystore configuration.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →