Skip to content

Firebase App Distribution을 통한 CD 구축

p-chanmin edited this page Feb 20, 2024 · 1 revision

Firebase App Distribution를 사용하여 자동으로 CD를 구축해보도록 하자

meetmeet 프로젝트의 App을 Github Action을 통해 CD를 구축하기 위해서 Github Action을 사용한다.

Github Action을 통해 자동으로 빌드 및 배포를 하지만 그냥 진행하게 되면 빌드 과정에서 gitignore에 추가한 local.properties , google-service.json 파일이 없어서 빌드가 되지 않는 문제에 직면하고, keystore.jks의 정보를 통해 빌드가 필요한 경우에도 문제가 발생한다.

이러한 문제를 해결하면서 순서대로 CD를 구축해보자!

1. local.propertiesbuild.gradle.kts 설정

meetmeet 앱은 카카오 로그인 기능이 있기 때문에 kakao app key나 auth host 값을 local.properties에 저장해두고 있다.

추가로 keystore의 정보도 local.properties에 한번에 저장하여 build.gradle.kts에서 release를 빌드할 때 설정을 추가해보자. 이 때 keystore.jks 파일은 app/keystore.jks에 위치해야 한다.

# local.properties

sdk.dir=
KAKAO_NATIVE_APP_KEY=
KAKAO_AUTH_HOST=

SIGNED_KEY_ALIAS=
SIGNED_KEY_PASSWORD=
SIGNED_STORE_PASSWORD=
SIGNED_STORE_FILE=
// app: build.gradle.kts

...

defaultConfig {
	...
}

signingConfigs {
    create("releaseConfig") {
        keyAlias = getPropertyKey("SIGNED_KEY_ALIAS")
        keyPassword = getPropertyKey("SIGNED_KEY_PASSWORD")
        storePassword = getPropertyKey("SIGNED_STORE_PASSWORD")
        storeFile = file(getPropertyKey("SIGNED_STORE_FILE"))
    }
}

buildTypes {
    release {
        signingConfig = signingConfigs.getByName("releaseConfig")
        ...
    }
}

...

2. Secrets 설정

repository setting에서 Security 부분의 Secrets and variables 에 필요한 정보를 입력한다.

  • GOOGLE_SERVICES_JSON
  • LOCAL_PROPERTIES_CONTENTS
  • KEYSTORE_BASE64 - 인코딩 된 keystore
  • FIREBASE_APP_ID - 파이어베이스 앱 아이디
  • CREDENTIAL_FILE_CONTENT - 배포 관리자

다음의 총 5개의 정보를 등록한다

3. Service Credentials File Content

Firebase App Distribution를 통해 자동 배포를 위해서는 앱 배포 관리자와 그 계정의 키가 필요하다.

Firebase에서 프로젝트를 생성했다면, Google Cloud console에도 자동으로 프로젝트가 생성되어 있을 것이다.

Google Cloud console에서 해당 프로젝트에 접속하여 IAM 및 관리자서비스계정+서비스 계정 만들기 를 통해 앱 배포 관리자를 만든다.

image

다음으로 액세스 권한을 부여한다.

Firebase 제품Firebase 앱 배포 관리자 를 부여한다.

image

생성된 계정의 설정에서 키 관리에 들어간다.

image

키 추가새 키 만들기JSON만들기 를 통해 새로운 키를 만들고 다운로드 한다.

다운로드 된 JSON 파일을 secrets에 등록한다.

image

필요한 5개의 정보를 secrets에 저장해두었다.

4. yml 작성

