자동 iOS 빌드와 GitHub 액션을 사용하여 match
CI/CD를 위한 Capacitor 앱 설정은 복잡하고 시간이 많이 걸립니다. 필요한 정보는 다음과 같습니다.
새로운 빌드에 권장: Capgo 빌드를 사용하십시오.
현재 __CAPGO_KEEP_0__ 빌드를 사용하는 것을 권장합니다. Capgo 빌드와 Capgo CLI Capacitor 빌드는 CI/CD를 위해 __CAPGO_KEEP_1__에서 제공됩니다. 이 Fastlane Match 가이드는 기존 GitHub 액션 PIPELINE을 유지하는 팀에게 유지됩니다. 그러나 새로운 iOS 빌드는 Capgo CLI를 사용하여 Fastlane, Match 저장소, Xcode 러너, 인증서, 업로드 스크립트를 유지 관리하지 않도록 하십시오.
Capgo 빌드는 CI/CD를 위해 Capgo에서 제공됩니다.
Fastlane Match, Xcode 러너, 인증서, 프로비전 프로파일, 업로드 스크립트 유지 관리를 생략하십시오. Capgo 빌드 기존 CI/CD pipeline에서 signed native iOS 빌드를 실행합니다:
- 웹 빌드 후 __CAPGO_KEEP_0__ 빌드를 __CAPGO_KEEP_1__ Actions, GitLab CI, Jenkins, 또는 로컬 스크립트에서 트리거합니다.Trigger Capgo 빌드를 GitHub Actions, GitLab CI, Jenkins, 또는 로컬 스크립트 후 웹 빌드와
npx cap sync. - : 앱 스토어 연결 키, 인증서, 배포 프로파일, 비밀번호, 팀 ID를 자신의 CI 비밀에 저장합니다.자연어 러너 유지 관리
- : __CAPGO_KEEP_0__ 빌드는 유지 관리된 애플 빌드 환경을 제공하므로 macOS 러너, Xcode 이미지, Fastlane, 또는 Match 저장소 관리를 하지 않아도 됩니다.Capgo 빌드는 유지 관리되는 Apple 빌드 환경을 제공하므로 macOS 실행자, Xcode 이미지를 관리할 필요가 없습니다.
- : QA를 위해 다운로드한 signed 아티팩트를 제출하거나 __CAPGO_KEEP_0__ __CAPGO_KEEP_1__를 통해 릴리즈 빌드를 제출할 수 있습니다.: QA에서 서명된 아티팩트를 다운로드하거나 Capgo CLI을 통해 릴리스 빌드를 제출합니다.
Pricing
- Capgo
- 자동 업데이트와 매월 약 15개의 네이티브 빌드 포함
- 추가 빌드 분량은 분당 크레딧으로 청구됩니다
수동 설정 안내서
다음과 같이 하세요:
iOS에 대한 지속적인 배포를 Fastlane과 GitHub 액션을 사용하여 match를 사용하여
준비 사항
이 튜토리얼을 계속하기 전에...
- Fastlane이 설치되어 개발 머신에 있습니다.
- iOS 개발자 프로그램 회원입니다.
- 읽고 싶은 마음이 🤣…
- 많은 개발자 팀이 있다면, 더 간단한 워크플로우를 위해 fastlane 인증 를 사용하는 것을 추천합니다.
가격에 대한 중요한 점

