
CD는 코드가 검증된 후 자동으로 테스트 환경이나 프로덕션에 배포되어 빠른 피드백과 짧은 릴리스 주기를 보장하는 방식입니다.
-> 키워진 닭을 죽이고 생닭얻어서 화로에 일일이 넣고 익은후에 빼서 냠냠쩝쩝하는거보다 용암으로 자동화해서 상자에 넣어지는거랑 똑같음
하나씩 파트별로 나눠져 있으니 알아서보셈
개지랄맞은 정책들
2025년 8월 31일부터 적용되는 요구사항

나머진 있는 추천으로

android {
compileSdk = 35 // ✅ Google Play 요구사항
defaultConfig {
targetSdk = 35 // ✅ Google Play 요구사항
minSdk = 24 // ✅ 적절한 호환성
}
}

<!-- src/main/AndroidManifest.xml -->
<activity
android:name=".MainActivity"
android:exported="true"> <!-- ✅ 이것만 확인 -->
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
그외는 필요시 설정할 것
알림 기능: PendingIntent 설정
블루투스 기능: 블루투스 권한 변경
백그라운드 작업: WorkManager 사용
위치 서비스: 위치 권한 설정
짧은 지식으로 정의한 기본적인 순서는 이러함

1. 개발중 테스트

2. 출시 직전 내부 테스트
Internal Track: 소수 테스터 대상 (최대 100명, 구글 계정 등록)
Closed Track: 내부 QA + 외부 베타 테스터 (좀 더 확장 가능)
Firebase로 테스트 끝난 앱을 Play Console Internal Track에 업로드 → 실제 Play 스토어를 통해 설치 가능

3. 출시 단계
Firebase Distribution을 통한 CICD는 방법이 많음
엄청많으니까 알아서 찾으셈 본인은 구글 플레이스토에 올려야해서
배포조건
1. 최초 수동 업로드: 앱 최초 등록 및 패키지명 설정 정책
2. Service Account JSON: API 인증을 위한 Google Cloud 보안 체계
3. Android Keystore: Android 앱 서명 보안 정책
4. Developer API 활성화: 프로그래밍 방식 앱 관리를 위한 권한 체계
라는걸 고려했을때 본인은 GitHub Actions + Fastlane을 사용할 예정
GithubAction 은 yml파일 형태로 자동 CICD를 생성 할 수 있음.
CI/CD 파이프라인의 전체적인 오케스트레이션을 담당할거임.
코드나 다른 변경사항 감지하면 업데이트 자동으로 해주는거라 생각하면편함

예를 들어 이런식으로 코드를 짜서 돌려주면

이런식으로 자동으로 gif의 사진들을 하루가 지날때마다 README.md 에서 바꿔줄 수 있음
궁금한건 여기 참고
등등.. 앱 자체에 특화된 자동화 도구라고 생각하면 좋을듯
우리는 구글 플레이스토어의 버젼관리에 맞게끔 설정할 생각임.
우리는 일단 QA 단계를 위한 CICD 배포만을 설정할것임.






2. 앱등록










알아서 보고 Gradle들 안에 Import후 Sync now


맥북기준이라 다른환경은 알아서 찾아보셈
$ ruby --version
ruby 2.7.2p137 (2020-10-01 revision 5445e04352) [x86_64-darwin19]
대충 2.5이상 넘으면 될듯 본인은 3.1 버젼임 만약아니다 ?
brew install rbenv
rbenv install 2.7.2
rbenv global 2.7.2
이렇게 설치


만약 없으면
gem install bundler
bundler --version
앱 프로젝트 디렉토리로 이동
# 프로젝트 루트 디렉토리로 이동 (예시)
cd /path/to/your/android/project
프로젝트 루트에서 Gemfile을 생성
cat > Gemfile << 'EOF'
source "https://rubygems.org"
gem "fastlane"
EOF
의존성을 설치
bundle update
설치확인
ls -la | grep Gemfile

bundle exec fastlane init
전에 있던 com.ymd.listup을 넣어줄거임

GooglePlay 연결은 안시켰으니까 그냥 엔터

Google Play Console에 앱이 이미 업로드되어 있다면: y
아직 앱을 업로드하지 않았다면: n

이렇게뜨면 기본세팅은 완료된거임

나머지내용들은 설정이나 가이드라인 등등 읽어보면 앎

Fastfile과 Appfile이 생성되었는지 확인
ls -la fastlane/

기본 테스트
bundle exec fastlane test



bundle exec fastlane add_plugin firebase_app_distribution
Fastlane이 Gemfile을 수정해서 플러그인 기능을 활성화하려고 하는거
Y 누르기

Firebase App Distribution 플러그인이 잘깔렸다는 소리임

방법은 두가지가있음
Firebase CLI 인증:
개발자 개인 Google 계정으로 로그인
브라우저 팝업으로 인증
로컬 개발 환경에 적합
토큰이 만료되면 재로그인 필요
개발자가 직접 실행할 때 편리함
서비스 계정 인증:
Google Cloud에서 생성한 기계 계정
JSON 키 파일로 인증
CI/CD 파이프라인에 적합
만료 없이 지속적 사용 가능
사람이 개입하지 않는 자동화에 필수
본인은 자동화까지 해서 GithubAction까지 할 예정이니까, 서비스 인증 계정으로 진행할거임

Google Cloud Console -> 전체 프로젝트
가면 저렇게 Firebase로 만들어진 프로젝트가 있을거임
Firebase 프로젝트 = Google Cloud 프로젝트 (동일한 것)
Firebase는 Google Cloud의 서비스 중 하나라서 자동으로 저렇게 생기는듯

