모바일IOS
11

Mac 없이 Flutter 앱을 TestFlight로 배포하는 방법 (Codemagic 활용)

Flutter로 iOS 앱을 개발했지만 Mac이 없거나 Xcode를 다뤄본 경험이 없는 개발자를 위한 실전 배포 가이드입니다.

Mac 없이 Flutter 앱을 TestFlight로 배포하는 방법 (Codemagic 활용)

Codemagic을 활용하면 Mac 없이도 TestFlight 배포 자동화 파이프라인을 구축할 수 있습니다.


목차

  1. 전체 흐름
  2. 사전 준비 - Apple Developer 계정
  3. 용어 정리
  4. Bundle ID 등록
  5. Flutter 프로젝트 Bundle ID 수정
  6. App Store Connect 앱 등록
  7. App Store Connect API Key 발급
  8. Codemagic 설정
  9. 빌드 실행
  10. 자주 하는 실수 모음
  11. 빌드 오류 해결 실전 사례
  12. 빌드 성공 확인
  13. 테스터에게 앱 공유하기

전체 흐름

Apple Developer 계정 가입 ($99/년)
        ↓
Bundle ID 등록 (Apple Developer)
        ↓
Flutter 프로젝트 Bundle ID 수정
        ↓
App Store Connect에 앱 등록
        ↓
App Store Connect API Key 발급
        ↓
Codemagic 연결 및 설정
        ↓
빌드 실행 → TestFlight 자동 업로드
        ↓
테스터 초대

1. 사전 준비 - Apple Developer 계정

iOS 앱 배포를 위해서는 Apple Developer Program 가입이 필수입니다.

계정 승인 후 App Store Connect와 Apple Developer Portal에 모두 접근 가능합니다.

image → 계정 승인 완료된 상태의 Apple Developer 대시보드


2. 용어 정리

배포 과정에서 반복적으로 등장하는 핵심 용어를 먼저 정리합니다.

Bundle ID

앱의 주민등록번호에 해당하는 전 세계 유일한 고유 식별자입니다.

형식: com.회사or개인이름.앱이름

예시:
com.kakao.talk       → 카카오가 만든 톡 앱
com.instagram.app    → 인스타그램
com.misnawk.duo      → misnawk가 만든 duo 앱

한 번 앱스토어에 출시하면 변경이 불가하므로 신중하게 결정합니다.

TestFlight

Apple이 제공하는 공식 베타 테스트 플랫폼입니다. 앱스토어 정식 출시 전 최대 10,000명의 테스터에게 앱을 배포할 수 있습니다. 베타 심사는 보통 1~2일 소요됩니다.

Codemagic

Flutter 앱의 빌드 및 배포를 자동화하는 CI/CD 서비스입니다. Mac 없이도 iOS 앱 빌드가 가능하다는 것이 가장 큰 장점이며, 월 500분 무료 빌드를 제공합니다.

Provisioning Profile

Apple이 특정 앱을 특정 기기에서 실행하도록 허가하는 인증서입니다. TestFlight 배포 시에는 반드시 App store 타입을 선택해야 합니다.

App Store Connect API Key

Codemagic 같은 외부 서비스가 Apple 계정에 접근할 수 있도록 허가하는 인증 키입니다. .p8 형식의 파일로 발급됩니다.


3. Bundle ID 등록

Apple Developer Portal에서 본인의 Bundle ID를 먼저 등록해야 합니다.

image

→ 좌측 메뉴에서 Identifiers가 선택된 상태, + 버튼이 보이는 화면

developer.apple.com/account 접속
→ Certificates, Identifiers & Profiles
→ 좌측 메뉴 Identifiers
→ 우측 상단 + 버튼
→ App IDs 선택 → Continue
→ App 선택 → Continue
→ Description: 앱 이름 입력
→ Bundle ID: Explicit 선택
→ 입력창에 com.{이름}.{앱이름} 입력
→ Continue → Register

image → Description과 Explicit Bundle ID가 입력된 상태

⚠️ 주의: Flutter 기본값인 com.example.앱이름은 반드시 변경해야 합니다. Apple이 배포를 거부할 수 있으며, 빌드 오류의 원인이 됩니다.


4. Flutter 프로젝트 Bundle ID 수정

Flutter 프로젝트의 실제 Bundle ID는 ios/Runner.xcodeproj/project.pbxproj 파일에서 관리됩니다.

ios/Runner/Info.plist를 열어보면 $(PRODUCT_BUNDLE_IDENTIFIER)라는 변수만 표시되는데, 실제 값은 반드시 project.pbxproj에서 수정해야 합니다.

