CI/CD를 위한 Capacitor 앱 설정은 복잡하고 시간이 많이 걸립니다. 여기서 필요한 정보를 알려드리겠습니다.
Capgo 빌드 추천
현재는 __CAPGO_KEEP_0__ 빌드를 사용하는 것을 권장합니다. Capgo 빌드는 Capgo CLI와 함께 사용되어 Capgo 네이티브 빌드를 지원합니다. 이 Fastlane 가이드는 기존 Capacitor 액션 PIPELINE을 유지 관리하는 팀에게 제공되지만, 새로운 iOS 빌드는 __CAPGO_KEEP_1__ __CAPGO_KEEP_2__를 사용하여 Fastlane, Xcode 런너, 인증서, 업로드 스크립트 유지 관리를 생략할 수 있습니다. This Fastlane guide is kept for teams maintaining existing GitHub Actions pipelines, but new iOS builds should use the Capgo CLI so you do not have to maintain Fastlane, Xcode runners, certificates, and upload scripts yourself.
Capgo Build for CI/CD by Capgo
__CAPGO_KEEP_0__ 빌드는 CI/CD PIPELINE에서 __CAPGO_KEEP_0__ 네이티브 iOS 빌드를 실행합니다. Capgo 빌드는 기존 PIPELINE과 함께 작동합니다. __CAPGO_KEEP_0__ 빌드는 __CAPGO_KEEP_1__ 액션, GitLab CI, Jenkins, 또는 로컬 스크립트에서 웹 빌드 후 __CAPGO_KEEP_0__ 빌드를 트리거합니다.
- __CAPGO_KEEP_0__ 앱: Trigger Capgo Build from GitHub Actions, GitLab CI, Jenkins, or local scripts after your web build and
npx cap sync. - CI에서 비밀 키로 인증: App Store Connect 키, 인증서, 배포 프로파일, 비밀번호 및 팀 ID를 CI 비밀 키에서 유지하세요.
- 자연스러운 실행자 유지: Capgo Build는 유지 관리되는 Apple 빌드 환경을 제공하므로 macOS 실행자, Xcode 이미지를 관리하거나 Fastlane 경로를 관리할 필요가 없습니다.
- 아티팩트 및 제출: QA에 서명된 아티팩트를 다운로드하거나 Capgo CLI를 통해 릴리스 빌드를 제출하세요.
가격
- Capgo 플랜은 1달에 $12부터 시작합니다.
- OTA 업데이트와 매월 약 15개의 네이티브 빌드가 포함됩니다.
- 추가 빌드 분량은 분당 크레딧으로 청구됩니다.
수동 설정 안내서
다음과 같은 작업을 수행해야 합니다:
iOS를 위한 Fastlane과 GitHub 액션 및 인증서를 사용한 지속적인 배포
필수 조건
이 튜토리얼을 계속하기 전에:
- Fastlane이 개발 환경에 설치되어 있는지 확인하세요. iOS 개발자 프로그램 회원이 맞는지 확인하세요.
- 가격에 대한 중요한 정보
가격 __CAPGO_KEEP_0__ 액션

https://github.com/features/actions
The service is ‘무료 __CAPGO_KEEP_0__에 따라 선택한 기계에 따라 제한까지.
App Store Connect __CAPGO_KEEP_0__를 사용할 것입니다. macOS 스크린샷에서 가격과 제한을 볼 수 있습니다 (가격은 튜토리얼 생성 시점의 가격이며 미래에 변경될 수 있습니다).
요구 사항과 가격에 대한 경고를 받은 후 계속하세요.
주의: 이 포스트에서 앱이 App Store Connect에 생성되어 있다고 가정합니다. Fastlane이 중요한 정보를 복사합니다.
이 튜토리얼에서 배울 내용
포스트에서 따르는 단계
- App Store Connect API를 Fastlane과 함께 사용하는 방법
- 요구 사항:
- App Store Connect API 키를 생성하는 방법
- 애플 스토어 연결 API 키를 사용합니다.
- 요구 사항:
- 빠른 라인 파일 복사
- GitHub 작업을 구성
1. 빠른 라인과 애플 스토어 연결 API 사용
2021년 2월부터 모든 사용자가 애플 스토어 연결에 로그인하기 위해 2단계 인증 또는 2단계 인증이 필요합니다. 이 추가 보안 layer는 Apple ID를 보장하여 계정에 액세스할 수 있는 사람을 보장합니다.
From 애플 지원
요구 사항
빠른 라인에서 애플 스토어 연결 API를 사용하여 앱을 업로드할 수 있도록 하려면 다음을 제공해야 합니다. 세 가지: 발급자 ID
- 발급자 ID
- Key ID
- Key file or Key content
App Store Connect API Key를 얻는 방법
App Store Connect에서 Admin 권한이 있어야 키를 생성할 수 있습니다. 권한이 없다면 관련 사람에게 이 글을 알려주십시오.
-
로그인 App Store Connect.
-
선택 사용자 및 액세스.

