2026년 독점 원격 Mac CI에서 CocoaPods와 Swift Package Manager 혼합 의존성 운영
iOS CI / DevOps 2026-04-08

2026년 독점 원격 Mac CI에서 CocoaPods와 Swift Package Manager 혼합 의존성: 캐시 디렉터리, 동시성 격리, SSH로 재현 가능한 xcodebuild 매개변수 의사결정 매트릭스+FAQ

레거시 Podfile과 최신 SPM 모듈이 한 저장소에 공존하면, CI에서 막히는 지점은 “빌드 명령 한 줄”보다 캐시가 어디에 쌓이는지, 병렬 잡이 같은 디스크를 어떻게 밟는지, SSH 비대화형 세션에서 환경 변수가 어디까지 전달되는지입니다. 이 글은 독점 원격 Mac 한 노드를 전제로 혼합 의존성 운영 런북을 정리합니다. 전체 파이프라인 관점은 2026년 원격 Mac mini를 이용한 iOS CI 구축: Xcode에서 TestFlight까지의 전체 프로세스와 함께 보시면 좋습니다.

1. 전제: 혼합 의존성에서 “한 번에 하나의 진실”을 고정한다

CocoaPods는 Rubygems·Pods/·(때로) *.xcworkspace를, SPM은 Package.resolved·SourcePackages·Xcode의 패키지 그래프를 끌고 옵니다. 둘 다 활성화되면 동일한 타깃에 두 해석기가 개입할 수 있어, CI에서는 다음을 먼저 동결합니다: (1) pod install이 성공하는 락 파일/커밋 해시, (2) SPM의 Package.resolved 버전, (3) Xcode·CLI 도구 메이저 버전. 원격 전용 노드에서 컴파일 자원을 어떻게 쓸지는 SSH를 통한 원격 Mac mini M5의 리소스 풀·Xcode 26 클러스터 구축에서 다룬 “풀 단위 스로틀”과도 연결됩니다.

2. 캐시 디렉터리 지도(2026년 기준 체크포인트)

아래는 혼합 프로젝트에서 자주 섞이는 경로입니다. 팀 표준에 맞춰 “공유 캐시 vs 잡 전용 캐시”를 먼저 결정하세요.

영역 대표 경로·산출물 CI 메모
CocoaPods specs ~/.cocoapods 에이전트 사용자 홈에 고정하면 재사용률↑. 다중 계정이면 경로 분리 필수.
Pods 체크아웃 프로젝트의 Pods/ 워크스페이스 캐시로 올리지 말고 저장소에 커밋 여부를 팀 규칙으로 명시.
SPM 체크아웃 보통 SourcePackages(프로젝트 상대) 또는 글로벌 캐시 Xcode가 선택한 “로컬 패키지 위치”와 xcodebuild -resolvePackageDependencies 순서를 문서화.
빌드 산출·색인 DerivedData 병렬 잡마다 분리하지 않으면 모듈 캐시 충돌·부분 손상이 납니다.

실무 팁: SSH로 접속한 자동화 계정에서 HOME과 TMPDIR가 로컬 로그인과 다르면 CocoaPods/SPM이 “같은 머신인데 캐시가 비어 있는 것처럼” 보입니다—런북에 echo $HOME·echo $TMPDIR를 프리플라이트로 넣으세요.

3. 동시성: “독점 Mac”이어도 디스크·시뮬레이터는 공유 자원이다

테넌트 간 경합은 없어도, 한 호스트에서 여러 CI 잡을 띄우면 다음이 겹칩니다: DerivedData 락, CoreSimulator 서비스, 키체인/서명 컨텍스트, SPM 글로벌 캐시. 권장 패턴은 (1) 잡 ID별 DERIVED_DATA_PATH, (2) 동시 시뮬레이터 테스트 상한, (3) pod install과 패키지 해석을 직렬화하는 가드(또는 잡 큐)입니다. “한 번에 하나의 pod install”은 Rubygems 락과 네트워크 재시도 폭주를 줄이는 데 특히 효과적입니다.

4. xcodebuild 매개변수 의사결정 매트릭스(SSH·재현성 중심)

목표가 로그에 남는 한 줄 재현인지, 최대 캐시 적중인지에 따라 플래그 우선순위가 달라집니다.

