fastlane 설정 IOS

박정빈·2026년 4월 10일

React Native 사용기

목록 보기
37/40

iOS Fastlane 설정값 정리

1. deliver (App Store 배포)

파라미터명허용 값 및 상세 설명기본값 (Default)
app_identifiercom.gg24.app 같은 앱의 번들 식별자. (Appfile에 설정되어 있다면 생략 가능)Appfile 값
usernameApple ID 이메일 주소. API Key 사용 시 불필요Appfile 값
api_key_pathApp Store Connect API Key JSON 파일 경로. Apple ID 인증 대신 권장되는 방식(없음)
team_idApp 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

2. pilot (TestFlight 배포)

파라미터명허용 값 및 상세 설명기본값 (Default)
app_identifier앱의 번들 식별자. (Appfile에 설정되어 있다면 생략 가능)Appfile 값
usernameApple ID 이메일 주소Appfile 값
api_key_pathApp 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_descriptionTestFlight 앱에서 표시되는 베타 앱 설명(없음)
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

3. gym (iOS 빌드)

파라미터명허용 값 및 상세 설명기본값 (Default)
schemeXcode 프로젝트의 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
xcargsxcodebuild에 전달할 추가 인수. 예: "PROVISIONING_PROFILE_SPECIFIER='match AppStore'"(없음)
derived_data_pathXcode 빌드 산출물 저장 경로. CI에서 캐싱에 활용 가능(없음)
buildlog_path빌드 로그 저장 디렉토리~/Library/Logs/gym

4. match (코드 서명 관리)

파라미터명허용 값 및 상세 설명기본값 (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_idApple Developer Portal 팀 IDAppfile 값
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

0개의 댓글