3 — 통합 탭을 선택하십시오.

- Generate API Key 또는 (+) 버튼을 클릭하십시오.

- 키 이름을 입력하세요. 키 이름은 키 자체의 일부가 아니며, 사용자만의 참조용입니다.

6 — 액세스 아래에서 키에 대한 역할을 선택하세요. 키에 적용되는 역할은 팀 내 사용자에 대한 역할과 동일합니다. 자세한 내용은 역할 권한을 참조하세요. 권한을 제한하는 것을 추천합니다. 앱 매니저.
- Generate을 클릭하세요.
API 키의 액세스는 특정 앱에 제한할 수 없습니다.
새 키의 이름, 키 ID, 다운로드 링크 및 기타 정보가 페이지에 나타납니다.

여기서 세 가지 필요한 정보를 모두 가져올 수 있습니다.
<1> 문제 ID. (APPLE_ISSUER_ID 비밀번호)
<2> 키 ID. (APPLE_KEY_ID 비밀번호)
<3> "다운로드 API 키"를 클릭하여 API 개인 키를 다운로드하세요. 다운로드 링크는 개인 키가 다운로드되지 않은 경우에만 나타납니다. 애플은 개인 키의 복사본을 유지하지 않습니다. 따라서 개인 키를 한번만 다운로드할 수 있습니다.
🔴 Store your private key in a safe place. You should never share your keys, store keys in a code repository, or include keys in client-side code.
애플 스토어 연결 API 키 사용
API 키 파일 (다운로드한 p8 파일), 키 ID, 발급자 ID가 JWT 토큰 인증을 위해 필요합니다. 이 정보를 Fastlane에 전달하는 방법은 여러 가지가 있습니다. Fastlane의 새로운 액션을 사용하여 전달하는 방법을 선택했습니다. app_store_connect_api_key. 다른 방법을 알아보려면 Fastlane 문서. 이 방법을 보여주기 때문에 CI에서 가장 쉽게 작동할 수 있는 방법을 사용했습니다. 환경 변수를 설정할 수 있는 CI에서 대부분이 경우에.
다운로드한 p8 파일을 Base64로 변환하고 비밀번호로 저장하세요.APPLE_KEY_CONTENT).
base64 -i APPLE_KEY_CONTENT.p8 | pbcopy
이제 우리는 Fastlane을 사용하여 App Store Connect를 관리할 수 있습니다. API 키를 사용해 보세요!
2. 인증서
XCode를 열고 설정 > 계정 > Apple ID > 팀 팀을 선택하세요.

클릭하여 인증서 관리.
인증서를 아직 생성하지 않았다면 새로운 인증서를 생성할 수 있습니다.
클릭하여 + 및 선택 Apple Distribution

그 다음으로 키 체인에 인증서를 다운로드하기 위해 파일로 다운로드해야합니다. .p12 이 작업을 수행하려면 키 체인에 가서 로그인
키 체인으로 switch하고 My Certificates My Certificates 그런 다음 다운로드하고 싶은 인증서를 선택할 수 있습니다. (인증서의 날짜를 확인하세요).