IAM 및 관리자 -> IAM
보면 저렇게 역할 다 부여된거 확인


서비스 계정 -> 등록된 이메일 클릭


아 그리고 편집자권한 주고가야함 안그럼 Firebase 권한없다고뜸

키로 넘어가서 새 키 만들기



키를 프로젝트 파일안에 잘 넣어두셈 일단
추후에 깃에 올릴떈, Base64로 인코딩해야함

Firebase Console → 프로젝트 설정 → 일반 탭에서 Android 앱 ID 복사

본인 프로젝트 파일의 fastlane 폴더 -> Fastfile
을 가보면 이렇게 되어있을거임
# This file contains the fastlane.tools configuration
# You can find the documentation at https://docs.fastlane.tools
#
# For a list of all available actions, check out
#
# https://docs.fastlane.tools/actions
#
# For a list of all available plugins, check out
#
# https://docs.fastlane.tools/plugins/available-plugins
#
# Uncomment the line if you want fastlane to automatically update itself
# update_fastlane
default_platform(:android)
platform :android do
desc "Runs all the tests"
lane :test do
gradle(task: "test")
end
desc "Submit a new Beta Build to Crashlytics Beta"
lane :beta do
gradle(task: "clean assembleRelease")
crashlytics
# sh "your_script.sh"
# You can also use other beta testing services here
end
desc "Deploy a new version to the Google Play"
lane :deploy do
gradle(task: "clean assembleRelease")
upload_to_play_store
end
end
대충 알아서 추가
desc "Build and distribute to Firebase App Distribution"
lane :distribute do
gradle(task: "bundleRelease")
firebase_app_distribution(
app: "아까 복사한 앱 ID",
service_credentials_file: "갖다놓은 키 경로",
testers: "your.email@example.com", # 실제 테스터 이메일로 변경
release_notes: "New test build from Fastlane",
android_artifact_type: "AAB"
)
end
테스트용 이메일로 바꿔놓고 로컬에서 테스트해보자
프로젝트 폴더롤 가서
bundle exec fastlane distribute

엄
AAB로 빌드하려면 Google Play Account연결이 필수 인 것 같다.
APK로 빌드후, 추후에 수정하도록하자.
gradle(task: "bundleRelease") → gradle(task: "assembleRelease")
android_artifact_type: "AAB" → android_artifact_type: "APK"
로 수정


Firebase App Distribution에도 성공적이라는걸 알 수 있음
참고로 Fastlane과 Firebase App Distribution 둘다 테스터 이메일 등록되어 있어야 확실하게 사용자에게 이메일이 가고
만약 한번도 이메일까서 설치 안했다면 다음 업데이트때도 오진 않을거임
우선 Github에 키가 올라가니까 이거부터 인코딩을 해주자
cd /폴더위치
base64 -i 키파일.json | pbcopy
그럼 클립보드에 나타날거임 복붙해보셈
ewog.....
이제 이걸
GitHub → 본인의 리포지토리 → Settings → Secrets and variables → Actions
New repository secret 에 추가함녀됨

이제 Actions -> setup a new workflow yourself 클릭

여기다가 알아서 코드 작성하셈

그 후
# service_credentials_file: "로컬용",
service_credentials_file: "./firebase-service-account.json",
로컬말고 깃헙에서 설정할 수 있게 해줘여함
마지막으로 올리기전에 .gitignore 설정ㅈ은 필수임
# Firebase credentials
firebase-service-account.json
본인 키파일-*.json
# Android signing keys
*.keystore
*.jks
# Fastlane
fastlane/report.xml
fastlane/Preview.html
fastlane/screenshots
fastlane/test_output
추가해주자
참고로 저런 방식으로 .yml 파일 만들었으면 Push전에 한번 pull 받고 진행해야함

올리면 저렇게 자동으로 된걸 확인 가능함
QA를 위한 CD (Continuous Deployment)는 이정도면 충분
테스터 이메일 설정해놨으면

이렇게올꺼임

매번 합칠대마다 저런식으로 생길꺼임
버젼은 본인 플젝에 설정할 수 있는데,
app/build.gradle.kts 파일에서 설정 가능함

versionCode
- 정수 값 (1부터 2,100,000,000까지)
- 앱 업데이트 판단 기준
- 새 빌드마다 반드시 증가 (1 → 2 → 3...)
- 사용자에게 표시되지 않음
versionName
- 문자열 값 (예: "1.0.0", "1.0.1", "2.0.0")
- 사용자에게 표시되는 버전
- 형식 자유 (보통 major.minor.patch 형식 사용)
뭔 소리세요 하시면
// 첫 출시
kotlinversionCode = 1
versionName = "1.0.0"
// 버그 수정
kotlinversionCode = 2
versionName = "1.0.1"
// 기능 추가
kotlinversionCode = 3
versionName = "1.1.0"
// 대규모 업데이트
kotlinversionCode = 4
versionName = "2.0.0"
이런식으로 kotlinversionCode는 내부에서 시스템이 "어느 버전이 최신인지" 판단할 때 사용하는거고
외부로 보여지는 versionName인거임 예시를 하나 더 들자면
versionCode = 15
versionName = "2.3.1"
-> 사용자는 "2.3.1" 버전만 보고, 시스템은 내부적으로 15번째 빌드라는 거임
# gradle/libs.versions.toml
[versions]
...
versionCode = "2"
versionName = "1.0.1"
// app/build.gradle.kts
defaultConfig {
versionCode = libs.versions.versionCode.get().toInt()
versionName = libs.versions.versionName.get()
// ...
}
해보진 않았는데 저거 하나로
이 설정 하나로 Firebase App Distribution + Google Play Store 모두 적용된다곤함