상황 우선 고려 플래그·설정 트레이드오프
SPM 해석을 CI에서 명시적으로 고정 -resolvePackageDependencies, 스킴·프로젝트 명시, 필요 시 클린 해석 순서 정의 네트워크 변동 시 첫 빌드 시간↑. 아티팩트 캐시와 짝을 이루면 완화.
병렬 잡 간 산출물 격리 -derivedDataPath(또는 환경 변수로 동일 효과), 잡별 빌드 번들 경로 기록 디스크 사용량↑. 보존 TTL 정책 필요.
워크스페이스 대 프로젝트 선택 CocoaPods가 생성한 *.xcworkspace를 스킴과 함께 고정 .xcodeproj만 지정해 “SPM만 보인다”는 클래스의 오류 방지.
코드 서명·프로비저닝(헤드리스) 서명 설정을 스킴·빌드 설정에 고정, 키체인 잠금 경쟁 최소화 동시 잡이 같은 키체인 아이템을 건드리면 플레이크↑. 잡 분리 또는 순차 구간 필요.

SSH 재현 체크리스트: 동일한 (a) Xcode 선택, (b) xcode-select 경로, (c) LANG/LC_ALL, (d) Ruby/CocoaPods 번들러 여부, (e) 프록시·Git SSH 설정—을 한 번에 출력하는 스크립트를 붙이면 “어제 되고 오늘 안 됨”을 줄입니다.

5. FAQ

Q1: pod install은 됐는데 SPM 패키지만 자꾸 다시 받아요.

Package.resolved가 커밋되어 있는지, CI가 다른 브랜치 체크아웃을 보고 있는지 먼저 확인하세요. 캐시 디렉터리가 잡마다 달라지면 “매번 새로 받는 것처럼” 보일 수 있습니다.

Q2: DerivedData를 공유하면 빌드가 빨라지지 않나요?

동시 쓰기가 없는 읽기 전용 스냅샷이면 도움이 될 수 있지만, 혼합 의존성·병렬 잡에서는 손상과 플레이크 비용이 큽니다. 보통은 잡별 분리 + 선택적 아티팩트 캐시가 안전합니다.

Q3: CocoaPods와 SPM이 같은 심볼/모듈을 중복 링크한다고 나옵니다.

의존성 그래프 상에서 동일 라이브러리가 두 경로로 들어온 경우입니다. 버전 핀닝, 타깃 가시성, use_frameworks! 여부를 함께 점검해야 하며 CI에서만 가리기 어렵습니다—로컬 재현 후 고정이 우선입니다.

Q4: SSH 세션에서만 실패합니다.

로그인 셸이 아닌 비로그인 셸이라 PATH·Ruby 버전 매니저 초기화가 빠졌을 가능성이 큽니다. 에이전트가 사용하는 셸 프로파일과 동일한 래퍼 스크립트를 강제하세요.

Q5: 캐시를 전부 지우면 되나요?

장애 트리아지에는 종종 유효하지만, 운영 비용과 네트워크 부하가 큽니다. 무엇을 지웠는지(Pods vs DerivedData vs SPM 캐시)를 로그에 남기고, 다음 빌드 SLA를 알고 실행하세요.

Apple Silicon macOS에서 혼합 의존성 CI를 굳히려면

CocoaPods와 SPM을 한 저장소에서 다루는 팀에게 원격 빌드 머신이 해야 할 일은 “명령을 실행”이 아니라 동일한 Xcode·Ruby·Git·캐시 경로를 장시간 유지하는 것입니다. macOS on Apple Silicon은 통합 메모리로 대형 Swift 모듈 그래프 컴파일에 유리하고, Gatekeeper·SIP는 일반적인 Windows 빌드 호스트보다 악성 코드 표면이 좁습니다. Mac mini급 장비는 유휴 전력이 매우 낮아 상시 노드로 두기 쉽고, 소음도 적어 사무실·랙 외곽 배치에도 부담이 적습니다.

원격 독점 Mac에서 캐시·동시성·SSH 재현성을 표준화했다면, 다음 단계는 하드웨어를 “빌드가 버틸 만큼” 안정적으로 고정하는 일입니다. Mac mini M4는 그 출발점으로 균형이 좋습니다—지금 구성해 두면 혼합 의존성 이슈는 워크플로와 락 파일 쪽으로 집중할 수 있습니다.

CocoaPods+SPM CI 전용 독점 원격 Mac이 필요하신가요?

SSHMac Remote Mac mini

캐시 경로와 xcodebuild 기준선을 한 노드에 고정한 뒤, 동시성과 서명을 조율하세요.

홈에서 옵션 보기