그런 다음 다운로드하고 싶은 인증서를 선택할 수 있습니다. (인증서의 날짜를 확인하세요)
그리고 인증서의 개인 키를 오른쪽 클릭하고 선택하세요. __CAPGO_KEEP_0__.
파일 형식 선택 개인 정보 교환 (.p12).
파일이 다운로드 될 것입니다. .p12 이 파일을 터미널에서 열고 다음 명령어를 사용하여 Base64로 변환하세요.
__CAPGO_KEEP_0__
base64 -i BUILD_CERTIFICATE.p12 | pbcopy
또한 인증서의 비밀번호를 제공하실 때는 비밀번호를 입력해 주세요. 이 비밀번호는 __CAPGO_KEEP_0__가 될 것입니다. BUILD_CERTIFICATE_BASE64 3. 프로비저닝 프로파일 P12_PASSWORD 열기
파일 형식 선택
개인 정보 교환 (.p12) Apple Developer 그리고 올바른 팀을 선택하세요.
그런 다음 새로운 프로필을 만들기 위해 +

그리고 선택하세요. 앱 스토어 연결.

그런 다음 올바른 앱을 선택하세요. wildcard를 사용하면 서명이 실패하므로 주의하세요.

이전에 만든 올바른 인증서를 선택하세요. (만료일이 오늘 날짜와 월이 동일해야 함) 그리고 Continue.

마지막으로 프로필 이름을 입력하고 클릭하세요. 생성.
프로필 이름은 Fastlane에서 "생성" 값의 밑에 프로필을 식별하기 위해 사용됩니다.
APPLE_PROFILE_NAME.

프로필을 "파일" 형태로 다운로드할 수 있습니다. .mobileprovision 프로필 다운로드