https://github.com/features/actions
서비스는 제한에 따라 선택한 기계에 따라 '무료'입니다.
이번 튜토리얼에서 사용할 macOS 기계의 가격과 제한을 볼 수 있습니다 (가격은 튜토리얼이 생성된 시점의 가격이며, 미래에 변경될 수 있습니다)
🔴 요구 사항과 가격에 대해 경고한 후, 계속하기를 원하신다면...
📣 In 이 글에서 앱이 iTunes Connect에 생성되어 있고 Apple 생태계의 인증서가 존재한다고 가정합니다. Fastlane이 모든 것을 복사합니다!
Let's dive in!
이 글에서 따르는 단계
- App Store Connect API을 Fastlane Match와 함께 사용하기
- 필요 조건
- App Store Connect API 키 생성하기
- App Store Connect API 키 사용하기
- Fastlane 파일 복사하기
- Fastlane match 구성하기
1. App Store Connect API을 Fastlane Match와 함께 사용하기
2021년 2월부터 App Store Connect에 로그인하는 모든 사용자는 2단계 인증 또는 2단계 인증이 필요합니다. Apple ID에 추가 보안을 제공하여 계정에 액세스하는 사람을 단일 사람으로만 보장합니다.
From Apple 지원
match를 사용하기 위해 시작하는 것은 기존 인증서를 취소해야합니다. 그러나 걱정하지 마십시오, 새로운 인증서를 직접 받을 것입니다.
요구 사항
App Store Connect API를 사용할 수 있도록 Fastlane이 필요합니다. 세 가지 발급자 ID.
- 키 ID.
- 키 파일 또는 키 내용.
- App Store Connect __CAPGO_KEEP_0__ 키 생성
애플 스토어 커넥트 API 키 생성
1 — App Store Connect로 로그인
2 — 애플 스토어 연결.
2 — 선택 사용자 및 액세스.

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

4 — Generate API 키 또는 (+) 버튼을 클릭하십시오.

5 — 키 이름을 입력하십시오. 키 이름은 키 자체의 일부가 아니며, 사용자만의 참조용입니다.

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

