배포와 인프라8 분 읽기

completed 100%는 게시가 아니다

Android 릴리스를 API로 자동화하고 'completed 100%'면 배포 완료로 기록했습니다. 어느 날 리젝 메일이 왔는데 트랙 상태는 여전히 completed였습니다. API는 '트랙에 배정됐다'를 말할 뿐 '사람들이 받고 있다'를 말하지 않습니다. 데이터 보안 양식은 아예 API로 손댈 수도 없습니다.

#android#google-play#api#gotchas
개념 도식: completed 100%·listing saved·commit ok 초록 체크 셋이 쌓여 있는데, 앱 상태는 REJECTED이고 유저 기기엔 이전 버전이 떠 있다. completed는 트랙 배정이지 서빙이 아니다.
초록 체크가 셋인데 유저에게 가는 건 이전 버전이었다. completed = 트랙 배정, ≠ 서빙.

Android 앱 릴리스를 API로 자동화해두고 있습니다. 빌드를 올리고, 트랙에 배정하고, 17개 로케일 스토어 리스팅을 갱신하고, commit합니다. API가 성공을 반환하면 배포 완료로 기록하죠.

어느 날 리젝 메일이 왔습니다. 데이터 보안 양식에 이메일 주소가 누락됐다는 지적이었습니다. 그런데 트랙 상태를 조회하면 status=completed, rollout 100%였습니다.

completed는 서빙의 증거가 아니다

트랙 조회가 completed를 반환해도, 앱 상태가 "거부됨"이면 그 릴리스는 서빙되지 않습니다. 유저에게는 이전 버전이 계속 제공됩니다. API는 "내가 시킨 대로 트랙에 배정됐다"를 말할 뿐, "사람들이 그걸 받고 있다"를 말하지 않습니다.

리스팅 문구도 마찬가지입니다. 거부 상태에서 --listing-only commit이 성공하고 조회 API가 새 문구를 돌려줘도, 그건 콘솔 측에 저장된 값일 뿐 공개 페이지에는 반영되지 않습니다. 그래서 공개 반영은 스토어 페이지를 직접 긁어 확인해야 합니다.

curl -A "Mozilla/5.0" "https://play.google.com/store/apps/details?id=<pkg>&hl=<locale>"
# ⚠️ 구 문구가 신 문구를 부분 포함하면 오탐 → 신 문구에만 있는 토큰으로 매칭

여기서 또 걸렸습니다. 구 문구가 신 문구를 부분 포함하면 오탐이 납니다. 한국어 리스팅에서 구 문구가 신 문구의 일부 구절을 그대로 담고 있어, 단순 문자열 포함 검사가 "반영됨"으로 잘못 판정했습니다. 신 문구에만 있는 토큰으로 매칭해야 합니다.

신호 의미하는 것 의미하지 않는 것
tracks().listcompleted 100% 트랙에 배정됨 유저에게 서빙됨
listings().get → 새 문구 콘솔에 저장됨 공개 페이지에 반영됨
commit 성공 편집이 커밋됨 심사 통과

데이터 보안 양식은 API로 손댈 수 없다

리젝의 원인이 된 데이터 보안 양식은 읽지도 쓰지도 못합니다. androidpublisher v3에 해당 리소스가 없습니다. 콘솔 UI 전용이고, 앱 콘텐츠 관련 양식 6종이 전부 그렇습니다.

즉 이 리젝은 자동화로 해결할 수 없고, 사람이 브라우저를 열어야 합니다. 자동화가 할 수 있는 최선은 "코드가 실제로 무엇을 기기 밖으로 보내는지" 목록을 뽑아 양식 답변의 근거를 만드는 것까지입니다. 실제로 그렇게 했습니다 — 인증 코드에서 이메일과 사용자 ID 전송을 확인하고, 매니페스트에서 위치 권한을 확인해 답변 항목을 정리했습니다.

리젝 메일은 누락된 데이터 유형을 정확히 지목합니다. 지목이 코드와 맞으면 이의신청 대상이 아닙니다. 양식을 고치는 게 정답입니다. 이 경우 OAuth로 이메일이 실제 전송되고 있었으므로 지적이 정확했습니다.

재제출 절차:

1. 각 데이터 유형의 하위 질문까지 전부 답변 (수집/공유, 처리 목적, 필수·선택)
2. 마지막 단계까지 저장
3. 게시 개요 → "검토를 위해 전송"
→ 통과하면 대기 중이던 릴리스와 리스팅 변경이 함께 게시된다. re-push 불필요.

실측: 위 절차로 재제출하니 같은 날 1시간 내 통과했고, 대기 중이던 릴리스와 17로케일 리스팅이 함께 자동 게시됐습니다. 안내되는 "최대 7일"보다 훨씬 빨랐습니다 — 데이터 보안 단독 교정은 심사 부담이 작은 것으로 보입니다.

등장 앱: Plotta (Android) · iOS.

Plotta 화면

정직하게

  • 몇 달 동안 "트랙 completed = 배포 완료"로 기록해왔습니다. 그 기간의 릴리스 기록 중 실제로 게시되지 않은 게 있는지 소급 검증하지 않았습니다. 지금 기록은 신뢰도가 떨어진 상태입니다.
  • 재제출 절차에도 함정이 있었습니다. 양식에서 데이터 유형 체크만 하고 저장하면 반영되지 않습니다. 하위 질문을 전부 답하고 마지막 단계까지 저장한 다음, 게시 개요에서 "검토를 위해 전송"까지 눌러야 합니다. 중간에 저장하고 끝낸 줄 알았던 시도가 한 번 있었습니다.
  • 개인정보처리방침과 양식 내용이 일치해야 하는데, 방침 페이지가 CDN 챌린지에 막혀 CLI로 fetch가 안 됩니다. 브라우저로만 확인 가능합니다 — 이 검증도 자동화 밖입니다.
  • 통과 판정을 스토어 페이지의 메타 태그와 버전 블록으로 했습니다. 이건 관찰이지 API가 보증하는 상태가 아닙니다. 더 나은 방법을 찾지 못했습니다.

같은 계열의 함정이 iOS에도 있습니다 — 제출 API가 성공을 반환해도 실제 심사 상태와 스토어 반영은 별개입니다. version not editable의 주체는 버전이 아니었다와 묶으면 "배포 API의 성공은 무엇을 보증하고 무엇을 보증하지 않는가"라는 한 쌍이 됩니다.

당신의 배포 자동화가 마지막에 기록하는 그 completed, 유저 기기에 그 버전이 실제로 떴다는 뜻입니까, 아니면 그냥 트랙에 배정됐다는 뜻입니까? 스토어 페이지를 한 번 긁어보면 갈립니다.

관련 글