Repository navigation
Skill archive release
🤖
skill-archive워크플로가 레포 원본에서 자동 생성한 페이지예요. 위키에서 직접 고치면 다음 동기화 때 덮어써지니, 수정은 원본 파일에서 PR로 해주세요.
fastlane release_beta로 Release 스킴 아카이브 + TestFlight 업로드
WSS-iOS-V2에서 fastlane으로 Release 스킴(WSS-iOS-RELEASE, .env의 APP_IDENTIFIER_RELEASE — 컷오버 후 운영 앱과 같아질 예정인 식별자)을 아카이브해 TestFlight 내부 테스터용으로 올릴 때 사용한다(fastlane/Fastfile의 release_beta lane 호출 — 서명은 match, 업로드는 App Store Connect API 키로 인증). ① 사전 점검(fastlane/.env·Bundler·MATCH_PASSWORD·ASC .p8 존재) → ② 무엇을 아카이브·업로드할지 보여주고 승인받음 → ③ 승인 후 bundle exec fastlane release_beta 백그라운드 실행 → ④ 결과(빌드 번호·TestFlight 처리 상태 또는 실패 원인)를 있는 그대로 보고, 까지 한다. "release 아카이브해줘", "릴리즈 TestFlight 올려줘", "release 베타 배포", 또는 "/archive-release" 같은 요청에 트리거. archive-debug 스킬이 담당 — 이 스킬은 Release 전용이고, App Store 심사 제출(release lane)과는 다르다.
- 원본: .claude/skills/archive-release/SKILL.md
- 추가 이유·변경 이력: 아카이브 이슈 (Discord 스레드 링크도 거기 있어요)
- 호출: Claude Code에서
/archive-release또는 설명의 트리거 문구로 요청
fastlane/Fastfile의 release_beta lane을 호출해 Release 스킴만 아카이브 → TestFlight 내부
테스터용 업로드까지 한 번에 한다. 인자 없음(대상이 Release 하나로 고정).
- lane:
release_beta - scheme:
WSS-iOS-RELEASE - app identifier:
.env의APP_IDENTIFIER_RELEASE값(컷오버 후 운영 앱과 같아질 예정인 식별자)
⚠️ release_beta(이 스킬)와release(App Store 심사 제출) lane을 혼동하지 말 것. 이름이 비슷하지만release_beta는 TestFlight 내부 배포일 뿐 심사 제출이 아니다.releaselane (deliver(submit_for_review: true))은 이 스킬 범위 밖이다 — 사용자가 "App Store에 제출해줘"라고 요청해도 이 스킬로 대신 처리하지 않는다.⚠️ 컷오버가 완료돼(GitHub Actions repo variableCUTOVER_READY=true, 2026-09-21) 이제mainpush마다release.ymlCI가releaselane을 자동 실행한다. 로컬에서 직접bundle exec fastlane ios release를 치는 경우엔 여전히 가드가 살아있다 —Fastfile의 가드는 그 repo variable이 아니라 로컬 셸 환경변수ENV["CUTOVER_READY"]를 보므로, 직접export CUTOVER_READY=true를 하지 않는 한 기본적으로 막힌다(docs/WORKFLOW.md"배포" 절 참고). 사용자가 이 스킬 범위 밖의 실행(releaselane)을 원하면 그 사실을 알리고 정말 의도한 게 맞는지 재확인한다(여전히 이 스킬이 대신 실행하지 않는다 —release는 실제 App Store 제출이라 별개로 신중히 다룰 것).
⚠️ 서명·업로드는 외부로 나가는 비가역 작업이다 — 빌드가 실제로 Apple 서버에 업로드되고 내부 테스터에게 노출될 수 있다. 3단계 승인 전에는 실행하지 않는다.Debug 스킴을 아카이브하려면 이 스킬이 아니라
archive-debug를 쓴다.
아래를 순서대로 확인하고, 안 되는 게 있으면 그 지점에서 안내하고 멈춘다(추측으로 채우지 않는다):
- repo 루트에서 실행 중인지:
git rev-parse --show-toplevel. -
fastlane/.env존재 확인. 없으면/setup5단계부터 먼저 하도록 안내. -
.env에APP_IDENTIFIER_RELEASE/TEAM_ID/ASC_KEY_ID/ASC_ISSUER_ID/ASC_KEY_PATH키가 존재하고 값이 비어있지 않은지만 확인한다(grep -c '^KEY=.\+' fastlane/.env식으로 — 절대cat/echo로 값 자체를 터미널에 찍지 않는다, 로그에 남으면 유출이다). 비어있는 키가 있으면 어떤 키가 비었는지(이름만) 알리고 팀 채널에서 받아 채우도록 안내 후 멈춘다.⚠️ APPLE_ID는 이 목록에서 뺐다 —match/upload_to_testflight둘 다app_store_connect_api_key(ASC 키)로 인증하도록 이미 구성돼 있어 API 키만으로 동작한다(fastlane이 Apple ID/2FA 로그인 대신 API 키 인증을 지원하는 이유 자체가 이거다).Appfile의apple_id(ENV["APPLE_ID"])는 V1에서 그대로 가져온 값이라 남아있을 뿐 — 비어있어도(RubyENV["APPLE_ID"]가nil을 반환할 뿐) Appfile 파싱이 깨지지 않는다. 만약 실행 중 실제로 Apple ID를 요구하는 에러가 나면(예상 밖 액션이 그 값을 쓰는 경우) 그때 이 판단을 재검토할 것. -
ASC_KEY_PATH가 가리키는.p8파일이 실제로 존재하는지(ls로 존재 여부만, 내용 안 읽음). 없으면 팀 채널에서 받아 그 경로에 두도록 안내하고 멈춘다. - Ruby/Bundler:
bundle -v. 없으면/setup5단계 안내. -
Gemfile.lock존재 확인 — 없으면 이번이 첫 실행이라는 뜻, 3단계 승인 후bundle install을 먼저 실행한다(생성된Gemfile.lock은 커밋 대상 — Ruby 애플리케이션 관례상 버전 고정을 위해 커밋한다, 라이브러리의 gitignore 관례와 다름). -
MATCH_PASSWORD셸 환경변수 확인(존재 여부만, 값 출력 금지). 없어도 치명적이진 않다 — 이 세션이 터미널처럼 완전한 대화형 TTY가 아니라 macOS Keychain에 이미 캐시된 값이 없으면match가 "Bailing out instead of asking for a password, since this is non-interactive mode" 로 조용히 실패할 수 있다는 걸 미리 경고만 하고 넘어간다(사용자가 이미 로컬 터미널에서sync_dev_certificates나 이 스킬을 한 번 성공시켜 Keychain에 캐시해뒀다면 문제없다 — 이 스킬은 그 상태를 확인할 방법이 없으므로 실패하면 이 원인부터 의심하도록 4단계에서 안내한다).
- 위 점검을 통과했으면, 무엇을 하는지 정확히 요약해서 보여주고 승인을 받는다:
-
release_betalane, schemeWSS-iOS-RELEASE, app identifier(.env의APP_IDENTIFIER_RELEASE값). - "아카이브 후 TestFlight 내부 테스터용으로 업로드됨(
distribute_external: false)"임을 명시하고, 이는 App Store 심사 제출이 아님을 다시 확인시킨다. - App Store Connect 레코드는 이미 확인·검증됐다(운영 레코드와 동일, 2026-09-21 실제 심사 승인까지
받음) — 더 이상 "레코드 자체가 없을 수 있다"는 리스크는 아니다.
⚠️ 이 식별자는 컷오버 후 운영 앱과 같아질 예정이라 특히 신중히 다룰 것.
-
- 승인 없이 3단계로 넘어가지 않는다.
- repo 루트에서:
bundle install(Gemfile.lock 없을 때만) →bundle exec fastlane release_beta. ⚠️ 오래 걸린다(약 44개 모듈tuist generate+아카이브+업로드, 수 분~십수 분) — Bash 도구를run_in_background: true로 실행하고, 완료 시 재알림을 기다리거나 필요하면Monitor로 진행 상황을 확인한다. 포그라운드로 돌려 타임아웃에 걸리지 않게 할 것.- 실행 로그에 민감정보가 섞여 나올 수 있다(서명 관련 경로 등) — 에러 진단에 필요한 부분만 사용자에게
보여주고,
.env의 실제 키 값이나.p8파일 내용 자체를 그대로 재출력하지 않는다.
-
성공: 빌드 번호(
increment_build_number_with_date가 만든yymmddvv), TestFlight 처리 상태 (skip_waiting_for_build_processing: true라 업로드 직후 반환됨 — App Store Connect에서 처리 완료는 별도 확인 필요하다고 안내). -
실패: fastlane이 뱉은 에러를 그대로 보여준다(추측으로 "아마 이래서 그럴 거예요"라고 뭉개지 않는다).
자주 겪을 수 있는 원인(모두 코드 수정이 아니라 계정/콘솔 쪽 확인이 먼저다):
-
MATCH_PASSWORD/Keychain 문제 → 위 1단계 경고 참고. - 프로비저닝 프로파일에 서명 문제 →
sync_dev_certificates가 아니라match(type: "appstore")를 쓰므로 development 기기 등록과는 무관하다 — Apple Developer 계정의 App Store 배포 인증서 자체를 의심할 것.
-
-
Release 스킴 전용 — Debug는
archive-debug. App Store 제출(releaselane)은 어느 쪽도 대신 호출하지 않는다. -
실행은 2단계 승인 후에만 — 사전 점검·요약까지는 승인 없이 진행해도 되지만, 실제
bundle exec fastlane호출은 외부 비가역 작업이다. -
비밀값은 존재 여부만 확인하고 값 자체는 절대 출력하지 않는다 —
.env·.p8·MATCH_PASSWORD전부. - 실패를 뭉개지 않는다 — fastlane 에러를 그대로 보여주고, 원인이 코드가 아니라 계정/콘솔 설정일 가능성부터 짚는다(Release 식별자의 App Store Connect 앱 레코드 자체는 아직 미검증 상태라 실패가 오히려 자연스러울 수 있다 — Debug 쪽은 이미 성공 사례가 있다).