image → Ctrl+H 찾아바꾸기 창이 열린 상태, com.example.duocom.misnawk.duo 입력된 화면

GitHub에서 직접 수정하는 방법

  1. GitHub → ios/Runner.xcodeproj/project.pbxproj 파일 열기
  2. 우측 상단 연필(✏️) 아이콘 클릭
  3. Ctrl+H 로 찾아바꾸기 실행
  4. 찾기: com.example.앱이름 → 바꾸기: com.{이름}.{앱이름}
  5. Replace All 클릭 (총 6곳이 한 번에 변경됨)
  6. Commit changes 클릭

변경되는 6곳은 다음과 같습니다.

변경 위치설명
Runner - Debug개발용 빌드
Runner - Release배포용 빌드
Runner - Profile성능 측정용 빌드
RunnerTests - Debug테스트 개발용
RunnerTests - Release테스트 배포용
RunnerTests - Profile테스트 성능용

5. App Store Connect 앱 등록

image

→ 플랫폼 iOS 체크, 이름/번들ID/SKU 입력

appstoreconnect.apple.com 접속 후 앱 → + 버튼 → 신규 앱 클릭

항목입력값
플랫폼iOS
이름앱 이름
기본 언어한국어
번들 ID3단계에서 등록한 Bundle ID 선택
SKU앱 고유 코드 (예: myapp001, 외부 미노출)
사용자 액세스 권한전체 액세스

SKU는 내부 관리용 식별자로 외부에 노출되지 않습니다. 한 번 설정하면 변경이 불가하므로 간단하고 명확하게 입력합니다.


6. App Store Connect API Key 발급

Codemagic이 Apple 계정에 접근하기 위한 API Key를 발급합니다.

image → "App Store Connect API 액세스 요청이 승인되었습니다" 메시지와 API 키 생성 버튼이 보이는 화면

appstoreconnect.apple.com
→ 사용자 및 액세스
→ 통합 탭
→ App Store Connect API → 팀 키
→ + 버튼 또는 API 키 생성 클릭
→ 이름: Codemagic
→ 액세스: App Manager
→ 생성

생성 후 다음 세 가지를 반드시 저장합니다.

항목위치
Issuer ID키 목록 상단 고정 표시
Key ID생성된 키 행 좌측
.p8 파일다운로드 버튼 클릭하여 즉시 저장

⚠️ 매우 중요: .p8 파일은 생성 직후 단 한 번만 다운로드 가능합니다. 화면을 닫으면 재다운로드가 불가능하므로 반드시 즉시 저장합니다. 분실 시 키를 삭제하고 재생성해야 합니다.


7. Codemagic 설정

7-1. GitHub 연결 및 앱 등록

codemagic.io 접속 후 GitHub 계정 연결 및 Flutter 프로젝트를 선택합니다.

7-2. Developer Portal 연결

→ Developer Portal이 미연결 상태(빨간 점)인 화면 (Connect 클릭 전)

우측 상단 프로필 → Integrations
→ Developer Portal → Connect 클릭
→ API key name: Codemagic 입력
→ Issuer ID 입력
→ Key ID 입력
→ .p8 파일 업로드
→ Save

Developer Portal 연결은 계정 단위로 한 번만 설정하면 이후 모든 앱 프로젝트에서 재사용 가능합니다.

7-3. iOS code signing 설정

image

앱 선택 → Workflow Editor → Distribution → iOS code signing

항목설정값
Code signing methodAutomatic
App Store Connect API keyCodemagic (발급한 키 선택)
Provisioning profile typeApp store
Bundle identifiercom.{이름}.{앱이름}

⚠️ Provisioning profile type을 Development로 설정하면 TestFlight 업로드가 되지 않습니다. 반드시 App store를 선택합니다.

→ Enable App Store Connect publishing 체크, Submit to TestFlight beta review 체크된 상태

Distribution 섹션에서 App Store Connect 항목 펼치기

항목설정값
Enable App Store Connect publishing✅ 체크
App Store Connect API keyCodemagic (발급한 키 선택)
Submit to TestFlight beta review✅ 체크

설정 완료 후 우측 상단 Save changes 클릭


8. 빌드 실행

→ Build branch: main 선택, Select workflow: Default Workflow 선택된 상태

우측 상단 Start new build 클릭
→ Build branch: main 선택
→ Select workflow: Default Workflow
→ Start new build 클릭

빌드 소요 시간은 보통 10~20분입니다. 빌드 성공 시 App Store Connect의 TestFlight 탭에 자동으로 업로드됩니다. 이후 Apple의 베타 심사(1~2일)를 거쳐 테스터 초대가 가능합니다.

