- 초기 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 도구 체인을 지정함
- xcode-select --install로 설치하는 /Library/Developer/CommandLineTools에는 clang과 git이 있지만, iOS SDK, notarytool, devicectl 등 전체 앱 개발 도구는 들어 있지 않음
- Xcode가 이미 설치돼 있다면 별도의 Command Line Tools 패키지는 필요하지 않음
- 라이선스 동의와 추가 구성요소 설치도 CLI에서 처리할 수 있음
XcodeGen으로 프로젝트 재현하기
- XcodeGen은 Xcode 프로젝트 설정을 YAML로 관리하고 빌드할 때마다 .xcodeproj를 다시 생성함
- GitHub에서 다운로드하거나 Homebrew로 설치할 수 있음
- .xcodeproj는 macOS에서 파일처럼 보이는 폴더이며, Xcode가 내부 파일과 참조를 계속 바꾸기 때문에 Git 저장소에서 충돌이나 불필요한 변경이 생길 수 있음
- project.yml만 Git에 커밋하고 생성된 .xcodeproj는 무시하면 프로젝트 설정을 재현 가능한 상태로 유지할 수 있음
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은 키체인에 저장된 프로필로 인증하며, 프로필을 처음 만들 때 앱 전용 암호를 대화형으로 입력해야 함
- 공증 프로필은 다른 앱의 것을 빌려 쓰지 말고 앱 이름에 맞춰 생성해야 다른 환경에서 조용히 실패하는 상황을 피할 수 있음
- 앱 전용 암호는 Apple ID 암호와 다르며, Apple ID 사이트의 Sign-In & Security → App-Specific Passwords에서 생성함
- Apple ID 암호를 바꾸면 앱 전용 암호가 별도 경고 없이 만료될 수 있음
- 공증 중 401 invalid credentials가 발생하면 설정 전체를 의심하기 전에 앱 전용 암호 만료부터 확인해야 함
- 프로필 저장 여부는 다음 명령으로 검증함
- 앱 전용 암호를 Claude Code가 접근할 수 있는 1Password 보관함에 저장하면 새 앱의 공증 프로필 생성도 에이전트에 맡길 수 있음
- --password로 암호 입력까지 자동화할 수 있지만 셸 기록에 암호가 남을 수 있으므로, 한 번 직접 입력한 뒤 키체인이나 1Password에 보관하는 방식을 사용함
로컬 서명 설정과 비밀 정보 분리
- 실제 서명에 필요한 팀 ID와 번들 접두사는 Local.xcconfig에 저장함
- Local.xcconfig는 .gitignore에 추가해 프로젝트별 로컬 설정이 저장소에 들어가지 않도록 함
- 서명 개인 키는 로그인 키체인에, 공증용 앱 전용 암호는 notarytool 키체인 프로필에 남으므로 비밀 정보가 Git에 기록되지 않음
release.sh로 Mac 배포 자동화하기
- 저장소의 scripts/release.sh가 Mac 앱의 전체 배포 파이프라인을 한 명령으로 실행함
-
스크립트는 다음 순서로 동작함
- 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에 복사된 앱도 다시 검사해 복사 과정에서 번들이 손상되는 경우를 잡아냄
- 다른 공증 프로필이 필요하면 환경 변수로 덮어쓸 수 있음
에이전트에 배포 규칙 전달하기
- release.sh가 한 번의 명령으로 배포를 수행한다면, CLAUDE.md나 AGENTS.md는 에이전트가 세션마다 별도 지시 없이 그 명령을 사용하도록 만듦
- 문서에는 프로젝트 재생성, 단위 테스트, 빠른 macOS 빌드, 실제 배포 명령을 기록함
- 두 빌드 경로의 차이도 문서에 명시해야 함
- CODE_SIGNING_ALLOWED=NO 빌드는 CI와 빠른 로컬 확인에 적합함
- 실제 메뉴 막대 앱 배포, 격리 속성 통과, iCloud 동기화에는 Developer ID 서명과 공증을 수행하는 release.sh가 필요함
- 한 앱에서 만든 방식을 다른 저장소에서 참조하도록 지시하면 Claude Code가 이후 앱에도 같은 설정을 복제할 수 있음
빠른 무서명 빌드와 테스트
- Swift Package Manager 기반 단위 테스트는 Xcode 빌드 없이 실행함
- macOS 앱의 빠른 컴파일 확인은 서명을 끈 상태로 수행함
- iOS 앱과 위젯 확장의 시뮬레이터 빌드도 같은 방식으로 실행 가능함
- CODE_SIGNING_ALLOWED=NO로 만든 임시 서명 빌드는 컴파일과 시뮬레이터 실행에 사용할 수 있음
- 이 빌드는 Gatekeeper가 거부하며, 팀 접두사가 없어 iCloud KVS와 App Group 같은 권한이 결합되지 않으므로 배포용으로는 사용할 수 없음
실제 iPhone에 헤드리스 배포하기
- iOS 기기 배포에는 Mac 앱과 같은 공증 단계가 없으며, xcodebuild와 devicectl을 사용함
- 실제 기기용 앱은 Apple Development 인증서와 개발 프로비저닝 프로필로 빌드하고 서명함
- 생성된 .app은 연결된 기기의 UDID를 지정해 설치함
- 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 작성까지 끝내면 이후 새 빌드 배포는 한 문장 또는 한 명령으로 실행할 수 있음

7 hours ago
2






English (US) ·