Capacitor 앱의 CI/CD 설정은 복잡하고 시간이 많이 걸릴 수 있습니다. 다음 내용을 확인해 보세요:
신규 빌드 권장 사항: Capgo Build 사용
이제 다음을 권장합니다: Capgo CLI를 활용한 Capgo Build native Capacitor 빌드를 위해. 이 Fastlane 가이드는 기존 GitHub Actions 파이프라인을 유지 관리하는 팀을 위한 것입니다. 하지만 새로운 Android 빌드는 Capgo CLI를 사용하는 것이 좋습니다. 그래야 Fastlane, Gradle runner, keystore, upload 스크립트를 직접 관리할 필요가 없습니다.
사전 요구사항
시작하기 전에 다음 설정을 완료해야 합니다:
- 관리자 권한이 있는 GitHub 계정
- 올바른 서명으로 Google Play Store에 이미 출시된 앱
- Android 서명 키 및 keystore 파일
- Play Store API가 활성화된 Google Cloud Console 프로젝트
- 적절한 권한을 가진 서비스 계정
- GitHub Actions 워크플로우 이해하기
- Fastlane 설정에 대한 지식
- 파이프라인 유지 관리 및 디버깅 시간
Capgo이 제공하는 CI/CD용 Capgo Build
Fastlane, Gradle runner, keystore, upload-script 유지 관리를 건너뛰세요. Capgo 빌드 기존 CI/CD 파이프라인에서 서명된 네이티브 Android 빌드를 실행합니다:
- 기존 파이프라인과 완벽하게 연동: 웹 빌드 완료 후 GitHub Actions, GitLab CI, Jenkins 또는 로컬 스크립트를 통해 Capgo Build를 트리거하고
npx cap sync. - CI secrets를 통한 서명 처리: Android keystore, key alias, 비밀번호 및 Play Console 서비스 계정 JSON을 자체 CI secrets에서 안전하게 관리하세요.
- Native runner 관리 부담 없음: Capgo Build는 관리형 Android 빌드 환경을 제공하므로, SDK 이미지나 Gradle 캐시 문제, Fastlane lane을 직접 관리할 필요가 없습니다.
- 아티팩트 및 제출: QA용 서명된 아티팩트를 다운로드하거나 Capgo CLI을 통해 릴리스 빌드를 제출하세요.
요금제
- Capgo 플랜은 월 $12부터 시작합니다
- OTA 업데이트 및 월 약 15회의 Native Build 포함
- 추가 빌드 시간은 크레딧을 통해 분 단위로 과금됩니다
수동 설정 가이드
다음 단계를 따라 진행하세요:
GitHub Actions 가격 안내