테스터 초대 방법은 두 가지입니다.

방법특징
이메일 초대특정인 지정 초대
공개 링크링크 공유만으로 참여 가능

자주 하는 실수 모음

실제 배포 과정에서 겪기 쉬운 실수들을 정리합니다.

❌ 실수 1: Bundle ID를 기본값으로 둔 채 진행

Flutter 프로젝트 생성 시 Bundle ID가 com.example.앱이름으로 자동 설정됩니다. 이 상태로 Apple Developer에 등록하면 추후 배포 거부 가능성이 있으며, App Store Connect에 등록한 Bundle ID와 코드의 Bundle ID가 불일치하여 빌드 오류가 발생합니다.

해결: project.pbxproj에서 Ctrl+H로 com.example.앱이름을 일괄 변경합니다.

❌ 실수 2: Provisioning profile type을 Development로 설정

Development는 로컬 테스트용입니다. TestFlight 배포를 위해서는 반드시 App store를 선택해야 합니다.

→ 그 옆에 App store로 변경된 올바른 화면 캡처 (after) 나란히 배치

❌ 실수 3: .p8 파일 저장을 놓침

API Key 생성 직후 .p8 파일 다운로드 버튼이 표시되는데, 화면을 닫으면 재다운로드가 불가능합니다. 생성 즉시 반드시 저장합니다.

❌ 실수 4: 4곳의 Bundle ID가 불일치

다음 4곳의 Bundle ID가 모두 동일해야 합니다. 하나라도 다르면 code signing 오류가 발생합니다.

위치확인 방법
Apple Developer → Identifiers등록된 Bundle ID 확인
App Store Connect → 앱 정보번들 ID 항목 확인
Flutter → project.pbxprojPRODUCT_BUNDLE_IDENTIFIER 값 확인
Codemagic → iOS code signingBundle identifier 항목 확인

9. 빌드 오류 해결 실전 사례

첫 빌드에서 만난 오류들과 해결 방법을 정리합니다.

오류 1: .env 파일을 찾을 수 없음

No file or variants found for asset: .env.
Failed to bundle asset files.

원인: flutter_dotenv 패키지를 사용하는 경우 pubspec.yaml.env가 assets로 등록되어 있는데, .env 파일은 보안상 .gitignore에 등록되어 GitHub에 올라가지 않기 때문입니다.

해결: Codemagic 환경변수와 Pre-build script를 활용합니다.

Step 1 · Environment variables 등록

→ Variable name: ENV_FILE, Secure 체크된 상태

Codemagic → Workflow Editor
→ Environment variables 섹션 펼치기
→ + 버튼
→ Variable name: ENV_FILE
→ Variable value: 로컬 .env 파일 전체 내용 붙여넣기
→ Secure 체크 ✅
→ Add

Step 2 · Pre-build script 등록

→ 스크립트 섹션 전체가 보이도록 캡처 (Pre-build / Post-build / Pre-publish / Post-publish 위치 구분 가능하게)

#!/bin/sh
set -e
echo "$ENV_FILE" > $CM_BUILD_DIR/.env

이 스크립트가 빌드 시작 전에 .env 파일을 자동으로 생성합니다.

⚠️ 주의: Pre-build script, Post-build script, Pre-publish script, Post-publish script 등 여러 스크립트 입력창이 있습니다. 반드시 Pre-build script에 입력해야 합니다.

💡 보안 팁: .env 파일을 GitHub에 올리는 것은 보안상 위험합니다. Codemagic의 Secure 변수는 암호화되어 저장되고 빌드 로그에도 노출되지 않으므로 이 방식이 훨씬 안전합니다.


오류 2: App Store Connect에 앱을 찾을 수 없음

Cannot determine the Apple ID from Bundle ID 'com.misnawk.duo' and platform 'IOS'. (12)
Failed to publish duo.ipa

원인: 빌드는 성공했지만 App Store Connect에 해당 Bundle ID로 등록된 앱이 없어서 업로드가 실패한 것입니다.

해결: App Store Connect에서 앱을 먼저 등록합니다. (5단계 참고)


오류 3: Build Mode가 Debug로 설정됨

Flutter archive not built in Release mode.

원인: Codemagic Build 섹션의 Mode가 Debug로 설정되어 있으면 TestFlight 업로드가 불가합니다.

해결: Workflow Editor → Build 섹션 → Mode → Release 선택


10. 빌드 성공 확인

모든 설정이 완료되면 다음과 같이 빌드가 진행됩니다.

