fastlane에서 Unexpected Error로 iOS 앱을 제출할 수 없는 문제 해결하기

전수열
전수열
May 27, 2020 · 9 min read

새 버전을 앱스토어에 제출하기 위해 GitHub에 태그를 푸시하고 배포 파이프라인이 실행되기를 기다렸습니다. 하지만 20분간의 빌드가 끝나고 들려온 것은 슬픈 소식이었습니다.

Image for post
Image for post

에러 원인을 확인하기 위해 빌드 로그를 보았지만 Unexpected Error라는 것 외에는 특별히 도움이 되는 정보가 없었습니다. 처음 겪는 문제라, 일시적인 서버 장애라고 생각하고 두어 번을 더 실행해 보았지만 결과는 같았습니다.

Image for post
Image for post

예정대로 릴리즈를 내보내기 위해서는 이 문제를 빨리 해결해야 했습니다.

정보 수집

정확히 어떤 단계에서 에러가 발생하는지를 먼저 확인할 필요가 있었습니다. 위 로그를 가지고 알 수 있는 것은 ‘Uploading metadata to App Store Connect’ 단계에서 문제가 발생했다는 것과, ‘Unexpected Error’ 라는 것입니다. 메타데이터를 업로드하는 단계에서 발생한 예상치 못한 에러라니. 모호해도 너무 모호합니다. 더 많은 정보가 필요합니다.

빠른 피드백을 위해 로컬 머신에 에러를 재현할 수 있는 간단한 스크립트를 작성했습니다. 빌드나 스크린샷 업로드를 모두 제외하고 메타데이터만 올리는 fastlane 스크립트입니다.

lane :metadata do
upload_to_app_store(
force: true,
skip_binary_upload: true,
skip_screenshots: true,
app_version: '3.55.0',
build_number: '934',
)
end

그리고 상세한 로그를 보기 위해 — verbose 옵션을 사용해서 실행했습니다.

bundle exec fastlane metadata --verbose

이번에는 stack trace 정보까지 함께 출력됩니다. handle_itc_response() 함수에서 Spaceship::Tunes::PotentialServerError 에러가 발생한 것을 볼 수 있습니다. 앱스토어 커넥트 API에서 에러가 난 것임을 확인할 수 있습니다.

검색