.github/workflow/***.yml에 작성하여 Action에 해당하는 내용을 작성한다.

name: Build & upload to Firebase App Distribution

on:
  push:
    tags:
      - "v*.*.*"

태그 이름이 v*.*.* 형식과 일치할 때 푸시 이벤트에 대응하여 GitHub Actions 워크플로우를 트리거한다.

jobs:
  build:
    runs-on: ubuntu-latest

    defaults:
      run:
        working-directory: ./android

build 작업을 Ubuntu 최신 버전에서 실행하며, 기본 작업 디렉토리를 ./android로 설정한다.

현재 meetmeet 프로젝트는 android와 backend가 분리되어 있기 때문에 기본 작업 디렉토리를 구분하였다.

env:
      LOCAL_PROPERTIES_CONTENTS: ${{ secrets.LOCAL_PROPERTIES_CONTENTS }}
      GOOGLE_SERVICES_JSON: ${{ secrets.GOOGLE_SERVICES_JSON }}

환경 변수 LOCAL_PROPERTIES_CONTENTSGOOGLE_SERVICES_JSON을 GitHub Secrets에서 가져와 설정한다.

steps:
      - name: Checkout
        uses: actions/checkout@v4

소스 코드를 체크아웃하는 단계로, actions/checkout@v4 액션을 사용한다.

- name: set up JDK 17
        uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: 17

JDK 17을 설치하는 단계로, actions/setup-java@v4 액션을 사용하며, 배포판으로 'temurin'을 선택한다.

- name: Grant Permission for gradlew
        run: chmod +x ./gradlew

gradlew 스크립트에 실행 권한을 부여한다.

- name: Decode And Save Keystore Base64
        run: |
          echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 --decode > app/meetmeetkey.jks

      - name: Create google-services.json
        run: echo "$GOOGLE_SERVICES_JSON" > app/google-services.json

      - name: Create local.properties
        run: |
          echo "$LOCAL_PROPERTIES_CONTENTS" > local.properties

Base64로 인코딩된 Keystore를 디코드하여 meetmeetkey.jks로 저장하고, google-services.jsonlocal.properties 파일을 생성한다.

- name: Build Release APK
        run: ./gradlew :app:assembleRelease

릴리스 APK를 빌드한다.

- name: Upload Release Build to Artifacts
        uses: actions/upload-artifact@v3
        with:
          name: release-artifacts
          path: android/app/build/outputs/apk/release/
          if-no-files-found: error

릴리스 빌드를 GitHub 아티팩트로 업로드한다.

image

github action에서 Artifacts를 확인할 수 있다.

- name: Create Github Release
        uses: softprops/action-gh-release@v1
        with:
          generate_release_notes: true
          files: |
            android/app/build/outputs/apk/release/app-release.apk

GitHub 릴리스를 생성하고, android/app/build/outputs/apk/release/app-release.apk 위치에 있는 APK 파일을 릴리스에 첨부한다.

자동으로 릴리스 노트도 생성하도록 한다.

- name: Upload to Firebase App Distribution
        uses: wzieba/Firebase-Distribution-Github-Action@v1
        with:
          appId: ${{secrets.FIREBASE_APP_ID}}
          serviceCredentialsFileContent: ${{ secrets.CREDENTIAL_FILE_CONTENT }}
          groups: 팀-밋밋
          file: android/app/build/outputs/apk/release/app-release.apk

Firebase App Distribution에 APK 파일을 업로드한다.

테스터 그룹으로는 미리 지정해 놓은 그룹의 이름을 명시하여 추가한다.

5. CD 구축 완료

image

image

image

v0.2.2 태그를 통해서 Action을 실행하고 Firebase App Distribution에 versionName(versionCode) 이름으로 APK파일을 배포할 수 있었다!

⚽️협업 룰

코딩 컨벤션

📔회고

팀 회고

개인 회고

K004 김근범

K016 박찬민

K032 이해림

J153 차세찬

J156 최다정

👨‍🏫멘토링 회의록

💻개발일지

Android

K004 김근범

K016 박찬민

K032 이해림

J153 차세찬

J156 최다정

💡트러블슈팅

Android

K004 김근범

K016 박찬민

K032 이해림

J153 차세찬

J156 최다정

📋회의록

스크럼 회의

스프린트 회의

밋밋 회의

공통

BackEnd

Android

기획

Clone this wiki locally