DevOps / CI·CD 2026년 4월 30일

2026-04-30 iOS CI 마이그레이션: Intel x86_64에서 Apple Silicon ARM64, 임대 클라우드 Macxcodebuild(HK / JP / KR / SG / US)

MacXCode 엔지니어링 팀 2026년 4월 30일 약 24분

Apple은 여전히 Intel용 Xcode를 내지만 2026년에는 대부분의 모바일 팀이 더 이상 배포하지 않는 x86_64 슬라이스에 클라우드 비용을 내지 않습니다. 큐가 낡은 Intel Mac mini를 가리키는데 제품 바이너리가 arm64뿐이면 의존성 그래프 이중 유지와 느린 xcodebuild test 콜드 스타트에 돈을 쓰게 됩니다. 이미 홍콩·도쿄·서울·싱가포르·미국Mac mini M4 빌더로 옮긴 경쟁사보다 불리합니다. 이 글(2026-04-30)은 영업 자료가 아니라 릴리스 엔지니어용 마이그레이션 브리프입니다. 팻 바이너리 재고, ARCHS 정규화, Apple Silicon 슬라이스가 없는 CocoaPods 벤더 정리, 플레이크를 신뢰할 만큼의 이중 매트릭스, 기본 라우팅을 ARM64로 바꾸되 레거시 CLI용 브레이커 경로를 남기는 흐름을 다룹니다. 원격 Archive, 병렬 Xcode, 다중 Xcode와 xcode-select, 병렬 부하에서 달라지는 Swift 6 엄격 동시성과 함께 읽으세요.

스냅샷: “내 M3에서 된다”는 것만으로는 부족하다

노트북은 죄를 숨깁니다. 따뜻한 모듈 캐시, Rosetta를 통과한 투명한 툴체인, 인간의 인내. CI는 몇 분 안에 드러내야 합니다. 마이그레이션 중임을 알리는 세 신호:

  • 링커 오류undefined symbols for architecture arm64라고 하는데 벤더 XCFramework의 lipo -archs에 아직 x86_64가 남아 있다.
  • 시뮬레이터 목적지 드리프트: Intel 시대 destination이 YAML에 남아 있고 새 Xcode 번들에서 디바이스 이미지가 사라졌다.
  • 러너 라벨 거짓: GitHub Actions나 Buildkite 태그가 macos-intel인데 셸은 실제 arm64(운영이 이름을 재사용).
추적할 숫자: 중간 규모 앱에서 ARM64 정규화 후 클린 xcodebuild build 벽시계를 35% 이상 줄이는 것을 목표로 하고, Intel 용량을 없애기 전 이중 큐를 14일 관측한다.

바이너리 재고: Swift를 탓하기 전에 x86_64를 증명한다

Carthage/Build, Pods/, ThirdParty/ 아래의 .framework, .a, 사전 컴파일 XCFramework를 순회합니다. 마이그레이션 티켓에 붙일 두 명령:

find . \( -name "*.framework" -o -name "*.a" -o -name "*.xcframework" \) -print0 | xargs -0 -I@ sh -c 'echo "@:"; lipo -info "@" 2>/dev/null || file "@"'

Intel 전용 슬라이스만 파는 벤더가 보이면 상업 스레드를 열고, EXCLUDED_ARCHS=arm64 해킹으로 Rosetta를 본 엔지니어에게 몰래 보내지 마세요. 셀프호스티드 러너와 함께하는 임대 호스트에서는 탐지 스크립트를 하나의 인프라 리포에 모아 모든 리전이 같은 버전을 돌리게 하세요. JPUS가 어긋나면 “도쿄는 초록, 버지니아는 빨강” 티켓이 번식합니다.

러너 책임: Intel 레인과 ARM 레인

전환기에는 각 레인에 명시적 보장을 두고 둘 다 “같은 CI”인 척하지 마세요.

레인 담당 담당하면 안 되는 것
ARM64 기본 기본 PR 검사, 시뮬레이터 테스트, TestFlight용 Archive arm64 빌드가 없는 레거시 CLI(샌드박스 없이)
Intel 브레이커 업데이트 대기 중인 벤더 바이너리, 일회성 패리티 장기 서명. 프로덕션 키와 얽지 않기
스모크 하이브리드 필요 시 file 등으로 팻 슬라이스를 검증하는 스크립트 iOS 앱 타깃에 대한 숨은 Rosetta 의존

xcodebuild 플래그와 빌드 설정을 정책으로

공유 xcconfig나 Fastlane env export에 한 번 논의해 상속시킵니다.

설정 ARM64 CI 권장 비고
ARCHS arm64 앱과 확장에서 스킴이 다를 때 “standard”보다 명시가 안전.
ONLY_ACTIVE_ARCH Release형 CI는 NO. 내부 루프 Debug에서 얇은 슬라이스를 허용하면 YES. 여기가 어긋나면 실기기 대 시뮬레이터에서 플레이크가 난다.
EXCLUDED_ARCHS[sdk=iphonesimulator*] Apple Silicon 호스트에서는 대개 비움 Intel 시대 제외가 arm64 시뮬 빌드를 실수로 막지 않았는지 확인.

