2026 임대 클라우드 Mac CI에서 ExportOptions.plist와 App Store Connect API로 iOS IPA보내기
이미 SSH로 Apple Silicon 클라우드 Mac에 접속해 xcodebuild archive를 돌리는 팀이라도, 다음 관문인 IPA보내기와 App Store 전달에서 파이프라인이 조용히 부패합니다. ExportOptions.plist의 method 오류, Xcode 서명 설정과 어긋난 수동 프로비저닝 맵, 더 이상 권장되지 않는 altool 가정이 남은 업로드 단계가 대표적입니다. 이 글은 2026년 기준 MacXCode가 홍콩·일본·한국·싱가포르·미국 동부 고객으로부터 받는 사례를 바탕으로, 누가(분산 iOS 팀), 무엇을(재현 가능한보내기 + API 업로드 체인), 어떻게(표·7단계·FAQ)를 한 번에 정리합니다. 함께 읽으면 좋은 글: 원격 Archive 자동화, 원격 서명 최적화, macOS 바이너리도 배포한다면 notarytool 패턴입니다.
실제 CI에서 -exportArchive가 실패할 때(“내 맥에선 된다”로 끝나지 않음)
보내기는 plist 하나와 CLI 한 줄처럼 보이지만, 운영에서는 아래 실패 유형이 지배적입니다. 로그 한 줄만으로는 원인 파악이 어려워 재현에 시간이 듭니다.
- 프로비저닝 드리프트 — 배포용 프로파일은 흔히 12개월 주기로 만료됩니다. 여섯 달 전에 캐시한 경로를 CI가 계속 쓰면 아카이브는 성공해도
error: exportArchive로 끝납니다. - method 불일치 — 엔터프라이즈 MDM 사이드로드에는
ad-hoc가 필요한데app-store를 고르거나 그 반대. 업로드는 성공해도 테스터 기기에 설치되지 않습니다. - 단일 호스트 병렬 작업 — 두보내기가 동일한
~/exports/release에 쓰면 레이스가 납니다. 24GB 통합 메모리 Mac mini M4에서는 경로를 작업 UUID로 분리하지 않으면 동시 3개 레인이 실무 상한에 가깝습니다. - 업로드 지연 — 약 220MB IPA를 12Mbps 상향으로 올리면 App Store Connect에 빌드가 보이기까지 24분 이상 걸릴 수 있습니다. 싱가포르 빌더에서 미동부 중심 엔드포인트로 올리면 체감이 더 큽니다.
여기에 Xcode 마이너 업데이트 이후 경고 임계값이 바뀌어 이전에는 통과하던 설정이 막히는 사례도 있습니다. 따라서 성공 빌드마다 툴체인 문자열을 메타데이터로 남기는 것이 장기적으로 비용을 줄입니다.
security find-identity -v -p codesigning과 ExportOptions.plist 앞 200자(민감값 마스킹)를 출력하세요. 실패 시 서명이 먼저 사라졌는지 plist 의미가 먼저 바뀌었는지를 가릴 수 있습니다.
ExportOptions.plist에서 실제로 고르는 배포 method
method는 장식이 아니라 엔타이틀먼트 처리, 심볼 업로드 기본값, 레거시 bitcode 기대까지 연결됩니다. TestFlight·엔터프라이즈·스토어 공개를 논의할 때 공통 어휘로 쓰세요.
| method 값 | 주요 대상 | 업로드 목표 | 운영 메모 |
|---|---|---|---|
app-store |
공개 App Store + TestFlight | App Store Connect 처리 대기열 | App Store 배포 프로파일 필요. 많은 템플릿이 심볼 업로드를 기본 활성화. |
ad-hoc |
등록 기기 / QA | MDM 또는 수동 설치가 흔함 | UDID 목록 신선도가 핵심. 임대 기기에서 푸시 검증에 적합. |
enterprise |
내부 전용 | 내부 CDN / MDM | 엔터프라이즈 프로그램 자격 필요. 클라우드 Mac에서도 키체인 분리 권장. |
development |
엔지니어 디버깅 | 직접 설치 | 반복이 가장 빠름. 첫 신뢰는 도움말의 VNC 절차를 참고. |
멀티 타깃 앱에서는 익스텐션마다 프로파일 요구가 달라 provisioningProfiles 사전을 PR 리뷰 범위에 넣는 것이 안전합니다. 저장소에 거대한 plist를 두기보다 CI 템플릿에서 생성하는 편이 드리프트가 적습니다.
method 밖의 고신호 키
Fastlane이 항상 깔린 임대 빌더는 드뭅니다. 아래 키 오설정이 지원 티켓을 부풀립니다. StackOverflow 길이의 plist는 과감히 다이어트하세요.
| 키 | 설정 시점 | 잘못 쓰면 |
|---|---|---|
signingStyle |
자동 vs 수동 프로파일 선택 | manual인데 provisioningProfiles 없으면 즉시 실패. automatic은 다중 팀에서 잘못 고를 수 있음. |
provisioningProfiles |
수동 멀티 타깃 | 익스텐션 누락은 부분보내기나 런타임 크래시로 이어짐. |
teamID |
한 호스트에 여러 Apple 팀 | 잘못된 teamID는 “서명 인증서 없음”처럼 보임. |
uploadSymbols |
TestFlight 크래시 분석 | 끄면 업로드는 빨라지지만 스택 심볼화가 어려워짐. |
compileBitcode |
레거시 파이프라인만 | 최신 iOS는 무시되는 경우가 많지만 오래된 Watch 타깃에서 예외가 있음. |
DERIVED_DATA_PATH는 임대 Mac 로컬 NVMe에 두세요. NFS DerivedData는 중간 규모 앱의 콜드보내기에 4~9분 정도 패널티가 쉽게 붙습니다.
7단계 런북: .xcarchive에서 ASC에 보이는 빌드까지
- 툴체인 고정 기록 —
xcodebuild -version,xcode-select -p,sw_vers를 반드시 로그. - 아카이브 무결성 —
Products/Applications/YourApp.app존재와codesign --verify --deep --strict. - 레인별 plist 렌더링 —
EXPORT_METHOD,TEAM_ID를 CI 변수에서. API issuer id는 서명 인증서와 분리 보관. - UUID 디렉터리로보내기 — 예:
exports/${BUILD_UUID}/로 충돌 방지. - export 실행 — 키체인 정책이 허용할 때만
-allowProvisioningUpdates. - 체크섬과 보관 — IPA SHA-256을 메타데이터화. dSYM은 최소 90일 보관이 일반적 지침.
- ASC API 업로드 — JWT 기반 도구를 표준화하고 Apple 상관 ID를 로그에 남김.
xcodebuild -exportArchive -archivePath ./build/YourApp.xcarchive -exportPath ./out -exportOptionsPlist ExportOptions.plist
성숙한 운영에서는보내기 CPU 시간보다 업로드 대기 시계가 병목이 되기도 합니다. 지역별로 워커를 두고 상행 경로를 짧게 만드는 투자가 효과를 냅니다. 요금과 리전은 pricing에서 비교하세요.
App Store Connect API vs 대화형 Transporter
Transporter.app는 일회 검증에 적합하지만, CI는 역할이 좁은 API 키로 표준화해야 합니다. Finder 스테이징을 거치지 않는 API 경로는 종종 더 빠르며, 심볼 gzip과 IPA 전송을 파이프라인화하기 쉽습니다. 싱가포르 빌더에서 글로벌 ASC 처리로 보낼 때도 JSON 오류 본문을 아티팩트로 저장하면 에스컬레이션이 빨라집니다.
온콜 플레이북에 MacXCode 도움말의 연결 요구사항을 링크해 두면 심야에 포트를 의심하는 왕복이 줄어듭니다.
공유 클라우드 Mac의 함정과 회피
스쿼드별로 베어메탈 Mac mini M4를 임대하는 편이 사무실 “펫” 맥 한 대를 나눠 쓰는 것보다 안정적인 이유는 키체인과 스토리지 격리가 명확하기 때문입니다. 그래도 멀티테넌트라면:
- macOS 사용자를 분리하거나 제품선마다 키체인 파일을 분리.
- 매주
~/Library/Developer/Xcode/Archives에서 21일 초과분 삭제. 아카이브 비대는보낸 뒤에도 계속됨. - launchd나 Actions 서비스 정의에
DEVELOPER_DIR를 명시해 GUI 로그인으로 Xcode가 바뀌는 일을 방지.
디스크는 IPA보다 오래된 시뮬레이터 데이터나 복수 Xcode 잔여물이 압박하는 경우가 많고, 여유가 15% 아래로 떨어지면 I/O 지연이 비선형으로 악화됩니다.
FAQ: 헤드리스 빌더에서보내기와 업로드
| 질문 | 실무 답변 |
|---|---|
| 모든 브랜치에 동일 plist 재사용 가능한가요? | method와 서명 스타일이 불변이면 가능. bundle id가 다른 기능 브랜치는 CI에서 plist 조각을 생성해 오래된 provisioningProfiles를 피하세요. |
| 여전히 전체 Xcode.app가 필요한가요? | 대부분의 iOS보내기 경로에서 필요합니다. CLT만 있는 호스트는 IDE 관리 자산이 부족합니다. 블로그 색인의 CLT 비교 글을 참고하세요. |
| 지역별 M4보내기 노드는 어디서 빌릴까요? | pricing에서 HK/JP/KR/SG/US를 비교하고 테스터 위치와 데이터 레지던시를 동시에 만족시키세요. |
왜 베어메탈 Mac mini M4는보내기 시간을 예측하기 쉬운가
보내기는 CPU·디스크·서명의 삼중 제약입니다. 통합 메모리는 .xcarchive를 뜨겁게 유지하고 번들 재봉인 시 I/O를 받칩니다. Apple Silicon의 AES 성능은 내부 미러로 암호화 업로드하는 파이프라인에서도 도움이 됩니다. 지원되지 않는 가상화 스택에 macOS를 억지로 올리는 것보다, 실제 Mac mini M4는 Xcode 릴리스 노트에 가까운 동작을 반환하고 오케스트레이터에서 SSH나 VNC로 조작하기만 하면 됩니다. MacXCode의 홍콩·일본·한국·싱가포르·미국 풀은 TestFlight 검증팀 가까이에 워커를 두면서 호스트 단위로 서명 자산을 격리하는 설계에 맞습니다.
한 줄 요약:ExportOptions.plist를 코드처럼 리뷰·버전관리하고, 프로덕션과 동급 머신에서보내기를 검증하세요. 레인을 늘릴 때는 단일 Mac에 과부하를 주기 전에 노드를 추가하고, pricing과 help로 연결과 용량을 확인하세요.
실제 M4에서 IPA보내기 레인 확장
HK / JP / KR / SG / US 빌더에 아카이브와보내기 여유를 줄 1TB 또는 2TB NVMe.