xcodebuild 내보내기 IPA 실패: 2026 원격 Mac에서 어떻게 고칠까?

xcodebuild 내보내기 IPA 실패: 2026 원격 Mac에서 어떻게 고칠까?

Archive는 성공했는데 IPA가 나오지 않는다면 다시 빌드하지 말고, 같은 xcarchive를 기준으로 ExportOptions.plist, 서명 자산, Provisioning Profile, Entitlements와 원격 세션 권한을 순서대로 확인해야 합니다. Archive와 Export는 서로 다른 단계이므로 하나의 성공이 다른 단계의 성공을 보장하지 않습니다.

이 글은 SSH나 지속적 통합 스크립트에서 xcodebuild를 실행하는 독립 개발자와 소규모 팀을 위한 runbook입니다. 원격 Mac을 상시 iOS 패키징 서버로 사용하면서 그래픽 환경에서는 성공하지만 원격 작업에서는 실패하는 경우에도 적용할 수 있습니다.

Archive 성공과 IPA 내보내기를 분리해 기록합니다

Apple의 Xcode 앱 분배 절차처럼 Build, Archive, Export, Upload는 서로 다른 처리 구간으로 봐야 합니다. 여기서 Build는 앱을 컴파일하는 과정이고, Archive는 배포에 사용할 보관 파일을 만드는 과정입니다. Export는 보관 파일에서 분배용 IPA를 만드는 과정이며, Upload는 만들어진 빌드를 App Store Connect로 보내는 과정입니다.

다음 로그처럼 Archive 화면에는 성공이 표시되지만 출력 폴더가 비어 있을 수 있습니다.

Archive succeeded
exportArchive failed
error: exportArchive failed with an error
output directory: /private/tmp/release

이때 마지막 줄의 종료 상태만 보고 다시 컴파일하면 원래 오류가 사라지거나 다른 오류에 가려질 수 있습니다. 먼저 아래 자료를 하나의 작업 묶음으로 보존합니다.

  • 같은 xcarchive의 전체 경로
  • 같은 Xcode 활동 로그와 분배 로그
  • xcodebuild 전체 출력
  • 사용한 ExportOptions.plist
  • 실행 사용자와 현재 작업 경로
  • 실패 뒤에도 남아 있는 중간 파일

그 다음 첫 번째 유효한 오류를 찾습니다. 오류가 보관 파일 입력인지, 내보내기 설정인지, 서명 체인인지, 원격 권한인지 분류해야 합니다.

보관 파일의 내용과 내보내기 조건을 대조합니다

xcarchive는 단순히 이름만 존재하면 되는 파일이 아닙니다. Archive 내부에 예상한 앱, 확장 기능, 내장 프레임워크, Info.plist, 서명 정보가 들어 있어야 합니다. 다중 Target, App Clip 또는 확장 기능이 있는 프로젝트라면 각각의 Bundle ID와 권한을 따로 확인해야 합니다.

검수 순서는 다음과 같이 고정하는 편이 좋습니다.

  1. Archive에 사용한 Scheme과 Configuration을 기록합니다.
  2. 일반 기기용 대상이 아니라 배포에 맞는 기기 대상을 선택했는지 확인합니다.
  3. 보관 파일 안에 주 앱과 모든 확장 기능이 함께 있는지 확인합니다.
  4. Organizer의 Validate 또는 Distribute App 결과를 기록합니다.
  5. 같은 archivePath를 사용해 명령줄 내보내기 결과를 비교합니다.

그래픽 환경의 Distribute App이 실패하면 스크립트만 고쳐서는 해결되지 않습니다. 반대로 그래픽 환경에서는 성공하고 명령줄만 실패한다면 보관 파일보다 ExportOptions.plist나 실행 세션을 먼저 의심해야 합니다.

주의: Archive를 삭제하거나 다시 만들기 전에 원본 경로와 로그를 복사해 두어야 합니다. 보관 파일을 지우면 현재 오류를 비교할 기준과 서명 상태를 확인할 증거가 함께 사라질 수 있습니다.

ExportOptions.plist는 목표 분배 방식에 맞춰 비교합니다

테스트 기기용 분배, App Store Connect 제출용 분배, 그 밖의 분배 방식은 같은 설정 파일을 그대로 공유한다고 가정하면 안 됩니다. 현재 Xcode에서 가능한 키와 값은 실행 환경의 xcodebuild -helpApple의 Xcode 분배 문서로 다시 확인해야 합니다. 오래된 예제 파일을 그대로 복사하는 방식은 피해야 합니다.

