Configure GitHub Actions for continuous integration of a Kotlin Multiplatform application
This guide shows an example of continuous integration for a Kotlin Multiplatform application set up with GitHub Actions. You'll set up a workflow that runs shared tests and builds artifacts for Android, iOS, and desktop on every push or pull request to the main branch.
This guide is based on the Jetcaster KMP sample. You can see the action and workflow configuration in the repository or follow the steps below for a step-by-step description.
This guide suggests setting up CI in two parts:
Reusable composite GitHub Action that sets up Java and Gradle
Main GitHub Actions workflow that runs tests and triggers platform-specific builds on every push or pull request to the
mainbranch.
Create a composite action for Gradle setup
Create a composite action to synchronize Java and Gradle configuration across jobs. You will reuse this action in workflow jobs to make sure that the same configuration is used for all builds.
In this example, the action installs Java 17 and configures the default Gradle version. To set up the action, create the file .github/actions/gradle-setup/action.yml:
Define the build workflow
Define when the workflow runs and configure Gradle options:
The workflow should run on every push or pull request to the
mainbranch.Gradle options should disable the Gradle daemon and enable parallel execution with caching.
Create the file .github/workflows/build.yml with the base configuration:
With this configuration, you can also trigger the workflow manually using workflow_dispatch.
Now you can add jobs to run tests and build application artifacts.
Run shared tests
This job runs tests using the jvmTest Gradle task to validate changes before building the app for all platforms:
Check out the repository to run tests for.
Use the composite
gradle-setupaction that you prepared earlier to set up Java and Gradle.Run the tests with the
./gradlewcommand.Upload test reports as an artifact to the
**/build/reports/tests/directory.
To set up this job, add the following to the .github/workflows/build.yml file:
Once tests are run, the workflow should build the application artifacts.
Build the Android debug package
This job builds the Android debug APK using the :mobile:assembleDebug Gradle task:
Check out the repository to build the package from.
Use the composite
gradle-setupaction that you prepared earlier to set up Java and Gradle.Build the APK with the
./gradlewcommand.Upload the built package from the
mobile/build/outputs/apk/debug/directory.
Add the following to the .github/workflows/build.yml file, continuing the jobs section:
Build the iOS simulator application
This job targets the iOS Simulator to avoid having to properly sign the app. The application is built using xcodebuild:
Check out the repository to build the application from.
Use the composite
gradle-setupaction that you prepared earlier to set up Java and Gradle.Build the iOS application using
xcodebuild— the example shows the options used for the Jetcaster KMP sample.Upload the folder with the built application (everything inside
build/Build/Products/Debug-iphonesimulator/*) as an artifact.
The iOS application is built on a macOS runner (macos-latest), which includes xcodebuild.
Continue modifying the .github/workflows/build.yml file:
Push and test your CI
The CI workflow is going to be triggered for the first time when you push the workflow configuration to the main branch or create a pull request with these configuration files.
You can check the workflow results in the Actions tab of your repository to verify that everything works correctly.
Remember that you can also trigger the workflow manually: select the workflow in the list of actions on the left and click Run workflow.
What’s next
For a complete CI configuration example, see the Jetcaster sample, which also includes jobs to build desktop JVM applications for macOS, Windows, and Linux.
For guidance on publishing applications to app stores with GitHub Actions, see Marco Gomiero’s series of posts on the subject.