지금까지 나는 앱을 직접 버전을 올리고 -> 빌드하고 -> 파일을 첨부하여 스토어에 올리는 방식으로 작업을 진행했다.
이 과정 역시 사람이 직접 하는 것이기에,, 실수가 있지 않을까 걱정도 많이 되었고 여간 귀찮은 일이 아니었다...!!
그러던 중 Fastlane을 이용해 CI/CD 구축이 되어 있는 프로젝트에 참여하게 되었고 이걸 접한 후에 나는 신세계를 경험했다 🥹
1. Fastlane이란?
- Ruby 기반의 Android 및 iOS의 배포를 자동으로 도와주는 오픈소스 프로젝트
- 앱의 빌드, 배포, 플러그인 연결(ex. 슬랙 메시지 전송) 등이 가능
- 올리브영에서도 Android의 CI/CD를 Firebase App Distribution + Fastlane 조합으로 사용
Firebase App Distribution 공식 문서에서는 gradle, fastlane 등으로 배포하는 방식을 안내한다.
처음에는 Gradle 방식으로 시도해 보았는데, build.gradle에 코드를 추가해 주어야 한다는 점이 마음에 들지 않았다.
또한, 테스트 앱 배포만을 위한 것이 아니라 Play Store에도 올릴 수 있기를 원했기에 fastlane으로 작성하게 되었다!
2. Fastlane 설치 (Mac)
나는 해당 블로그를 참고하여 Ruby, Bundler를 설치했다.
(homebrew를 이용하는 방법 등 다양한 방법이 존재하지만, 가장 권장하는 방법은 Bundler를 이용하여 설치하는 것. 따라서 Ruby와 Bundler로 설치할 예정)
(1) Ruby 설치
$ brew upgrade
$ brew install rbenv ruby-build
$ rbenv versions
$ rbenv install -l
$ rbenv install 3.1.2
$ rbenv global 3.1.2
(2) Bundler 설치
$ gem install bundler
이렇게 설치 이후 ./gemfile을 생성하고 fastlane을 업데이트 해주면 설치는 끝난다.
(나는 기존 작업자가 해당 설정과 fastlane init은 완료해 두었기에, 바로 test lane을 실행해 보았다)
$ bundle exec fastlane test
3. Fastfile, Appfile
- Appfile 패키지명과 json secret file의 경로를 입력하는 파일
- Fastfile fastlane에 대한 설정을 정의하는 파일
AppFile에는 패키지명과 PlayConsole에 접근 가능한 google service key json파일의 경로를 입력하고,
Fastfile에서 각 lane별 액션을 정의하면 된다.
google-key.json은 해당 글의 'Collect your Google credentials' 영역을 참고하여 '서비스 계정 사용자' 권한으로 키를 생성하면 된다.
경로에 넣은 키는 아래 명령어를 통해 확인한다.
$ fastlane run validate_play_store_json_key
4. dotenv 설치
dotenv를 이용해 keystore의 정보를 inject 해주어야 했기에, gem으로 dotenv를 설치했다.
$ gem install dotenv
설치 후에 fastlane 디렉토리에 .env 파일을 추가하고 아래 형식으로 정의해 두면 fastfile에서 사용 가능하다.
# 서명 키 경로
export LANG=en_US.UTF-8
SIGNED_STORE_FILE='~~~/android_key'
## 사용
ENV['FIREBASE_CREDENTIALS_FILE']
4. Fastfile 기본 구조
기본 구조는 아래와 같다.
default_platform(:android)
platform :android do
# test - 프로젝트에 대한 모든 테스트 실행
desc "Runs all the tests"
lane :test do
gradle(task: "test")
end
5. apk, aab 파일 빌드
gradle 명령어를 이용해 파일을 빌드한다. (아래 예시는 debug로 apk파일을 빌드한다)
# 1. apk 파일 빌드 (assemble: apk, bundle: aab)
gradle(task: "clean assembleDebug")
6. Firebase App Distribution에 배포
(1) 프로젝트에 Firebase 플러그인 추가 https://firebase.google.com/docs/android/setup?hl=ko
(2) Fastlane용 플러그인 설치
$ bundle exec fastlane add_plugin firebase_app_distribution
(3) Firebase 업로드용 Google Service 키 생성 ('Firebase 앱 배포 관리자' 권한)
#2. firebase_app_distribution으로 배포
release = firebase_app_distribution(
app: "앱ID",
service_credentials_file: ENV['FIREBASE_CREDENTIALS_FILE'],
groups: "tester",
release_notes: version_name + "(" + version_code + ")" + " DEV"
)
7. Play Store 테스트 트랙에 배포
PlayStore에는 Appfile에 정의된 google-key.json이 validate 하다면, 문제 없이 올라갈 것이다.
공식 문서를 참고해 원하는 대로 옵션을 설정하면 된다!
- release_status: 'draft'는 파일을 업로드까지만 해주고, 심사 요청은 콘솔에서 직접 눌러야 한다
(프로덕션 배포를 한번도 하지 않은 앱이면 draft 상태로만 업로드 가능하다고 하며, 나도 한번 더 콘솔에서 확인해야 안전할 것 같다는 생각이 들어 해당 옵션을 설정했다) - track: 'internal'은 배포를 원하는 트랙 이름을 설정하면 된다. 'production, beta(공개 테스트), alpha(비공개 테스트), internal(내부 테스트)' 트랙에 올라가며, 내가 새로 만든 트랙에 업로드하려면 해당 트랙 이름을 그대로 넣으면 된다.
#2. Play Store에 배포
supply(
skip_upload_images: true,
skip_upload_screenshots: true,
skip_upload_metadata: true,
skip_upload_apk: true,
release_status: 'draft',
track:'internal',
package_name: 'com.example.app',
aab_paths:''
)
8. Slack 웹훅으로 메시지 전송
slack 설정도 아주 간단하다... ㅋㅋ Slack Webhook url을 생성해서 넣어주기만 하면 끝!
웹훅 url 설정은 해당 글을 참고하면 금방 만든다.
#3. Slack에 메시지 전송
slack(
slack_url: ENV['SLACK_URL'],
message: "[환경] AOS #{versionName} version - #{track} 배포"
)
이렇게 해서 나는 크게 두 개의 lane을 구성했다.
lane | 앱 | 배포 위치 |
distribute | debug apk | Firebase App Distribution |
deploy | release aab | Play Store Production |
'distribute' lane 코드 전문 예시
### Debug -> Firebase App Distribution
desc "Deploy Debug Build to Firebase App Distribution"
lane :distribute do
gradle(task: "clean assembleDebug")
path = '../app/build.gradle'
version_name_re = /versionName\s+"(\d+\.\d+\.\d+)"/
version_code_re = /versionCode\s+(\d+)/
s = File.read(path, encoding: 'UTF-8')
version_name = s[version_name_re, 1]
version_code = s[version_code_re, 1]
release = firebase_app_distribution(
app: "앱ID',
service_credentials_file: ENV['FIREBASE_CREDENTIALS_FILE'],
groups: "tester",
release_notes: version_name + "(" + version_code + ")" + " DEV"
)
end
프론트 CI/CD 구축만 해봤지, 안드로이드 CI/CD 구축은 처음이라 너무 재미있었다!
나중에는 Github Actions와 연동해 branch에 Pull Request merge 시, 배포가 진행되도록 하는 식으로 구현해서 CI까지 완벽하게 해보고 싶다!
프론트 CI/CD 구축 내용도 나중에 빨리 정리해 보아야 겠다 🙄
'💻 Android' 카테고리의 다른 글
[Android] Android CI/CD 구축하기 (2) - BuildType으로 개발/운영 환경 분리 (0) | 2024.05.25 |
---|---|
[Android] Android CI/CD 구축하기 (1) - Firebase App Distribution, Play store 테스트 트랙 (0) | 2024.05.25 |
[Android] Android 13 마이그레이션 (0) | 2024.03.09 |
[Android/IOS] 인앱 리뷰 기능 추가하기 (2) | 2023.09.23 |
[Android] 인스타그램 DM으로 공유하기 기능 만들기 (0) | 2023.09.23 |