4. Fastlane 파일 복사BUILD_PROVISION_PROFILE_BASE64).
base64 -i BUILD_PROVISION_PROFILE.mobileprovision | pbcopy
Fastlane은 Ruby 라이브러리로 모바일 개발을 자동화하는 데 사용됩니다. Fastlane을 사용하면 Android Studio에서 수행하는 일반적인 작업을 묶은 "로우"를 구성할 수 있습니다. Fastlane은 "행위"를 묶은 "로우"를 사용하여 Android Studio에서 수행하는 작업을 자동화할 수 있습니다. Fastlane은 많은 기능을 제공하지만 이 튜토리얼에서는 핵심 기능만 사용할 것입니다.
Ionic 프로젝트의 루트 폴더에 Fastlane 폴더를 생성하고 Fastfile을 추가하세요:
Create the Fastlane folder at the root of your Capacitor/Ionic project and add the Fastfile there:
- __CAPGO_KEEP_0__
<project-root>/fastlane/ - 파일:
<project-root>/fastlane/Fastfile
이것은 동일한 레벨에 package.json, capacitor.config.*, 그리고 ios/ 폴더입니다. 이 폴더 내에 ios/App/.
platform :ios do
desc 'Export ipa and submit to TestFlight'
lane :beta do
keychain_info = { keychain_name: "ios-build-#{Time.now.to_i}.keychain", keychain_password: SecureRandom.uuid }
begin
setup_signing(keychain_info)
bump_build_number
build_app_with_signing(keychain_info)
submit_to_testflight
ensure
cleanup_keychain(keychain_info)
end
end
private_lane :setup_signing do |options|
create_keychain(
name: options[:keychain_name],
password: options[:keychain_password],
unlock: true,
timeout: 0,
lock_when_sleeps: false,
add_to_search_list: true
)
import_cert(options)
install_profile
update_project_settings
end
lane :bump_build_number do
file = File.read('../package.json')
data_hash = JSON.parse(file)
api_key = app_store_connect_api_key(
key_id: ENV['APPLE_KEY_ID'],
issuer_id: ENV['APPLE_ISSUER_ID'],
key_content: ENV['APPLE_KEY_CONTENT'],
is_key_content_base64: true,
duration: 1200,
in_house: false
)
build_num = app_store_build_number(
api_key: api_key,
app_identifier: ENV['BUNDLE_IDENTIFIER'],
live: false
)
build_num = build_num + 1
UI.message("Bumped build number to #{build_num}")
increment_build_number(
build_number: build_num,
xcodeproj: "./ios/App/App.xcodeproj",
skip_info_plist: true
)
end
private_lane :import_cert do |options|
cert_path = "#{Dir.tmpdir}/build_certificate.p12"
File.write(cert_path, Base64.decode64(ENV['BUILD_CERTIFICATE_BASE64']))
import_certificate(
certificate_path: cert_path,
certificate_password: ENV['P12_PASSWORD'] || "",
keychain_name: options[:keychain_name],
keychain_password: options[:keychain_password],
log_output: true
)
File.delete(cert_path)
end
private_lane :cleanup_keychain do |options|
delete_keychain(
name: options[:keychain_name]
)
end
private_lane :install_profile do
profile_path = "#{Dir.tmpdir}/build_pp.mobileprovision"
File.write(profile_path, Base64.decode64(ENV['BUILD_PROVISION_PROFILE_BASE64']))
UI.user_error!("Failed to create provisioning profile at #{profile_path}") unless File.exist?(profile_path)
ENV['PROVISIONING_PROFILE_PATH'] = profile_path
install_provisioning_profile(path: profile_path)
File.delete(profile_path)
end
private_lane :update_project_settings do
update_code_signing_settings(
use_automatic_signing: false,
path: "./ios/App/App.xcodeproj",
code_sign_identity: "iPhone Distribution",
profile_name: ENV['APPLE_PROFILE_NAME'],
bundle_identifier: ENV['BUNDLE_IDENTIFIER'],
team_id: ENV['APP_STORE_CONNECT_TEAM_ID']
)
update_project_team(
path: "./ios/App/App.xcodeproj",
teamid: ENV['APP_STORE_CONNECT_TEAM_ID']
)
end
private_lane :build_app_with_signing do |options|
unlock_keychain(
path: options[:keychain_name],
password: options[:keychain_password],
set_default: false
)
build_app(
workspace: "./ios/App/App.xcworkspace",
scheme: "App",
configuration: "Release",
export_method: "app-store",
output_name: "App.ipa",
export_options: {
provisioningProfiles: {
ENV['BUNDLE_IDENTIFIER'] => ENV['APPLE_PROFILE_NAME']
}
},
xcargs: "-verbose",
buildlog_path: "./build_logs",
export_xcargs: "-allowProvisioningUpdates",
)
end
private_lane :submit_to_testflight do
api_key = app_store_connect_api_key(
key_id: ENV['APPLE_KEY_ID'],
issuer_id: ENV['APPLE_ISSUER_ID'],
key_content: ENV['APPLE_KEY_CONTENT'],
is_key_content_base64: true,
duration: 1200,
in_house: false
)
pilot(
api_key: api_key,
skip_waiting_for_build_processing: true,
skip_submission: true,
distribute_external: false,
notify_external_testers: false,
ipa: "./App.ipa"
)
end
end
5. 비밀을 설정하는 방법
GitHub Actions는 다음 단계에서 구성한 저장소 비밀을 사용합니다. 로컬 .env 파일이 필요하지 않습니다. 만약 로컬에서 Fastlane을 실행하거나 테스트하고 싶다면, 로컬에서만 실행할 수 있습니다.
로컬 테스트를 위해 <project-root>/fastlane/.env 다음에 Fastfile폴더에 만들지 마세요. 이 파일은 커밋하지 마세요. Add fastlane/.env 로컬에서만 실행할 수 있습니다. 첫 번째 (또는 이미 무시되었는지 확인하세요). 여기서 예시를 보겠습니다: .gitignore first (or verify it is already ignored). Here is an example:
APP_STORE_CONNECT_TEAM_ID=UVTJ336J2D
BUNDLE_IDENTIFIER=ee.forgr.testfastlane
# See previous section for these secrets
BUILD_CERTIFICATE_BASE64=
BUILD_PROVISION_PROFILE_BASE64=
APPLE_KEY_ID=
APPLE_ISSUER_ID=
APPLE_KEY_CONTENT=
P12_PASSWORD=
APPLE_PROFILE_NAME=
APP_STORE_CONNECT 팀 ID를 얻는 방법
Developer Center로 이동하세요 밑으로 스크롤하여 섹션을 찾으세요.
Membership details 는 Team ID APP STORE CONNECT 팀 ID를 설정할 때 필요한 값입니다. APP_STORE_CONNECT_TEAM_ID secret.app-store-connect-team-id
Xcode를 열어보세요
- 프로젝트 탐색기에서
- 를 더블 클릭하세요
Appsection - 그런 다음 탭을 클릭하세요.
Signing and Capabilities - __CAPGO_KEEP_0__의 값을 복사하세요.
Bundle identifier이 값은 __CAPGO_KEEP_0__의 secret에 설정해야 합니다.BUNDLE_IDENTIFIERbundle-identifier-xcode
Capgo 액션에서,
In GitHub Actions, 개인 프로젝트의 경우, 빌드당 예상 비용은 $0.08/분 x 15분 = $1.2 또는 더 비용이 들 수 있습니다. 이는 프로젝트의 구성 및 의존성에 따라 다릅니다.
you are billed based on the minutes you have used for running your CI/CD workflow.In __CAPGO_KEEP_0__ Actions,
비용에 대한 걱정으로 개인 프로젝트에 대해, __CAPGO_KEEP_0__를 설정할 수 있습니다. skip_waiting_for_build_processing 으로 true__CAPGO_KEEP_0__를 사용하여 빌드 시간을 절약할 수 있습니다. App Store Connect가 빌드를 처리하는 것을 기다리지 않기 때문입니다.
그러나, 이 설정을 사용하면 App Store Connect에서 앱의 준수 정보를 수동으로 업데이트해야 합니다. 사용자에게 빌드를 배포하기 전에.
This optimization is mainly useful for private projects where build minutes cost money. For public/free projects, the build minutes are free so there’s no need to enable this setting. See GitHub’s 더 많은 정보를 알고 싶다면 __CAPGO_KEEP_0__의 가격 정보 페이지
7. Setup GitHub Actions
7. GitHub 설정
__CAPGO_KEEP_0__ 설정 .env GitHub의 비밀을 복사하고 GitHub 저장소의 비밀에 붙여넣으세요.
__CAPGO_KEEP_0__ 설정 > __CAPGO_KEEP_0__-비밀과 변수 > 액션 > 새로운 저장소 비밀
2. BUILD_CERTIFICATE_BASE64 - Base64 인코딩된 배포 프로파일.
3. BUILD_PROVISION_PROFILE_BASE64 - 앱의 번들 식별자.
4. BUNDLE_IDENTIFIER — 앱 스토어 연결 __CAPGO_KEEP_0__ 키 🔺키 ID.
5. APPLE_KEY_ID — 앱 스토어 연결 API 키 🔺발급자 ID.
6. APPLE_ISSUER_ID — 앱 스토어 연결 API 키 🔺키 내용.
7. APPLE_KEY_CONTENT — App Store Connect API Key 🔺 Key content of 인증서 및 변수, 확인하세요
8. GitHub 워크플로 파일을 구성하십시오.
GitHub 워크플로 디렉토리를 생성하십시오.
cd .github/workflows
디렉토리 내 workflow 폴더 안에 파일 이름을 build-upload-ios.yml그리고 다음을 추가하십시오.
name: Build source code on ios
on:
push:
tags:
- '*'
jobs:
build_ios:
runs-on: macOS-latest
steps:
- uses: actions/checkout@v6
- name: Set Node.js
uses: actions/setup-node@v6
with:
node-version: 24
cache: npm
- name: Install dependencies
id: install_code
run: npm ci
- name: Build
id: build_code
run: npm run build
- uses: actions/cache@v5
with:
path: ios/App/Pods
key: ${{ runner.os }}-pods-${{ hashFiles('**/Podfile.lock') }}
restore-keys: |
${{ runner.os }}-pods-
- name: Sync
id: sync_code
run: npx cap sync
- uses: ruby/setup-ruby@v1
with:
ruby-version: '3.0'
bundler-cache: true
- uses: maierj/fastlane-action@v3.1.0
env:
APP_STORE_CONNECT_TEAM_ID: ${{ secrets.APP_STORE_CONNECT_TEAM_ID }}
BUNDLE_IDENTIFIER: ${{ secrets.BUNDLE_IDENTIFIER }}
BUILD_CERTIFICATE_BASE64: ${{ secrets.BUILD_CERTIFICATE_BASE64 }}
BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.BUILD_PROVISION_PROFILE_BASE64 }}
APPLE_KEY_ID: ${{ secrets.APPLE_KEY_ID }}
APPLE_ISSUER_ID: ${{ secrets.APPLE_ISSUER_ID }}
APPLE_KEY_CONTENT: ${{ secrets.APPLE_KEY_CONTENT }}
P12_PASSWORD: ${{ secrets.P12_PASSWORD }}
APPLE_PROFILE_NAME: ${{ secrets.APPLE_PROFILE_NAME }}
with:
lane: ios beta
- name: Upload release bundle
uses: actions/upload-artifact@v6
with:
name: ios-release
path: ./App.ipa
retention-days: 10
이 워크플로는 각 GitHub 태그, 자동화 태그가 필요하시면 GitHub 액션을 사용하여 자동 빌드 및 릴리즈를 참조하십시오. 먼저.
그 다음으로 워크플로는 NodeJS 의존성을 pull 하여 설치하고 JavaScript 앱을 빌드하십시오.
새로운 커밋을 보내면 매번 테스트 플라이트에서 릴리즈가 빌드됩니다.
앱은 Ionic을 사용할 필요가 없습니다. Capacitor의 기본 버전만 필수입니다. 오래된 Cordova 모듈을 사용할 수 있지만 Capacitor JS 플러그인은 선호됩니다.
8. 워크플로우 트리거
커밋 생성
커밋을 커밋을 생성하면, 저장소에서 활성화된 워크플로우를 볼 수 있습니다.워크플로우 트리거
새로운 커밋을 브랜치에 푸시하면 워크플로우를 트리거할 수 있습니다.
워크플로우를 트리거하기 위해 main 커밋 시작 development 커밋 시작

