런북 — App Store Connect 앱 레코드 만들기 (`asc-create-app`)
Bundle ID 는 있는데 App Store Connect 에 이 앱의 레코드가 없고, **CLI 경로를 쓸 수 없을 때.**
등급 미검증 — 이 화면은 가드 없는 실행에서 한 번 쓰였다. 가드를 갖춘 첫 실행은 드라이런 뒤에 사람이 지켜보며 한다. 공통 절차는
cc-dev:grok-bot-handoff, 구분·권한·검증은 SKILL.md.
언제#
Bundle ID 는 있는데 App Store Connect 에 이 앱의 레코드가 없고, CLI 경로를 쓸 수 없을 때.
먼저 — CLI 경로 [문서]#
공개 API 에는 앱 생성이 없지만, fastlane produce 는 Apple ID 로그인(2단계 인증)으로 레코드를 만든다. 아래 전제(Bundle ID·SKU·이름·App Store 기본 언어가
confirmed)를 먼저 맞추고, 사람이 자기 터미널에서 실행한다. 비밀번호·인증 코드는 그 터미널에만 넣는다.
# 값은 값 시트의 confirmed 값을 그대로 옮긴다 — Bundle ID 는 API 로 이미 등록했으므로 --skip_devcenter
fastlane produce -u <apple-id> \
-a <ios.bundleIds.prod> --sku <ios.sku> --app_name "<store.name>" --language "<ios.primaryLocale>" \
--skip_devcenter
-
cob init5단계·cob ios create는 값 시트가 아니라 Fastfile 이 계산한 Bundle ID·SKU·이름으로, 여러 flavor(dev·stg·prod)의 레코드를 만든다. 계산 값이 확정 값과 같고 그 flavor 들의 레코드가 모두 필요할 때만 쓴다. Xcode 프로젝트의 Bundle ID 와 다른 값으로 레코드를 만들면 그 레코드에는 빌드를 올릴 수 없다. -
이 런북의 값은 prod 기준이다(
ios.bundleIds.prod·ios.sku). 다른 flavor 의 레코드가 필요하면 그 flavor 의 SKU 칸(예:ios.skus.stg)을 값 시트에 더해 사람이 확정한 뒤 같은 절차로 만든다. - CLI 도 쓸 수 없을 때(Apple ID 로그인을 할 수 있는 터미널이 없는 경우 등)만 아래 봇 절차로 간다.
세션으로 무인 실행 [문서 · 미검증]#
Apple 2단계 인증은 TOTP 가 아니라서(코드가 신뢰하는 기기·전화번호로만 온다) 비밀번호 관리자로 자동화할 수 없다. 대신 사람이 한 번 로그인해 만든 세션을 CI 가 다시 쓴다. 이 경로로 레코드를 만든 기록은 아직 없다.
# 사람이 CI 와 같은 머신에서 한 번 — 2단계 인증은 여기서 끝난다
fastlane spaceauth -u <bot-apple-id>
# 출력된 세션 문자열을 비밀 저장소에 FASTLANE_SESSION 으로 넣고,
# CI 에는 FASTLANE_USER(<bot-apple-id>)와 함께 준다 — 위 produce 명령의 -u 도 같은 계정이다
- 세션의 유효기간은 1일~1개월 사이로 들쭉날쭉하다. 최소 한 달에 한 번 다시 만들고, 만료는 실행이 실패해서야 드러나므로 만든 날을 기록해 둔다. 세션은 지역에 묶이므로 CI 와 같은 머신에서 만든다.
- 세션을 가진 쪽은 그 Apple ID 의 웹 권한을 그대로 쓴다. 전용 Apple ID 에 앱 레코드를 만들 수 있는 가장 좁은 역할만 준다(SKILL.md §3). 계정 소유자(Account Holder)의 세션은 만들지 않는다.
-
Fastfile 이
create_app_online에username을 고정 값으로 넘기면 세션의 계정과 달라져 다시 로그인을 요구한다.username: ENV["FASTLANE_USER"]처럼 환경 변수로 받는다. - 세션 문자열은 비밀값이다 — 로그·이슈·브리프·값 시트에 남기지 않는다. 같은 세션으로 asc-app-privacy 의 업로드도 돈다.
전제#
- Bundle ID 등록과 capability 켜기가 끝났다 — API 로 한다(apple-provisioning-setup 1·2단계)
-
레코드가 없음을 확인했다 — SKILL.md
§7 의 Spaceship 조회 결과가
MISSING - 봇 절차의 봇 계정: Developer 역할 + Users and Access 에서 "앱 레코드 만들기" 허용 — 작업하는 동안만(SKILL.md §3)
-
칸 기준 점검(value-sheet.md
§3)에 넣을 전제 칸:
store.name ios.primaryLocale ios.bundleIds.prod ios.sku(봇 절차면botAccount apple.teamName도) -
SKU 는 레코드를 만든 뒤 바꿀 수 없고, Bundle ID 는 첫 빌드를 올린 뒤 바꿀 수 없다. Bundle ID 는 Xcode 프로젝트의 값과 같아야 한다. 둘 다 사람이 값 시트에서
confirmed로 확정한 값만 쓴다. 생성기가 넣은 SKU 는proposal이다
봇 절차 — CLI 를 쓸 수 없을 때#
입력값#
| 화면 칸 | 값 시트 키 |
|---|---|
| Platforms | iOS (브리프에 직접) |
| Name | store.name |
| Primary Language | ios.primaryLocale |
| Bundle ID | ios.bundleIds.prod |
| SKU | ios.sku |
| User Access | (브리프에 직접 — 제한하면 대상 사용자까지 적는다) |
순서 — 브리프 §3 에 옮긴다#
- Apps 목록에서 같은 이름·같은 Bundle ID 의 앱을 검색한다. 있으면 멈추고 보고한다
- New App 을 연다
- 위 표대로 입력한다. Bundle ID 목록에 값이 없으면 멈춘다(식별자 등록이 먼저다)
- Create: Ask first — 사람이 화면에 들어간 SKU·Bundle ID 를 보고 Allow once
- 만들어진 앱의 Apple ID(숫자)를 보고한다
멈추고 사람을 부를 때 — 브리프 §4 에 더한다#
- 이름이 이미 쓰이고 있다는 오류 → 멈추고 보고한다. 다른 이름을 지어내지 않는다
- Bundle ID 가 목록에 없다
- 약관 동의 배너가 나온다 — Account Holder 만 동의할 수 있다
기대 결과#
| field | type | status | source |
|---|---|---|---|
| app | record | filled — value 는 Apple ID(숫자) | console |
| name · primaryLanguage · bundleId · sku · userAccess | setting | filled | brief |
검증#
-
API: SKILL.md
§7 의 Spaceship 조회. 식별자·이름·SKU·기본 언어가 확정 값과 같고, 앱 id 가 CLI 출력이나 봇이 보고한 값과 같으면
verified. -
확인한 앱 id 를 값 시트
ios.ascAppleId에confirmed(sourceconsole)로 넣는다.