가장 안전한 비교 기준은 그래픽 환경에서 한 번 성공한 내보내기입니다.

  • 성공한 분배 목표를 기록합니다.
  • 그래픽 내보내기에서 생성되거나 사용된 설정을 별도 파일로 보관합니다.
  • method가 실제 목표와 일치하는지 확인합니다.
  • 자동 서명인지 수동 서명인지 구분합니다.
  • 팀 정보와 각 Bundle ID의 프로파일 연결을 대조합니다.
  • 현재 Xcode의 도움말에 해당 키가 존재하는지 확인합니다.

기존 파일에 키를 계속 추가하는 방식은 실패 원인을 더 찾기 어렵게 만듭니다. 작은 변경 하나만 적용하고 같은 xcarchive로 다시 실행해야 합니다.

서명 체인과 권한은 네 부분으로 나눠 확인합니다

IPA 내보내기에서 서명 문제를 찾을 때는 인증서 하나만 보면 안 됩니다. Apple은 인증서 종류와 용도를 구분하고 있으며, 실제 작업에는 인증서와 개인 키가 함께 필요합니다.

다음 네 항목을 별도로 확인합니다.

  • 인증서: 현재 목적에 맞는 서명 신원이 키체인에 있는지 확인합니다.
  • 개인 키: 인증서 파일만 가져온 것이 아니라 대응하는 개인 키도 존재하는지 확인합니다.
  • Provisioning Profile: Bundle ID, 팀 정보와 분배 목적이 현재 Archive와 맞는지 대조합니다.
  • Entitlements: Archive 안의 앱과 확장 기능이 프로파일에서 허용한 권한과 일치하는지 확인합니다.

프로파일은 Apple 계정 도움말의 프로파일 관리 절차에 따라 확인합니다. 주 앱은 맞지만 확장 기능의 프로파일이 다르거나, 앱 권한이 바뀌었는데 오래된 보관 파일을 재사용하면 내보내기 단계에서 막힐 수 있습니다.

자동 서명을 사용하는 프로젝트라면 해당 계정과 팀 권한이 현재 세션에서 유효한지 확인합니다. 수동 서명이라면 Target별 프로파일 매핑과 실제 키체인 항목을 명시적으로 대조합니다. 인증서를 바로 폐기하거나 프로파일을 전부 삭제하는 것은 첫 조치가 아닙니다. 먼저 어떤 Target의 어떤 권한이 불일치하는지 백업한 뒤 필요한 항목만 수정해야 합니다.

그래픽 로그인과 SSH 세션의 차이를 비교합니다

로컬에서 IPA가 만들어지는데 원격 Mac에서 실패한다면 프로젝트보다 세션 환경을 먼저 비교해야 합니다. SSH와 그래픽 로그인은 같은 계정 이름을 사용해도 키체인 잠금 상태, 개발자 도구 경로, 임시 폴더, 작업 경로와 권한이 다를 수 있습니다.

다음 항목을 대화형 터미널과 무인 작업에서 각각 기록합니다.

  1. 실제 실행 사용자와 그룹을 확인합니다.
  2. xcode-select가 가리키는 개발자 도구 경로를 확인합니다.
  3. Archive와 ExportOptions.plist의 절대 경로를 사용합니다.
  4. 서명에 필요한 개인 키를 현재 세션에서 읽을 수 있는지 확인합니다.
  5. 출력 폴더와 임시 폴더에 쓰기 권한이 있는지 확인합니다.
  6. 실패 후 로그와 중간 파일이 정리되지 않는지 확인합니다.
  7. 작업이 중단된 뒤 같은 Archive로 다시 내보내기가 가능한지 확인합니다.

계정 권한은 단순히 관리자 여부로 판단하지 않습니다. App Store Connect 역할도 업로드 과정과 관련될 수 있으므로 Apple의 역할별 권한 안내를 함께 확인해야 합니다. 다만 업로드 권한 문제와 IPA 생성 실패는 다른 문제입니다. IPA가 로컬 폴더에 만들어지지 않는다면 먼저 Export 단계의 로그를 봐야 합니다.

실패 원인별 다음 조치를 결정합니다