fastlane는 스크립트가 실패하면 GitHub 이슈를 검색하도록 유도합니다. 자동으로 검색해주는 이슈들은 전혀 연관성이 없었고, 추가 링크를 통해서 한 개의 이슈(#14214)를 확인할 수 있었습니다.

Image for post
Image for post

이슈의 댓글을 모두 살펴봤습니다. 첫 번째 댓글은 로그를 확인해보라는 댓글이었습니다.

Image for post
Image for post

로그를 보면 조금 더 상세한 정보가 있지 않을까 하는 기대를 가지고 열어보았지만, 앱스토어 커넥트 서버에서 Unexpected Error를 반환하는 것 외에는 더 많은 정보를 얻지 못했습니다. 이미 알고 있는 정보입니다.

DEBUG [01:38:40]: << POST ra/apps/458165974/platforms/ios/versions/836157375: 500 {"data"=>nil, "messages"=>{"warn"=>nil, "error"=>["Unexpected Error"], "info"=>nil}, "statusCode"=>"ERROR"}
DEBUG [01:38:40]: Request was successful

두 번째 댓글은 state와 country 관련 정보를 주석처리했더니 해결됐다는 내용이었습니다.

Image for post
Image for post

fastlane/metadata/trade_representative_contact_information 디렉토리의 country.txtstate.txt 내용을 모두 제거해서 빈 파일로 만들어봤지만 여전히 문제가 재현됐습니다.

마지막 댓글은 스크립트를 수정해서 해결했다고 자랑하는(?) 글이었습니다.

Image for post
Image for post
뭘 어떻게 수정했는지를 알려줘야지…

추론

정보 수집 과정에서는 뾰족한 해결책을 찾을 수 없었습니다. 따라서 생길 수 있을 법한 몇 가지 가설을 세웠습니다. Unexpected Error는 사실상 모든 경우를 포괄할 수 있기 때문에 최대한 많은 경우의 수를 생각하려 했습니다.

  1. 앱스토어 커넥트 서버에 장애가 있을 것이다.
  2. fastlane 버전에 문제가 있을 것이다.
  3. 빌드 머신에 문제가 있을 것이다.
  4. 프로젝트에 문제가 있을 것이다.
  5. 애플 계정에 문제가 있을 것이다.
  6. 메타데이터에 문제가 있을 것이다.

가설 1. 앱스토어 커넥트 서버에 장애가 있을 것이다.
갑작스럽게 문제가 생겼고, 예상치 못한 에러라는 것을 봤을 때 서비스 장애가 원인일 수 있겠다는 생각을 했습니다. 이런 경우 공식 Status 페이지를 가장 먼저 참고하고, 두 번째로는 트위터에서 실시간 트윗을 검색합니다. Status 페이지에서도 문제가 없고, 트위터에서 #fastlane #appstore #outage 등의 키워드로 검색했을 때 실시간 검색 결과가 없는 것을 확인했습니다.
👉 탈락

가설 2. fastlane 버전에 문제가 있을 것이다.
기존에 사용하던 버전은 2.145.0입니다. 지난주 릴리즈에서 같은 버전을 사용했는데 문제가 없었습니다. 애플의 코드 변경에 종속적인 fastlane의 특성상 불안정한 경우가 많기 때문에, 혹시나 하는 마음으로 최신 버전인 2.148.1로 업그레이드 해보았지만 여전히 문제가 발생합니다.
👉 탈락

가설 3. 빌드 머신에 문제가 있을 것이다.
빌드 머신에서 크리덴셜을 잘못 꺼내오거나, 빌드 캐시를 복구할 때 일부 파일에 문제가 생겼을 가능성을 의심했습니다. 배포 파이프라인을 몇 번 재시도 하는 동안 여러 대의 빌드 머신에서 작동되었고, 모두 실패했습니다. 로컬 머신에서도 테스트해 보았으나 같은 문제가 발생합니다.
👉 탈락

가설 4. 프로젝트 설정에 문제가 있을 것이다.
여러 명의 개발자가 코드를 작성하기 때문에 미처 리뷰하지 못한 프로젝트 설정 변경이 있을 수 있습니다. 관련이 있을 법한 디렉토리의 커밋 히스토리를 모두 탐색했지만 변화가 없었습니다. 또한 개인 프로젝트에서 같은 스크립트를 실행했더니 동일한 문제로 실패했습니다.
👉 탈락

가설 5. 애플 계정에 문제가 있을 것이다.
정책 변경에 동의하지 않았거나 계정 권한을 잘못 설정하는 등의 문제를 생각했습니다. Account Holder 계정으로 앱스토어 커넥트와 애플 개발자 사이트에 접속해 보았으나 별다른 경고가 없었습니다. 권한도 그대로 가지고 있었습니다. 개인 프로젝트에서 개인 애플 계정을 사용해서 테스트해 보았으나 똑같은 문제가 발생했습니다.
👉 탈락

가설 6. 메타데이터에 문제가 있을 것이다.
불과 일주일 전 릴리즈만 해도 잘 됐고, 메타데이터 변경이 일절 없었기 때문에 가장 가능성이 낮습니다. 그리고 메타데이터에 문제가 있었다면 충분히 많은 검색 결과가 있었을 것입니다. 따라서 마지막 가설로 남겨뒀습니다. 하지만 셜록의 유명한 말처럼, 나머지 가능성을 모두 제거하고 남은 것은 사실일 가능성이 있어 검증할 필요가 있었습니다.

Image for post
Image for post

메타데이터에 문제가 있었을까?

fastlane 메타데이터에는 여러 파일이 존재합니다. 정확히 어떤 메타데이터에서 문제가 생겼는지를 확인하기 위해 수동으로 이진 탐색했습니다. 파일들 중 절반을 다른 곳으로 옮겨두고 스크립트를 실행합니다. 만약 문제가 생긴다면 또 반을 나눠서 테스트하는 과정을 반복합니다. 문제가 생기지 않는다면 옮겨둔 다른 절반에서 같은 과정을 반복합니다.

O(log N)의 시간복잡도를 가진 이진 탐색의 효율성 덕분에 금방 문제의 파일을 발견할 수 있었습니다. fastlane/metadata/trade_representative_contact_information/country.txt 파일을 제거하니까 문제가 사라졌습니다. 분명 이슈를 검색해서 나온 댓글을 따라 내용을 모두 삭제했을 때에는 문제가 여전히 있었는데, 파일을 삭제하니까 문제가 해결됐습니다. 유효성 검사에서 실패한 것을 의심했습니다.

해결하기

country.txt의 기존 값은 Korea, Republic Of 였습니다. '대한민국'을 표현하는 값이 어떤 값으로 변경해야 하는지 확인할 필요가 있었습니다. 하지만 fastlane에서 사용하는 API는 비공식이기 때문에 별도의 문서가 존재하지 않습니다. fastlane으로 앱스토어 커넥트에 등록된 메타데이터를 직접 내려받으면 최신 값을 얻을 수 있을 것 같았습니다.

bundle exec fastlane deliver download_metadata -m "./itc-metadata"

그리고 나서 country.txt값을 확인해 보았더니 South Korea였습니다. 같은 값으로 수정하고 스크립트를 실행했더니 성공했습니다. 문제 해결!

결론

불과 저번주 수요일 저녁까지만 해도 문제 없이 릴리즈되었습니다. 따라서 최근에 앱스토어 커넥트에 변경이 있었을 것 같습니다. 하필이면 인터넷에 자료가 많지 않은 대한민국 표기 방식의 변화라 더욱 찾기 어려웠습니다. 혹시나 같은 현상으로 문제를 겪고 계신 다른 개발자분들께 도움이 되기를 바랍니다.

StyleShare

스타일쉐어의 모든 과정을 기록합니다.

전수열

Written by

전수열

A lazy developer 😴 I write many code to write less code. Born in 1995 and started coding from 2005.

StyleShare

스타일쉐어의 모든 과정을 기록합니다. 공동 저자가 될 멋진 동료를 기다리고 있습니다. join@stylesha.re

전수열

Written by

전수열

A lazy developer 😴 I write many code to write less code. Born in 1995 and started coding from 2005.

StyleShare

스타일쉐어의 모든 과정을 기록합니다. 공동 저자가 될 멋진 동료를 기다리고 있습니다. join@stylesha.re

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store