
빌드하고 브라우저 열어서 플레이 콘솔(Play Console)에 드래그, 트랙 고르고 릴리스 노트 적고 Rollout까지. 이 6단계를 커밋 하나 고칠 때마다 반복하고 계신가요?
AAB 손 업로드 왕복을 안드로이드 스튜디오(Android Studio) 안에서 접고, 내부 테스트 트랙까지 바로 직결시켜본 기록입니다. 초보 튜토리얼은 아니에요. 서명 키 만들어봤고, 플레이 개발자 계정($25) 결제해서 수동 업로드 한 번쯤은 해본 분들을 위한 글입니다. 'Publish for Testing' 실사용 후기, 계정 연결에서 크게 막혔던 자리, 그리고 손 배포와 자동화를 갈라 쓰는 기준까지 겪은 대로 적었습니다.
AAB 실기기 설치가 안 되는 이유부터, 그 6단계 왕복
지난 몇 달간 사이드 프로젝트를 클로드 코드(Claude Code)로 굴리면서 하루에도 몇 번씩 반복한 게 이거였어요. Build > Generate Signed Bundle/APK 눌러서 .aab 뽑고, 브라우저 열어서 플레이 콘솔 로그인하고, 트랙 고르고, Create release 누르고, 파일 드래그하고, 릴리스 노트 쓰고, 검토하고 Rollout.
여기서 "그냥 AAB를 폰에 설치하면 안 되나" 싶으실 텐데요. 근데 그게 원래 안 됩니다. .apk 랑 달리 AAB는 기기에 직접 못 깔거든요.
AAB는 기기별로 딱 맞는 split APK로 쪼개져서 설치되는데요. 그 쪼개는 작업이 Play 서버에서 일어납니다. 그래서 내 폰에서 확인하려면 Play 테스트 트랙에 올리거나, 로컬에선 bundletool 로 직접 쪼개야 해요. 이 구조가 자동화를 고민하게 된 출발점이었습니다.

안드로이드 스튜디오 Play Console 업로드, 'Publish for Testing'의 실체
Generate Signed App Bundle 마법사 마지막 단계에 'Publish for Testing' 같은 항목이 보이는 버전이 있긴 합니다. 근데 여기서 솔직하게 말씀드릴 게 있어요.
"IDE에 내장된 원클릭 배포 버튼" 의 실체는 스튜디오 버전마다 다르고, 공식 문서로 깔끔하게 확인되지 않는 부분이 있는 것 같습니다. 그러니 본인 스튜디오의 최신 릴리스 노트를 먼저 확인하시는 게 정확해요.
실무에서 말하는 "스튜디오에서 바로 업로드" 는 대부분 이겁니다. 그래들 플레이 퍼블리셔(Gradle Play Publisher, GPP) 같은 Gradle 태스크를 IDE의 Gradle 패널에서 더블클릭으로 실행하는 방식이죠. 마법사 버튼 하나를 기대하고 오면 구현이랑 살짝 어긋나니까, 이 둘은 구분해두시는 게 좋습니다.
첫 목표는 무조건 내부 테스트(internal) 트랙으로 잡았어요. 최대 100명까지, 올리면 수 분 내로 반영돼서 가장 빠르거든요. 게다가 Play 서명이랑 코드 축소까지 거쳐서 실배포에 가깝고, 인앱결제·구독·광고까지 테스트할 수 있어서 반복 개발 루프에는 이만한 진입점이 없더군요.
internal·closed·open, 신규 앱과 기존 앱은 올릴 수 있는 트랙이 다르다
테스트 트랙은 크게 세 가지입니다.
- Internal: 최대 100명, 수 분 내 반영으로 가장 빠릅니다. 반복 확인용으로 최적이에요.
- Closed: 지정한 테스터만 참여합니다. 프로덕션으로 올리기 전 테스터 규모·기간 요건이 걸릴 수 있어요.
- Open: 스토어에서 누구나 참여합니다.
Closed 랑 Open 은 올리면 사전 출시 보고서(pre-launch report)로 기기·버전 이슈를 자동으로 잡아준다고 해요.
여기서 놓치기 쉬운 게 있어요. 신규 앱 첫 릴리즈는 스토어 등재 정보나 콘텐츠 등급 같은 초기 절차가 남아 있어서 바로 못 여는 트랙이 있습니다. 반면 이미 올려둔 기존 앱이면 internal 트랙은 업로드하자마자 열리는 경우가 많아요. 그래서 하루에 여러 번 확인하는 개발 루프라면 alpha·beta 보다 internal 이 훨씬 빠른 자리라고 봅니다.