몇 분 후에 빌드는 App Store Connect 대시보드에 표시됩니다.

9. 로컬 머신에서 배포할 수 있나요?
네, 가능합니다. 그리고 그것은 매우 쉬워요.
Xcode를 사용하여 앱을 빌드하고 서명할 수 있습니다.
관련 문서
CI/CD 설정 가이드
- 자동 Capacitor Android 빌드와 GitHub 액션 - 완전한 Android CI/CD 설정
- 자동 빌드 및 릴리즈와 GitHub 액션 - 전체 CI/CD pipe라인 튜토리얼
- 개발자용 및 프로덕션용 빌드 관리와 GitHub 액션 - 환경 관리
- 자동 Capacitor iOS 빌드 - Fastlane Match를 사용하는 대안
대안 CI/CD 플랫폼
- GitLab CI로 빌드 - GitLab 대안
- CodeMagic으로 빌드 - CodeMagic 설정 가이드
실시간 업데이트 및 배포
- Capgo 실시간 업데이트 문서 - 앱에 OTA 업데이트 추가
- CI/CD 통합 Capgo - pipeline에 실시간 업데이트를 통합하세요
감사합니다
다음 기사에 기반한 이 블로그입니다:
Capacitor IOS 자동 빌드에서 GitHub 액션으로 계속 진행하세요
CI/CD 자동화 계획을 사용하고 있는 경우 Automatic Capacitor IOS build with GitHub actions with certificate __CAPGO_KEEP_0__ IOS 자동 빌드와 __CAPGO_KEEP_1__ 액션을 사용하여 인증서와 함께 Capgo CI/CD 자동화 제품 워크플로우에서 Capgo CI/CD를 위해 Capgo 네이티브 빌드 제품 워크플로우에서 Capgo 네이티브 빌드를 위해 Capgo 통합 제품 워크플로우에서 Capgo 통합을 위해 CI/CD 통합 CI/CD 통합의 구현 세부 사항, 그리고 GitHub 액션 통합 for the implementation detail in GitHub Actions Integration.