Kotlin Multiplatform 애플리케이션의 지속적 통합을 위한 GitHub Actions 설정
이 가이드는 GitHub Actions로 설정된 Kotlin Multiplatform 애플리케이션의 지속적 통합(CI, Continuous Integration) 예시를 보여줍니다. main 브랜치에 대한 모든 푸시(push) 또는 풀 리퀘스트(pull request) 발생 시 공통 테스트를 실행하고 Android, iOS 및 데스크톱용 아티팩트(artifact)를 빌드하는 워크플로를 설정하게 됩니다.
이 가이드는 Jetcaster KMP 샘플을 기반으로 합니다. 레포지토리에서 액션 및 워크플로 설정을 확인하거나, 아래의 단계별 설명을 따라갈 수 있습니다.
이 가이드에서는 CI를 두 부분으로 나누어 설정하는 방법을 제안합니다:
- Java 및 Gradle을 설정하는 재사용 가능한 컴포지트 GitHub 액션(composite GitHub Action)
main브랜치에 대한 모든 푸시 또는 풀 리퀘스트 시 테스트를 실행하고 플랫폼별 빌드를 트리거하는 메인 GitHub Actions 워크플로
Gradle 설정을 위한 컴포지트 액션 생성
여러 잡(job)에서 Java 및 Gradle 구성을 동기화하기 위해 컴포지트 액션(composite action)을 생성합니다. 모든 빌드에 동일한 구성이 사용되도록 워크플로 잡에서 이 액션을 재사용하게 됩니다.
이 예시에서 액션은 Java 17을 설치하고 기본 Gradle 버전을 구성합니다. 액션을 설정하려면 .github/actions/gradle-setup/action.yml 파일을 생성하세요:
name: gradle-setup
description: Setup Java and Gradle
runs:
using: "composite"
steps:
- name: Setup Java
uses: actions/[email protected]
with:
java-version: "17"
distribution: "temurin"
- name: Setup Gradle
uses: gradle/actions/[email protected]빌드 워크플로 정의
워크플로가 실행되는 시점을 정의하고 Gradle 옵션을 구성합니다:
- 워크플로는
main브랜치에 대한 모든 푸시 또는 풀 리퀘스트 시 실행되어야 합니다. - Gradle 옵션은 Gradle 데몬(daemon)을 비활성화하고 캐싱을 포함한 병렬 실행을 활성화해야 합니다.
기본 구성을 포함하여 .github/workflows/build.yml 파일을 생성하세요:
name: Build
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
workflow_dispatch:
env:
GRADLE_OPTS: "-Dorg.gradle.jvmargs=-Xmx4096M -Dorg.gradle.daemon=false -Dorg.gradle.parallel=true -Dorg.gradle.caching=true"이 구성을 사용하면 workflow_dispatch를 사용하여 워크플로를 수동으로 트리거할 수도 있습니다.
이제 테스트를 실행하고 애플리케이션 아티팩트를 빌드하는 잡을 추가할 수 있습니다.
공통 테스트 실행
이 잡은 모든 플랫폼용 앱을 빌드하기 전에 변경 사항을 검증하기 위해 jvmTest Gradle 태스크를 사용하여 테스트를 실행합니다:
- 테스트를 실행할 레포지토리를 체크아웃(check out)합니다.
- 앞서 준비한 컴포지트
gradle-setup액션을 사용하여 Java와 Gradle을 설정합니다. ./gradlew명령으로 테스트를 실행합니다.- 테스트 리포트를
**/build/reports/tests/디렉터리에 아티팩트로 업로드합니다.
이 잡을 설정하려면 .github/workflows/build.yml 파일에 다음 내용을 추가하세요:
jobs:
test:
name: Run tests
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Gradle setup
uses: ./.github/actions/gradle-setup
- name: Run unit tests
run: ./gradlew jvmTest
- name: Upload test reports
uses: actions/upload-artifact@v4
with:
name: test-reports
path: "**/build/reports/tests/"테스트가 실행되면 워크플로는 애플리케이션 아티팩트를 빌드해야 합니다.
Android 디버그 패키지 빌드
이 잡은 :mobile:assembleDebug Gradle 태스크를 사용하여 Android 디버그 APK를 빌드합니다:
- 패키지를 빌드할 레포지토리를 체크아웃합니다.
- 앞서 준비한 컴포지트
gradle-setup액션을 사용하여 Java와 Gradle을 설정합니다. ./gradlew명령으로 APK를 빌드합니다.mobile/build/outputs/apk/debug/디렉터리에서 빌드된 패키지를 업로드합니다.
.github/workflows/build.yml 파일의 jobs 섹션을 이어서 다음과 같이 작성하세요:
jobs:
# ...
build-android:
name: Build Android
runs-on: ubuntu-latest
needs: test
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Gradle setup
uses: ./.github/actions/gradle-setup
- name: Build Android debug APK
run: ./gradlew :mobile:assembleDebug
- name: Upload Android debug APK
uses: actions/upload-artifact@v4
with:
name: android-apk
path: mobile/build/outputs/apk/debug/*.apkiOS 시뮬레이터 애플리케이션 빌드
이 잡은 앱에 정식으로 서명(signing)해야 하는 번거로움을 피하기 위해 iOS 시뮬레이터를 대상으로 합니다. 애플리케이션은 xcodebuild를 사용하여 빌드됩니다:
- 애플리케이션을 빌드할 레포지토리를 체크아웃합니다.
- 앞서 준비한 컴포지트
gradle-setup액션을 사용하여 Java와 Gradle을 설정합니다. xcodebuild를 사용하여 iOS 애플리케이션을 빌드합니다. 예시는 Jetcaster KMP 샘플에 사용된 옵션을 보여줍니다.- 빌드된 애플리케이션이 포함된 폴더(
build/Build/Products/Debug-iphonesimulator/*내부의 모든 항목)를 아티팩트로 업로드합니다.
iOS 애플리케이션은 xcodebuild가 포함된 macOS 러너(runner, macos-latest)에서 빌드됩니다.
.github/workflows/build.yml 파일을 계속 수정합니다:
jobs:
#...
build-ios:
name: Build iOS simulator app
runs-on: macos-latest
needs: test
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Gradle setup
uses: ./.github/actions/gradle-setup
- name: Build iOS simulator app
run: |
xcodebuild build \
-project JetcasterMigration/JetcasterMigration.xcodeproj \
-configuration Debug \
-scheme JetcasterMigration \
-sdk iphonesimulator \
-derivedDataPath ./build \
-verbose
- name: Upload app folder
uses: actions/upload-artifact@v4
with:
name: iphonesimulator-app
path: build/Build/Products/Debug-iphonesimulator/*CI 푸시 및 테스트
CI 워크플로는 워크플로 구성을 main 브랜치에 푸시하거나 이러한 구성 파일이 포함된 풀 리퀘스트를 생성할 때 처음으로 트리거됩니다.
레포지토리의 Actions 탭에서 워크플로 결과를 확인하여 모든 것이 올바르게 작동하는지 검증할 수 있습니다.
워크플로를 수동으로 트리거할 수도 있다는 점을 기억하세요. 왼쪽의 액션 목록에서 워크플로를 선택하고 Run workflow를 클릭하면 됩니다.
다음 단계
전체 CI 구성 예시는 macOS, Windows 및 Linux용 데스크톱 JVM 애플리케이션 빌드 잡도 포함하고 있는 Jetcaster 샘플을 참조하세요.
GitHub Actions를 사용하여 앱 스토어에 애플리케이션을 게시하는 방법에 대한 안내는 이 주제에 관한 Marco Gomiero의 포스트 시리즈를 참조하세요.