단계설명
Preparing build machineMac M2 빌드 머신 준비
Fetching app sourcesGitHub에서 코드 가져오기
Installing SDKsFlutter SDK 설치
Set up code signing identities인증서 자동 설정
Installing dependenciespub get 실행
Pre-build script.env 파일 자동 생성
Building iOS앱 빌드
PublishingApp Store Connect 업로드
App Store distributionTestFlight 배포 처리

빌드 완료 후 Artifacts 섹션에서 .ipa 파일을 직접 다운로드할 수도 있습니다.

이후 App Store Connect → TestFlight 탭에서 빌드가 업로드된 것을 확인할 수 있으며, Apple 베타 심사(1~2일) 통과 후 테스터 초대가 가능합니다.


11. GitHub Push 시 자동 빌드 설정 (CI/CD)

지금까지 설정한 것은 수동으로 Start new build를 눌러야 빌드가 실행되는 방식입니다. GitHub에 push할 때마다 자동으로 빌드 및 TestFlight 배포가 되도록 설정합니다.

image → Trigger on push 체크, Watched branch patterns에 main이 입력된 상태

Codemagic → duo 앱 → Workflow Editor
→ Build triggers 섹션 펼치기
→ Trigger on push ✅ 체크
→ Watched branch patterns: * 지우고 main 입력
→ Add pattern 클릭
→ Save changes

설정 완료 후 동작 방식은 다음과 같습니다.

브랜치빌드 실행 여부
main push✅ 자동 빌드 + TestFlight 자동 업로드
다른 브랜치 push❌ 실행 안 함

⚠️ 주의: Watched branch patterns을 *로 두면 모든 브랜치에 push할 때마다 빌드가 실행되어 월 무료 빌드 500분이 빠르게 소진됩니다. 반드시 main으로 변경합니다.

테스터 초대 방법

테스터 초대는 내부 테스터외부 테스터 두 가지 방식이 있습니다.

구분내부 테스터외부 테스터
인원최대 100명최대 10,000명
베타 심사❌ 불필요✅ 필요 (1~2일)
조건App Store Connect 계정 보유자누구든 가능
추천 대상팀 내부 테스트일반 사용자 베타 테스트
--

12. 테스터에게 앱 공유하기

빌드가 TestFlight에 업로드된 후 테스터를 초대할 수 있습니다.

빌드 업로드 확인

Codemagic에서 빌드가 성공했더라도 TestFlight에 즉시 표시되지 않을 수 있습니다. Apple 서버에서 바이너리를 처리하는 데 최대 30분~1시간 소요됩니다.

빌드가 표시되지 않을 경우 다음을 확인합니다.

Codemagic → 마지막 빌드 클릭
→ Publishing 단계 로그 확인
→ App Store distribution 단계 성공 여부 확인

처리가 완료되면 TestFlight 탭에 빌드가 표시됩니다.


공개 링크로 공유 (가장 간단)

베타 심사 통과 후 링크 하나로 누구든 설치할 수 있습니다.

→ 공개 링크 토글이 ON된 상태와 링크가 표시된 화면

App Store Connect → TestFlight 탭
→ 좌측 메뉴 "외부 테스터"
→ 그룹 생성 또는 기존 그룹 선택
→ 공개 링크 활성화 토글 ON
→ 링크 복사 → 카카오톡/문자로 공유

테스터가 해야 할 것:

공유받은 링크 클릭
→ App Store에서 TestFlight 앱 설치 (무료)
→ 초대 수락
→ 앱 설치 및 사용

이메일로 직접 초대

특정인을 지정하여 초대하는 방법입니다.

→ 이메일 입력창과 추가 버튼이 보이는 화면

App Store Connect → TestFlight 탭
→ 좌측 메뉴 "내부 테스팅" 또는 "외부 테스터"
→ + 버튼 → 이메일 입력
→ 초대 메일 발송

상대방의 Apple ID 이메일로 초대 메일이 발송됩니다.


마무리

Mac 없이 Flutter iOS 앱을 TestFlight로 배포하는 전체 과정을 정리하였습니다. 초기 설정이 다소 복잡하지만, 한 번 파이프라인을 구축해두면 이후에는 GitHub에 코드를 푸시하는 것만으로 TestFlight 배포가 자동화됩니다.

첫 빌드에서 실패하더라도 당황할 필요는 없습니다. 빌드 로그에 오류 원인이 상세히 표시되므로 로그를 확인하며 단계적으로 해결해 나가시기 바랍니다.

image -> [테스트 심사진행중]

댓글

(0)
Mac 없이 Flutter 앱을 TestFlight로 배포하는 방법 (Codemagic 활용) | 강민석의 개발블로그