플래그는 고정된 DEVELOPER_DIR와 짝을 이룹니다. xcode-select 매트릭스가 없으면 같은 프로젝트를 두 Xcode가 다르게 해석하는 회고가 지옥이 됩니다.

CocoaPods, SwiftPM, ARM64와 싸우는 바이너리 그래프

CocoaPods는 Intel에서 rsync하지 말고 arm64 호스트에서 Pods/를 재생성해 스크립트 페이즈가 올바른 아키로 컴파일되게 합니다. SwiftPM은 Package.resolved의 바이너리 타깃에 arm64-apple-ios가 있는지 확인합니다. 프레임워크가 늦으면 임시 소스 빌드나 포크 고정. 이자는 매일 쌓입니다.

Rosetta 함정: uname -marm64여도 file $(which node)가 x86_64이면 OpenClaw나 JS 린터가 조용히 번역 실행—CPU를 태우고 크래시 로그를 혼란스럽게 합니다.

이중 레인 일정: 큐 깊이, 메모리, 디스크

Mac mini는 빛나지만 16 GB에서 무거운 Archive 세 개와 UI 테스트를 동시에 올리면 무너집니다. 마이그레이션 중에는 측정한 메모리 압에 맞춰 호스트당 동시 xcodebuild를 제한하고 “ARM 컴파일만”과 “ARM Archive” 풀을 라벨로 나눕니다. ARM64여도 DerivedData는 작아지지 않습니다. 실험이 서로 캐시를 쫓아내지 않도록 DerivedData 격리와 함께 마이그레이션하세요.

SRE가 Jira에 붙일 수 있는 8단계

  1. 컷오버 주말 72시간 전부터 의존성 범프 동결.
  2. 모든 리전 호스트에서 재고 스크립트 실행, 차이를 인프라 리포에 커밋.
  3. 확장 포함 모든 스킴에 xcconfig 정책 적용.
  4. arm64 클린 checkout에서 Pods와 SwiftPM 재부트스트랩.
  5. 동일 시드로 이중 큐를 켜 벽시계·플레이크율·아티팩트 크기 비교.
  6. 기본 PR 라우팅을 ARM64로 바꾸고 Intel 레인은 읽기 전용.
  7. 14일 관측. 실패율이 튀면 시크릿이 아니라 라벨로 롤백.
  8. Intel을 폐기하거나 청구 태그를 뗀 전문 잡으로 강등.

지표 표: 임대 M4에서 “성공”의 모습

지표 Intel 기준(예) ARM64 목표
클린 빌드 p50 19.5분 같은 커밋에서 12.0분 이하
시뮬레이터 UI 테스트 p95 41분 목적지 정규화 후 28~33분
주간 전력 비용 대리(정규화) 1.00 대기 와트와 처리량 합산 0.62~0.78

예시 숫자는 Grafana나 Buildkite 히스토그램으로 바꾸세요. 원시 데이터 없는 마이그레이션 덱은 내지 마세요.

FAQ: Rosetta, 시뮬레이터, 서명

질문 실무 답(2026-04-30)
속도를 위해 Rosetta로 CI를 돌려야 하는가 iOS 컴파일에는 아니요. 네이티브 arm64 툴체인이 이김. Rosetta는 주변 레거시 CLI만.
아키별로 서명 아이덴티티를 나눠야 하는가 아이덴티티 자체는 아키 비의존. 다만 프로비저닝과 엔타이틀먼트는 실제 출하 바이너리와 맞추고 그래프 변경 후 재보내기.

서명 자동화는 키체인과 프로비저닝 CI를 계속합니다. 아키 마이그레이션은 숨은 프로필 불일치를 드러냅니다.

마이그레이션에 베팅한다면 베어메탈 Mac mini M4

ARM64 CI는 클럭만이 아니라 하이퍼바이저에 거짓말하지 않는 결정적 툴체인 이야기입니다. MacXCode 리전의 1~2 TB NVMe 임대 Mac mini M4는 이중 레인을 얹고 여러 DEVELOPER_DIR 트리를 남기며 엔지니어가 다른 시간대에 잠든 동안의 DerivedData 스파이크도 흡수할 여유를 줍니다. 그 여유가 플래그 데이를 무서운 이벤트가 아니라 측정·되돌리기 가능한 롤아웃으로 바꿉니다. 두 번째 노드 추가 가격이 투명한 것도 돕습니다. 프롬프트 감사가 필요하면 VNC는 최소한. 일상 마이그레이션은 grep 가능한 SSH 로그에 둡니다.

레거시 레인 옆에 네이티브 ARM64 빌더 세우기

Mac mini M4 · HK / JP / KR / SG / US · SSH / 선택 VNC