여기서 세 가지 필요한 정보를 모두 가져올 수 있습니다.
<1> 이슈 ID.
<2> 키 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 키를 사용하여 앱 스토어 연결
The API Key 파일 (p8 파일을 다운로드한 파일), 키 ID, 발급자 ID가 인증 토큰을 생성하기 위해 JWT 토큰을 만들기 위해 필요합니다. 이러한 정보를 Fastlane에 입력하는 방법은 여러 가지가 있습니다. Fastlane의 새로운 액션을 사용하여 app_store_connect_api_keyFastlane 문서를 참조하세요. .Fastlane을 관리하는 방법을 보여주기 위해 App Store Connect __CAPGO_KEEP_0__ 키를 사용하는 것이 좋습니다.
현재 우리는 Fastlane을 App Store Connect API 키로 관리할 수 있습니다.
Fastlane은 안드로이드 스튜디오에서 일반적인 모바일 개발 작업을 자동화하기 위해 만들어진 루비 라이브러리입니다. Fastlane을 사용하면 사용자 정의 '레인'을 구성할 수 있으며, 이 레인에 포함된 '액션'을 사용하여 여러 작업을 수행할 수 있습니다. Fastlane은 많은 기능을 제공하지만, 이 튜토리얼에서는 Fastlane의 핵심 액션만 사용할 것입니다.
프로젝트의 루트 폴더에 Fastlane 폴더를 만들고 다음 파일을 복사하세요: Fastfile
Appfile
default_platform(:ios)
DEVELOPER_APP_IDENTIFIER = ENV["DEVELOPER_APP_IDENTIFIER"]
DEVELOPER_APP_ID = ENV["DEVELOPER_APP_ID"]
PROVISIONING_PROFILE_SPECIFIER = ENV["PROVISIONING_PROFILE_SPECIFIER"]
TEMP_KEYCHAIN_USER = ENV["TEMP_KEYCHAIN_USER"]
TEMP_KEYCHAIN_PASSWORD = ENV["TEMP_KEYCHAIN_PASSWORD"]
APPLE_ISSUER_ID = ENV["APPLE_ISSUER_ID"]
APPLE_KEY_ID = ENV["APPLE_KEY_ID"]
APPLE_KEY_CONTENT = ENV["APPLE_KEY_CONTENT"]
GIT_USERNAME = ENV["GIT_USERNAME"]
GIT_TOKEN = ENV["GIT_TOKEN"]
def delete_temp_keychain(name)
delete_keychain(
name: name
) if File.exist? File.expand_path("~/Library/Keychains/#{name}-db")
end
def create_temp_keychain(name, password)
create_keychain(
name: name,
password: password,
unlock: false,
timeout: 0
)
end
def ensure_temp_keychain(name, password)
delete_temp_keychain(name)
create_temp_keychain(name, password)
end
platform :ios do
lane :build do
build_app(
configuration: "Release",
workspace: "./ios/App/App.xcworkspace",
scheme: "App",
export_method: "app-store",
export_options: {
provisioningProfiles: {
DEVELOPER_APP_ID => "#{PROVISIONING_PROFILE_SPECIFIER}"
}
}
)
end
lane :refresh_profiles do
match(
type: "development",
force: true)
match(
type: "adhoc",
force: true)
end
desc "Register new device"
lane :register_new_device do |options|
device_name = prompt(text: "Enter the device name: ")
device_udid = prompt(text: "Enter the device UDID: ")
device_hash = {}
device_hash[device_name] = device_udid
register_devices(
devices: device_hash
)
refresh_profiles
end
lane :closed_beta do
keychain_name = TEMP_KEYCHAIN_USER
keychain_password = TEMP_KEYCHAIN_PASSWORD
ensure_temp_keychain(keychain_name, keychain_password)
api_key = app_store_connect_api_key(
key_id: APPLE_KEY_ID,
issuer_id: APPLE_ISSUER_ID,
key_content: APPLE_KEY_CONTENT,
duration: 1200,
in_house: false
)
match(
type: 'appstore',
git_basic_authorization: Base64.strict_encode64("#{GIT_USERNAME}:#{GIT_TOKEN}"),
readonly: true,
keychain_name: keychain_name,
keychain_password: keychain_password,
api_key: api_key
)
gym(
configuration: "Release",
workspace: "./ios/App/App.xcworkspace",
scheme: "App",
export_method: "app-store",
export_options: {
provisioningProfiles: {
DEVELOPER_APP_ID => "#{PROVISIONING_PROFILE_SPECIFIER}"
}
}
)
pilot(
apple_id: "#{DEVELOPER_APP_ID}",
app_identifier: "#{DEVELOPER_APP_IDENTIFIER}",
skip_waiting_for_build_processing: true,
skip_submission: true,
distribute_external: false,
notify_external_testers: false,
ipa: "./App.ipa"
)
delete_temp_keychain(keychain_name)
end
lane :submit_review do
version = ''
Dir.chdir("..") do
file = File.read("package.json")
data = JSON.parse(file)
version = data["version"]
end
deliver(
app_version: version,
submit_for_review: true,
automatic_release: true,
force: true, # Skip HTMl report verification
skip_metadata: false,
skip_screenshots: false,
skip_binary_upload: true
)
end
end
Appfile
app_identifier(ENV["DEVELOPER_APP_IDENTIFIER"])
apple_id(ENV["FASTLANE_APPLE_ID"])
itc_team_id(ENV["APP_STORE_CONNECT_TEAM_ID"])
team_id(ENV["DEVELOPER_PORTAL_TEAM_ID"])
Fastlane
match match iOS의 code 인증서를 위한 새로운 접근 방식입니다. Fastlane match는 팀이 iOS 앱에 필요한 인증서와 프로비저닝 프로파일을 관리하기 쉽게 해줍니다.
새로운 비공개 저장소 이름을 생성하세요 certificates, 예를 들어 GitHub 개인 계정 또는 조직에서.
iOS 앱에 Fastlane match 초기화 하세요.
fastlane match init
그런 다음 Git Storage 옵션 #1을 선택하세요.
[01:00:00]: fastlane match supports multiple storage modes, please select the one you want to use:1. git2. google_cloud3. s3?
새로 생성된 저장소의 URL을 할당하세요.
[01:00:00]: Please create a new, private git repository to store the certificates and profiles there[01:00:00]: URL of the Git Repo: <YOUR_CERTIFICATES_REPO_URL>
Fastlane 폴더 내에 파일이 생성되었습니다. Matchfile 그리고
_git_url_인증서 저장소의 HTTPS URL로 설정되어야 합니다. SSH를 사용할 수도 있지만, SSH를 사용하려면 별도의 단계를 수행해야 합니다.
# ios/Matchfilegit_url("https://github.com/gitusername/certificates")storage_mode("git")type("appstore")
다음으로, 인증서를 생성하고 Fastlane Match에서 요청할 때 사용할 자격증명을 입력하세요.
GitHub 액션은 나중에 암호화된 인증서 저장소의 암호를 사용하기 위해 올바르게 기억해 두세요.
fastlane match appstore
모든 것이 잘 진행되면 다음과 같은 것을 볼 수 있을 것입니다:
[01:40:52]: All required keys, certificates and provisioning profiles are installed 🙌
GitHub와 필요한 권한과 관련된 문제가 발생한 경우, 이 포스트가 도움이 될 수 있습니다. 포스트 Git에 대한 인증 토큰을 생성하는 데 도움이 될 것입니다.
생성된 인증서와 배포 프로파일은 인증서 저장소 리소스에 업로드됩니다.

