Apple은 Xcode 27 beta 4에 Apple Silicon과 macOS Tahoe 26.4 이상을 요구합니다. Apple의 Xcode 시스템 요구 사항에 따르면 Xcode 26.6은 안정 버전으로 구분되므로, 2026년 7월 31일 현재 생산 Runner를 Xcode 27로 즉시 교체해서는 안 됩니다. 이번 주에는 Xcode 26.6을 유지하고, 별도 Apple Silicon 맥에 Xcode 27 GitHub Actions 자체 호스팅 Runner를 추가한 뒤 빌드, 테스트, 서명, Archive를 모두 검증해야 합니다.
이 글은 iOS 또는 macOS CI/CD를 담당하는 DevOps 엔지니어를 위한 배포 절차입니다. 로컬 Apple Silicon 맥이 없지만 SSH로 계속 실행되는 빌드 호스트가 필요한 개발자, 여러 앱의 도구 체인 전환과 롤백 정책을 정해야 하는 개발 책임자도 대상입니다.
마지막 검토: 2026년 7월 31일. Xcode 시스템 요구 사항, Xcode 27 Release Notes, GitHub Actions Runner 문서를 기준으로 확인했습니다. Apple 또는 GitHub가 베타 상태, Runner 라벨, 지원 아키텍처를 변경하면 실제 배포 전에 다시 확인해야 합니다.
이번 주 실행 순서를 먼저 고정합니다
Xcode 27 전환의 첫 단계는 설치가 아니라 작업 범위 제한입니다. 안정 빌드와 베타 검증을 서로 다른 Runner로 나누면 실패가 생산 릴리스로 번지는 것을 막을 수 있습니다.
| 시점 | 실행 항목 | 통과 신호 | 실패 시 조치 |
|---|---|---|---|
| 오늘 오전 | 칩, 운영체제, SSH, 관리자 권한 확인 | 도구 체인 명령이 실행됨 | 호스트 또는 운영체제 교체 |
| 오늘 오후 | Xcode 27 Runner 등록 | GitHub에서 Online 표시 | 토큰, 네트워크, 서비스 점검 |
| 첫날 | 실제 앱의 빌드와 서명 검증 | Archive까지 완료 | Xcode 26.6 유지 |
| 첫 주 | 로그, 캐시, 권한, 실패 단계 검토 | 두 환경의 차이 기록 | Xcode 27 Job 중지 |
GitHub는 Xcode 27 호스팅 이미지를 공개 프리뷰로 제공하고 있으며, 해당 이미지는 ARM64 Runner를 대상으로 합니다. 공개 프리뷰는 테스트에 사용할 수 있지만, 이미지 변경 가능성까지 포함하므로 생산 환경 전환의 근거로 단독 사용해서는 안 됩니다. (GitHub 공식 변경 기록)
이동 전에 호스트와 파이프라인 경계를 확인합니다
Xcode 27 beta 4는 Apple Silicon 맥과 macOS Tahoe 26.4 이상이 필요합니다. 인텔 맥이나 이전 운영체제를 검증 노드로 가정하면 설치 단계에서 중단될 수 있습니다. 베타의 알려진 문제는 Xcode 27 Release Notes에서 확인해야 하며, 공식 출시일이나 향후 호환성을 추정해 생산 전환 일정을 정해서는 안 됩니다.
호스트 확인 항목
| 확인 영역 | 검증 기준 | 확인 방법 |
|---|---|---|
| 칩 | Apple Silicon, arm64 | uname -m |
| 운영체제 | macOS Tahoe 26.4 이상 | sw_vers |
| Xcode | 승인된 Xcode 27 beta 버전 | xcodebuild -version |
| Swift | 프로젝트 요구 사항과 일치 | swift --version |
| 연결 | SSH와 GitHub 통신 가능 | SSH 접속, 네트워크 정책 |
| 권한 | Runner 설치와 서비스 등록 가능 | 관리자 권한 확인 |
저장 공간은 Xcode 앱만 기준으로 계산하면 안 됩니다. Simulator 런타임, Swift Package Manager 의존성, CocoaPods 의존성, DerivedData, Archive 산출물이 함께 사용되기 때문입니다. 최소 용량을 일반화하기보다 기존 프로젝트의 최근 캐시와 Archive 크기를 측정하고, 베타 검증용 여유 공간을 별도로 확보해야 합니다.
배포 전에는 다음 상태도 문서화합니다.
- 생산 Job이 사용하는 Xcode 경로
- Swift 언어 모드와 SDK
- Simulator 기기와 운영체제 조합
- 의존성 캐시와 DerivedData 경로
- 인증서와 Provisioning Profile의 사용 범위
- Xcode 27 Runner가 처리할 저장소와 브랜치
- 정식 배포 이벤트가 베타 Runner로 유입되지 않는지 여부
Xcode 27 노드는 처음부터 모든 저장소를 처리하지 않아야 합니다. 비핵심 앱과 개발 브랜치만 허용하고, 정식 배포 브랜치와 배포용 서명 키는 기존 안정 환경에 남겨야 합니다.
첫 1시간에 Runner를 등록합니다
GitHub 공식 절차는 저장소나 조직 설정에서 자체 호스팅 Runner를 추가한 뒤 운영체제와 아키텍처에 맞는 Runner 프로그램을 내려받고 등록하는 방식입니다. 자체 호스팅 Runner 추가 문서에 표시되는 등록 토큰은 임시 값이므로 저장소에 고정하거나 여러 호스트에서 재사용해서는 안 됩니다.
실제 등록 순서는 다음과 같습니다.
- 저장소 또는 조직 설정에서 Actions와 Runners 메뉴를 엽니다.
- 새 자체 호스팅 Runner를 선택합니다.
- macOS와 ARM64에 맞는 설치 명령을 확인합니다.
- 원격 맥에 전용 Runner 디렉터리를 만듭니다.
- 공식 Runner 프로그램을 내려받습니다.
config.sh로 저장소 주소, 임시 토큰, Runner 이름을 입력합니다.- Apple Silicon, Xcode 27, 검증 환경을 구분하는 라벨을 지정합니다.
./run.sh로 최초 연결을 확인합니다.- GitHub 화면에서 Online 상태를 확인합니다.
- 작은 테스트 Job을 실행해 작업 수신 여부를 확인합니다.
라벨과 Runner Group을 분리합니다
Job은 runs-on의 라벨과 Runner Group 조건에 맞는 호스트로 전달됩니다. 라벨이 잘못되면 Job이 대기 상태에 머물고, 온라인 Runner가 있어도 작업이 시작되지 않을 수 있습니다. 따라서 라벨은 설명용 이름이 아니라 배포 안전장치로 관리해야 합니다.
| 구분 | 라벨 예시 | 목적 |
|---|---|---|
| 공통 | self-hosted |
자체 호스팅 노드 식별 |
| 운영체제 | macOS |
맥 Runner 선택 |
| 칩 | ARM64 |
Apple Silicon 구분 |
| 안정 버전 | xcode-26-6 |
생산 빌드 고정 |
| 검증 버전 | xcode-27 |
베타 Job 전용 |
| 범위 | ios-validation |
허용된 검증 작업 구분 |
Xcode 27을 삭제하거나 경로를 바꾼 뒤에는 기존 라벨을 즉시 수정해야 합니다. 실제 도구 체인과 라벨이 다르면 다른 Job이 의도하지 않은 호스트에서 실행될 수 있습니다.
재부팅 뒤에도 Runner가 실행되도록 구성합니다
SSH 세션에서 run.sh만 실행하면 터미널이 끊긴 뒤 Runner도 종료됩니다. 장기 실행 노드라면 공식 서비스 등록 절차를 사용해야 합니다. Runner 서비스 구성 문서의 절차에 따라 설치한 뒤 상태를 확인합니다.
cd ~/actions-runner-xcode27
./svc.sh install
sudo ./svc.sh start
설치 후에는 다음 신호를 순서대로 점검합니다.
- 서비스가 실행 중입니다.
- GitHub Runner 화면에 Online으로 표시됩니다.
- SSH 연결을 종료해도 Online 상태가 유지됩니다.
- 맥을 재부팅한 뒤 Runner가 다시 연결됩니다.
- 지정 라벨의 테스트 Job이 정상적으로 배정됩니다.
서비스가 Online인데 Job을 받지 못하면 라벨, Runner Group, 저장소 허용 범위를 먼저 확인해야 합니다. Offline 상태라면 네트워크보다 먼저 서비스 로그, 로그인 사용자, 디스크 상태를 분리해 확인하는 편이 빠릅니다.
두 Xcode 버전의 워크플로를 분리합니다
생산 Job은 Xcode 26.6에 고정하고, Xcode 27 Job은 수동 실행이나 지정 브랜치에서만 호출해야 합니다. Job 시작 부분에는 실제 Xcode, Swift, SDK, CPU 아키텍처를 출력해야 합니다. 경로를 명시하지 않으면 macOS의 기본 개발자 디렉터리 상태에 따라 결과가 달라질 수 있습니다.
jobs:
stable-build:
if: github.ref == 'refs/heads/main'
runs-on: [self-hosted, macOS, ARM64, xcode-26-6]
steps:
- uses: actions/checkout@v4
- name: 안정 도구 체인 확인
run: |
sudo xcode-select -s /Applications/Xcode_26.6.app
xcodebuild -version
swift --version
uname -m
- name: 안정 빌드
run: xcodebuild -workspace App.xcworkspace -scheme App build
beta-validation:
if: github.event_name == 'workflow_dispatch' || startsWith(github.ref, 'refs/heads/xcode27/')
runs-on: [self-hosted, macOS, ARM64, xcode-27]
steps:
- uses: actions/checkout@v4
- name: 베타 도구 체인 확인
run: |
sudo xcode-select -s /Applications/Xcode_27.app
xcodebuild -version
swift --version
xcodebuild -showsdks
uname -m
- name: 검증 빌드
run: xcodebuild -workspace App.xcworkspace -scheme App build
한 호스트에서 여러 Job이 동시에 실행되며 전역 xcode-select를 바꾸면 서로의 도구 체인에 영향을 줄 수 있습니다. 가능하면 안정 버전과 베타 버전을 서로 다른 호스트에 배치해야 하며, 같은 호스트를 사용할 때는 동시 실행을 제한하고 작업 디렉터리를 격리해야 합니다.
| 항목 | Xcode 26.6 생산 Job | Xcode 27 검증 Job |
|---|---|---|
| 실행 조건 | 기본 브랜치와 정식 이벤트 | 수동 실행 또는 검증 브랜치 |
| Runner 라벨 | xcode-26-6 |
xcode-27 |
| 캐시 | 기존 안정 캐시 | 별도 키와 경로 |
| 서명 | 정식 배포 가능 | 검증용 범위로 제한 |
| 산출물 | 배포 후보 | 비교와 문제 분석용 |
| 실패 처리 | 릴리스 차단 기준 | Job 중지와 원인 분류 |
Xcode 26.6과 Xcode 27은 DerivedData, Simulator 상태, 의존성 캐시를 공유하지 않는 것이 좋습니다. 캐시 키에는 도구 체인, SDK, 프로젝트 변경 식별자를 포함하고, 베타 산출물이 안정 Job으로 유입되지 않도록 Artifact 이름도 구분해야 합니다.
첫날에는 실제 앱으로 검증합니다
샘플 프로젝트만 통과한 상태는 마이그레이션 완료가 아닙니다. 정식 배포와 연결되지 않은 실제 앱의 검증 브랜치에서 다음 순서로 실행해야 합니다.
- [ ] 의존성이 잠금 파일에 따라 재현됩니다.
- [ ] 일반 컴파일이 완료됩니다.
- [ ] 단위 테스트가 완료됩니다.
- [ ] UI 테스트용 Simulator가 정상 생성됩니다.
- [ ] Archive가 생성됩니다.
- [ ] 코드 서명과 Provisioning Profile 검증이 완료됩니다.
- [ ] Xcode, Swift, SDK, 아키텍처가 로그에 기록됩니다.
- [ ] 동일 커밋을 Xcode 26.6에서 다시 실행합니다.
- [ ] 실패 단계와 로그 위치를 이슈에 남깁니다.
| 검증 단계 | 남길 정보 | 통과 기준 |
|---|---|---|
| 의존성 설치 | 잠금 파일, 패키지 버전 | 변경 없이 설치 완료 |
| 컴파일 | Xcode, Swift, SDK, 경고 | 오류 없이 완료 |
| 테스트 | Simulator와 운영체제 | 단위·UI 결과 보존 |
| Archive | 산출물 경로, 빌드 번호 | Archive 생성 |
| 서명 | 인증서와 Profile 식별 정보 | 검증 성공, 비밀값은 제외 |
Xcode 27에서만 실패하고 Xcode 26.6에서 통과한다면 즉시 프로젝트 코드의 문제로 결론 내리지 않아야 합니다. Release Notes의 알려진 문제, SDK 변화, 서드파티 의존성 지원 범위를 각각 비교해야 합니다. Xcode 27의 시험 결과는 베타 기능의 성능 평가가 아니라 현재 프로젝트가 다음 도구 체인에서 통과하는지 확인하는 호환성 자료로 다루는 편이 정확합니다.
비용과 운영 방식을 함께 비교합니다
검증 노드를 마련할 때는 장비 가격만 보지 말고 사용 기간, 상시 전원, 원격 관리, 장애 대응, 데이터 보존을 함께 계산해야 합니다. 공개 근거가 없는 가격이나 성능 수치는 특정 환경에 일반화하지 않는 것이 좋습니다.
| 방식 | 주요 비용 항목 | 적합한 상황 | 운영상 주의점 |
|---|---|---|---|
| 맥 한 대에 두 버전 설치 | 장비 추가 비용은 낮음 | 순차 실행과 단일 개발자 | 전역 경로와 캐시 충돌 |
| 별도 Apple Silicon 맥 구매 | 하드웨어, 유지보수, 전력 | 장기 고정 부하 | 초기 비용과 관리 책임 |
| 원격 맥을 주기적으로 사용 | 사용 기간, 저장 공간, 접속 | 베타 검증과 단기 확장 | 계약 기간과 데이터 보존 |
| GitHub 호스팅 이미지 | Actions 사용량과 대기 정책 | 빠른 공개 프리뷰 확인 | 이미지 변경과 ARM64 제한 |
로컬 장비가 CI를 계속 담당하기 어렵다면 Vuncloud의 원격 맥 지원 안내에서 SSH 접속과 장기 실행 조건을 먼저 확인할 수 있습니다. 장기간 한 대를 전용 CI 호스트로 운영해야 한다면 Mac mini 대여 방식도 함께 비교할 수 있습니다. 기존 맥 구매와 원격 맥 사용을 비교할 때는 사용 기간이 짧은지, 물리 장치가 필요한지, 관리자 권한과 저장소 접근을 직접 통제해야 하는지를 기준으로 판단해야 합니다.
| 운영 조건 | 원격 맥이 유리한 경우 | 직접 구매가 유리한 경우 |
|---|---|---|
| 사용 기간 | 베타 검증이나 단기 프로젝트 | 장기간 고정 운영 |
| 관리 책임 | 장비 관리 부담을 줄이고 싶은 경우 | 하드웨어와 보안을 직접 통제해야 하는 경우 |
| 접속 방식 | SSH와 원격 관리로 충분한 경우 | 물리 장치, 케이블, 특정 주변기기가 필요한 경우 |
| CI 역할 | 독립 검증 Runner가 필요한 경우 | 안정적인 전용 생산 노드가 필요한 경우 |
첫 주에는 롤백과 권한을 운영 규칙으로 만듭니다
다음 조건 중 하나라도 발생하면 Xcode 27 검증 Job을 중지하고 Xcode 26.6을 기본 경로로 유지해야 합니다.
- Archive가 반복적으로 실패합니다.
- 코드 서명 결과가 안정 환경과 다릅니다.
- UI 테스트가 Runner 상태에 따라 불규칙하게 실패합니다.
- 캐시 삭제 후에만 빌드가 통과합니다.
- Release Notes의 알려진 문제와 오류가 일치합니다.
- 프로젝트 코드와 도구 체인 중 원인을 분리하지 못했습니다.
롤백 시에는 베타 Job만 중지하고, 기존 안정 캐시와 산출물을 덮어쓰지 않아야 합니다. 동일 커밋을 Xcode 26.6에서 실행해 생산 경로가 정상인지 확인한 뒤, 실패 로그와 도구 체인 출력을 보존해야 다음 베타 업데이트에서 재검증할 수 있습니다.
공개 저장소의 외부 기여 코드가 서명 키와 내부망에 접근할 수 있는 Runner에서 실행되지 않도록 해야 합니다. 검증, 서명, 배포를 하나의 호스트와 하나의 Job에 묶으면 베타 오류와 보안 사고의 영향 범위가 함께 커집니다.
GitHub는 자체 호스팅 Runner가 매 작업마다 깨끗한 임시 환경으로 초기화된다고 보장하지 않습니다. GitHub Actions 보안 사용 지침은 신뢰하지 않는 워크플로 코드가 실행될 가능성을 고려해 저장소, Runner Group, 비밀값, 내부 네트워크 접근을 제한하도록 안내합니다.
검증 Runner에는 정식 배포 인증서를 넣지 않는 편이 안전합니다. 배포용 인증서가 필요하다면 보호된 Environment 승인 뒤 별도 Job에서 사용하고, 로그에 인증서 파일이나 Profile 내용을 출력하지 않아야 합니다.
자주 묻는 운영 판단
Xcode 27 자체 호스팅 Runner에는 어떤 맥과 운영체제가 필요합니까?
Xcode 27 beta 4는 Apple Silicon 맥에서만 설치와 실행이 가능하며 macOS Tahoe 26.4 이상이 필요합니다. 인텔 맥이나 이전 운영체제를 검증 노드로 사용하면 설치 단계에서 중단될 수 있습니다. Runner에서 xcodebuild -version, swift --version, uname -m을 실행해 실제 환경을 기록해야 합니다. (Apple 시스템 요구 사항)
Xcode 26.6과 Xcode 27을 함께 사용할 수 있습니까?
가능하지만 한 Job에서 전역 경로를 계속 바꾸는 방식은 피해야 합니다. 안정 Job과 베타 Job을 서로 다른 라벨로 라우팅하고, 캐시와 DerivedData를 분리해야 합니다. 정식 브랜치는 Xcode 26.6에 남기고 수동 실행이나 검증 브랜치에서만 Xcode 27을 호출하면 실패 범위를 제한할 수 있습니다.
원격 맥에서 Runner를 재부팅 뒤 자동 실행하려면 어떻게 합니까?
Runner 프로그램을 SSH 터미널에서 직접 실행하는 대신 서비스 등록 절차를 사용해야 합니다. 등록을 마친 Runner 디렉터리에서 ./svc.sh install과 sudo ./svc.sh start를 실행하고, SSH 연결을 종료한 뒤에도 Online 상태가 유지되는지 확인합니다. 재부팅 뒤 다시 연결되는지 확인해야 상시 CI 노드로 인정할 수 있습니다. (GitHub Runner 구성 문서)
Xcode 27 beta 빌드 실패 후 어떻게 되돌립니까?
먼저 의존성 설치, 컴파일, 테스트, Archive, 서명 중 어느 단계에서 실패했는지 분류합니다. Xcode 27 라벨을 사용하는 Job만 중지하고 Xcode 26.6 Job을 기본 경로로 돌립니다. 캐시와 산출물을 덮어쓰지 않은 상태에서 동일 커밋을 안정 노드에 실행해야 롤백이 실제로 검증됩니다.
자체 호스팅 Runner의 인증서와 저장소 권한은 어떻게 나눕니까?
Runner Group을 승인된 저장소로 제한하고, 검증 Job에는 정식 배포 비밀값을 주지 않는 방식이 기본입니다. 공개 저장소나 외부 기여 코드를 같은 Runner에서 실행하면 호스트와 비밀값에 접근할 위험이 있습니다. 배포 서명은 보호된 Environment 승인 뒤 별도 Job 또는 별도 노드에서 수행해야 합니다.
현재 환경이 GitHub 호스팅 Runner에만 의존한다면 이미지 변경, ARM64 제한, 대기 시간, 캐시 재구성이라는 단점이 남습니다. 로컬 맥 한 대에 두 버전을 함께 설치하는 방식도 장비를 계속 켜 두어야 하고 전역 Xcode 경로와 Simulator 상태가 충돌하기 쉽습니다. 반대로 Vuncloud의 원격 맥을 검증 기간 동안 사용하면 별도 Apple Silicon 호스트를 구매하지 않고 SSH로 장기 실행되는 CI 노드를 분리할 수 있습니다. 먼저 비생산 브랜치에서 Runner 등록과 Archive 검증을 끝낸 뒤 운영 전환 여부를 판단하는 순서가 적절합니다.
2026년 7월 31일 현재 Xcode 27은 생산 환경을 즉시 대체할 버전이 아니라, Xcode 26.6과 병행해 호환성과 서명을 확인해야 하는 검증 대상입니다. Apple Silicon과 macOS Tahoe 26.4 이상을 갖춘 독립 노드를 만들고 라벨, 캐시, 권한, 롤백 경계를 분리한 뒤 첫 주 검증 결과에 따라 기본 도구 체인 전환을 결정해야 합니다.
검증용 맥 환경을 지금 준비해 보세요
Vuncloud의 맥을 원격으로 대여해 별도의 장비 구매 없이 빌드 환경을 빠르게 구성할 수 있습니다.
필요한 기간만큼 맥을 사용하며 자체 호스팅 러너와 테스트 환경을 기존 배포 흐름과 분리해 운영할 수 있습니다.