AI/잡다한개발노트

KikiLeoBook 릴리즈 준비 — 패키지 리네임부터 GitHub Release까지

blacknabis 2026. 3. 29. 22:25
반응형

KikiLeoBook 릴리즈 준비 — 패키지 리네임부터 GitHub Release까지

이 글은 Claude Code를 사용하여 작업하고 작성하였습니다.


개요

아내에게 전달할 안드로이드 전자책 앱 KikiLeoBook의 첫 번째 릴리즈(v1.0.0)를 준비했다. 오늘 작업의 핵심은 앱 정체성 확립(패키지명/앱명 변경), 릴리즈 서명 설정, Firebase 연동, 그리고 GitHub Release를 통한 버전 관리 체계 구축이었다.


1. 패키지명 및 앱 이름 변경

기존 개발 단계에서 임시로 사용하던 이름을 정식 명칭으로 교체했다.

항목 변경 전 변경 후
패키지명 com.**** com.blacknabis.kikileobook
앱 이름 ****Book KikiLeoBook
DB 이름 ****book.db kikileobook.db
SharedPrefs 키 ****book_prefs kikileobook_prefs

소스 디렉터리 전체를 sed로 일괄 치환하고, 패키지 경로 디렉터리 구조도 함께 이동했다. 변경된 파일만 수십 개였지만 Claude Code가 일괄 처리해줘서 수작업 없이 깔끔하게 끝났다.


2. 시맨틱 버전 관리

// app/build.gradle.kts
versionCode = 1
versionName = "1.0.0"

이후 릴리즈마다 versionCode는 1씩 증가, versionName은 시맨틱 버전(major.minor.patch)으로 관리하기로 했다.


3. 설정 화면 추가

라이브러리 화면 툴바에 설정 아이콘을 추가하고, 설정 화면 최하단에 앱 버전을 표시하도록 구현했다.

// SettingsActivity.kt
val versionName = packageManager.getPackageInfo(packageName, 0).versionName
binding.tvVersion.text = versionName

4. 릴리즈 키스토어 생성 및 서명 설정

Play Store를 거치지 않는 APK 직접 배포이므로, 릴리즈 서명용 키스토어를 직접 생성해 관리한다.

keytool -genkeypair -v \
  -keystore signin/kikileobook-release.jks \
  -alias kikileobook \
  -keyalg RSA -keysize 2048 \
  -validity 10000

키스토어와 비밀번호는 signin/ 디렉터리에서 관리하며, private 레포이므로 git에도 함께 포함했다.

Gradle 서명 설정

keystore.properties를 Java Properties가 아닌 커스텀 파서로 읽도록 처리했다. 비밀번호에 특수문자(#)가 포함될 경우 Properties 파싱 오류가 발생하기 때문이다.

// build.gradle.kts
val keystoreProperties = mutableMapOf<String, String>().apply {
    keystorePropertiesFile.readLines().forEach { line ->
        val trimmed = line.trim()
        if (trimmed.isNotEmpty() && !trimmed.startsWith("#") && trimmed.contains("=")) {
            val idx = trimmed.indexOf("=")
            put(trimmed.substring(0, idx).trim(), trimmed.substring(idx + 1))
        }
    }
}

5. Firebase 연동 업데이트

패키지명이 바뀌었으므로 Firebase Console에 새 앱(com.blacknabis.kikileobook)을 등록하고, 디버그/릴리즈 SHA-1 지문을 모두 등록했다.

구분 SHA-1
디버그 2a:10:f3:d9:...
릴리즈 5d:9f:8a:13:...

포인트: SHA-1 등록 후에는 반드시 google-services.json을 재다운로드해서 app/ 디렉터리에 교체해야 한다. 그렇지 않으면 빌드에 이전 OAuth 설정이 그대로 반영된다.

Claude Code의 Chrome 제어 기능(MCP)을 활용해 Firebase Console 브라우저 자동화로 SHA-1 등록, google-services.json 다운로드까지 자동으로 처리했다.


6. Google OAuth 동의 화면 확인

Google Cloud Console에서 OAuth 동의 화면 상태를 확인했다. 프로덕션 단계로 설정되어 있어 별도 테스터 등록 없이 모든 Google 계정으로 로그인 가능하다.

  • 테스트 모드: 등록된 테스트 사용자만 로그인 가능
  • 프로덕션 모드: 누구나 로그인 가능 ✅

7. 릴리즈 APK 빌드

./gradlew clean assembleRelease
# BUILD SUCCESSFUL in 1m 23s
# 49 actionable tasks: 49 executed

클린 빌드를 통해 캐시 없이 최신 google-services.json이 완전히 반영된 APK를 생성했다.

  • 출력 경로: app/build/outputs/apk/release/app-release.apk
  • 파일 크기: 8.7MB

8. GitHub Release 버전 관리

릴리즈 APK를 GitHub Releases로 관리하기로 했다. 매 릴리즈마다:

  1. versionCode / versionName 업데이트
  2. assembleRelease 빌드
  3. git tag vX.X.X && git push origin vX.X.X
  4. GitHub Release 생성 + APK 첨부

첫 번째 릴리즈:

    • 태그: v1.0.

 

APK 배포는 Play Store를 사용하지 않으므로, GitHub Release에서 직접 다운로드하거나 카카오톡/구글 드라이브로 전달한다.


트러블슈팅

키스토어 비밀번호 특수문자 문제

처음에 Dhdudghks1!@# 비밀번호로 키스토어를 생성했는데, Gradle 빌드 시 "keystore password was incorrect" 오류가 계속 발생했다. \# 이스케이프, Java Properties 파서 교체 등 여러 방법을 시도했지만 실패. 결국 bash의 ! 히스토리 확장 이슈로 키스토어 생성 자체가 잘못된 것으로 판단, 단순 비밀번호로 키스토어를 새로 생성해 해결했다.

에뮬레이터에서 Google 로그인 실패

앱플레이어(에뮬레이터) 환경에서 Google 로그인 시 SIGN_IN_CANCELLED(12501) 오류 발생. SHA-1이나 설정 문제가 아닌 에뮬레이터 환경 자체의 Google Play Services 비표준 동작이 원인. 실제 안드로이드 기기에서는 정상 작동한다.


마치며

패키지명 변경부터 Firebase 재등록, 릴리즈 서명, GitHub Release까지 꽤 많은 작업이었지만 Claude Code 덕분에 브라우저 자동화, 코드 일괄 수정, 빌드 명령 실행을 한 세션에서 끊김 없이 처리할 수 있었다. 특히 Firebase Console SHA-1 등록을 MCP Chrome 도구로 자동화한 부분이 인상적이었다.

앞으로 기능 추가할 때마다 버전을 올리고 GitHub Release로 관리할 예정이다.

반응형