서비스 계정 AndroidPublisher API 설정에서 401/403으로 크게 막혔다
솔직히 여기서 한 번 크게 헤맸어요. 제일 흔한 함정이기도 하고요.
플레이 콘솔에서 서비스 계정 권한을 승인하는 것 과, GCP에서 AndroidPublisher API를 활성화하는 것 은 완전히 별개 절차입니다. 이걸 같은 거라고 착각하면 둘 중 하나가 빠진 채로 계속 401이나 403을 맞게 돼요. 저는 API 활성화를 안 한 상태에서 권한만 주고 왜 안 되나 한참 봤어요.
두 개 다 맞춰놓고 나면 GPP 최소 설정은 생각보다 짧습니다.
play {
serviceAccountCredentials.set(file("android_publisher.json"))
track.set("internal")
defaultToAppBundles.set(true)
// artifactDir.set(file("path/to/app-bundle-dir")) // 기존 aab 재사용
}
그리고 ./gradlew publishBundle 을 Gradle 패널에서 더블클릭하면 internal 트랙까지 바로 올라갑니다. 이미 뽑아둔 AAB를 재활용하고 싶으면 주석 처리한 artifactDir 를 열어주면 되고요.
한 가지 꼭 주의하실 게 있어요. 저 JSON 자격증명 파일은 배포 권한을 그대로 들고 있습니다. 그러니 리포지토리에 커밋하면 절대 안 되고, 시크릿 매니저나 .gitignore 로 격리해두셔야 합니다. 유출되면 손 배포보다 훨씬 큰 사고가 날 수 있어요.
참고로 저는 로컬에서는 홈 디렉터리 바깥의 별도 폴더에 두고 경로로만 참조하고 있습니다.

Play Console 수동 업로드 자동화가 필요한 순간, 손 배포와 갈라 쓰는 기준
여기서 오해 하나 정리하고 갈게요. GPP는 공식 도구가 아닙니다. 서드파티인데 사실상 표준처럼 쓰이는 것뿐이에요. 그리고 CI 서버가 꼭 있어야 되는 것도 아닙니다. 로컬 Gradle 만으로 internal 직결까지 오늘 당장 됩니다.
팀이 커지거나 배포 빈도가 높아지면 그때 r0adkll/upload-google-play(GitHub Actions)나 젠킨스(Jenkins)의 google-play-android-publisher 를 얹는 거죠. 크로스플랫폼이 필요하면 패스트레인(fastlane)의 upload_to_play_store 도 대안입니다.
그럼 언제 자동화하고 언제 손으로 두느냐. 제 기준은 이래요.
- 1인·저빈도 프로젝트라면 서비스 계정·GCP API·JSON 보안 세팅하는 초기 비용이 오히려 커서, 수동이 더 단순할 때가 많습니다.
- 하루에 여러 번 쏘는 팀이라면 태스크 한 번 실행이 압도적으로 낫습니다.
그리고 하나 더. production 직결은 개인적으로 권하지 않아요. internal 이나 closed 까지만 자동화하고, 프로덕션은 수동으로 승격하는 게 안전하다고 봅니다. closed 도 테스터·기간 요건 때문에 자동화한다고 즉시 승격되는 게 아니니까요.
결국 이 왕복 6단계를 태스크 한 번으로 접고 나니, 플레이 콘솔 창을 마지막으로 언제 열었는지 흐릿해지더라고요. 손 배포를 완전히 버리라는 얘기는 아닙니다. internal 트랙 직결은 CI 없이도 오늘 세팅할 수 있으니, 일단 여기까지만 자동화해두고 프로젝트 빈도에 맞춰 손 배포와 갈라 쓰는 선을 잡아두는 겁니다.
이번 글에선 Play 트랙에 직결시키는 데까지만 다뤘는데, 서버 없이 로컬에서 bundletool 로 split APK를 직접 뽑아 폰에 바로 꽂는 방법은 다음 글에서 더 자세히 풀어볼게요.

'Android 개발 > Gradle・빌드' 카테고리의 다른 글
| Kotlin Java 26 지원, JDK만 올리면 Gradle 9.4에서 빌드가 멈춥니다 (0) | 2026.09.24 |
|---|---|
| KAPT 빌드가 4분씩 잡아먹길래, KSP2로 갈아탄 이야기 (0) | 2026.09.18 |
| AGP 9.3 조용히 나왔습니다 — 6년차가 실무에서 체감한 변화만 (0) | 2026.09.13 |
| 초록불 뒤에 숨은 JAR: Gradle 의존성 검증 실전 삽질기 (0) | 2026.09.12 |
| 빌드가 5분으로 늘어났는데 범인을 모를 때, Build Analyzer로 태스크를 잡았습니다 (0) | 2026.09.05 |