아래 조건 목록은 같은 xcarchive를 기준으로 어느 방향으로 수정할지 정하는 도구입니다. 각 항목을 확인한 뒤 하나의 조건만 바꾸고 다시 Export를 실행합니다.

  • [ ] archivePath가 실제 파일을 가리키지 않으면 입력 경로 문제로 판정합니다. 상대 경로를 절대 경로로 바꾸고 보관 파일의 읽기 권한을 확인합니다.
  • [ ] Archive 안에 주 앱이나 확장 기능이 없으면 Archive 문제로 판정합니다. Scheme, Configuration, 대상 기기를 수정한 뒤 새 보관 파일을 만듭니다.
  • [ ] Archive는 정상이고 그래픽 내보내기도 실패하면 분배 설정 또는 서명 문제로 판정합니다. 목표 분배 방식과 Target별 프로파일을 다시 대조합니다.
  • [ ] 그래픽 내보내기는 성공하지만 SSH만 실패하면 원격 세션 문제로 판정합니다. 실행 사용자, 키체인, 개발자 도구 경로와 출력 폴더 권한을 비교합니다.
  • [ ] IPA는 생성되지만 App Store Connect 전송만 실패하면 Upload 문제로 분리합니다. Export 설정을 바꾸지 말고 업로드 로그와 계정 역할을 확인합니다.
  • [ ] 같은 Archive로 반복 성공하고 중단 후에도 복구되면 상시 원격 패키징 조건을 충족한 것으로 봅니다.
  • [ ] 그래픽 세션에서만 성공하거나 로그가 사라지면 무인 운영 조건을 충족하지 못한 상태로 판단합니다. 키체인과 로그 보존 방식을 먼저 수정합니다.

이 목록의 마지막 두 항목이 특히 중요합니다. 한 번 생성된 IPA보다 같은 입력을 반복해서 처리할 수 있는지가 원격 Mac의 운영 가능성을 결정하기 때문입니다.

독립 원격 Mac을 상시 패키징 서버로 쓸지 판단합니다

원격 Mac을 선택할 때는 단순히 Archive가 한 번 성공했는지가 아니라 반복 가능한 내보내기 조건을 확인해야 합니다. 다음 비교 목록으로 기존 환경과 독립 원격 Mac을 평가할 수 있습니다.

기존 개발 컴퓨터

  • 그래픽 로그인에서는 서명이 되지만 SSH에서 실패하면 무인 운영 점수는 낮게 봅니다.
  • 개인 키가 사용자 계정에만 묶여 있거나 키체인 잠금 상태에 의존하면 자동화에 불리합니다.
  • 작업이 끝난 뒤 임시 폴더가 정리되어 로그를 잃는다면 원인 재현성이 낮습니다.
  • 다른 개발 작업과 패키징 작업이 같은 디스크와 키체인을 공유하면 변경 원인을 분리하기 어렵습니다.

독립 원격 Mac

  • 같은 xcarchive와 같은 설정 파일로 반복 내보내기가 가능해야 합니다.
  • SSH 사용자, 키체인, 개발자 도구 경로와 출력 경로를 고정할 수 있어야 합니다.
  • 작업 중단 뒤에도 로그와 보관 파일을 남겨 복구 여부를 확인해야 합니다.
  • 여러 Target의 프로파일과 Entitlements를 하나씩 검수할 수 있어야 합니다.

독립 원격 Mac을 검토한다면 먼저 원격 Mac 환경 구성과 검수 안내를 참고해 세션 구조를 확인할 수 있습니다. 장비를 장기간 보유할지 비교할 때는 Mac mini 요금 안내처럼 구매와 원격 사용의 비용 항목을 나눠 보는 편이 좋습니다. 여기서 비용이나 성능을 미리 단정하기보다, 현재 프로젝트의 반복 내보내기와 복구 조건을 실제로 통과하는지가 우선입니다.

자주 발생하는 증상을 단계별로 분리합니다

Archive가 존재하지 않는 경우

archivePath가 실제 경로와 다르거나 작업 디렉터리가 SSH 실행 때 달라졌을 수 있습니다. 상대 경로를 절대 경로로 바꾸고, 명령 실행 직전에 파일 존재 여부와 읽기 권한을 출력합니다.

Archive는 있지만 앱이 빠진 경우

잘못된 Scheme, Configuration 또는 대상 선택으로 보관했을 가능성이 있습니다. 주 앱과 확장 기능의 구조를 확인하고 Organizer에서 Validate를 실행합니다. 이 경우 ExportOptions.plist를 먼저 바꾸면 문제를 놓칠 수 있습니다.

설정은 읽히지만 서명이 실패하는 경우

분배 방식과 프로파일 매핑을 확인합니다. 인증서와 개인 키가 한 쌍인지 확인하고, Archive 안의 Entitlements와 현재 프로파일을 비교합니다. 프로파일을 지우기 전에 원본 파일과 연결된 Bundle ID를 보관해야 합니다.

출력 폴더가 비어 있는 경우

출력 경로가 존재하는지, 현재 SSH 사용자가 쓸 수 있는지 확인합니다. 실패 로그가 별도 임시 폴더에 남는지도 확인합니다. 작업 종료 후 자동 정리 단계가 결과를 지우는 스크립트도 함께 점검해야 합니다.

