Xcode를 열지 않고 Mac·iOS 앱 빌드와 배포하기
요약
Xcode GUI 없이 CLI 도구만으로 Mac 및 iOS 앱의 빌드, 서명, 배포 전 과정을 자동화하는 방법을 설명합니다. `xcodebuild`, `notarytool` 등의 셸 도구를 활용하여 프로젝트 생성부터 공증, 실제 기기 설치까지 마우스 없이 처리할 수 있습니다. 이 과정은 초기 설정 후에는 스크립트 기반으로 완전히 자동화 가능하며, Claude Code 같은 LLM 에이전트를 이용해 워크플로를 구축하는 것도 가능합니다.
핵심 포인트
- `xcodebuild`, `notarytool` 등 CLI 도구만으로 앱 빌드 및 배포가 가능함.
- 프로젝트 설정은 XcodeGen을 사용하여 YAML 기반으로 관리하고 재현성을 높일 수 있음.
- 배포 자동화는 스크립트와 LLM 에이전트를 결합하여 워크플로를 구축하는 것이 핵심임.
- 개발 환경 초기 설정(인증서, 라이선스)에는 여전히 GUI 또는 대화형 터미널이 필요함.
- 초기 Apple 계정·인증서 설정을 마치면
Xcode.app 내부 CLI 도구만으로 Mac과 iOS 앱의 빌드, 서명, 배포를 자동화할 수 있음project.yml
에서XcodeGen으로.xcodeproj
를 재생성하고,xcodebuild
,notarytool
,stapler
,devicectl
로 프로젝트 생성부터 Mac 공증과 iPhone 설치까지 처리함- Mac 배포는
scripts/release.sh
하나로 아카이브,Developer ID 서명, 공증, 티켓 스테이플링, Gatekeeper 검증,/Applications
설치를 순서대로 실행하며 실패 시 즉시 중단됨 - 빠른 컴파일과 테스트에는
CODE_SIGNING_ALLOWED=NO
를 사용할 수 있지만, 이임시 서명 빌드는 Gatekeeper를 통과하지 못하고 iCloud KVS와 App Group 권한도 실제 팀 ID에 결합되지 않음 - 서명 개인 키와 공증 암호는
로그인 키체인에 보관하고,CLAUDE.md
또는AGENTS.md
에 명령과 배포 규칙을 기록하면 Claude Code 같은 에이전트가 전체 워크플로를 반복 실행할 수 있음
Xcode GUI 없이 처리할 수 있는 범위
- Xcode 자체는 설치해야 하지만 실행할 필요는 없으며,
xcodebuild
,notarytool
,stapler
,devicectl
은 모두Xcode.app 내부의 셸 도구로 독립 실행됨 - Apple ID 로그인, Developer ID 인증서 생성, 공증 암호 저장 같은
최초 설정에는 GUI 또는 대화형 터미널이 필요함 - 초기 설정을 끝내면 프로젝트 생성, 빌드, 아카이브, 서명된 앱 내보내기, 공증, 검증, 설치, 실제 iPhone 배포까지 마우스 없이 처리 가능함
- 설정이나 스크립트 작성이 막힐 때는 Claude Code 또는 다른 LLM 코딩 도구에 작업 요구사항과 프로젝트별 값을 제공해 워크플로를 만들 수 있음
전체 Xcode 도구 체인 선택
xcode-select -p
의 결과가/Applications/Xcode.app/Contents/Developer
인지 먼저 확인해야 함- 독립형 Command Line Tools가 선택돼 있다면 다음 명령으로
전체 Xcode 도구 체인을 지정함
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
xcode-select --install
로 설치하는/Library/Developer/CommandLineTools
에는clang
과git
이 있지만, iOS SDK,notarytool
,devicectl
등 전체 앱 개발 도구는 들어 있지 않음- Xcode가 이미 설치돼 있다면 별도의 Command Line Tools 패키지는 필요하지 않음
- 라이선스 동의와 추가 구성요소 설치도 CLI에서 처리할 수 있음
sudo xcodebuild -license accept
sudo xcodebuild -runFirstLaunch
XcodeGen으로 프로젝트 재현하기
- XcodeGen은 Xcode 프로젝트 설정을 YAML로 관리하고 빌드할 때마다
.xcodeproj
를 다시 생성함 - GitHub에서 다운로드하거나 Homebrew로 설치할 수 있음
brew install xcodegen
.xcodeproj
는 macOS에서 파일처럼 보이는 폴더이며, Xcode가 내부 파일과 참조를 계속 바꾸기 때문에 Git 저장소에서 충돌이나 불필요한 변경이 생길 수 있음하고 생성된project.yml
만 Git에 커밋.xcodeproj
는 무시하면 프로젝트 설정을 재현 가능한 상태로 유지할 수 있음
xcodegen generate
Apple 개발자 계정과 인증서 설정
- Xcode의
Settings → Accounts
에서 Apple ID를 추가해야 함 - 앱 배포와 공증에는
유료 Apple Developer 계정이 필요함 Settings → Accounts → Apple ID → Manage Certificates… → + → Developer ID Application
에서 배포용 인증서를 생성함Apple Development와Developer ID Application은 용도가 다름- Apple Development는 자신의 기기에서 실행하거나 iPhone으로 전송해 로컬 디버깅할 때 사용함
- Developer ID Application은 다른 사람의 Mac에서도 Gatekeeper를 통과하는 공증된
.app
을 배포할 때 필요함
- Developer ID Application 인증서를 만들면 인증서와 대응하는 개인 키가 로그인 키체인에 설치됨
- 실제 서명에는 개인 키가 사용되며 다시 다운로드할 수 없으므로, 삭제하지 말고
키체인을 백업해야 함
공증 자격 증명을 키체인에 저장하기
- Mac 앱 공증은 서명된 앱을 Apple에 업로드해 악성 코드 검사를 받는 과정임
notarytool
은 키체인에 저장된 프로필로 인증하며, 프로필을 처음 만들 때 앱 전용 암호를 대화형으로 입력해야 함
xcrun notarytool store-credentials App-Name \
--apple-id "you@example.com" \
--team-id YOUR-TEAM-ID
- 공증 프로필은 다른 앱의 것을 빌려 쓰지 말고
앱 이름에 맞춰 생성해야 다른 환경에서 조용히 실패하는 상황을 피할 수 있음 - 앱 전용 암호는 Apple ID 암호와 다르며, Apple ID 사이트의
Sign-In & Security → App-Specific Passwords
에서 생성함 - Apple ID 암호를 바꾸면 앱 전용 암호가 별도 경고 없이 만료될 수 있음
- 공증 중
401 invalid credentials
가 발생하면 설정 전체를 의심하기 전에 앱 전용 암호 만료부터 확인해야 함
- 공증 중
- 프로필 저장 여부는 다음 명령으로 검증함
xcrun notarytool history --keychain-profile App-Name
- 앱 전용 암호를 Claude Code가 접근할 수 있는 1Password 보관함에 저장하면 새 앱의 공증 프로필 생성도 에이전트에 맡길 수 있음
--password
로 암호 입력까지 자동화할 수 있지만셸 기록에 암호가 남을 수 있으므로, 한 번 직접 입력한 뒤 키체인이나 1Password에 보관하는 방식을 사용함
로컬 서명 설정과 비밀 정보 분리
- 실제 서명에 필요한 팀 ID와 번들 접두사는
Local.xcconfig
에 저장함
cp Local.xcconfig.example Local.xcconfig
BUNDLE_PREFIX = your.real.prefix
DEVELOPMENT_TEAM = YOUR-TEAM-ID
Local.xcconfig
는.gitignore
에 추가해 프로젝트별 로컬 설정이 저장소에 들어가지 않도록 함- 서명 개인 키는 로그인 키체인에, 공증용 앱 전용 암호는
notarytool
키체인 프로필에 남으므로비밀 정보가 Git에 기록되지 않음
release.sh
로 Mac 배포 자동화하기
- 저장소의
scripts/release.sh
가 Mac 앱의 전체 배포 파이프라인을 한 명령으로 실행함
./scripts/release.sh
스크립트는 다음 순서로 동작함
xcodegen
과 공증 프로필이 존재하는지 사전 확인xcodegen generate
로 프로젝트 재생성xcodebuild archive
로 Release 아카이브 생성ExportOptions.plist
와xcodebuild -exportArchive
로 Developer ID 서명 앱 내보내기- 앱을 ZIP으로 묶어
notarytool submit --wait
로 Apple에 제출 stapler staple
로 공증 티켓 부착spctl
로 Gatekeeper 허용 여부 검증- 기존 프로세스를 종료하고 앱을
/Applications
에 복사 lsregister
로 설치된 앱 등록- 설치된 번들의 티켓과 Gatekeeper 상태 재검증
모델이 일반적인 배포 절차를 알고 있더라도
스킴 이름, 팀 ID, 공증 프로필 이름, 설치 위치같은 프로젝트별 정보는 사용자가 제공해야 함 -
첫 스크립트가 실패하면 실행 결과를 바탕으로 수정하는 반복 과정이 필요하지만, 워크플로가 안정된 뒤에는 별도 수정 없이 배포 명령만 실행할 수 있음
실패와 불완전한 배포 방지
set -euo pipefail
은 명령 하나라도 실패하면 스크립트를 즉시 중단해 불완전한 상태를 성공으로 처리하지 않도록 함cd "$(dirname "$0")/.."
는 스크립트를 어느 디렉터리에서 호출하더라도 저장소 루트로 이동시킴사전 검사 블록은 시간이 오래 걸리는 아카이브 전에xcodegen
과 공증 프로필을 확인함- 내보낸 앱뿐 아니라
/Applications
에 복사된 앱도 다시 검사해 복사 과정에서 번들이 손상되는 경우를 잡아냄 - 다른 공증 프로필이 필요하면 환경 변수로 덮어쓸 수 있음
TZED_NOTARY_PROFILE=<name> ./scripts/release.sh
에이전트에 배포 규칙 전달하기
release.sh
가 한 번의 명령으로 배포를 수행한다면,CLAUDE.md
나AGENTS.md
는 에이전트가 세션마다 별도 지시 없이 그 명령을 사용하도록 만듦- 문서에는 프로젝트 재생성, 단위 테스트, 빠른 macOS 빌드, 실제 배포 명령을 기록함
xcodegen generate
swift test
xcodebuild -project YOUR-APP-NAME.xcodeproj \
-scheme YOUR-APP-NAME-macOS \
-destination 'platform=macOS' \
CODE_SIGNING_ALLOWED=NO build
./scripts/release.sh
- 두 빌드 경로의 차이도 문서에 명시해야 함
CODE_SIGNING_ALLOWED=NO
빌드는 CI와 빠른 로컬 확인에 적합함- 실제 메뉴 막대 앱 배포, 격리 속성 통과, iCloud 동기화에는 Developer ID 서명과 공증을 수행하는
release.sh
가 필요함
- 한 앱에서 만든 방식을 다른 저장소에서 참조하도록 지시하면 Claude Code가 이후 앱에도 같은 설정을 복제할 수 있음
빠른 무서명 빌드와 테스트
- Swift Package Manager 기반 단위 테스트는 Xcode 빌드 없이 실행함
swift test
- macOS 앱의 빠른 컴파일 확인은 서명을 끈 상태로 수행함
xcodebuild -project TZed.xcodeproj \
-scheme TZed-macOS \
-destination 'platform=macOS' \
CODE_SIGNING_ALLOWED=NO build
- iOS 앱과 위젯 확장의 시뮬레이터 빌드도 같은 방식으로 실행 가능함
xcodebuild -project TZed.xcodeproj \
-scheme TZed-iOS \
-destination 'generic/platform=iOS Simulator' \
CODE_SIGNING_ALLOWED=NO build
CODE_SIGNING_ALLOWED=NO
로 만든임시 서명 빌드는 컴파일과 시뮬레이터 실행에 사용할 수 있음- 이 빌드는 Gatekeeper가 거부하며, 팀 접두사가 없어 iCloud KVS와 App Group 같은 권한이 결합되지 않으므로 배포용으로는 사용할 수 없음
실제 iPhone에 헤드리스 배포하기
- iOS 기기 배포에는 Mac 앱과 같은 공증 단계가 없으며,
xcodebuild
와devicectl
을 사용함 - 실제 기기용 앱은 Apple Development 인증서와 개발 프로비저닝 프로필로 빌드하고 서명함
xcodebuild -project TZed.xcodeproj \
-scheme TZed-iOS \
-destination 'generic/platform=iOS' \
-allowProvisioningUpdates \
-derivedDataPath build/ios \
archive -archivePath build/TZed-iOS.xcarchive
- 생성된
.app
은 연결된 기기의 UDID를 지정해 설치함
xcrun devicectl device install app \
--device <DEVICE-UDID> build/ios/…/TZed.app
devicectl list devices
는 연결되고 페어링된 기기와 UDID를 보여줌-allowProvisioningUpdates
를 지정하면 필요한개발 프로비저닝 프로필을 가져옴
GUI 없이 코드 서명이 작동하는 방식
Developer ID Application 인증서를 만들 때 Apple은 인증서를 발급하고, Mac은 대응하는
개인 키를 생성해 둘 다 로그인 키체인에 저장함 -
xcodebuild
가 호출하는codesign
은 개인 키로 바이너리를 서명하고, Apple 루트 인증서로 이어지는 인증서를 앱에 포함해 서명자를 검증할 수 있게 함 -
signingStyle: automatic
을 사용하면xcodebuild
가 팀 ID에 맞는 인증서를 선택하고 필요한 프로비저닝 프로필을 Apple에서 가져옴 -
따라서 프로비저닝 프로필을 저장소에 커밋할 필요가 없음
권한, 공증, 스테이플링
- 각 타깃의
.entitlements
파일에는 샌드박스, 네트워크 클라이언트, iCloud KVS, App Group 같은 권한이 들어 있음 - 권한은 실제 팀 ID로 서명할 때 결합되므로 임시 서명 빌드에서는 iCloud와 App Group이 정상 작동하지 않음
서명과 공증은 서로 다른 단계임- 서명은 누가 앱을 만들었는지 증명함
- 공증은 Apple이 서명된 앱을 악성 코드 검사한 뒤 티켓을 발급하는 절차임
- 스테이플링은 그 티켓을 앱에 붙여 오프라인에서도 Gatekeeper가 신뢰하도록 함
- 숨겨진 UI를 사용하는 메뉴 막대 앱인
LSUIElement
앱에서는 공증이 XProtect의 탐지를 피하는 데 필요함
- 각 타깃의
수동 검증 명령
codesign -dv --verbose=4 /Applications/TZed.app spctl -a -vvv -t exec /Applications/TZed.app stapler validate /Applications/TZed.app
codesign
은 서명자와 인증서를 확인함spctl
은 Gatekeeper가 실행을 허용할지 검사함stapler validate
는 공증 티켓이 부착됐는지 검증함
에이전트가 실행하는 표준 도구
- 별도의 빌드용 MCP 서버나 전용 플러그인은 필요하지 않으며, Claude Code는
비대화형 셸에서 표준 CLI를 실행함 - 사용하는 도구는
xcodebuild
,xcrun notarytool
,xcrun stapler
,spctl
,codesign
,devicectl
,xcodegen
,swift
임 CLAUDE.md
는 공증 프로필 명명 규칙, 빠른 빌드와 실제 배포의 차이, 배포 시release.sh
를 사용해야 한다는 규칙을 에이전트에 전달함- 최초
notarytool store-credentials
만 대화형 단계로 남기고 이후 과정은 모두 자동화할 수 있음
Xcode GUI 작업을 CLI로 대체하기
- Xcode가 관리하는
.xcodeproj
생성은project.yml
과xcodegen generate
로 대체함 ⌘B
또는 Run 버튼은xcodebuild … build
에 대응함Product → Archive
는xcodebuild … archive
로 처리함- Organizer의 앱 배포는
xcodebuild -exportArchive
로 대체 가능함 - Organizer 업로드는
xcrun notarytool submit --wait
로 수행함 - 자동 티켓 부착에는
xcrun stapler staple
을 사용함 /Applications
로 드래그 앤드 드롭하는 설치 과정은cp -R
과lsregister
로 처리함- 실제 iPhone의 Run 동작은
xcodebuild archive
와devicectl device install
로 대체함 - Xcode와 XcodeGen 설치, 최초 자격 증명 설정,
release.sh
와CLAUDE.md
작성까지 끝내면 이후 새 빌드 배포는한 문장 또는 한 명령으로 실행할 수 있음
AI 자동 생성 콘텐츠
본 콘텐츠는 GeekNews의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기