React Native iOS 빌드
Node와 CocoaPods를 준비하고 React Native 앱을 iOS 시뮬레이터용으로 빌드합니다, Expo prebuild 프로젝트도 같은 흐름입니다
React Native 앱의 ios/ 프로젝트를 시뮬레이터용으로 빌드합니다, 러너 VM에는 Node가 미리 깔려 있지 않으므로 스크립트가 Node 22를 받고, CocoaPods로 네이티브 의존성을 설치한 뒤 xcodebuild로 빌드합니다
이 흐름은 저장소의 React Native 워크플로 템플릿과 프레임워크 실측 스크립트(Expo 55, React Native 0.83 픽스처)에서 가져왔고, 같은 구성의 잡이 실제 맥에서 빌드에 성공한 기록이 위키에 있습니다
준비
package-lock.json이 커밋되어 있어야npm ci가 됩니다ios/폴더가 커밋되어 있거나, 없으면 Expo가expo prebuild로 만듭니다- 스킴 이름과 워크스페이스 경로(보통
ios/<App>.xcworkspace)
빌드 스크립트
#!/bin/bash
set -euo pipefail
work="$PWD"
XCODE_WORKSPACE="App.xcworkspace" # ios/ 안의 워크스페이스 이름
XCODE_SCHEME="App" # 스킴 이름
# 1. Node 22 (VM에 없으므로 잡 안에서 받습니다)
curl -fsSL https://nodejs.org/dist/latest-v22.x/SHASUMS256.txt -o node-checksums.txt
node_archive=$(awk '/ node-v[0-9.]+-darwin-arm64.tar.gz$/ {print $2}' node-checksums.txt)
curl -fsSL "https://nodejs.org/dist/latest-v22.x/$node_archive" -o "$node_archive"
grep " $node_archive\$" node-checksums.txt | shasum -a 256 -c -
mkdir -p node-runtime && tar -xzf "$node_archive" -C node-runtime --strip-components=1
export PATH="$work/node-runtime/bin:$PATH"
node --version
# 2. JavaScript 의존성
npm ci
# 3. ios/ 가 없으면 Expo prebuild
if [ ! -d ios ]; then
npx --no-install expo prebuild --platform ios --no-install
fi
# 4. CocoaPods
if [ -f Gemfile ]; then
bundle config set --local path vendor/bundle && bundle install
(cd ios && bundle exec pod install)
elif [ -f ios/Podfile.lock ]; then
(cd ios && pod install --deployment)
else
(cd ios && pod install)
fi
# 5. 시뮬레이터 빌드 (서명 없음)
xcodebuild -workspace "ios/$XCODE_WORKSPACE" \
-scheme "$XCODE_SCHEME" -configuration Debug \
-destination 'generic/platform=iOS Simulator' \
-derivedDataPath build/rn CODE_SIGNING_ALLOWED=NO build
mkdir -p ci-output
app=$(find build/rn/Build/Products -name '*.app' -maxdepth 3 | head -1)
ditto -c -k --keepParent "$app" ci-output/ios-simulator.zip실행
XENOCI_API_KEY=xci_live_… xenocast build --script ./ci.sh --timeout 45 \
--artifacts 'ci-output/*.zip'node_modules는 올리지 않아도 됩니다, 업로드는 현재 폴더를 통째로 묶으니 .gitignore에 있는 큰 폴더는 미리 지우거나 --dir로 깨끗한 폴더를 지정하세요, 워크스페이스와 스킴 이름은 스크립트 위쪽 변수에 적습니다
시간과 비용 줄이기
- Node 아카이브와
npm ci가 매번 돕니다, 잡마다 새 VM이라 캐시가 남지 않으니 의존성이 큰 프로젝트는timeout_minutes를 넉넉히 두세요 pod install --deployment는Podfile.lock이 있을 때만 됩니다, 잠금 파일을 커밋하면 해석 시간이 줄고 실패도 줍니다- 빌드가 받는 호스트(nodejs.org, npm 레지스트리, CocoaPods CDN)에 문제가 있으면 연결 오류로 실패합니다, 로그의 호스트 이름을 확인하세요