Flutter 빌드·배포 실무 체크리스트
Flutter 빌드·배포 실무 체크리스트
요약: 스토어 제출 전에 서명, 권한, 릴리스 빌드, 관측을 한 장으로 점검한다.
1. 왜 / 언제
flutter run이 되는 것과 스토어 바이너리는 다르다. 디버그 빌드는 느리고, 로그가 남고, 서명이 개발용이다.
이 목록은 출시 직전에 한 번 훑는 용도다. 각 항목은 왜 막히거나 사고가 나는지를 한 줄로 붙인다. 통과하지 않은 채 flutter build만 돌리지 않는다.
2. 품질
-
flutter analyze가 통과한다 — 분석기가 남는 오류는 스토어 빌드·CI에서 다시 막히고, null 실수는 크래시가 된다. - 주요 흐름에 위젯·유닛 테스트가 있다 — 로그인·결제·목록처럼 한 번 깨지면 리뷰·평점이 바로 무너진다.
- 대비·큰 글자·스크린 리더 라벨을 확인한다 — 스토어 접근성 거절과 실제 사용자 이탈을 동시에 줄인다.
- 가로·노치·키보드에서 overflow가 없다 — 릴리스에서만 드러나는 노란 줄은 리뷰 스크린샷을 망친다.
- 빈 목록·네트워크 실패·권한 거절 화면이 있다 — 성공 경로만 있으면 현장 로그가 “무한 스피너”로만 남는다.
flutter analyze
flutter test
analysis_options.yaml의 linter를 팀 표준으로 고정한다. 개인 IDE 설정에 의존하지 않는다.
3. 성능·용량
-
flutter run --release로 체감한다 — 디버그 jank를 최적화하면 없는 병을 고치게 된다. - 이미지 해상도와 포맷을 줄인다 — 번들 용량과 스크롤 디코드 비용이 스토어 다운로드를 결정한다.
- 디버그 로그·테스트 에셋을 뺀다 —
print와 미사용 에셋은 용량과 정보 유출을 만든다. - DevTools로 드롭 프레임 구간을 본다 — 첫 화면·목록 스크롤이 60fps를 못 지키면 리뷰에 “느리다”가 적힌다.
-
const와 빌더 리스트를 지킨다 — 불필요 리빌드는 저가 기기에서만 재현된다.
flutter run --release
flutter build apk --analyze-size
아이콘·스플래시는 플랫폼 가이드 크기를 맞춘다. 임의 PNG를 늘리면 가장자리가 깨져 보인다.
4. Android
-
applicationId가 최종 패키지명이다 — 한 번 스토어에 올리면 바꿀 수 없다. -
versionName/versionCode를 올린다 — 같은 코드로 재제출하면 Play가 거부한다. - 업로드 키스토어와 Play App Signing을 확인한다 — 키를 잃으면 앱을 업데이트할 수 없다.
- R8 minify/shrink를 릴리스에 켠다 — 용량과 심볼 노출을 줄인다. 리플렉션 코드는 keep 규칙이 필요하다.
- 권한을 최소로 둔다 — 쓰지 않는 위치·전화 권한은 정책 거절 사유다.
-
minSdk와 대상 SDK가 스토어 요구를 충족한다 — 타깃 미달은 업로드 단계에서 막힌다.
# pubspec.yaml
version: 1.2.0+12
+12가 Android versionCode로 간다. 빌드마다 증가시킨다.
flutter build appbundle
Play에 올리는 산출물은 APK보다 AAB가 기본이다. 내부 테스터에게만 APK를 쓴다.
키스토어는 저장소에 커밋하지 않는다. CI 시크릿으로만 주입한다.
5. iOS
- Bundle ID가 최종이다 — App ID·인증서·스토어 기록이 이 문자열에 묶인다.
- 배포 인증서와 프로비저닝이 만료되지 않았다 — Archive 실패의 대부분이 여기다.
- Info.plist 권한 설명이 실제 용도와 같다 — 문구 없는 카메라/추적 권한은 리뷰 거절이다.
-
flutter build ipa또는 Xcode Archive가 통과한다 — 로컬run성공은 서명된 IPA를 보장하지 않는다. - 가로 지원·노치·다크모드를 스크린샷 기기에서 본다 — 리뷰어가 보는 기기와 디버그 폰이 다르다.
flutter build ipa
버전은 pubspec.yaml과 Xcode Marketing Version을 맞춘다. 어긋나면 업로드가 거절된다.
6. 보안·운영
- API 키를 앱에 박지 않는다 — 바이너리에서 문자열이 추출된다. 가능하면 백엔드가 대리 호출한다.
- 토큰은 보안 저장소에 둔다 — 일반 prefs는 백업에 포함될 수 있다.
- 인증서 피닝은 팀 정책으로 결정한다 — 켜면 인증서 교체 때 앱이 전면 실패한다.
- Crashlytics 등 크래시 리포트를 켠다 — 스토어 리뷰에는 안 나오는 기동 크래시를 볼 수단이 필요하다.
- dev/prod 엔드포인트를 분리한다 — 프로덕션 앱이 스테이징을 치면 데이터가 섞인다.
- 로그에 PII·토큰을 남기지 않는다 — 릴리스 로그도 수집기로 나간다.
환경은 --dart-define 또는 flavor로 나눈다. 소스의 const api = 'https://prod...' 한 줄에 의존하지 않는다.
flutter build appbundle --dart-define=API_BASE=https://api.example.com
7. Flavor와 CI
-
dev/prodflavor 또는 엔트리가 나뉜다 — 한 바이너리가 두 환경을 치면 실수로 운영 API를 친다. - CI가
analyze→test→build순으로 돈다 — 로컬에서만 빌드하면 키·JDK 차이가 출시 당일에 드러난다. - 서명 파일은 CI 시크릿이다 — 워크스페이스에
*.jks가 있으면 유출과 같다. - 아티팩트(AAB/IPA)를 빌드 번호로 보관한다 — 롤백할 바이너리가 없으면 스토어 콘솔에만 의존하게 된다.
flutter analyze
flutter test
flutter build appbundle --release --dart-define=API_BASE=https://api.example.com
앱 아이콘·스플래시·표시 이름이 flavor마다 다르면 테스터가 어떤 빌드인지 구분한다. 같은 아이콘의 prod/dev는 설치 혼선을 만든다.
8. 스토어·롤백
- 스토어 설명·스크린샷·개인정보 처리 방침 URL이 있다 — 메타 누락은 바이너리와 별개로 거절된다.
- 내부 테스트 트랙을 먼저 돈다 — 서명·권한 문제는 프로덕션 직전이 아니라 내부에서 터져야 한다.
- 롤백 방법을 적어 둔다 — Play/App Store는 이전 버전 재활성 절차가 다르다.
- 지원 OS 버전을 공지에 적는다 — minSdk/iOS 최소가 사용자 기기와 맞는지 미리 알린다.
9. 흔한 실수
| 실수 | 왜 막히는가 |
|---|---|
| 디버그 빌드를 스토어에 올린다 | 느리고 로그가 남으며 서명이 개발용이다 |
| 버전 코드를 안 올린다 | Play/App Store가 같은 빌드를 거부한다 |
| 키스토어를 Git에 둔다 | 유출 시 앱 업데이트가 공격자에게 넘어간다 |
| 권한 설명 없이 카메라/위치 | 리뷰 거절이다 |
| 크래시 리포트 없이 출시 | 현장 기동 실패를 알 수 없다 |
정리
Flutter 릴리스는 flutter build 한 줄이 아니다. 서명·권한·스토어 메타·관측이 위 목록을 통과하는 일이다. 각 항목의 “왜”를 건너뛴 체크는 체크가 아니다.
연습
flutter analyze와flutter test를 로컬에서 통과시킨다.flutter run --release로 목록 스크롤을 실기기에서 확인한다.pubspec.yaml버전을 올리고 AAB 또는 IPA를 만든다.- 이 글의 체크리스트를 통과/미통과로 표시하고, 미통과 항목의 “왜”를 팀에 공유한다.
댓글
0아직 댓글이 없습니다. 첫 댓글을 남겨보세요.