Firebase Distribution

앱 버전이 올라갈 때 마다 직접 apk를 추출하고 파이어베이스에 접속해서 apk를 올려서 테스터 배포를 하는 작업이 개발과 별개이면수 번거럽다고 생각이 들었다.

따라서 PR을 날리면 자동으로 파이어베이스 테스터 배포까지 마치도록 CI/CD를 구성하도록 했다.(원래는 GitAction으로 Build 만 했음)


Git Action, Firebase, Google Could Platform 을 활용해 테스터 자동배포하는 과정이며

Firebase App Distribution Git Action 오픈소스를 사용했다.


1. Google Could Platform, Firebase 같은 계정으로 가입

2. GCP Service Account 생성

서비스 계정을 만들고 아래와 같이 Firebase App distribution manager 권한을 준다.

2 서비스계정생성


그렇게 아래와 같이 생성된 계정을 확인할 수 있다.

3  추가된 계정 확인


위 계정에 키를 만들어주고 저장한다.

4 서비스키 추가


3. Git Secret 에 Service Account Key 저장

Git Secret에 CREDENTIAL_FILE_CONTENT 라는 이름으로 GCP Service Account Key 를 저장했다.


4. AAB 배포를 원한다면…

아래와 같은 workflow step을 추가해서 .aab 파일을 만들어야한다.

KEYSTORE_FILE , KEYSTORE_PASSWORD , KEY_PASSWORD 3가지를 정보를 Git Secret 에 추가적으로 저장해야한다.

이때 KEYSTORE_FILE 경우에는 읽지 못하는 파일이기 때문에 base64 인코딩을 해준 파일을 업로드하면 된다. 친절히도 signingKeyBase64 라는 이름의 변수로 받는다.


아래는 각각 base64 인코딩하는 커맨드와 Git Action 에서 AAB를 만드는 workflow 코드이다.

openssl base64 -in [keystore 파일명] -out [인코딩될 파일 이름]
#      - name: Assemble release build
#        run: ./gradlew bundleRelease
#
#      - name: Signing App Bundle
#        uses: r0adkll/sign-android-release@v1
#        with:
#            releaseDirectory: app/build/outputs/bundle/release
#            signingKeyBase64: $
#            alias: $
#            keyStorePassword: $
#            keyPassword: $


테스트용으로 AAB 말고 APK를 채택한 이유

AAB로 테스트를 하려고 했는데 AAB는 앱 서명을 Google Play에서 직접 해주기 때문에 APK를 만드려면 Google Play Console 개발자 계정까지 등록을 해줘야한다.

AAB가 구글 플레이 콘솔에서 서명을 해주기 때문에 보안적인 측면에서 우수하고 console에서 기기 특성에 맞는 리소스만 apk에 합쳐주기 때문에 기기마다 각각 완성된 APK 파일의 크기가 더 적기 때문에 AAB를 통한 배포를 강제한다.

하지만 테스트에 경우 디자이너, 기획자분들까직 각각 추가적인 기기 설정을 해주는 번거러움이 있어서 APK파일을 통해 테스트하기로 결정.


5. 파이어베이스 테스터그룹 추가

파이어베이스 App Distribution 에 들어가서 테스터 그룹을 만들고 테스트 APK 메일을 보낼 팀원들의 계정을 추가해준다.

5. PR 라벨 적용

7 배포성공

자동 배포는 성공했으나 원하지 않는 PR에서도 계속 APK 배포메일이 가져서 아래 코드를 추가해 PR Label 을 통해 CD가 동작하도록 변경해주었다.

if: $

6. 완성된 CI/CD workflow

# 기존에 사용하던 단순 Build CI
name: Walkie Android CI
on:
  pull_request:
    branches: [ "main", "develop", "compose/develop" ]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: set up JDK 11
        uses: actions/setup-java@v3
        with:
          java-version: '11'
          distribution: 'zulu'
          cache: gradle

      - name: Grant execute permission for gradlew
        run: chmod +x gradlew

      - name: Create google-service
        run: echo '$' > ./presentation/google-services.json

      - name: Create Local Properties
        run: echo '$' > ./local.properties

      - name: Build with Gradle
        run: ./gradlew build

      - name: Build Debug APK
        run: bash ./gradlew assembleDebug --stacktrace

      - name: Assemble release build
        run: ./gradlew bundleRelease

      - name: Signing App Bundle
        uses: r0adkll/sign-android-release@v1
        with:
          releaseDirectory: app/build/outputs/bundle/release
          signingKeyBase64: $
          alias: $
          keyStorePassword: $
          keyPassword: $

      - name: 테스트용 AAB artifact 업로드
        uses: actions/upload-artifact@v3
        with:
          name: app-release.aab
          path: app/build/outputs/bundle/release/app-release.aab


# 새롭게 추가한 Firebase App Distribution CD
name: Walkie Firebase Distribution
on:
  pull_request:
    branches: [ "main", "develop", "compose/develop" ]
    types: [ labeled ]

jobs:
  build:
    if: $
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - name: set up JDK 11
        uses: actions/setup-java@v3
        with:
          java-version: '11'
          distribution: 'zulu'
          cache: gradle

      - name: Grant execute permission for gradlew
        run: chmod +x gradlew

      - name: Create google-service
        run: echo '$' > ./presentation/google-services.json

      - name: Create Local Properties
        run: echo '$' > ./local.properties

      - name: Build with Gradle
        run: ./gradlew build

      - name: Build Debug APK
        run: bash ./gradlew assembleDebug --stacktrace

      - name: Upload artifact to firebase app distribution
        uses: wzieba/Firebase-Distribution-Github-Action@v1
        with:
          appId: $
          serviceCredentialsFileContent: $
          groups: walkieDeveloper
          file: app/build/outputs/apk/debug/app-debug.apk


이상으로 Firebase App Distribution 를 사용한 CI/CD 구성 회고를 마치겠습니다.

감사합니다.