Kmp ci cd
Skill almasumdev/awesome-kotlin-multiplatform-agent-skills/.github/skills/build_and_tooling/kmp-ci-cd
Curated agent skills, conventions, and workflows for building Kotlin Multiplatform (KMP) apps with AI coding agents.
npx -y skills add almasumdev/awesome-kotlin-multiplatform-agent-skills --skill kmp-ci-cdAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
What its author says it does
Copied from the file, not written here
GitHub Actions CI/CD for Kotlin Multiplatform — matrix builds (ubuntu for JVM/Android/JS, macOS for iOS), caching, Maven Central / SPM / CocoaPods publishing. Use when wiring CI or a release pipeline.
SKILL.md
6.0 KB, as published. Nobody here has run it
KMP CI/CD
Instructions
KMP CI needs both Linux (for Android, JVM, JS, Wasm) and macOS (for iOS). Split the matrix so macOS runners — the expensive ones — only do what they must.
1. Matrix workflow
# .github/workflows/ci.yml
name: CI
on:
push: { branches: [ main ] }
pull_request:
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
jobs:
jvm-and-android:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with: { distribution: temurin, java-version: '17' }
- uses: gradle/actions/setup-gradle@v4
- run: ./gradlew :shared:jvmTest :shared:testDebugUnitTest :shared:jsTest --no-daemon --stacktrace
ios:
runs-on: macos-14
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with: { distribution: temurin, java-version: '17' }
- uses: gradle/actions/setup-gradle@v4
- run: sudo xcode-select -s /Applications/Xcode_15.4.app
- run: ./gradlew :shared:iosSimulatorArm64Test --no-daemon --stacktrace
- run: ./gradlew :shared:assembleSharedReleaseXCFramework --no-daemon
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with: { distribution: temurin, java-version: '17' }
- uses: gradle/actions/setup-gradle@v4
- run: ./gradlew ktlintCheck detekt --no-daemon
2. Caching
gradle/actions/setup-gradle@v4 already caches the Gradle build cache, configuration cache, and wrapper. For Kotlin/Native, add:
- name: Cache konan
uses: actions/cache@v4
with:
path: ~/.konan
key: konan-${{ runner.os }}-${{ hashFiles('**/*.gradle.kts', 'gradle/libs.versions.toml') }}
restore-keys: konan-${{ runner.os }}-
~/.konan holds the Kotlin/Native toolchain and precompiled platform libs — ~2 GB, but saves 5-10 min per macOS job.
3. Android app build + instrumentation
android-app:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with: { distribution: temurin, java-version: '17' }
- uses: gradle/actions/setup-gradle@v4
- run: ./gradlew :androidApp:assembleRelease --no-daemon
- uses: actions/upload-artifact@v4
with: { name: android-apk, path: androidApp/build/outputs/apk/release/*.apk }
4. Publishing to Maven Central
publish:
if: startsWith(github.ref, 'refs/tags/v')
runs-on: macos-14
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with: { distribution: temurin, java-version: '17' }
- uses: gradle/actions/setup-gradle@v4
- env:
ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.OSSRH_USERNAME }}
ORG_GRADLE_PROJECT_mavenCentralPassword: ${{ secrets.OSSRH_PASSWORD }}
ORG_GRADLE_PROJECT_signingInMemoryKey: ${{ secrets.SIGNING_KEY }}
ORG_GRADLE_PROJECT_signingInMemoryKeyPassword: ${{ secrets.SIGNING_KEY_PASSWORD }}
run: ./gradlew publishAllPublicationsToMavenCentralRepository --no-daemon --no-configuration-cache
Use the vanniktech Maven publish plugin, which handles all KMP publications (kotlinMultiplatform, androidRelease, iosArm64, etc.) out of the box.
5. XCFramework → Swift Package Manager
Publish the release XCFramework as a GitHub release asset and point a Package.swift at it:
// Package.swift in a separate repo my-shared-swift
let package = Package(
name: "Shared",
platforms: [.iOS(.v14)],
products: [.library(name: "Shared", targets: ["Shared"])],
targets: [
.binaryTarget(
name: "Shared",
url: "https://github.com/me/my-kmp/releases/download/v1.2.3/Shared.xcframework.zip",
checksum: "…compute via `swift package compute-checksum`…"
),
]
)
Automate the release:
- name: Zip XCFramework
run: |
cd shared/build/XCFrameworks/release
zip -r Shared.xcframework.zip Shared.xcframework
- name: Compute checksum
id: sum
run: echo "sum=$(swift package compute-checksum shared/build/XCFrameworks/release/Shared.xcframework.zip)" >> $GITHUB_OUTPUT
- uses: softprops/action-gh-release@v2
with:
files: shared/build/XCFrameworks/release/Shared.xcframework.zip
body: |
XCFramework checksum: `${{ steps.sum.outputs.sum }}`
Then open a PR to the SPM repo bumping URL + checksum.
6. CocoaPods publishing (only if consumers still use pods)
- run: ./gradlew :shared:podPublishReleaseXCFramework --no-daemon
- run: pod trunk push shared/build/cocoapods/publish/release/Shared.podspec
env:
COCOAPODS_TRUNK_TOKEN: ${{ secrets.COCOAPODS_TRUNK_TOKEN }}
7. Release hygiene
- Tag with semver (
v1.2.3); the publish workflow keys on tags. - Fail builds on XCFramework size growth beyond a threshold (e.g. +10%).
- Keep one linting job (
ktlintCheck,detekt) required for PR merges. - Gradle configuration cache should be on in CI; if a publish task breaks it, pass
--no-configuration-cacheonly to that job.
Checklist
- JVM/Android/JS jobs run on
ubuntu-latest; iOS onmacos-14(or later). -
~/.konancached — macOS jobs noticeably faster. - Lint + tests required for PR merge.
- Tag-triggered publish job pushes to Maven Central and (if used) SPM / CocoaPods.
- XCFramework zipped and checksummed; SPM
Package.swiftpoints to a stable release URL. - Secrets (signing key, OSSRH, trunk token) stored in GitHub Actions secrets, never in the repo.
- CI matrix cancels on new pushes via the
concurrencyblock.