GitHub Actions는 저장소 유형에 따라 무료 사용 시간을 제공합니다:
- Public 저장소: 월 2,000분
- Private 저장소: 월 2,000분 (Linux runner 기준)
Private 프로젝트의 경우 분당 약 $0.008의 비용이 발생합니다. 일반적인 빌드에는 3~5분이 소요됩니다.
수동 설정 단계
- Android Keystore 생성
- Google Play 서비스 계정 설정
- Fastlane 설정
- GitHub secrets 구성하기
- GitHub Actions 워크플로 생성
1. Android Keystore 생성
Android 앱을 서명하고 배포하려면 keystore 파일이 필요합니다. 이는 최초 1회만 설정하면 됩니다.
keytool로 Keystore 생성하기
터미널에서 다음 명령어를 실행하세요:
keytool -genkey -v -keystore my-release-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000
다음 항목을 입력해야 합니다:
- Keystore 비밀번호: 강력한 비밀번호를 설정하세요 (나중에
KEYSTORE_STORE_PASSWORD) - Key 비밀번호: 강력한 비밀번호를 설정하세요 (나중에
KEYSTORE_KEY_PASSWORD) - 이름, 조직 등: 상세 정보를 입력하세요
주의사항
-
이 값들을 안전하게 보관하세요:
- Keystore 파일 경로 (예:)
my-release-key.keystore) - Key alias (예:
my-key-alias) - 다음 용도로 필요합니다:KEYSTORE_KEY_ALIAS - Keystore password - 다음 용도로 필요합니다:
KEYSTORE_STORE_PASSWORD - Key password - 다음 용도로 필요합니다:
KEYSTORE_KEY_PASSWORD
- Keystore 파일 경로 (예:)
-
Keystore 파일 백업: 분실 시 출시된 앱을 업데이트할 수 없습니다
-
보안 유지: Keystore 파일을 git에 커밋하지 마세요
-
안전하게 보관: 보안이 유지되는 여러 곳에 백업본을 보관하세요
대안: 기존 Keystore 사용
이미 앱을 출시했다면, 처음에 사용했던 것과 동일한 keystore를 사용해야 합니다. 위치는 다음과 같습니다:
- 앱을 처음 빌드했던 로컬 환경에서
- Play Console → 설정 → 앱 서명 (Google Play 앱 서명을 사용하는 경우)
2. Google Play 서비스 계정 설정
GitHub Actions가 Google Play에 빌드를 upload 할 수 있도록 서비스 계정이 필요합니다.
단계 2.1: Google Cloud 프로젝트 생성
- 다음으로 이동: Google Cloud Console
- 새 프로젝트를 생성하거나 기존 프로젝트를 선택하세요
- 프로젝트 ID를 확인하세요
단계 2.2: Google Play Developer API 활성화
- Google Cloud Console에서 다음으로 이동하세요 API 및 서비스 → 라이브러리
- “Google Play Android Developer API” 검색
- 클릭 활성화
2.3단계: 서비스 계정 생성
- 다음으로 이동: IAM 및 관리자 → 서비스 계정
- 클릭 서비스 계정 만들기
- 상세 정보 입력:
- 이름:
github-actions-uploader - 설명: “GitHub Actions에서 빌드를 업로드하기 위한 서비스 계정”
- 이름:
- 클릭 만들기 및 계속하기
- 지금은 역할 할당 건너뛰기 (클릭 계속하기, 그 다음 완료)
단계 2.4: 서비스 계정 키 생성
- 새로 생성된 서비스 계정을 클릭하세요
- 다음으로 이동: 키 탭
- 클릭 키 추가 → 새 키 생성
- 선택 JSON 형식
- 클릭 생성
- JSON 파일이 다운로드됩니다 - 안전한 곳에 저장하세요, 나중에 필요합니다
단계 2.5: Play Console 액세스 권한 부여
- 다음으로 이동: Google Play Console
- 다음으로 이동: 설정 → API 액세스
- 아래 서비스 계정, 클릭하여 액세스 권한 부여 서비스 계정에 대한
- 한편, 앱 권한 탭, 앱 추가
- 한편, 계정 권한 탭, 다음 권한을 부여하세요:
- 앱 정보 조회 및 대량 보고서 다운로드 (읽기 전용)
- 초안 앱 생성, 수정 및 삭제
- 테스트 트랙에 앱 출시
- 프로덕션, 제외 및 기타 트랙에 앱 출시
- 클릭 사용자 초대
- 클릭 초대장 보내기
단계 2.6: JSON 키 확인
다운로드한 JSON 파일은 다음과 같은 형태여야 합니다:
{
"type": "service_account",
"project_id": "your-project-id",
"private_key_id": "...",
"private_key": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n",
"client_email": "github-actions-uploader@your-project-id.iam.gserviceaccount.com",
"client_id": "...",
"auth_uri": "https://accounts.google.com/o/oauth2/auth",
"token_uri": "https://oauth2.googleapis.com/token",
"auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
"client_x509_cert_url": "..."
}
GitHub secrets 설정 단계에서 이 파일을 base64로 변환하게 됩니다.
3. Fastlane 설정
프로젝트 루트 디렉토리에 fastlane 프로젝트 루트 폴더에 다음을 추가합니다: Fastfile 다음 내용으로 작성하세요:
default_platform(:android)
KEYSTORE_KEY_ALIAS = ENV["KEYSTORE_KEY_ALIAS"]
KEYSTORE_KEY_PASSWORD = ENV["KEYSTORE_KEY_PASSWORD"]
KEYSTORE_STORE_PASSWORD = ENV["KEYSTORE_STORE_PASSWORD"]
platform :android do
desc "Deploy a beta version to the Google Play"
private_lane :verify_changelog_exists do |version_code: |
changelog_path = "android/metadata/en-US/changelogs/#{version_code}.txt"
UI.user_error!("Missing changelog file at #{changelog_path}") unless File.exist?(changelog_path)
UI.message("Changelog exists for version code #{version_code}")
end
private_lane :verify_upload_to_staging do |version_name: |
UI.message "Skipping staging verification step"
end
lane :beta do
keystore_path = "#{Dir.tmpdir}/build_keystore.keystore"
File.write(keystore_path, Base64.decode64(ENV['ANDROID_KEYSTORE_FILE']))
json_key_data = Base64.decode64(ENV['PLAY_CONFIG_JSON'])
# Get previous build number and increment
previous_build_number = google_play_track_version_codes(
package_name: ENV['DEVELOPER_PACKAGE_NAME'],
track: "internal",
json_key_data: json_key_data,
)[0]
current_build_number = previous_build_number + 1
sh("export NEW_BUILD_NUMBER=#{current_build_number}")
# Build the app
gradle(
task: "clean bundleRelease",
project_dir: 'android/',
print_command: false,
properties: {
"android.injected.signing.store.file" => "#{keystore_path}",
"android.injected.signing.store.password" => "#{KEYSTORE_STORE_PASSWORD}",
"android.injected.signing.key.alias" => "#{KEYSTORE_KEY_ALIAS}",
"android.injected.signing.key.password" => "#{KEYSTORE_KEY_PASSWORD}",
'versionCode' => current_build_number
})
# Upload to Play Store
upload_to_play_store(
package_name: ENV['DEVELOPER_PACKAGE_NAME'],
json_key_data: json_key_data,
track: 'internal',
release_status: 'completed',
skip_upload_metadata: true,
skip_upload_changelogs: true,
skip_upload_images: true,
skip_upload_screenshots: true,
)
end
end
4. GitHub Secrets 설정
keystore와 서비스 계정 JSON이 준비되었으므로, 이제 이를 GitHub에 안전하게 저장해야 합니다.
단계 4.1: GitHub Secrets 접속
- GitHub의 리포지토리로 이동합니다
- 클릭 설정 → Secrets 및 변수 → 액션
- 클릭 새로운 repository secret
단계 4.2: 필수 Secret 추가
다음 Secret을 하나씩 추가하세요:
PLAY_CONFIG_JSON
- 단계 2.4에서 다운로드한 서비스 계정 JSON 파일을 사용하세요
- base64로 변환하세요:
macOS/Linux의 경우:
base64 service_account_key.json | pbcopy
Windows (PowerShell)의 경우:
[Convert]::ToBase64String([IO.File]::ReadAllBytes("service_account_key.json")) | Set-Clipboard
- 다음 이름으로 새 Secret을 생성하고
PLAY_CONFIG_JSONbase64 문자열을 붙여넣으세요
ANDROID_KEYSTORE_FILE
- keystore를 base64로 변환하세요:
macOS/Linux의 경우:
base64 my-release-key.keystore | pbcopy
Windows (PowerShell)의 경우:
[Convert]::ToBase64String([IO.File]::ReadAllBytes("my-release-key.keystore")) | Set-Clipboard
- 다음 이름으로 새 Secret을 생성하고
ANDROID_KEYSTORE_FILEbase64 문자열을 붙여넣으세요
KEYSTORE_KEY_ALIAS
keystore 생성 시 사용한 key alias로 새 secret을 만드세요 (예: my-key-alias)
KEYSTORE_KEY_PASSWORD
keystore 생성 시 설정한 key password로 새 secret을 만드세요
KEYSTORE_STORE_PASSWORD
keystore 생성 시 설정한 keystore 비밀번호로 새로운 secret을 생성하세요
DEVELOPER_PACKAGE_NAME
앱의 package name을 사용하여 새로운 secret을 생성하세요 (예: com.example.app)
package name은 다음에서 확인할 수 있습니다: android/app/build.gradle 하위 applicationId
4.3단계: 모든 Secret 확인
다음 6개의 secret이 모두 설정되었는지 확인하세요:
- ✅ PLAY_CONFIG_JSON
- ✅ ANDROID_KEYSTORE_FILE
- ✅ KEYSTORE_KEY_ALIAS
- ✅ KEYSTORE_KEY_PASSWORD
- ✅ KEYSTORE_STORE_PASSWORD
- ✅ DEVELOPER_PACKAGE_NAME
5. GitHub Actions 워크플로 생성
생성 .github/workflows/build-upload-android.yml:
name: Build and Deploy Android App
on:
push:
tags:
- '*'
jobs:
build_android:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Setup Node.js
uses: actions/setup-node@v6
with:
node-version: 24
cache: npm
- name: Install dependencies
run: npm ci
- name: Cache Gradle
uses: actions/cache@v5
with:
path: |
~/.gradle/caches
~/.gradle/wrapper
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
restore-keys: |
${{ runner.os }}-gradle-
- name: Build app
run: npm run build
- name: Sync Capacitor
run: npx cap sync
- name: Setup Java
uses: actions/setup-node@v5
with:
distribution: 'zulu'
java-version: '17'
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.0'
bundler-cache: true
- name: Run Fastlane
uses: maierj/fastlane-action@v3.1.0
env:
PLAY_CONFIG_JSON: ${{ secrets.PLAY_CONFIG_JSON }}
ANDROID_KEYSTORE_FILE: ${{ secrets.ANDROID_KEYSTORE_FILE }}
DEVELOPER_PACKAGE_NAME: ${{ secrets.DEVELOPER_PACKAGE_NAME }}
KEYSTORE_KEY_ALIAS: ${{ secrets.KEYSTORE_KEY_ALIAS }}
KEYSTORE_KEY_PASSWORD: ${{ secrets.KEYSTORE_KEY_PASSWORD }}
KEYSTORE_STORE_PASSWORD: ${{ secrets.KEYSTORE_STORE_PASSWORD }}
with:
lane: android beta
- name: Upload artifact
uses: actions/upload-artifact@v2
with:
name: android-release
path: ./android/app/build/outputs/bundle/release/app-release.aab
retention-days: 10
작동 원리
- 워크플로 실행을 위한 Git tag 생성
- GitHub Actions가 앱을 빌드합니다
- Fastlane을 통해 Google Play 베타 채널로 업로드
- 앱이 자동으로 업데이트됩니다
빌드 시간 및 비용
- 빌드 시간: 3-5분
- 프라이빗 레포 비용: 빌드당 약 $0.04
- 오픈 소스 프로젝트 무료 이용
관련 문서
CI/CD 설정 가이드
- GitHub Actions를 활용한 자동 Capacitor iOS Build - iOS CI/CD 전체 설정 가이드
- GitHub Actions를 활용한 자동 Build 및 Release 구현하기 - 전체 CI/CD 파이프라인 튜토리얼
- GitHub Actions로 개발 및 프로덕션 빌드 관리하기 - 환경 관리
대체 CI/CD 플랫폼
- GitLab CI로 빌드하기 - Android를 위한 GitLab 대안
- CodeMagic으로 빌드하기 - CodeMagic 설정 가이드
Live Updates 및 배포
- Capgo Live Updates 문서 - 앱에 OTA 업데이트 추가
- Capgo를 활용한 CI/CD 통합 - 파이프라인에 Live Update 통합
리소스
GitHub actions를 이용한 자동 Capacitor Android build 그 이상
사용 중이라면 GitHub actions를 이용한 자동 Capacitor Android build CI/CD 자동화를 계획하려면, 다음을 연결하세요 Capgo CI/CD 설정하기 Capgo CI/CD의 제품 워크플로우용, Capgo Native Build Capgo Native Builds의 제품 워크플로우용, Capgo 연동 서비스 Capgo Integrations의 제품 워크플로우용, CI/CD 통합 CI/CD Integration의 구현 세부 사항은, 그리고 GitHub Actions 연동 GitHub Actions Integration의 구현 세부 사항을 참고하세요.