Flutter 튜토리얼 65편: CI/CD 설정 - 자동화된 빌드와 배포 파이프라인 구축
요약
핵심 요지
- 문제 정의: 수동 빌드와 배포는 시간이 많이 걸리고 휴먼 에러가 발생하기 쉽다.
- 핵심 주장: CI/CD 파이프라인을 구축하면 빌드, 테스트, 배포 과정을 자동화하여 개발 효율성과 안정성을 높일 수 있다.
- 주요 근거: Flutter 공식 문서에서 소개하는 fastlane, Codemagic, GitHub Actions 등의 도구를 활용한다.
- 한계: 초기 설정에 시간이 필요하며, 각 플랫폼별 인증서와 프로비저닝 관리가 복잡할 수 있다.
문서가 설명하는 범위
- CI/CD의 개념과 Flutter 앱에서의 필요성
- fastlane을 사용한 로컬 빌드 자동화
- 주요 CI/CD 서비스 비교 및 설정
- GitHub Actions를 활용한 실전 파이프라인 구축
읽는 시간: 30분 | 난이도: 고급
참고 자료
- Continuous delivery with Flutter - Flutter 공식 CI/CD 가이드
문제 상황
Flutter 앱을 App Store와 Google Play에 배포하려면 여러 단계를 거쳐야 합니다. 수동으로 진행하면 빌드 명령 실행, 인증서 관리, 스토어 업로드 등 반복적인 작업이 발생합니다.
기존 방식의 한계
# 수동 배포 과정 - iOSflutter build ipa --release# Xcode에서 Archive# App Store Connect에 업로드# 메타데이터 수동 입력# 심사 제출
# 수동 배포 과정 - Androidflutter build appbundle --release# Google Play Console 접속# 앱 번들 업로드# 릴리스 노트 작성# 출시문제는 다음과 같습니다.
- 매번 동일한 명령을 반복해야 한다
- 휴먼 에러로 잘못된 빌드가 배포될 수 있다
- 여러 환경(개발, 스테이징, 프로덕션)별 빌드 관리가 어렵다
- 팀원 간 빌드 환경 차이로 문제가 발생할 수 있다
해결 방법
챕터 1: CI/CD 개념 이해
Why
NOTE
CI/CD1는 코드 변경 시 자동으로 빌드, 테스트, 배포가 진행되는 방식입니다. 개발자는 코드 작성에 집중하고, 반복적인 작업은 자동화 시스템이 처리합니다.
What
NOTECI/CD는 두 가지 개념으로 구성됩니다.
flowchart LR subgraph CI["CI - 지속적 통합"] A[코드 Push] B[자동 빌드] C[자동 테스트] end subgraph CD["CD - 지속적 배포"] D[릴리스 빌드] E[스토어 업로드] F[심사 제출] end A --> B --> C --> D --> E --> F
용어 영문 설명 CI Continuous Integration 코드 변경을 자주 통합하고 자동으로 빌드/테스트 CD Continuous Delivery 언제든 배포 가능한 상태 유지 CD Continuous Deployment 자동으로 프로덕션까지 배포
How
TIPFlutter 앱의 일반적인 CI/CD 파이프라인 구성입니다.
# 파이프라인 단계stages:- lint # 코드 스타일 검사- test # 단위/위젯 테스트- build # 앱 빌드- deploy # 스토어 배포// 각 단계에서 실행되는 명령// 1. Lint// flutter analyze// dart format --set-exit-if-changed .// 2. Test// flutter test// 3. Build// flutter build ipa --release// flutter build appbundle --release// 4. Deploy// fastlane ios release// fastlane android release
Watch out
WARNINGCI/CD를 도입한다고 모든 문제가 해결되는 것은 아닙니다. 테스트 커버리지가 낮으면 CI를 통과해도 버그가 배포될 수 있습니다. 자동화와 함께 테스트 품질도 관리해야 합니다.
결론: CI/CD는 빌드, 테스트, 배포 과정을 자동화하여 개발 효율성과 안정성을 높인다.
챕터 2: fastlane 기초 설정
Why
NOTE
fastlane2은 iOS와 Android 앱의 빌드와 배포를 자동화하는 도구입니다. 로컬에서도 사용할 수 있고, CI/CD 서비스와 통합하여 사용할 수도 있습니다.
What
NOTEfastlane은 Ruby 기반 도구로, lane이라는 단위로 작업을 정의합니다.
flowchart TD subgraph fastlane F[Fastfile] L1[beta lane] L2[release lane] A1[build_app] A2[upload_to_testflight] A3[upload_to_play_store] end F --> L1 F --> L2 L1 --> A1 --> A2 L2 --> A1 --> A3
파일 역할 Fastfilelane 정의 파일 Appfile앱 ID, 팀 ID 등 설정 Matchfile코드 서명 인증서 관리 설정
How
TIPfastlane 설치 및 초기 설정 방법입니다.
Terminal window # macOS에서 fastlane 설치brew install fastlane# 또는 gem으로 설치gem install fastlane# iOS 프로젝트 초기화cd iosfastlane init# Android 프로젝트 초기화cd androidfastlane initiOS용 기본 Fastfile 예시입니다.
# ios/fastlane/Fastfiledefault_platform(:ios)platform :ios dodesc "Push a new beta build to TestFlight"lane :beta do# 버전 증가increment_build_number(xcodeproj: "Runner.xcodeproj")# 앱 빌드build_app(workspace: "Runner.xcworkspace",scheme: "Runner",export_method: "app-store")# TestFlight 업로드upload_to_testflight(skip_waiting_for_build_processing: true)enddesc "Push a new release build to App Store"lane :release dobuild_app(workspace: "Runner.xcworkspace",scheme: "Runner",export_method: "app-store")upload_to_app_store(skip_metadata: true,skip_screenshots: true)endendAndroid용 기본 Fastfile 예시입니다.
# android/fastlane/Fastfiledefault_platform(:android)platform :android dodesc "Deploy a new beta build to Play Store Internal Track"lane :beta do# Flutter 빌드sh("flutter build appbundle --release")# Play Store 업로드upload_to_play_store(track: "internal",aab: "../build/app/outputs/bundle/release/app-release.aab")enddesc "Deploy a new release build to Play Store"lane :release dosh("flutter build appbundle --release")upload_to_play_store(track: "production",aab: "../build/app/outputs/bundle/release/app-release.aab")endend
Watch out
WARNINGfastlane은 Ruby 환경이 필요합니다. macOS에는 Ruby가 기본 설치되어 있지만, 버전 문제가 발생할 수 있습니다.
Terminal window # Ruby 버전 관리자 설치 권장brew install rbenvrbenv install 3.2.0rbenv global 3.2.0# 환경 변수 설정echo 'eval "$(rbenv init -)"' >> ~/.zshrc
결론: fastlane을 사용하면 복잡한 빌드와 배포 과정을 간단한 명령으로 자동화할 수 있다.
챕터 3: iOS 코드 서명 자동화
Why
NOTEiOS 앱 배포의 가장 어려운 부분은
코드 서명3입니다. 인증서와 프로비저닝 프로파일을 팀원 간에 공유하고 관리하는 것이 복잡합니다.
What
NOTEfastlane match는 인증서와 프로비저닝 프로파일을 Git 저장소에서 중앙 관리합니다.
flowchart LR subgraph Team["개발팀"] D1[개발자 1] D2[개발자 2] CI[CI 서버] end subgraph Storage["저장소"] G[Git Repo] C[인증서] P[프로파일] end D1 -->|"match"| G D2 -->|"match"| G CI -->|"match"| G G --> C G --> P
타입 용도 파일 development 개발용 Development 인증서 + 프로파일 adhoc 테스트 배포용 Distribution 인증서 + Ad Hoc 프로파일 appstore 스토어 배포용 Distribution 인증서 + App Store 프로파일
How
TIPfastlane match 설정 방법입니다.
Terminal window # 비공개 Git 저장소 생성 후 match 초기화fastlane match init# 인증서 생성 및 저장소에 업로드fastlane match developmentfastlane match adhocfastlane match appstoreMatchfile 설정입니다.
# ios/fastlane/Matchfilestorage_mode("git")type("appstore") # 기본 타입app_identifier(["com.example.app"])# CI 환경에서는 readonly 모드 사용readonly(is_ci)Fastfile에서 match 사용합니다.
# ios/fastlane/Fastfileplatform :ios dolane :beta do# match로 인증서 동기화match(type: "appstore")build_app(workspace: "Runner.xcworkspace",scheme: "Runner",export_method: "app-store",export_options: {provisioningProfiles: {"com.example.app" => "match AppStore com.example.app"}})upload_to_testflightendend
Watch out
WARNINGmatch 저장소에는 민감한 정보가 포함됩니다. 반드시 비공개 저장소를 사용하고, 암호화 비밀번호를 안전하게 관리하세요.
Terminal window # 환경 변수로 비밀번호 관리export MATCH_PASSWORD="your-secure-password"# CI에서는 시크릿으로 설정# GitHub Actions: secrets.MATCH_PASSWORD# Codemagic: Environment variables
결론: fastlane match를 사용하면 팀 전체가 동일한 인증서를 공유하여 코드 서명 문제를 해결한다.
챕터 4: CI/CD 서비스 비교
Why
NOTE클라우드 기반
CI/CD 서비스4를 사용하면 빌드 서버를 직접 관리할 필요가 없습니다. 각 서비스마다 특징이 다르므로 프로젝트에 맞는 서비스를 선택해야 합니다.
What
NOTEFlutter 공식 문서에서 소개하는 주요 CI/CD 서비스입니다.
flowchart TD subgraph Apple["Apple 생태계"] XC[Xcode Cloud] end subgraph GitHub["GitHub 생태계"] GA[GitHub Actions] end subgraph Specialized["모바일 특화"] CM[Codemagic] BS[Bitrise] AC[Appcircle] end
서비스 특징 무료 플랜 Flutter 지원 Codemagic Flutter 특화, 쉬운 설정 월 500분 네이티브 Bitrise 모바일 특화, 풍부한 플러그인 월 300분 네이티브 GitHub Actions GitHub 통합, 유연한 설정 월 2000분 YAML 설정 Xcode Cloud Apple 네이티브, Xcode 통합 월 25시간 Swift/Flutter Appcircle 모바일 특화, 엔터프라이즈 기능 월 300분 네이티브
How
TIP각 서비스의 선택 기준입니다.
// 서비스 선택 가이드if (team.usesGitHub && team.wantsFlexibility) {return 'GitHub Actions';} else if (team.prefersSimplicity && team.isFlutterOnly) {return 'Codemagic';} else if (team.needsEnterprise && team.hasComplexWorkflow) {return 'Bitrise';} else if (team.isAppleCentric && team.mainlyIOS) {return 'Xcode Cloud';}각 서비스 시작 방법입니다.
Terminal window # Codemagic# 1. codemagic.io 접속# 2. GitHub/GitLab 연동# 3. Flutter 프로젝트 선택# 4. 자동 설정 완료# GitHub Actions# 1. .github/workflows/flutter.yml 생성# 2. 워크플로우 YAML 작성# 3. Secrets 설정# 4. Push하면 자동 실행
Watch out
WARNING무료 플랜의 빌드 시간 제한을 확인하세요. Flutter 앱 빌드는 시간이 오래 걸리므로 대규모 프로젝트에서는 유료 플랜이 필요할 수 있습니다.
# 빌드 시간 참고iOS 빌드: 10-20분Android 빌드: 5-15분테스트: 5-10분전체 파이프라인: 20-45분
결론: 프로젝트 규모, 팀 환경, 예산을 고려하여 적합한 CI/CD 서비스를 선택한다.
챕터 5: GitHub Actions 기본 설정
Why
NOTE
GitHub Actions5는 GitHub에 내장된 CI/CD 서비스입니다. 추가 서비스 가입 없이 GitHub 저장소에서 바로 사용할 수 있습니다.
What
NOTEGitHub Actions는 워크플로우 파일로 CI/CD를 정의합니다.
flowchart TD subgraph Workflow["Workflow"] T[Trigger] J1[Job 1] J2[Job 2] end subgraph Job["Job"] S1[Step 1] S2[Step 2] S3[Step 3] end T -->|"on: push"| J1 T -->|"on: push"| J2 J1 --> S1 --> S2 --> S3
개념 설명 예시 Workflow 자동화 프로세스 전체 flutter.ymlJob 동일 러너에서 실행되는 단위 build-android,build-iosStep Job 내의 개별 작업 flutter test,flutter buildAction 재사용 가능한 작업 단위 actions/checkout@v4
How
TIP기본 Flutter CI 워크플로우입니다.
.github/workflows/flutter-ci.yml name: Flutter CIon:push:branches: [main, develop]pull_request:branches: [main]jobs:analyze-and-test:runs-on: ubuntu-lateststeps:- name: Checkoutuses: actions/checkout@v4- name: Setup Flutteruses: subosito/flutter-action@v2with:flutter-version: "3.27.0"channel: "stable"cache: true- name: Get dependenciesrun: flutter pub get- name: Analyzerun: flutter analyze- name: Format checkrun: dart format --set-exit-if-changed .- name: Run testsrun: flutter test --coverage- name: Upload coverageuses: codecov/codecov-action@v3with:file: coverage/lcov.infoAndroid 빌드 Job입니다.
build-android:needs: analyze-and-testruns-on: ubuntu-lateststeps:- name: Checkoutuses: actions/checkout@v4- name: Setup Javauses: actions/setup-java@v4with:distribution: "zulu"java-version: "17"- name: Setup Flutteruses: subosito/flutter-action@v2with:flutter-version: "3.27.0"channel: "stable"cache: true- name: Get dependenciesrun: flutter pub get- name: Build APKrun: flutter build apk --release- name: Build App Bundlerun: flutter build appbundle --release- name: Upload APKuses: actions/upload-artifact@v4with:name: android-apkpath: build/app/outputs/flutter-apk/app-release.apk- name: Upload AABuses: actions/upload-artifact@v4with:name: android-aabpath: build/app/outputs/bundle/release/app-release.aab
Watch out
WARNINGGitHub Actions의 무료 플랜은 Linux 러너만 무료입니다. iOS 빌드에 필요한 macOS 러너는 분당 비용이 10배 더 높습니다.
# 러너별 비용 (분당)runs-on: ubuntu-latest # 무료 2000분 포함runs-on: macos-latest # 무료 200분 포함 (10배 비용)runs-on: windows-latest # 무료 1000분 포함 (2배 비용)
결론: GitHub Actions를 사용하면 별도 서비스 없이 GitHub 내에서 CI/CD를 구축할 수 있다.
챕터 6: iOS 빌드 자동화
Why
NOTEiOS 빌드는 macOS에서만 가능하고, 코드 서명이 필요합니다. CI 환경에서 이를 자동화하려면 인증서와 프로파일을 안전하게 관리해야 합니다.
What
NOTEiOS 빌드 파이프라인의 구조입니다.
flowchart LR subgraph CI["CI 환경"] C[Checkout] M[match] B[Build] U[Upload] end subgraph Secrets["Secrets"] S1[MATCH_PASSWORD] S2[APP_STORE_CONNECT_API_KEY] S3[DEPLOY_KEY] end Secrets --> M C --> M --> B --> U
시크릿 용도 MATCH_PASSWORD인증서 저장소 암호화 키 MATCH_GIT_BASIC_AUTHORIZATION인증서 저장소 접근 토큰 APP_STORE_CONNECT_API_KEYApp Store Connect API 인증
How
TIPGitHub Actions에서 iOS 빌드 및 배포 설정입니다.
.github/workflows/ios-release.yml name: iOS Releaseon:push:tags:- "v*"jobs:build-ios:runs-on: macos-lateststeps:- name: Checkoutuses: actions/checkout@v4- name: Setup Flutteruses: subosito/flutter-action@v2with:flutter-version: "3.27.0"channel: "stable"cache: true- name: Setup Rubyuses: ruby/setup-ruby@v1with:ruby-version: "3.2"bundler-cache: trueworking-directory: ios- name: Install fastlanerun: |cd iosbundle install- name: Setup SSH for matchwith:ssh-private-key: ${{ secrets.MATCH_DEPLOY_KEY }}- name: Get dependenciesrun: flutter pub get- name: Build and deployenv:MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}APP_STORE_CONNECT_API_KEY_ID: ${{ secrets.ASC_KEY_ID }}APP_STORE_CONNECT_API_ISSUER_ID: ${{ secrets.ASC_ISSUER_ID }}APP_STORE_CONNECT_API_KEY_CONTENT: ${{ secrets.ASC_KEY_CONTENT }}run: |cd iosbundle exec fastlane betaApp Store Connect API 키를 사용하는 Fastfile입니다.
# ios/fastlane/Fastfiledefault_platform(:ios)platform :ios dobefore_all do# App Store Connect API 키 설정app_store_connect_api_key(key_id: ENV["APP_STORE_CONNECT_API_KEY_ID"],issuer_id: ENV["APP_STORE_CONNECT_API_ISSUER_ID"],key_content: ENV["APP_STORE_CONNECT_API_KEY_CONTENT"],is_key_content_base64: true)endlane :beta do# 인증서 동기화 (CI에서는 readonly)match(type: "appstore",readonly: true)# Flutter 빌드sh("flutter build ipa --release")# TestFlight 업로드upload_to_testflight(ipa: "../build/ios/ipa/Runner.ipa",skip_waiting_for_build_processing: true)endend
Watch out
WARNINGApp Store Connect API 키는 Base64로 인코딩하여 저장해야 합니다.
Terminal window # API 키 파일을 Base64로 인코딩base64 -i AuthKey_XXXXXXXXXX.p8 | pbcopy# GitHub Secrets에 붙여넣기# ASC_KEY_CONTENT: (Base64 인코딩된 값)
결론: fastlane match와 App Store Connect API를 조합하면 iOS 빌드와 배포를 완전히 자동화할 수 있다.
챕터 7: Android 빌드 자동화
Why
NOTEAndroid 앱 배포에는
서명 키6가 필요합니다. CI 환경에서 서명 키를 안전하게 관리하고 자동으로 서명된 앱을 빌드해야 합니다.
What
NOTEAndroid 빌드 파이프라인의 구조입니다.
flowchart LR subgraph CI["CI 환경"] C[Checkout] K[Keystore 복원] B[Build AAB] S[Sign] U[Upload] end subgraph Secrets["Secrets"] S1[KEYSTORE_BASE64] S2[KEY_ALIAS] S3[KEY_PASSWORD] S4[PLAY_STORE_JSON] end Secrets --> K C --> K --> B --> S --> U
시크릿 용도 KEYSTORE_BASE64서명 키스토어 (Base64 인코딩) KEY_ALIAS키 별칭 KEY_PASSWORD키 비밀번호 STORE_PASSWORD키스토어 비밀번호 PLAY_STORE_CREDENTIALSGoogle Play API 인증 JSON
How
TIPGitHub Actions에서 Android 배포 설정입니다.
.github/workflows/android-release.yml name: Android Releaseon:push:tags:- "v*"jobs:build-android:runs-on: ubuntu-lateststeps:- name: Checkoutuses: actions/checkout@v4- name: Setup Javauses: actions/setup-java@v4with:distribution: "zulu"java-version: "17"- name: Setup Flutteruses: subosito/flutter-action@v2with:flutter-version: "3.27.0"channel: "stable"cache: true- name: Setup Rubyuses: ruby/setup-ruby@v1with:ruby-version: "3.2"bundler-cache: trueworking-directory: android- name: Decode keystorerun: |echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 --decode > android/app/upload-keystore.jks- name: Create key.propertiesrun: |cat > android/key.properties << EOFstorePassword=${{ secrets.STORE_PASSWORD }}keyPassword=${{ secrets.KEY_PASSWORD }}keyAlias=${{ secrets.KEY_ALIAS }}storeFile=upload-keystore.jksEOF- name: Get dependenciesrun: flutter pub get- name: Build App Bundlerun: flutter build appbundle --release- name: Setup Play Store credentialsrun: |echo '${{ secrets.PLAY_STORE_CREDENTIALS }}' > android/play-store-credentials.json- name: Deploy to Play Storerun: |cd androidbundle exec fastlane betaAndroid용 Fastfile입니다.
# android/fastlane/Fastfiledefault_platform(:android)platform :android dolane :beta doupload_to_play_store(track: "internal",aab: "../build/app/outputs/bundle/release/app-release.aab",json_key: "play-store-credentials.json",skip_upload_metadata: true,skip_upload_images: true,skip_upload_screenshots: true)endlane :release doupload_to_play_store(track: "production",aab: "../build/app/outputs/bundle/release/app-release.aab",json_key: "play-store-credentials.json")endendbuild.gradle에서 서명 설정입니다.
android/app/build.gradle def keystoreProperties = new Properties()def keystorePropertiesFile = rootProject.file('key.properties')if (keystorePropertiesFile.exists()) {keystoreProperties.load(new FileInputStream(keystorePropertiesFile))}android {signingConfigs {release {keyAlias keystoreProperties['keyAlias']keyPassword keystoreProperties['keyPassword']storeFile file(keystoreProperties['storeFile'])storePassword keystoreProperties['storePassword']}}buildTypes {release {signingConfig signingConfigs.release}}}
Watch out
WARNING키스토어 파일을 절대 Git에 커밋하지 마세요.
.gitignore에 반드시 추가하세요.android/.gitignore key.properties*.jks*.keystoreplay-store-credentials.json
결론: 서명 키를 시크릿으로 관리하고 fastlane으로 Play Store 업로드를 자동화할 수 있다.
챕터 8: 버전 관리와 릴리스 전략
Why
NOTE앱 버전을 수동으로 관리하면 빌드 번호 충돌이나 버전 누락이 발생할 수 있습니다. CI/CD와 연동하여 버전을 자동으로 관리하면 이런 문제를 방지할 수 있습니다.
What
NOTE
시맨틱 버저닝7을 따르는 버전 관리 전략입니다.flowchart TD subgraph Version["버전 구조"] M[Major.Minor.Patch+Build] E["1.2.3+45"] end subgraph Triggers["버전 증가 트리거"] T1["호환성 깨짐 → Major"] T2["기능 추가 → Minor"] T3["버그 수정 → Patch"] T4["모든 빌드 → Build"] end M --> E T1 --> M T2 --> M T3 --> M T4 --> M
구성요소 설명 증가 시점 Major 호환성 깨지는 변경 대규모 리뉴얼 Minor 기능 추가 새 기능 릴리스 Patch 버그 수정 핫픽스 Build 빌드 번호 모든 CI 빌드
How
TIPGit 태그 기반 자동 버전 관리입니다.
.github/workflows/release.yml name: Releaseon:push:tags:- "v*.*.*"jobs:extract-version:runs-on: ubuntu-latestoutputs:version: ${{ steps.version.outputs.version }}build_number: ${{ steps.version.outputs.build_number }}steps:- name: Extract version from tagid: versionrun: |# v1.2.3 형식에서 버전 추출VERSION=${GITHUB_REF#refs/tags/v}echo "version=$VERSION" >> $GITHUB_OUTPUT# 빌드 번호는 GitHub run number 사용echo "build_number=${{ github.run_number }}" >> $GITHUB_OUTPUTbuild:needs: extract-versionruns-on: ubuntu-lateststeps:- name: Checkoutuses: actions/checkout@v4- name: Update version in pubspec.yamlrun: |VERSION="${{ needs.extract-version.outputs.version }}"BUILD="${{ needs.extract-version.outputs.build_number }}"sed -i "s/^version:.*/version: $VERSION+$BUILD/" pubspec.yaml- name: Buildrun: flutter build appbundle --releasepubspec.yaml 버전 설정입니다.
pubspec.yaml name: my_appdescription: My Flutter App# 버전 형식: major.minor.patch+build_number# CI에서 자동으로 업데이트됨version: 1.0.0+1environment:sdk: ">=3.0.0 <4.0.0"릴리스 워크플로우 예시입니다.
Terminal window # 새 버전 릴리스# 1. 변경사항 커밋git add .git commit -m "feat: add new feature"# 2. 태그 생성git tag -a v1.2.0 -m "Release version 1.2.0"# 3. 푸시 (태그 포함)git push origin main --tags# 4. CI/CD 자동 실행# - 테스트# - 빌드# - 스토어 배포
Watch out
WARNINGiOS와 Android의 빌드 번호는 항상 증가해야 합니다. 이전보다 낮은 빌드 번호로 업로드하면 스토어에서 거부됩니다.
# GitHub run_number를 사용하면 항상 증가 보장build_number: ${{ github.run_number }}# 또는 날짜 기반build_number: $(date +%Y%m%d%H%M)
결론: Git 태그와 CI/CD를 연동하면 버전 관리와 릴리스 프로세스를 자동화할 수 있다.
한계
- 복잡한 초기 설정: 인증서, API 키, 시크릿 등 초기 설정에 상당한 시간이 필요하다
- 플랫폼별 차이: iOS와 Android의 빌드/배포 방식이 달라 각각 설정해야 한다
- 비용: iOS 빌드를 위한 macOS 러너는 비용이 높고, 대규모 프로젝트는 유료 플랜이 필요하다
- 디버깅 어려움: CI 환경에서 발생하는 문제는 로컬에서 재현하기 어려울 수 있다
Footnotes
-
CI/CD(Continuous Integration/Continuous Delivery): 코드 변경을 자동으로 빌드, 테스트, 배포하는 개발 방식이다. ↩
-
fastlane(패스트레인): iOS와 Android 앱의 빌드와 배포를 자동화하는 오픈소스 도구이다. ↩
-
Code Signing(코드 서명): 앱의 출처와 무결성을 보장하기 위해 인증서로 서명하는 과정이다. ↩
-
CI/CD Service(CI/CD 서비스): 클라우드에서 빌드와 배포 파이프라인을 실행하는 서비스이다. ↩
-
GitHub Actions(깃허브 액션): GitHub에 내장된 CI/CD 및 자동화 플랫폼이다. ↩
-
Signing Key(서명 키): 앱에 디지털 서명을 하기 위한 암호화 키이다. ↩
-
Semantic Versioning(시맨틱 버저닝): Major.Minor.Patch 형식의 버전 관리 규칙이다. ↩
공유
이 글이 도움이 되었다면 다른 사람과 공유해주세요!