IPA는 만들어졌지만 업로드가 실패하는 경우

이것은 Export 실패가 아니라 Upload 단계의 문제일 수 있습니다. App Store Connect의 빌드 상태와 업로드 결과는 공식 빌드 업로드 상태 안내에서 확인합니다. IPA 생성과 업로드를 같은 오류로 묶지 않아야 수정 범위를 줄일 수 있습니다.

자주 묻는 내용을 로그와 원격 조건으로 확인합니다

Archive 성공 후 IPA가 없는 이유

Archive는 배포 파일이 아니라 보관 파일을 만드는 단계입니다. IPA 내보내기에서는 분배 방식, 서명 신원, 프로파일, 권한과 출력 경로를 다시 검사합니다. 따라서 보관 파일이 정상이어도 ExportOptions.plist나 SSH 세션의 키체인 접근 때문에 실패할 수 있습니다. 같은 보관 파일을 고정한 뒤 첫 오류를 찾아야 합니다.

종료 코드 70을 확인하는 순서

종료 코드 70은 그 자체로 특정 원인을 뜻한다고 단정하지 않습니다. 전체 출력에서 처음 나타난 오류를 찾고, archivePath, 설정 파일, 프로파일 매핑, 개인 키 접근, 출력 폴더 권한을 순서대로 확인합니다. 그래픽 환경과 SSH 환경에서 같은 보관 파일을 사용해 결과가 달라지는지도 기록해야 합니다.

ExportOptions.plist를 맞추는 방법

먼저 목표가 테스트 기기용인지, App Store Connect 제출용인지 구분합니다. 그 다음 성공한 그래픽 내보내기 설정을 비교 기준으로 삼고, 현재 장비의 xcodebuild -help와 Apple 문서에 해당 설정이 존재하는지 확인합니다. 팀 정보와 Target별 프로파일 매핑까지 맞아야 합니다.

SSH에서만 IPA 내보내기가 실패하는 이유

SSH 세션은 그래픽 로그인과 키체인 상태, 개발자 도구 경로, 임시 폴더와 권한이 다를 수 있습니다. 실행 사용자, 절대 경로, 개인 키 접근, 출력 폴더 권한을 두 세션에서 각각 기록해야 합니다. 로그인 셸에서 성공했다는 사실만으로 무인 작업 조건이 충족되지는 않습니다.

원격 Mac 무인 내보내기 검수 기준

한 번의 성공보다 반복성과 복구 가능성이 중요합니다. 동일한 xcarchive로 내보내기를 반복하고, 결과 IPA와 전체 로그를 보존하며, 작업 중단 뒤 재시작할 수 있는지 확인합니다. 그래픽 세션에서만 성공한다면 상시 서버로 사용하기 전에 키체인과 세션 권한을 수정해야 합니다.

수정 후에는 같은 Archive로 최종 검수합니다

수정이 끝나면 다시 Build부터 시작하지 말고 기존 xcarchive로 Export를 재실행합니다. 이 방식이면 변경한 항목이 ExportOptions.plist인지, 서명 자산인지, 원격 권한인지 분리할 수 있습니다.

최종 검수 기록에는 다음 내용을 남깁니다.

  • 사용한 Archive의 식별 정보
  • 목표 분배 방식
  • 실제 사용한 설정 파일
  • 인증서와 개인 키 확인 결과
  • 주 앱과 확장 기능의 프로파일 매핑
  • Entitlements 비교 결과
  • 실행 사용자와 키체인 조건
  • IPA 생성 경로와 파일 확인 결과
  • 작업 중단 후 재시작 결과

그래픽 환경에서는 통과하지만 현재 컴퓨터의 SSH 작업이 계속 불안정하다면, 기존 개발 환경을 계속 되풀이해 고치기보다 별도의 원격 Mac에서 같은 검수 묶음을 실행하는 편이 낫습니다. 반대로 장기간 고정된 고부하 작업이나 물리 장치 연결이 핵심이라면 직접 보유한 Mac이 더 적합할 수 있습니다.

현재 환경을 그대로 유지하면 로그인 세션에 의존한 키체인, 작업마다 달라지는 경로, 다른 개발 작업과 섞이는 로그 때문에 같은 오류를 반복해서 재현하기 어렵습니다. 이런 조건에서 MacDate의 원격 Mac을 임시 또는 상시 패키징 환경으로 시험하면, 먼저 동일한 xcarchive의 반복 내보내기와 작업 재시작 복구를 검증한 뒤 장기 운영 여부를 결정할 수 있습니다. 자세한 원격 Mac 선택 조건은 MacDate의 한국어 안내에서 확인할 수 있습니다.

더 읽어보기