마지막으로, 앱의 릴리스 구성에 대한 배포 프로파일을 업데이트하기 위해 Xcode에서 열어보세요. project XCode 인증서

MATCH
MATCH
CI/CD가 인증서와 배포 프로파일을 가져올 수 있도록 하기 위해.
In GitHub, GitHub으로 이동하세요. Settings → 개발자 설정 → 개인 액세스 토큰 → 클릭 Generate New Token → 체크박스를 선택하세요 repo 범위 → 클릭 Generate token.

개인 액세스 토큰이 생성되었습니다. 나중에 환경 변수로 사용하겠습니다. GIT_TOKEN.
그런 다음 Fastlane 폴더에서 생성된 match 파일을 Matchfile로 대체하세요.
CERTIFICATE_STORE_URL = ENV["CERTIFICATE_STORE_URL"]
GIT_USERNAME = ENV["GIT_USERNAME"]
GIT_TOKEN = ENV["GIT_TOKEN"]
FASTLANE_APPLE_ID = ENV["FASTLANE_APPLE_ID"]
git_url(CERTIFICATE_STORE_URL)
storage_mode("git")
type("appstore")
git_basic_authorization(Base64.strict_encode64("#{GIT_USERNAME}:#{GIT_TOKEN}"))
username(FASTLANE_APPLE_ID)
This will be used by GitHub Actions to import the certificates and provisioning profiles. And var will be set in GitHub Secrets, instead of hard-coding them in the file.
빌드 처리
In GitHub 액션에서 분량에 따라 청구됩니다. 개인 프로젝트의 경우 빌드당 예상 비용은 $0.08/분 x 15분 = $1.2
또는 프로젝트의 구성 또는 의존성에 따라 더 높을 수 있습니다. Live Update의 경우, 빌드가 처리된 후 앱의 호환성을 App Store Connect에서 수동으로 업데이트해야 합니다.이 옵션은 빌드 분수를 절약하기 위해 개인 프로젝트에서만 사용할 수 있습니다. 무료 프로젝트의 경우 이 문제는 전혀 없습니다.
가격 skip_waiting_for_build_processing to true.
__CAPGO_KEEP_0__ 액션은 GitHub Actions의 자동 빌드 기능을 제공합니다.
__CAPGO_KEEP_0__ 액션은 빌드 분수를 절약하기 위해 사용할 수 있습니다. pricing.
GitHub 액션은 빌드 분수를 절약하기 위해 사용할 수 있습니다.
GitHub 설정
값의 원천을 궁금해 하신 적이 있으세요? ENV 그것은 더 이상 비밀이 아닙니다 – 그것은 프로젝트의 비밀입니다. 🤦

