| 파라미터명 | 허용 값 및 상세 설명 | 기본값 (Default) |
|---|---|---|
| app_identifier | com.gg24.app 같은 앱의 번들 식별자. (Appfile에 설정되어 있다면 생략 가능) | Appfile 값 |
| username | Apple ID 이메일 주소. API Key 사용 시 불필요 | Appfile 값 |
| api_key_path | App Store Connect API Key JSON 파일 경로. Apple ID 인증 대신 권장되는 방식 | (없음) |
| team_id | App Store Connect 팀 ID. 여러 팀 소속일 때 명시 필요 | Appfile 값 |
| platform | 플랫폼 선택 • ios: iPhone/iPad 앱• appletvos: Apple TV 앱• osx: macOS 앱• xros: visionOS 앱 | ios |
| ipa | 업로드할 서명된 .ipa 파일 경로 | (없음) |
| skip_binary_upload | 바이너리 업로드 여부 • true: ipa 업로드를 건너뜀. 메타데이터만 수정할 때 유용• false: ipa 파일을 업로드 | false |
| skip_metadata | 텍스트 정보 업로드 여부 • true: 앱 설명, 키워드 등 메타데이터 수정을 건너뜀• false: 로컬 파일 내용으로 스토어 갱신 | false |
| skip_screenshots | 스크린샷 업로드 여부 • true: 스크린샷 수정을 건너뜀• false: 새 스크린샷으로 교체 | false |
| overwrite_screenshots | 스크린샷 덮어쓰기 • true: 기존 스크린샷 전체 삭제 후 새로 업로드• false: 기존 스크린샷 유지 | false |
| metadata_path | 메타데이터 파일이 위치한 폴더 경로 | ./fastlane/metadata |
| screenshots_path | 스크린샷 파일이 위치한 폴더 경로 | ./fastlane/screenshots |
| submit_for_review | 심사 제출 여부 • true: 업로드 후 자동으로 Apple 심사에 제출• false: 업로드만 하고 수동으로 심사 제출 | false |
| automatic_release | 심사 승인 후 출시 방식 • true: 승인 즉시 자동 출시• false: 개발자가 직접 릴리스 버튼을 눌러 수동 출시 | false |
| phased_release | 단계적 출시 (7일간 자동) • true: Apple 고정 스케줄에 따라 점진적 배포- 1일차: 1% → 2일차: 2% → 3일차: 5% → 4일차: 10% - 5일차: 20% → 6일차: 50% → 7일차: 100% • false: 승인 후 즉시 전체 사용자에게 배포 | false |
| reset_ratings | 평점 초기화 여부 • true: 새 버전 출시 시 기존 별점/리뷰 초기화• false: 기존 평점 유지 | false |
| price_tier | 앱 가격 등급 (0 = 무료, 1 = $0.99, 2 = $1.99 ...) | (없음) |
| app_review_information | 심사팀 전달 정보 (해시) • first_name: 담당자 이름• last_name: 담당자 성• phone_number: 연락처• email_address: 이메일• demo_user: 테스트 계정 ID• demo_password: 테스트 계정 비밀번호• notes: 심사팀 참고사항 | (없음) |
| submission_information | 제출 시 규정 관련 정보 (해시) • add_id_info_uses_idfa: IDFA 사용 여부• export_compliance_uses_encryption: 암호화 사용 여부• content_rights_contains_third_party_content: 서드파티 콘텐츠 포함 여부 | (없음) |
| force | 미리보기 확인 건너뜀 • true: HTML 미리보기 검증을 건너뜀. CI 환경에서 필수• false: 업로드 전 미리보기 확인 필요 | false |
| run_precheck_before_submit | 사전 검사 실행 여부 • true: 제출 전 App Store 규칙 위반 사항 자동 검사• false: 사전 검사 건너뜀 | true |
| 파라미터명 | 허용 값 및 상세 설명 | 기본값 (Default) |
|---|---|---|
| app_identifier | 앱의 번들 식별자. (Appfile에 설정되어 있다면 생략 가능) | Appfile 값 |
| username | Apple ID 이메일 주소 | Appfile 값 |
| api_key_path | App Store Connect API Key JSON 파일 경로 | (없음) |
| ipa | 업로드할 .ipa 파일 경로 | (없음) |
| distribute_external | 외부 테스터 배포 여부 • true: 외부 테스터에게 배포 (베타 심사 필요)• false: 내부 테스터에게만 배포 (심사 불필요, 최대 100명) | false |
| groups | 배포 대상 테스터 그룹명 배열. 예: ["내부 QA팀", "디자인팀"]distribute_external: true 시 외부 그룹 지정 가능 | (없음) |
| notify_external_testers | 외부 테스터 알림 여부 • true: 새 빌드 업로드 시 테스터에게 푸시 알림 발송• false: 알림 없이 조용히 배포 | true |
| changelog | 테스터에게 표시되는 "테스트할 내용" 텍스트 | (없음) |
| beta_app_description | TestFlight 앱에서 표시되는 베타 앱 설명 | (없음) |
| beta_app_feedback_email | 테스터 피드백 수신 이메일 주소 | (없음) |
| beta_app_review_info | 베타 심사팀 전달 정보 (해시) • contact_first_name: 담당자 이름• contact_last_name: 담당자 성• contact_phone: 연락처• contact_email: 이메일• demo_account_name: 데모 계정 ID• demo_account_password: 데모 계정 비밀번호• notes: 심사 참고사항 | (없음) |
| uses_non_exempt_encryption | 수출 규정 암호화 선언 • false: 비면제 암호화 미사용 선언. 매 빌드마다 뜨는 팝업 방지에 유용• true: 비면제 암호화 사용 | false |
| skip_submission | 배포 건너뜀 여부 • true: 바이너리 업로드만 하고 테스터 배포는 건너뜀• false: 업로드 후 테스터에게 배포까지 진행 | false |
| skip_waiting_for_build_processing | 빌드 처리 대기 여부 • true: App Store Connect의 빌드 처리 완료를 기다리지 않음• false: 처리 완료까지 대기 후 다음 단계 진행 | false |
| wait_processing_interval | 빌드 처리 상태 확인 주기 (초 단위) | 30 |
| expire_previous_builds | 이전 빌드 만료 여부 • true: 새 빌드 배포 시 이전 빌드를 만료 처리• false: 이전 빌드 유지 | false |
| 파라미터명 | 허용 값 및 상세 설명 | 기본값 (Default) |
|---|---|---|
| scheme | Xcode 프로젝트의 Scheme 이름. Shared로 체크되어 있어야 함 | (필수 값) |
| workspace | .xcworkspace 파일 경로. CocoaPods 사용 시 필수 | (없음) |
| project | .xcodeproj 파일 경로. workspace 미사용 시 지정 | (없음) |
| configuration | 빌드 구성 선택 • Debug: 개발/디버그용 빌드• Release: 배포용 최적화 빌드 | Release |
| clean | 빌드 전 클린 여부 • true: 빌드 전 xcodebuild clean 수행• false: 이전 빌드 캐시 활용 | false |
| export_method | 아카이브 내보내기 방식 • app-store: App Store / TestFlight 배포용• ad-hoc: 등록된 기기에 직접 설치용• enterprise: 기업 내부 배포용 (Enterprise 계정 필요)• development: 개발/테스트용 | (없음) |
| output_directory | 생성된 .ipa 파일 저장 디렉토리 경로 | . (현재 디렉토리) |
| output_name | 결과 IPA 파일명. 예: "gg24.ipa" | (없음) |
| codesigning_identity | 코드 서명에 사용할 인증서 이름. 예: "Apple Distribution: Company (XXXXXXXXXX)" | (없음) |
| skip_codesigning | 코드 서명 건너뜀 • true: 서명 없이 빌드. 시뮬레이터 빌드 시 유용• false: 정상적으로 코드 서명 진행 | false |
| xcargs | xcodebuild에 전달할 추가 인수. 예: "PROVISIONING_PROFILE_SPECIFIER='match AppStore'" | (없음) |
| derived_data_path | Xcode 빌드 산출물 저장 경로. CI에서 캐싱에 활용 가능 | (없음) |
| buildlog_path | 빌드 로그 저장 디렉토리 | ~/Library/Logs/gym |
| 파라미터명 | 허용 값 및 상세 설명 | 기본값 (Default) |
|---|---|---|
| type | 프로비저닝 프로필 타입 • development: 개발용 (디버그 빌드)• adhoc: Ad Hoc 배포용 (등록 기기 직접 설치)• appstore: App Store / TestFlight 배포용• enterprise: 기업 내부 배포용 | development |
| app_identifier | 앱 번들 식별자. 배열로 여러 앱 지정 가능 예: ["com.my.app", "com.my.app.widget"] | Appfile 값 |
| git_url | 인증서/프로필을 저장할 Git 저장소 URL | (필수 값) |
| git_branch | 사용할 Git 브랜치. 환경별 분리 가능 (예: production, development) | master |
| storage_mode | 인증서 저장 방식 • git: Git 저장소에 암호화하여 보관• google_cloud: Google Cloud Storage에 보관• s3: AWS S3에 보관 | git |
| readonly | 읽기 전용 모드 • true: 새 인증서/프로필 생성 없이 기존 것만 사용. CI 환경에서 권장• false: 필요 시 새로 생성 | false |
| force | 프로필 강제 갱신 • true: 매 실행마다 프로필을 강제로 새로 생성• false: 유효한 프로필이 있으면 재사용 | false |
| force_for_new_devices | 새 기기 등록 시 자동 갱신 • true: 새 기기가 등록되었을 때 프로필 자동 갱신 (adhoc/development만 해당)• false: 기기 변경과 무관하게 기존 프로필 유지 | false |
| team_id | Apple Developer Portal 팀 ID | Appfile 값 |
| keychain_name | 인증서를 저장할 키체인 이름 | login.keychain |
# iOS Fastlane 설정값 예시 Fastfile
# 실제 사용 시 gg24/ios/fastlane/Fastfile에 복사하여 사용
default_platform(:ios)
# ──────────────────────────────────────────────
# 공통 API Key 설정 (재사용을 위해 메서드로 분리)
# ──────────────────────────────────────────────
def api_key
app_store_connect_api_key(
key_id: "YOUR_KEY_ID",
issuer_id: "YOUR_ISSUER_ID",
key_filepath: "./fastlane/AuthKey_YOUR_KEY_ID.p8",
duration: 1200,
in_house: false
)
end
platform :ios do
# ──────────────────────────────────────────────
# 라이프사이클 블록
# ──────────────────────────────────────────────
before_all do |lane, options|
# 모든 lane 실행 전 공통 작업
ensure_git_status_clean # 커밋되지 않은 변경사항이 있으면 중단
end
after_all do |lane, options|
# 모든 lane 성공 후 공통 작업
notification(subtitle: "Fastlane 완료", message: "#{lane} 성공!")
end
error do |lane, exception, options|
# 에러 발생 시 처리
notification(subtitle: "Fastlane 실패", message: "#{lane}: #{exception.message}")
end
# ──────────────────────────────────────────────
# 1. 내부 테스트용 TestFlight 배포
# ──────────────────────────────────────────────
desc "내부 테스터 전용 TestFlight 배포 (심사 불필요, 최대 100명)"
lane :beta do
increment_build_number(xcodeproj: "MyApp.xcodeproj")
# gym: iOS 빌드
build_app(
workspace: "MyApp.xcworkspace",
scheme: "MyApp",
configuration: "Release",
clean: true,
export_method: "app-store",
output_directory: "./build",
output_name: "MyApp.ipa",
export_options: {
signingStyle: "automatic"
},
xcargs: "-allowProvisioningUpdates"
)
# pilot: TestFlight 업로드 (내부 테스터)
upload_to_testflight(
api_key: api_key,
distribute_external: false, # 내부 테스터만
skip_waiting_for_build_processing: false, # 업로드 후 처리 대기 시간을 건너뛸지 여부
changelog: "내부 테스트 빌드입니다."
)
end
# ──────────────────────────────────────────────
# 2. 외부 테스터 TestFlight 배포
# ──────────────────────────────────────────────
desc "외부 테스터 TestFlight 배포 (베타 심사 필요)"
lane :external_beta do
increment_build_number(xcodeproj: "MyApp.xcodeproj")
build_app(
workspace: "MyApp.xcworkspace",
scheme: "MyApp",
configuration: "Release",
clean: true,
export_method: "app-store",
export_options: {
signingStyle: "automatic"
},
xcargs: "-allowProvisioningUpdates"
)
upload_to_testflight(
api_key: api_key,
distribute_external: true, # 외부 테스터에게 배포
groups: ["외부 QA팀", "베타 테스터"], # 배포 대상 그룹 지정
notify_external_testers: true, # 테스터에게 알림 발송
changelog: "베타 테스트 빌드입니다. 피드백 부탁드립니다.",
uses_non_exempt_encryption: false, # 암호화 미사용 선언 (팝업 방지)
beta_app_review_info: { # 베타 심사 정보
contact_first_name: "길동",
contact_last_name: "홍",
contact_phone: "010-1234-5678",
contact_email: "hong@example.com",
demo_account_name: "testuser",
demo_account_password: "testpass123",
notes: "홈 탭에서 주요 기능을 확인할 수 있습니다."
},
submit_beta_review: true, # 베타 심사에 자동 제출
expire_previous_builds: true # 이전 빌드 만료 처리
)
end
# ──────────────────────────────────────────────
# 3. App Store 정식 출시 (즉시 배포)
# ──────────────────────────────────────────────
desc "App Store 정식 출시 - 승인 후 즉시 전체 배포"
lane :release do
increment_build_number(xcodeproj: "MyApp.xcodeproj")
build_app(
workspace: "MyApp.xcworkspace",
scheme: "MyApp",
configuration: "Release",
clean: true,
export_method: "app-store",
export_options: {
signingStyle: "automatic"
},
xcargs: "-allowProvisioningUpdates"
)
# deliver: App Store 배포
deliver(
api_key: api_key,
ipa: "./MyApp.ipa",
submit_for_review: true, # 업로드 후 심사 자동 제출
automatic_release: true, # 승인 즉시 자동 출시
phased_release: false, # 단계적 출시 비활성화 (즉시 전체 배포)
force: true, # HTML 미리보기 건너뜀 (CI 필수)
skip_metadata: true, # 메타데이터 업데이트 건너뜀
skip_screenshots: true, # 스크린샷 업데이트 건너뜀
run_precheck_before_submit: true, # 제출 전 규칙 위반 검사
submission_information: {
add_id_info_uses_idfa: false,
export_compliance_uses_encryption: false
},
app_review_information: {
first_name: "길동",
last_name: "홍",
phone_number: "010-1234-5678",
email_address: "hong@example.com",
demo_user: "testuser",
demo_password: "testpass123",
notes: "홈 탭에서 주요 기능을 확인할 수 있습니다."
}
)
end
# ──────────────────────────────────────────────
# 4. App Store 단계적 출시
# ──────────────────────────────────────────────
desc "App Store 출시 - 7일간 단계적 배포 (1%→2%→5%→10%→20%→50%→100%)"
lane :release_phased do
increment_build_number(xcodeproj: "MyApp.xcodeproj")
build_app(
workspace: "MyApp.xcworkspace",
scheme: "MyApp",
configuration: "Release",
clean: true,
export_method: "app-store",
export_options: {
signingStyle: "automatic"
},
xcargs: "-allowProvisioningUpdates"
)
deliver(
api_key: api_key,
submit_for_review: true,
automatic_release: true,
phased_release: true, # 7일간 단계적 출시 활성화
force: true,
skip_metadata: true,
skip_screenshots: true,
reset_ratings: false, # 기존 평점 유지
submission_information: {
add_id_info_uses_idfa: false,
export_compliance_uses_encryption: false
}
)
end
# ──────────────────────────────────────────────
# 5. 메타데이터만 업데이트 (빌드 없이)
# ──────────────────────────────────────────────
desc "App Store 메타데이터 및 스크린샷만 업데이트"
lane :update_metadata do
deliver(
api_key: api_key,
skip_binary_upload: true, # 바이너리 업로드 건너뜀
skip_metadata: false, # 메타데이터 업데이트
skip_screenshots: false, # 스크린샷 업데이트
overwrite_screenshots: true, # 기존 스크린샷 삭제 후 새로 업로드
metadata_path: "./fastlane/metadata",
screenshots_path: "./fastlane/screenshots",
force: true
)
end
# ──────────────────────────────────────────────
# 6. match를 활용한 코드 서명 동기화
# ──────────────────────────────────────────────
desc "개발용 인증서/프로필 동기화"
lane :sync_dev_certs do
match(
type: "development",
app_identifier: "com.my.app",
git_url: "https://github.com/your-org/certificates.git",
git_branch: "development",
storage_mode: "git",
readonly: false, # 필요 시 새로 생성
force_for_new_devices: true # 새 기기 등록 시 자동 갱신
)
end
desc "배포용 인증서/프로필 동기화"
lane :sync_release_certs do
match(
type: "appstore",
app_identifier: "com.my.app",
git_url: "https://github.com/your-org/certificates.git",
git_branch: "production",
storage_mode: "git",
readonly: true # CI에서는 읽기 전용 권장
)
end
# ──────────────────────────────────────────────
# 7. match + gym + pilot 조합 (CI/CD 전체 파이프라인)
# ──────────────────────────────────────────────
desc "CI/CD 전체 파이프라인: 코드 서명 → 빌드 → TestFlight"
lane :ci_beta do
# Step 1: 코드 서명 동기화
match(
type: "appstore",
app_identifier: "com.my.app",
git_url: "https://github.com/your-org/certificates.git",
readonly: true,
keychain_name: "ci_keychain" # CI 전용 키체인
)
# Step 2: 빌드
increment_build_number(xcodeproj: "MyApp.xcodeproj")
build_app(
workspace: "MyApp.xcworkspace",
scheme: "MyApp",
configuration: "Release",
clean: true,
export_method: "app-store",
derived_data_path: "./build/derived_data", # CI 캐싱 활용
buildlog_path: "./build/logs"
)
# Step 3: TestFlight 배포
upload_to_testflight(
api_key: api_key,
distribute_external: false,
skip_waiting_for_build_processing: true, # CI에서는 대기 건너뛰기
changelog: "CI 자동 빌드 ##{lane_context[SharedValues::BUILD_NUMBER]}"
)
end
# ──────────────────────────────────────────────
# Private Lane (외부 호출 불가, 내부에서만 사용)
# ──────────────────────────────────────────────
private_lane :build_release do |options|
build_app(
workspace: "MyApp.xcworkspace",
scheme: "MyApp",
configuration: options[:configuration] || "Release",
clean: options[:clean] || true,
export_method: options[:export_method] || "app-store",
export_options: {
signingStyle: "automatic"
},
xcargs: "-allowProvisioningUpdates"
)
end
end