iOS CI 빌드 시간 초과는 바로 Mac 노드를 늘리지 말고, 대기열·작업 인수·의존성·xcodebuild·시뮬레이터·서명·업로드 단계부터 나눠 점검해야 합니다. 건강한 노드가 계속 가득 차고 동시 작업 증가와 함께 대기열이 늘며 개별 작업 시간은 정상일 때만 Mac 증설이나 탄력형 Mac 임대를 검토하는 방식이 안전합니다.
이 글은 다음 담당자에게 맞습니다.
- 기업 IT 책임자: 새 Mac 자원이 실제 초과 문제를 해결하는지 판단해야 하는 담당자
- 플랫폼 엔지니어링 책임자: Runner 상태부터 빌드 단계까지 증거를 연결해야 하는 담당자
- 개발 생산성 및 릴리스 책임자: 피크 시간대 대기와 배포 지연을 줄여야 하는 담당자
[ SECTION_01 ] 전체 빌드 시간 대신 장애 구간을 먼저 고정합니다
전체 소요 시간 하나만 보면 원인을 찾기 어렵습니다. 작업이 아직 Runner에 배정되지 않았는지, Mac에 들어갔지만 의존성을 내려받는 중인지, xcodebuild가 실제로 멈췄는지 구분해야 합니다.
최소한 다음 일곱 단계의 시작과 종료 시각을 같은 기록에 남깁니다.
- 워크플로가 생성된 시각
- 작업이 대기열에 들어간 시각
- Mac Runner가 작업을 인수한 시각
- 소스와 의존성 준비가 끝난 시각
xcodebuild또는 테스트가 시작된 시각- 서명과 패키징이 끝난 시각
- 업로드가 성공하거나 실패한 시각
GitHub Actions를 사용한다면 자체 호스팅 Runner의 라벨과 작업 라우팅 규칙을 먼저 확인해야 합니다. 라벨은 작업을 특정 Runner 조건에 연결하는 기준이므로, 자체 호스팅 Runner 라우팅 공식 문서와 Runner 라벨 적용 문서를 함께 확인하는 편이 좋습니다.
iOS CI 빌드 시간 초과는 무엇부터 확인해야 할까요?
먼저 실패한 작업 하나를 골라 대기 시작, Runner 인수, 의존성 준비, 빌드, 서명, 업로드의 시각을 기록합니다. 이 자료가 없으면 Mac 용량 부족과 외부 서비스 지연을 구분할 수 없습니다.
[ SECTION_02 ] 첫 번째 단계: 빈 Mac이 있어도 작업이 멈추는 라우팅 문제
Mac Runner가 유휴 상태라는 사실만으로 작업을 받을 수 있다는 뜻은 아닙니다. 다음 조건이 어긋나면 빈 노드가 있어도 작업은 대기합니다.
- 워크플로가 요구하는 라벨과 Runner 라벨이 다름
- Runner Group에 해당 저장소 또는 조직의 접근 권한이 없음
- Runner가 온라인처럼 보이지만 실제 작업 수신 프로세스가 비정상임
- 동시 실행 제한이나 워크플로 의존성이 다음 작업을 막고 있음
- 특정 브랜치 또는 릴리스 작업이 전용 노드만 기다리고 있음
GitHub의 워크플로 문서는 작업이 요구하는 Runner 조건과 실제 노드의 라벨을 기준으로 라우팅합니다. 따라서 워크플로에서 자체 호스팅 Runner를 사용하는 공식 설명을 기준으로 작업 조건과 노드 조건을 나란히 기록해야 합니다.
Mac Runner가 비어 있는데도 파이프라인이 초과되는 이유는 무엇인가요?
대기 중인 작업과 빈 노드가 같은 라우팅 조건을 갖고 있는지 확인해야 합니다. 라벨, 그룹 권한, 동시 실행 제한 중 하나라도 다르면 유휴 노드는 용량 증설의 근거가 되지 않습니다.
주의: 대기열 길이는 건강한 노드가 실제로 작업을 인수한 뒤에야 용량 지표가 됩니다. 라우팅 실패로 쌓인 대기 작업을 근거로 Mac을 추가하면 같은 장애가 반복될 수 있습니다.
[ SECTION_03 ] 두 번째 단계: 의존성·캐시·네트워크의 가짜 용량 부족
소스 준비 단계가 길다면 Mac CPU보다 외부 연결을 먼저 봐야 합니다. Git 저장소, Git LFS, Swift Package, 사설 패키지 저장소, 프록시, 인증 서비스, Apple 관련 접근 경로가 각각 다른 지연을 만들 수 있습니다.
확인 항목은 다음과 같습니다.
- 처음 받는 의존성과 캐시 적중 작업의 단계 시간을 분리합니다.
- 실패 후 재시도 횟수와 재시도 사이의 대기 시간을 남깁니다.
- 패키지 버전 변경으로 캐시가 무효화됐는지 확인합니다.
- 사설 저장소 인증 실패를 네트워크 지연으로 오인하지 않습니다.
- 같은 의존성을 여러 작업이 동시에 내려받는지 확인합니다.
캐시는 다시 만들어도 되는 데이터의 전송과 해석 비용을 줄이는 도구입니다. 접근 권한 오류, 사설망 차단, 버전 변동, 인증서 만료를 해결하지는 못합니다. GitHub Actions 동시성 공식 문서를 참고해 중복 실행과 취소 정책도 함께 확인해야 합니다.
캐시를 늘리면 Mac 증설을 대신할 수 있나요?
의존성 준비가 전체 시간의 큰 부분을 차지하고 캐시 누락이 반복될 때는 효과가 있을 수 있습니다. 그러나 캐시 적중 후에도 xcodebuild가 느리거나 작업이 노드를 기다린다면 캐시만으로는 부족합니다. 단계별 시간과 재시도 기록이 먼저입니다.
[ SECTION_04 ] 세 번째 단계: Xcode와 실제 빌드 자원 분리
xcodebuild는 명령줄에서 빌드와 테스트를 실행하는 도구입니다. Xcode 설정, 프로젝트 빌드 시스템, DerivedData 위치, 테스트 대상, 시뮬레이터 상태가 모두 결과에 영향을 줍니다. Apple의 Xcode 명령줄 도구 참고 문서와 Xcode 빌드 시스템 설명을 기준으로 실행 명령과 환경 변수를 고정해 기록합니다.
다음 증상을 분리하면 단일 작업 문제와 노드 포화 문제를 구분할 수 있습니다.
- 한 작업만 느림: 프로젝트 변경, 의존성, DerivedData, 특정 테스트를 의심합니다.
- 여러 작업이 함께 느림: 메모리 압박, 디스크 경쟁, 동시 실행 수를 확인합니다.
- 빌드는 끝났지만 테스트가 멈춤: 시뮬레이터 부팅과 테스트 대상 상태를 확인합니다.
- 테스트 결과 수집이 길어짐: 결과 파일 처리와 업로드 구간을 따로 봅니다.
- 노드마다 결과가 다름: Xcode 선택 상태, SDK, 환경 변수, 캐시 위치를 비교합니다.
시뮬레이터 문제는 빌드 문제와 다르게 처리해야 합니다. Apple은 시뮬레이터와 실제 기기에서 앱을 실행하는 절차를 별도로 안내하므로, 시뮬레이터 및 실제 기기 실행 문서를 기준으로 부팅, 대상 선택, 테스트 실행을 분리해 기록합니다. 테스트 결과 해석도 Apple의 테스트 결과 설명에 따라 로그와 결과 파일을 따로 보관합니다.
Xcode 빌드가 느리면 Mac 노드를 추가해야 하나요?
단일 작업의 특정 단계만 느리다면 먼저 프로젝트, 의존성, 테스트 대상, 디스크와 메모리 상태를 최적화해야 합니다. 여러 건강한 노드가 동시에 바쁘고 대기 시간이 동시 작업 증가와 함께 커질 때만 용량 부족으로 판정합니다.
[ SECTION_05 ] 네 번째 단계: 서명 노드는 일반 빌드 노드와 분리합니다
서명은 단순한 CPU 작업이 아닙니다. 인증서, 개인 키, 키체인 잠금 상태, 접근 제어, 실행 계정, 프로비저닝 자산이 함께 맞아야 합니다. Apple의 배포 서명 코드 문서를 기준으로 서명 시작 전후의 로그와 키체인 상태를 별도로 남깁니다.
일반 PR 빌드와 배포 서명을 한 Mac에서 동시에 처리하면 다음 문제가 생길 수 있습니다.
- 개인 키 접근 권한을 넓혀야 하는 보안 부담
- 키체인 잠금 또는 실행 계정 차이로 인한 간헐적 실패
- 릴리스 작업이 일반 빌드 자원을 선점하는 현상
- 서명 오류를 Mac CPU 부족으로 잘못 판단하는 문제
서명 단계가 막혔다면 노드를 더 추가하기보다 전용 서명 노드, 제한된 Runner Group, 별도 자격 증명 정책을 먼저 검토합니다. 서명 자산을 일반 작업에 공유하지 않는 것이 우선입니다.
운영 경험: 생산 서명 노드와 PR 노드는 같은 용량 모델에 넣지 않는 편이 안전합니다. 서명 대기는 보안 정책과 자격 증명 문제일 수 있어, 빈 Mac을 추가해도 해결되지 않습니다.
[ SECTION_06 ] iOS CI 용량 판단 도구: 조건별로 다음 조치를 선택합니다
아래 항목은 작업 하나가 실패했을 때와 피크 시간대의 전체 상태를 함께 판단하는 용도입니다. 확인하지 못한 항목은 충족으로 표시하지 않습니다.
- [ ] 대기 시작 시각과 Runner 인수 시각이 기록되어 있습니다.
- [ ] 작업의 라벨과 실제 Runner 라벨이 일치합니다.
- [ ] Runner Group 권한과 동시 실행 제한을 확인했습니다.
- [ ] 의존성 다운로드, 캐시, 재시도, 사설 저장소 응답을 분리했습니다.
- [ ]
xcodebuild, 테스트, 시뮬레이터, 서명, 업로드의 시작과 종료 시각이 있습니다. - [ ] 같은 노드에서 단일 작업과 여러 동시 작업의 결과를 비교했습니다.
- [ ] 노드가 건강한 상태에서 계속 작업 중인지 확인했습니다.
- [ ] 동시 작업 증가에 따라 대기열도 증가하는지 확인했습니다.
판정은 다음처럼 진행합니다.
- 라우팅 또는 권한 항목이 확인되지 않으면 Mac을 늘리지 말고 Runner 설정을 수정합니다.
- 의존성 또는 캐시 단계만 길면 네트워크, 저장소, 캐시 정책을 먼저 조정합니다.
- 단일
xcodebuild작업만 길면 프로젝트와 테스트 구성을 먼저 분석합니다. - 서명 단계만 멈추면 전용 서명 노드와 자격 증명 격리를 검토합니다.
- 위 항목이 정상이고 건강한 노드가 계속 가득 차며 대기열이 동시성에 비례해 증가하면 고정 Mac 또는 공유 빌드 풀을 확장합니다.
- 부하가 릴리스 기간이나 단기 시험에만 몰리면 탄력형 원격 Mac 임대 PoC를 먼저 실행합니다.
이 조건 목록에서 마지막 두 항목만 확인됐을 때 Mac 용량 부족을 확장 근거로 인정하는 편이 안전합니다.
[ SECTION_07 ] 증거로 결정하는 Mac 확장 조건
용량 모델에는 작업 도착량, 피크 동시성, 평균 실행 시간, 허용 대기 시간, 고정 노드 수, 예비 용량, 장애 복구 요구를 변수로 넣습니다. 임의의 가격이나 성능 수치를 넣지 말고, 기업의 실제 작업 기록으로 값을 채워야 합니다.
Mac 구매와 임대의 비용 항목을 비교할 때는 장비 가격만 보지 않습니다. 구매안에는 감가, 예비 장비, 교체, 현장 접근, 전력, 운영 인력, 고장 대응을 포함합니다. 임대안에는 계약 기간, 접속 방식, 데이터 이동, 계정 관리, 종료 시 데이터 삭제 검증을 포함합니다. Mac 미니 렌탈 가격 안내는 실제 검토 단계에서 확인하되, 글에 없는 가격이나 성능을 가정해서는 안 됩니다.
[ SECTION_08 ] 확장 후 검증 절차
새 Mac을 추가한 뒤에는 노드가 온라인으로 보이는지만 확인하면 안 됩니다. 다음 순서로 실제 파이프라인을 검증합니다.
- 새 노드가 의도한 라벨과 Runner Group에 등록되는지 확인합니다.
- 실제 PR 작업이 새 노드에 배정되는지 확인합니다.
- 소스, Swift Package, Git LFS, 캐시 동작이 기존 노드와 일치하는지 확인합니다.
xcodebuild빌드와 테스트가 성공하는지 확인합니다.- 배포 서명 작업은 허용된 노드에서만 실행되는지 확인합니다.
- 결과 업로드와 오류 로그가 끝까지 남는지 확인합니다.
- 노드 재시작 뒤 Runner가 자동 복귀하고 다음 작업을 받을 수 있는지 확인합니다.
이 검증을 통과하지 못하면 증설 효과를 처리량으로 인정하지 않습니다. 특히 새 노드가 작업을 받지 못하거나 서명 자격 증명이 빠졌다면, 실제 용량은 늘지 않은 상태입니다.
[ SECTION_09 ] 기업용 판단을 다음 실행으로 연결합니다
iOS CI 빌드 시간 초과는 Mac 대수보다 단계별 증거가 먼저입니다. 대기열과 라우팅 문제는 설정을 고치고, 단일 작업 병목은 빌드와 의존성을 최적화하며, 건강한 노드의 지속 포화만 용량 확장의 근거로 삼아야 합니다.
현재 고정 Mac만 운영하면 피크 시간에 예비 용량이 부족하고, 장비 구매·교체·보안 운영을 직접 부담해야 하며, 짧은 릴리스 집중 부하에도 유휴 자원이 남을 수 있습니다. 반대로 탄력형 원격 Mac은 작업 배정, 의존성, 서명, 재시작 복구를 실제 파이프라인으로 검증해야 합니다. NOVAKVM을 검토한다면 한국 지역 Mac 주문 안내를 확인한 뒤, 먼저 한 개의 실제 워크플로로 대기·빌드·서명·복구 경로를 시험하는 방식이 적절합니다. 이후 기록된 결과로 단기 임대, 고정 Mac 구매, 혼합 구성을 결정해야 합니다.