1. APP_STORE_CONNECT_TEAM_ID - 애플 스토어 커넥트 팀의 ID를 설정하세요. 여러 팀에 속해 있다면.
2. DEVELOPER_APP_ID - 애플 스토어 커넥트에서 앱을 클릭하세요 → 앱 정보 → 앱 정보 아래로 스크롤하여 General Information 섹션을 찾으세요. Apple ID.
3. DEVELOPER_APP_IDENTIFIER - 앱의 번들 식별자.
4. DEVELOPER_PORTAL_TEAM_ID - 여러 팀에 속해 있다면 개발자 포털 팀의 ID를 설정하세요.
5. FASTLANE_APPLE_ID - 앱을 관리하는 데 사용하는 애플 ID 또는 개발자 이메일.
6. GIT_USERNAME " GIT_TOKEN - git username과 개인 접근 토큰.
7. MATCH_PASSWORD - match를 초기화할 때 assign한 passphrase는 certificate와 provisioning profile을 decrypt하기 위해 사용됩니다.
8. PROVISIONING_PROFILE_SPECIFIER - match AppStore <YOUR_APP_BUNDLE_IDENTIFIER>, 예를 들어. match AppStore com.domain.blabla.demo.
9. TEMP_KEYCHAIN_USER " TEMP_KEYCHAIN_PASSWORD - workflow에 임시 키체인 사용자 및 비밀번호를 assign합니다.
10. APPLE_KEY_ID 애플 스토어 연결 API 키 🔺키 ID.
11. APPLE_ISSUER_ID 애플 스토어 연결 API 키 🔺 발급자 ID.
12. APPLE_KEY_CONTENT — App Store Connect API 키 🔺 키 파일 또는 키 내용 .p8, 확인하세요.
13. CERTIFICATE_STORE_URL — Match 키의 repo url (ex: https://github.com/***/fastlane-match.git)
4. GitHub 설정 파일을 구성하세요.
GitHub workflow 디렉토리를 생성하세요.
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: 2.7.2
- uses: maierj/fastlane-action@v2.3.0
env:
DEVELOPER_APP_IDENTIFIER: ${{ secrets.DEVELOPER_APP_IDENTIFIER }}
DEVELOPER_APP_ID: ${{ secrets.DEVELOPER_APP_ID }}
PROVISIONING_PROFILE_SPECIFIER: match AppStore ${{ secrets.DEVELOPER_APP_IDENTIFIER }}
TEMP_KEYCHAIN_USER: ${{ secrets.TEMP_KEYCHAIN_USER }}
TEMP_KEYCHAIN_PASSWORD: ${{ secrets.TEMP_KEYCHAIN_PASSWORD }}
APPLE_ISSUER_ID: ${{ secrets.APPLE_ISSUER_ID }}
APPLE_KEY_ID: ${{ secrets.APPLE_KEY_ID }}
APPLE_KEY_CONTENT: ${{ secrets.APPLE_KEY_CONTENT }}
CERTIFICATE_STORE_URL: https://github.com/${{ secrets.CERTIFICATE_STORE_REPO }}.git
GIT_USERNAME: ${{ secrets.GIT_USERNAME }}
GIT_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
FASTLANE_APPLE_ID: ${{ secrets.FASTLANE_APPLE_ID }}
MATCH_USERNAME: ${{ secrets.FASTLANE_APPLE_ID }}
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
APP_STORE_CONNECT_TEAM_ID: ${{ secrets.APP_STORE_CONNECT_TEAM_ID }}
DEVELOPER_PORTAL_TEAM_ID: ${{ secrets.DEVELOPER_PORTAL_TEAM_ID }}
with:
lane: closed_beta
- name: Upload release bundle
uses: actions/upload-artifact@v2
with:
name: ios-release
path: ./App.ipa
retention-days: 60
이 workflow는 각 GitHub 태그 이후에 트리거되어야 합니다. 만약 태그 자동화가 필요하다면, tag을 먼저 참조하세요. 자동 빌드 및 릴리즈와 함께 GitHub 작업 first.
__CAPGO_KEEP_0__ workflow 디렉토리
새로운 커밋을 전송할 때마다 테스트 플라이트에서 릴리즈가 빌드됩니다.
Ionic을 사용할 필요가 없습니다. Capacitor의 기본 버전만 필수입니다. 옛날 Cordova 모듈을 사용할 수 있지만 Capacitor JS 플러그인은 선호됩니다.
5. 워크플로우 트리거
커밋 생성
Make a 워크플로우를 트리거하세요.새로운 커밋을 브랜치에 푸시하세요.
또는
새로운 커밋을 branch로 푸시하십시오. main or development 커밋이 시작되었습니다.

수분 후에 빌드는 App Store Connect 대시보드에서 사용할 수 있어야 합니다.

로컬 머신에서 배포할 수 있나요?
네, 가능합니다. 그리고 그것은 매우 쉬워요.
개인 저장소가 있다고 가정해 보겠습니다. 그리고 무료 플랜의 분량을 모두 사용했으며 새로운 릴리즈에 대해 돈을 지불하지 않으려는 경우, 또는 애플리케이션을 수동으로 제출하는 것을 선호하는 경우가 있습니다.
그럼 가보죠
확인, 먼저 my_project_path/fastlane 경로에 .env 파일을 생성해야 합니다. Fastfile, 자동으로 iOS 빌드를 위한 Capacitor GitHub 액션을 만들기 위해 비밀 _GitHub 에서 찾을 수 있는 우리의 속성들 중 일부입니다:
로컬 머신에서 배포하기 위한 .env 파일
현재, 터미널로 이동하여 터미널 컴퓨터에서 Fastlane을 실행할 수 있습니다: Fastlane .env 파일에 대한 필수 사항
fastlane closed_beta
.env 파일에 대한 필수 사항 .env ❌ .env 파일에 있는 데이터를 노출하지 않으려면, 우리의 .gitignore❌
fastlane/*.env
원격 머신의 GitHub Actions에서 발생하는 것과 동일하게 작동해야 합니다. 🍻

터미널 실행: $ Fastlane closed_beta
이까지 왔으면 축하합니다. 이제는 Fastlane과 GitHub Actions를 사용하여 iOS 앱에 대한 완전 자동화 프로세스를 갖게되었습니다.
각각의 새로운 커밋을 전송할 때마다, Google Play 콘솔에서 베타 채널에서 릴리즈가 빌드됩니다. 이 블로그를 개선하기 위해, 여러분의 피드백을 기다리고 있습니다. 질문이나 제안이 있으시면, 이메일로 알려주세요. martin@capgo.app
장치에서 빌드하기
장치에서 빌드가 필요하다면, 수동으로 프로비저닝에 추가해야 합니다.
맥에 장치를 연결하고 장치 메뉴를 열어보세요.
그런 다음 식별자 복사
그 다음에 명령어를 시작하세요:
fastlane register_new_device
이것은 디바이스 이름과 식별자를 설정하라고 물어볼 것입니다:

문제가 생긴다면
개발 장치가 테스트가 안되는 등 문제가 생긴다면 일반적으로 이 방법으로 해결할 수 있습니다.
문제가 생긴다면 마법의 명령어를 사용하세요:
fastlane match nuke development
fastlane match development
그 다음에: Shift(⇧)+Command(⌘)+K를 눌러 프로젝트를 정리하거나 Product > Clean(이름이 Clean Build Folder라고 표시될 수도 있음)을 선택하세요.
그 다음에 다시 앱을 디바이스에 설치해 보세요.
감사합니다.
이 블로그는 다음 글을 기반으로 합니다:
자동 Capacitor IOS 빌드와 GitHub 액션을 사용하여 match를 사용하여 계속 진행하세요.
If you are using Capgo. 자동 Capacitor IOS 빌드와 GitHub 액션을 사용하여 match를 사용하세요. 자동 __CAPGO_KEEP_0__ CI/CD와 연결하여 CI/CD 자동화 계획을 만드세요. Capgo CI/CD Capgo Native Builds Capgo 원시 빌드 Capgo Integrations Capgo 통합(Integrations) Capgo Integrations CI/CD 통합 CI/CD 통합 구현 세부 사항에 대해 GitHub 액션 통합 GitHub 액션 통합 구현 세부 사항에 대해