CLI / API 참조
foxstore-cli는 CI/CD용 비대화형 출시 API입니다. 여기서 API는 인수, 파일, stdout/stderr와 종료 코드로 구성된 명령줄 프로세스 인터페이스이며 HTTP 서비스는 제공하지 않습니다. foxstore-engine을 정적 링크한 단일 실행 파일로 데스크톱 클라이언트 설치나 실행이 필요 없고 데스크톱 SQLite 자격 증명도 읽지 않습니다.
CLI는 현재 Apple, Google Play, Huawei, WeChat 미니프로그램, Tencent MyApp, Honor, Samsung, Pgyer, vivo, Xiaomi와 OPPO의 출시 자동화를 지원합니다. 객체 스토리지, 리뷰, Analytics, 일상 인증서 관리, 이미지 최적화와 AI 앱 진단은 Engine과 Desktop에만 있으며 CLI에는 포함하지 않습니다.
CI/CD 연결 가이드로 GitHub Actions, GitLab CI 또는 Jenkins 연결을 시작한 후 이 페이지에서 매개변수를 확인하세요.
전역 호출 형식
foxstore-cli [--output human|json|ndjson] <command>| 매개변수 | 기본값 | 설명 |
|---|---|---|
--output | human | human은 터미널용, json은 구조화된 결과 하나, ndjson은 압축된 최종 결과 한 줄이며 현재 실시간 진행 이벤트는 없습니다. 하위 명령 앞뒤에 지정할 수 있습니다. |
--help | - | 현재 명령의 실제 도움말 표시. |
--version | - | 바이너리 버전 표시. |
--help / -h는 항상 도움말 텍스트를, --version / -V는 항상 버전 텍스트를 출력하며 기계 형식이어도 envelope로 감싸지 않습니다. 기계가 읽을 버전 정보는 version --output json을 사용하세요.
아래 유형에서 string은 문자열(ID도 문자열 유지), path는 Runner 로컬 경로, i64 / i32는 부호 있는 정수, u64 / u8은 음이 아닌 정수, f64는 부동소수점입니다. “선택”은 생략 가능하고 기본값이 없다는 뜻입니다. bool “플래그”는 인수 이름만, bool “값”은 true 또는 false가 필요합니다. 모든 publish/status 명령은 해당 Provider 자격 증명 매개변수를 상속합니다.
기본 명령:
foxstore-cli version
foxstore-cli providers --output json
foxstore-cli capabilities --provider apple --output json
foxstore-cli artifact inspect --file ./build/App.ipa --output json
foxstore-cli preflight apple --file ./build/App.ipa --output json
foxstore-cli preflight android --file ./build/App.aab --expected-package-name com.example.app --output json
foxstore-cli preflight huawei --file ./build/App.app --output json| 명령 | 매개변수 | 결과 |
|---|---|---|
version | 없음 | version과 engineSchemaVersion 반환. |
providers | 없음 | 바이너리에 컴파일된 Provider와 사용 가능 상태 반환. |
capabilities | 필수 --provider <string> | Provider 설명, cliPublish와 제외 기능. 명령별 schema는 아님. |
artifact inspect | 필수 --file <path> | 산출물 유형, 크기와 SHA-256. |
preflight apple | 필수 --file <path> | Apple IPA 사전 검사. |
preflight android | 필수 --file <path>, 선택 --expected-package-name <string> | Android 패키지 사전 검사 및 선택적 패키지명 확인. |
preflight huawei | 필수 --file <path> | HarmonyOS .app만 분석. Huawei APK/AAB는 preflight android 사용. |
providers는 정적 Provider 15개를 모두 표시하며 객체 스토리지는 cliPublish: excluded입니다. capabilities --provider ID: apple, google-play, huawei-appgallery, wechat-miniprogram, tencent-appstore, honor, samsung-galaxy-store, pgyer, vivo, xiaomi, oppo, aliyun, tencent-cloud, aws, minio. Huawei와 Samsung 하위 명령은 목록 ID가 아닌 huawei, samsung입니다.
artifact inspect는 유형, 크기와 SHA-256만 식별하며 서명은 검증하지 않습니다. preflight는 출시하지 않는 로컬 분석입니다. Apple 성공 envelope/종료 0이어도 data.status는 blocked일 수 있으므로 data.status == "ready"와 data.checks[].blocksUpload를 확인하세요. Android warnings도 팀 정책에 따라 처리하세요. publish apple은 사전 검사를 다시 수행하여 blocked 패키지를 막습니다. 사전 검사 통과가 스토어 수락을 뜻하지는 않습니다.
자격 증명 소스
Secret을 일반 명령줄 인수로 직접 전달할 수 없습니다. *-env는 환경 변수 이름, *-file은 CI가 만든 임시 파일 경로를 받으며 같은 Secret에 두 방식은 상호 배타적입니다. 모든 *-env는 선택 string, *-file은 선택 path입니다. 명시하지 않으면 아래 기본 환경 변수를 사용합니다.
| Provider | 기본 환경 변수 | 대체 매개변수 |
|---|---|---|
| Apple | APPLE_PRIVATE_KEY | --private-key-env / --private-key-file; Issuer ID와 Key ID는 각각 --issuer-id, --key-id |
| Google Play | GOOGLE_PLAY_CREDENTIALS_JSON | --credentials-env / --credentials-file |
| Huawei HarmonyOS | HUAWEI_SERVICE_ACCOUNT_JSON | --service-account-env / --service-account-file |
| Huawei Android | HUAWEI_ANDROID_API_CLIENT_JSON | --android-api-client-env / --android-api-client-file |
| WeChat 미니프로그램 | WECHAT_MINIPROGRAM_PRIVATE_KEY | --private-key-env / --private-key-file |
| Tencent MyApp | TENCENT_APPSTORE_USER_ID, TENCENT_APPSTORE_ACCESS_SECRET | --user-id-env / --user-id-file, --access-secret-env / --access-secret-file |
| Honor | HONOR_CLIENT_ID, HONOR_API_SECRET | --client-id-env / --client-id-file, --api-secret-env / --api-secret-file |
| Samsung | SAMSUNG_CREDENTIALS_JSON | --credentials-env / --credentials-file |
| Pgyer | PGYER_API_KEY, PGYER_USER_KEY | --api-key-env / --api-key-file, --user-key-env / --user-key-file |
| vivo | VIVO_ACCESS_KEY、VIVO_ACCESS_SECRET | --access-key-env / --access-key-file、--access-secret-env / --access-secret-file |
| Xiaomi | XIAOMI_USER_NAME, XIAOMI_API_SECRET, XIAOMI_PUBLIC_CERTIFICATE | --user-name-env / --user-name-file, --api-secret-env / --api-secret-file, --public-certificate-env / --public-certificate-file |
| OPPO | OPPO_CLIENT_ID、OPPO_CLIENT_SECRET | --client-id-env / --client-id-file、--client-secret-env / --client-secret-file |
Apple --issuer-id, --key-id는 doctor/publish/status 모두 필수 string입니다. JSON 자격 증명은 파일 경로 문자열이 아닌 전체 문서 내용을 전달합니다. Google/Huawei는 플랫폼에서 내보낸 JSON, Samsung은 { "serviceAccountId": "…", "privateKey": "…", "accessToken": null }을 사용합니다(앞 두 항목은 필수 string, accessToken은 선택 string). PEM 줄바꿈을 유지하고 실제 Secret을 명령, 저장소나 로그에 쓰지 마세요.
각 자격 증명 JSON의 내보내기 필드 형식을 유지하고 camelCase로 통일하지 마세요.
| 자격 증명 | 문서 필드(모두 string, 명시한 경우 외에는 필수) |
|---|---|
| Google Play | type은 service_account 고정, project_id, private_key_id, private_key, client_email, token_uri. |
| Huawei Service Account | key_id, private_key, sub_account, auth_uri, token_uri, auth_provider_cert_uri, client_cert_uri; project_id는 선택. |
| Huawei Android API Client | client_id、client_secret。 |
| Samsung | serviceAccountId, privateKey; accessToken은 선택. |
CLI는 *_FILE 환경 변수를 자동으로 읽지 않으므로 --private-key-file "$APPLE_KEY_FILE" 같은 인수를 명시하세요. Huawei의 네 소스 인수는 모두 상호 배타적입니다. doctor/status는 기본 HarmonyOS Service Account를 사용하고 Android는 --android-api-client-env HUAWEI_ANDROID_API_CLIENT_JSON 또는 --android-api-client-file <path>를 명시해야 합니다. publish는 .app / .apk|.aab로 유형을 선택하지만 혼동 방지를 위해 소스를 명시하는 편이 좋습니다.
연결 진단
doctor는 앱을 업로드하거나 제출하지 않고 자격 증명, Provider 연결 또는 로컬 실행 환경을 검사합니다. 보통 원격 요청을 하므로 오프라인 인수 검증으로 사용할 수 없습니다.
foxstore-cli doctor apple --issuer-id "$APPLE_ISSUER_ID" --key-id "$APPLE_KEY_ID" --output json
foxstore-cli doctor google-play --package-name com.example.app --output json
foxstore-cli doctor huawei --output json
foxstore-cli doctor pgyer --output json
foxstore-cli doctor tencent-appstore --output json
foxstore-cli doctor vivo --package-name com.example.app --output json
foxstore-cli doctor samsung --output json
foxstore-cli doctor wechat-miniprogram --output json
foxstore-cli doctor oppo --output json
foxstore-cli doctor honor --output json
foxstore-cli doctor xiaomi --output jsonApple은 --issuer-id, --key-id, Google Play는 --package-name, vivo는 --package-name이 필요하며 vivo는 --endpoint로 기본 프로덕션 주소를 바꿀 수 있습니다. Tencent MyApp은 string 환경 변수 TENCENT_APPSTORE_APP_ID, TENCENT_APPSTORE_PACKAGE_NAME도 필수입니다(doctor 명령줄 인수 없음). 다른 명령은 각 자격 증명 소스를 받습니다. WeChat은 개인 키 소스와 로컬 Node.js, miniprogram-ci, miniprogram-mp-ci만 검사하며 두 패키지는 현재 또는 상위 디렉터리 node_modules에서 찾을 수 있어야 합니다. 원격 업로드 권한은 검증하지 않습니다. Xiaomi는 고정된 탐색 패키지명을 조회하므로 대상 앱 status를 대신하지 않습니다.
출시 명령 및 매개변수
Apple App Store
foxstore-cli publish apple \
--issuer-id "$APPLE_ISSUER_ID" --key-id "$APPLE_KEY_ID" \
--app-id 1234567890 --file ./build/App.ipa --output ndjson필수 string: --issuer-id, --key-id, --app-id; 필수 path: --file, 그리고 개인 키 환경 변수 또는 파일이 필요합니다. CLI는 Build Upload API로 IPA를 업로드하며 성공 시 { "provider": "apple", "buildUploadId": "…" }를 반환합니다. App Store 심사 제출이나 Apple 후속 처리 및 TestFlight 배포 완료를 보장하지 않습니다.
Google Play
foxstore-cli publish google-play \
--package-name com.example.app --file ./build/App.aab \
--track internal --release-status completed \
--release-notes-file ./release-notes.json --output ndjson| 매개변수 | 필수/기본값 | 설명 |
|---|---|---|
--package-name, --file | 필수 string / path | Play 패키지명과 APK/AAB 경로. |
--track | string, internal | 대상 Track. |
--release-status | string, completed | draft, inProgress, completed만 허용. halted 불가. |
--user-fraction | 선택 f64 | inProgress에 필수이며 0 < 값 < 1. 다른 상태에는 지정 불가. |
--release-name | string, 빈 문자열 | 출시 이름. |
--release-notes-file | 선택 path | JSON 배열. 항목별 string language, text 필수. 생략 시 빈 배열. |
release-notes.json 예제:
[{ "language": "zh-CN", "text": "修复已知问题" }, { "language": "en-US", "text": "Bug fixes" }]Huawei AppGallery
foxstore-cli publish huawei \
--app-id 123456 --expected-package-name com.example.app \
--file ./build/App.app --submit true --timeout-seconds 240 --output ndjson| 매개변수 | 필수/기본값 | 설명 |
|---|---|---|
--app-id, --expected-package-name, --file | 필수 string / string / path | .app, .apk, .aab 지원. 자격 증명 유형이 패키지 플랫폼과 일치해야 함. |
--chinese-mainland-flag | 선택 i32 | HarmonyOS 업로드 지역 플래그 전용: 0 또는 1. |
--submit | bool 값, true | 업로드 후 출시 제출 여부. |
--release-time, --remark | 선택 string | 출시 시간: yyyy-MM-ddTHH:mm:ssZZ. 비고는 HarmonyOS 전용이며 입력 시 10–300자. |
--release-phase | i64, 0 | HarmonyOS 전용: 0 전체, 3 단계적 출시. |
--phased-release-description | 선택 string | HarmonyOS 전용. 단계 3에 필수, 최대 500자. |
--timeout-seconds | u64, 240 | Android 컴파일 폴링 예산 전용, 0보다 커야 함. 약 2초당 한 번으로 횟수 계산하며 요청 시간은 별도. 전체 deadline이 아니며 HarmonyOS는 사용하지 않음. |
Pgyer
foxstore-cli publish pgyer \
--file ./build/App.ipa --update-description "CI build" \
--timeout-seconds 180 --output ndjson--file은 필수 path(IPA/APK/HAP). --build-type은 선택 string: ios/ipa, android/apk, harmonyos/hap이며 기본적으로 확장자로 추정합니다. --update-description은 선택 string. --timeout-seconds는 u64, 기본 180, 0보다 커야 하며 인증, 업로드 티켓, 업로드와 폴링 전체 deadline입니다.
Tencent MyApp
foxstore-cli publish tencent-appstore \
--package-name com.example.app --app-id 1000123 --file ./build/App.apk \
--release-notes "修复已知问题" --deploy-type 1 --output ndjson--package-name, --app-id는 필수 string, --file은 필수 APK path. --release-notes는 string, 기본 빈 값. --deploy-type은 i64, 기본 1, 1/2(예약) 허용. --deploy-time은 선택 i64 초 타임스탬프이며 유형 2에 필수. --apk-64-only는 bool 플래그, 기본 false. 기존 앱을 업데이트합니다.
vivo
foxstore-cli publish vivo \
--package-name com.example.app --file ./build/App.apk --version-code 42 \
--online-type 1 --update-description "修复已知问题" --output ndjson--package-name은 필수 string, --file은 필수 APK path, --version-code는 필수 i64. --online-type은 i64, 기본 1, 1/2(예약) 허용. --scheduled-online-time은 선택 string이며 유형 2에 필수. --update-description은 선택 string. --endpoint는 string, 기본 https://developer-api.vivo.com.cn/router/rest, 다른 허용 값은 https://sandbox-developer-api.vivo.com.cn/router/rest뿐입니다.
Samsung Galaxy Store
foxstore-cli publish samsung \
--content-id 000007654321 --file ./build/App.apk \
--uses-gms true --submit true --output ndjson--content-id는 필수 string, --file은 필수 APK path. --uses-gms는 선택 bool 값(예: --uses-gms false)이며 생략 시 스토어 기존 바이너리의 GMS 설정을 유지합니다. --release-at은 선택 i64 Unix 밀리초로 현재보다 미래여야 하며 현재 콘텐츠가 FOR_SALE인 경우에만 이번 업데이트에 설정할 수 있습니다. --submit은 bool 값, 기본 true, 업로드만 하려면 --submit false.
WeChat 미니프로그램
foxstore-cli publish wechat-miniprogram \
--appid wx1234567890 --project-path ./miniprogram --version 1.2.3 \
--description "CI build" --robot 1 --output ndjson--appid, --version은 필수 string, --project-path는 필수 path. --description은 string, 기본 빈 값. --robot은 선택 u8, 1–30. --project-type은 string, 기본 miniProgram, 허용 값은 miniProgram, miniProgramPlugin, miniGame, miniGamePlugin. 코드 버전 업로드이며 자동 심사 제출/출시 명령이 아닙니다. 앞서 설명한 Node.js와 npm 패키지 2개가 필요합니다.
OPPO / HeyTap
foxstore-cli publish oppo --request-file ./oppo-release.json --output ndjson--request-file은 최상위 JSON 객체의 필수 path입니다. 아래는 전체 입력 필드이며 이름은 대소문자를 구분합니다.
| 필드 | JSON 유형 / 필수 | 제약 |
|---|---|---|
packageKind | string, 필수 | ordinary 또는 multi. 명시 필수. |
apkFiles | object[], 필수 | 항목별 string filePath, integer cpuCode 필수. 일반 패키지는 정확히 1개, cpuCode=0. 다중은 정확히 2개, 각각 32와 64. |
packageName, versionCode, appName | string, 필수 | versionCode는 양의 정수 문자열로 패키지와 일치해야 함. |
secondCategoryId, thirdCategoryId | integer, 필수 | 스토어의 유효한 카테고리 ID. |
summary | string, 필수 | 최대 13자, 공백이나 문장 부호 불가. |
detailDescription, updateDescription | string, 필수 | 각각 최소 20자 / 5자. |
privacyPolicyUrl, iconUrl, copyrightUrl | string, 필수 | 개인정보 처리방침, 업로드된 아이콘, 저작권 자료 URL. |
screenshotUrls | string[], 필수 | 업로드된 세로 스크린샷 URL 2–5개. |
testDescription | string, 필수 | 추가 테스트 설명, 빈 값 불가. |
businessContactName, businessContactEmail, businessContactMobile | string, 필수 | 비즈니스 담당자 연락처. |
ageLevel | integer, 필수 | 0보다 큰 유효한 연령 등급. |
adaptiveEquipment | integer, 필수 | 4, 5 또는 6. |
onlineType | integer, 필수 | 1 또는 2(예약). |
scheduledOnlineTime | string, 선택 | onlineType=2일 때 필수. |
landscapeScreenshotUrls | string[], 선택 | 업로드된 가로 스크린샷 URL. |
icpUrl, specialCertificateUrl, specialCertificateFileUrl | string, 선택 | 등록/특수 자격 URL. 앱 자격 요구사항에 따라 지정. |
adaptiveType | integer, 선택 | 호환 유형. |
예제 골격: 카테고리 ID, 자료 URL, 담당자와 등급을 실제 앱 정보로 바꾸세요. apkFiles는 빌드된 APK를 가리키며 CLI는 로컬 이미지를 원격 URL로 자동 변환하지 않습니다.
{
"packageKind": "ordinary",
"apkFiles": [{ "filePath": "./build/App.apk", "cpuCode": 0 }],
"packageName": "com.example.app", "versionCode": "42", "appName": "示例应用",
"secondCategoryId": 1, "thirdCategoryId": 1,
"summary": "便捷记录日常生活",
"detailDescription": "这是一款用于记录日常生活与管理个人事项的示例应用。",
"updateDescription": "修复已知问题并改善使用体验",
"privacyPolicyUrl": "https://example.com/privacy",
"iconUrl": "https://example.com/uploaded/icon.png",
"screenshotUrls": ["https://example.com/uploaded/1.png", "https://example.com/uploaded/2.png"],
"copyrightUrl": "https://example.com/uploaded/copyright.png",
"testDescription": "无需登录即可使用基础功能",
"businessContactName": "应用联系人", "businessContactEmail": "[email protected]",
"businessContactMobile": "13800000000", "ageLevel": 1,
"adaptiveEquipment": 4, "onlineType": 1
}Honor App Market
foxstore-cli publish honor \
--app-id 123456 --package-name com.example.app --file ./build/App.apk \
--audit-file ./honor-audit.json --output ndjson--app-id는 필수 i64, --package-name은 필수 string, --file(APK)과 --audit-file은 필수 path. 심사 JSON은 최상위 객체입니다.
| 필드 | JSON 유형 / 필수 | 제약 |
|---|---|---|
releaseType | integer, 필수 | 1 일반, 2 예약, 3 단계적 출시. |
forceUpdate | boolean, 필수 | 숫자가 아닌 true/false. |
testAccount, testPassword | string, 선택 | 심사 테스트 계정과 비밀번호. 비밀번호 파일은 CI에서 임시 생성. |
testComment | string, 선택 | 최대 500자. |
releaseTime | string, 선택 | releaseType=2일 때 필수. |
phasedReleasePercentage | string, 선택 | releaseType=3일 때 필수. 값은 0 초과 100 이하. |
phasedReleaseStart, phasedReleaseEnd | string, 선택 | releaseType=3일 때 필수. |
phasedReleaseNote | string, 선택 | releaseType=3일 때 필수, 최대 500자. |
releaseNotesLanguage, releaseNotes | string, 선택 | releaseNotes가 비어 있지 않으면 해당 언어 ID 필요. 설명 최대 500자. |
시간 문자열은 yyyy-MM-ddTHH:mm:ssZZ, 예: 2026-10-01T09:00:00+0800. 일반 출시의 최소 honor-audit.json:
{ "releaseType": 1, "forceUpdate": false }Xiaomi App Store
foxstore-cli publish xiaomi --request-file ./xiaomi-release.json --output ndjson--request-file은 필수 path. JSON은 최상위 객체이며 appInfo / RequestData 래퍼는 필요 없습니다.
| 필드 | JSON 유형 / 필수 | 제약 |
|---|---|---|
synchroType | integer, 필수 | 0 신규, 1 버전 업데이트, 2 정보 업데이트. 계정 및 앱 권한에 따름. |
appName, packageName, privacyUrl, iconPath | string, 필수 | 빈 값 불가. iconPath는 로컬 파일 경로. |
publisherName, versionName | string, 선택 | 개발자명과 버전명. |
category, keyWords, description, brief | string, 선택 | synchroType=0일 때 모두 필수. |
updateDescription | string, 선택 | synchroType=1일 때 필수. |
testAccount | string, 선택 | 직렬화된 JSON 문자열. 아래 참조. |
onlineTime | integer, 선택 | 출시 시간. |
suitableType | integer, 선택 | 0, 1 또는 2. |
apkPath | string, 선택 | synchroType=0/1일 때 필수. 로컬 APK. |
secondApkPath | string, 선택 | 두 번째 로컬 APK. |
screenshotPaths | string[], 기본 [] | 최대 5개. 신규 앱은 로컬 스크린샷 최소 3개. |
tabletScreenshotPaths | string[], 기본 [] | 최대 5개. 신규 앱이며 suitableType=1/2이면 최소 4개. |
버전 업데이트 xiaomi-release.json 예제(파일이 존재하며 대상 앱 요구사항을 충족해야 함):
{
"synchroType": 1, "appName": "示例应用", "packageName": "com.example.app",
"privacyUrl": "https://example.com/privacy", "iconPath": "./store/icon.png",
"apkPath": "./build/App.apk", "updateDescription": "修复已知问题"
}testAccount는 중첩 JSON을 인코딩한 문자열입니다. 예: "{\"zh_CN\":{\"auditNotes\":\"无需登录\"}}". 각 언어 키의 객체에는 auditNotes(최대 500자)와 accounts 배열(최대 5개)이 올 수 있습니다. 각 account 객체는 필수 integer t(1 또는 2), 선택 string a(계정), p(비밀번호), c(추가 값)를 가지며 문자열은 각각 최대 50자입니다. 계정과 비밀번호는 함께 입력하거나 함께 비워야 합니다. testAccount에 JSON 객체를 직접 전달하지 마세요.
상태 조회
WeChat 미니프로그램 업로드는 로컬 CI가 동기 결과를 반환하며 별도 status 명령은 없습니다. 결과가 불명확하면 WeChat 콘솔에서 확인하세요. 아래 조회는 같은 Provider 자격 증명이 필요합니다. 별도 표시가 없는 인수는 필수 string이며 모든 status는 한 번 조회로 연속 대기가 아닙니다.
| 명령 | 매개변수 |
|---|---|
status apple | --issuer-id, --key-id, 개인 키 소스. 볼 수 있는 Build를 업로드 시간 내림차순 조회. --app-id 필터나 buildUploadId 직접 조회 없음. |
status google-play | --package-name; Tracks 반환. |
status huawei | --app-id; HarmonyOS는 Service Account, Android는 API Client와 반복 지정 가능한 --package-id 최소 1개. |
status pgyer | --app-key; --build-key 선택. |
status tencent-appstore | --package-name、--app-id。 |
status vivo | --package-name; --endpoint 선택. |
status samsung | --content-id。 |
status oppo | --package-name; --version-code 선택. 다중 패키지는 --multi-package 추가(bool 플래그, 기본 false). |
status honor | --app-id와 하나 이상의 --release-id(app-id는 i64, 각 release-id는 반복 가능한 string). |
status xiaomi | --package-name。 |
기계용 출력 및 종료 코드
현재 schemaVersion은 문자열 "1"입니다. json은 들여쓰기 JSON, ndjson은 압축 JSON 한 줄입니다. 둘 다 최종 결과만 출력하고 업로드 진행 이벤트 스트림은 없습니다. 성공 envelope는 stdout, 인수 오류를 포함한 오류 envelope는 stderr로 출력됩니다. stdout만 파싱하거나 두 스트림을 하나의 JSON 파일로 합치지 마세요.
성공 예제(Apple 업로드이며 심사 통과/출시를 뜻하지 않음):
{ "schemaVersion": "1", "status": "success", "data": { "provider": "apple", "buildUploadId": "example-upload-id" } }오류 예제(구조만 표시):
{ "schemaVersion": "1", "status": "error", "error": { "code": "CLI_ARGUMENT_INVALID", "category": "input", "message": "缺少必填参数", "retryable": false } }data는 명령에 따라 객체 또는 배열이며 provider가 반드시 포함되지는 않습니다. error.code는 문자열, category는 아래 표의 고정 문자열, message는 설명, retryable은 boolean입니다. 상위 Secret/인증 정보는 제거되지만 입력 경로와 요청 JSON의 업무 텍스트는 팀 로그 정책으로 보호해야 합니다.
| 종료 코드 | 분류 | 파이프라인 처리 |
|---|---|---|
0 | 성공 | 명령 성공. 사전 검사/출시 데이터 판단은 여전히 필요하며 심사 통과나 스토어 출시가 아님. |
2 | input: 입력 또는 패키지 오류 | 인수 또는 빌드 산출물 수정. |
3 | credential: 자격 증명 오류 | Secret 이름, 임시 파일과 권한 확인. |
4 | network: 네트워크 오류 | retryable: true일 때만 정책에 따라 재시도. |
5 | provider: Provider 거부 또는 응답 오류 | 민감 정보가 제거된 코드를 읽고 권한, 자료 또는 플랫폼 상태 수정. |
6 | unsupported: 미지원 기능 | 성공으로 처리하지 않음. |
7 | result-unknown: 결과 불명 | 원격 쓰기가 발생했을 수 있음. 반드시 status로 먼저 대조하고 즉시 재출시하지 않음. |
10 | internal: CLI 내부 오류 | 버전과 민감 정보를 제거한 로그 보존 후 보고. |
재시도 및 대조 범위
종료 7 / result-unknown은 원격 쓰기가 발생했을 수 있음을 뜻하며 보통 retryable: false입니다. Pgyer는 업로드 시작 전 타임아웃에 4, 요청 전송 후에는 7을 반환할 수 있습니다. Huawei Android 컴파일 폴링 소진도 7입니다. 이는 알려진 결과 불명 분류이며 모든 플랫폼 중단이 완전한 오류 envelope를 낸다는 보장은 아닙니다. Runner 타임아웃, 프로세스 종료나 정전도 먼저 대조하세요.
명령 버전, 산출물 해시, 앱/패키지명, 버전, 빌드 번호와 반환된 원격 ID를 보존하세요. 위 status로 식별자와 원격 상태를 대조하며 status 종료 0만으로 해당 버전이 출시됐다고 판단하면 안 됩니다. Apple은 빌드 목록의 대상 앱과 빌드, Google Play는 Track과 versionCodes, Honor는 releaseId, Huawei Android는 packageId가 필요합니다. 실패 전에 ID를 못 받았거나 버전이 아직 목록에 없다면 스토어 콘솔에서 확인하세요. ID를 지어내거나 즉시 다시 publish하지 마세요.
Provider 공통 wait, cancel, reconcile, 통합 --timeout 또는 --dry-run 명령은 없습니다. retryable: true여도 재출시가 반드시 안전하지는 않으므로 원격 쓰기가 이미 발생했는지 판단하세요. Secret 주입, 출력 보존과 파이프라인 실패 유지의 전체 예제는 CI/CD 연결 가이드를 확인하세요.
