Firebase App Distribution with Github Actions using buildVariants

이태훈·2022년 5월 24일
1

안녕하세요. 오늘은 Github Actions를 통해 Firebase App Distribution에 앱을 업로드하는 것을 해보겠습니다.

Firebase 설정이 다 돼있다는 것을 가정으로 하겠습니다.

Build Variants 설정

Generate Version

먼저, 테스트 앱을 구분하기 위해 buildVariants를 설정하겠습니다.

version.properties

appVersion=0.90.092
testVersion=1

auto-version.gradle
ext {
	versionFile = new File(project.rootDir, 'version.properties')
	buildVersionName = {
		def version = readVersion()
		return version['appVersion'] as String
	}
	buildVersionCode = {
		def version = readVersion()['appVersion'] as String
		def code = version.substring(version.indexOf('.') + 1).replace('.', '')
		return code as int
	}
	getTestVersion = {
		def version = readVersion()
		return version['testVersion']
	}
}

Properties readVersion() {
	def version = new Properties()
	def stream
	try {
		stream = new FileInputStream(versionFile)
		version.load(stream)
	} catch (FileNotFoundException ignore) {
	} finally {
		if (stream != null) stream.close()
	}

	return version
}

자동으로 versionCode, versionName을 설정해주는 함수를 만들어줍니다.

Build Gradle 적용

다음으로 app/build.gradle에 적용해줍니다.

app/build.gradle

apply from: '../auto-version.gradle'

android {
	
    ...
    
    defaultConfig {
    	...
        versionCode = buildVersionCode()
        versionName = buildVersionName()
        ...
    }
    
    buildTypes {
    	debug {
        	versionNameSuffix "-SNAPSHOT"
            applicationIdSuffix '.debug'
            resValue "string", "app_name", "APP NAME DEBUG"
        }
        release {
        	...
        }
        internal {
        	versionNameSuffx "-BETA${getTestVersion()}"
            applicationIdSuffix '.internal'
            resValue "string", "app_name", "APP NAME INTERNAL"
        }
    }
}

UI/UX나 다른 개발 진행상황을 공유하기 위한 debug 버전과 내부 테스트를 위한 internal 버전을 만들어줍니다.

테스트하기 편하게 applicationIdSuffix를 통해 패키지네임을 다르게 해줍니다.

이러면 buildVariants 설정은 끝입니다.

Github Actions

Github Actions를 설정해줍니다.

Build Apk

먼저, Firebase App Distribution에 업로드할 apk 파일을 빌드 및 캐싱을 합니다.

- name: set up JDK 11
  uses: actions/setup-java@v3
    with:
      distribution: corretto
      java-version: 11
      cache: gradle
- name: build internal
  run: ./gradlew assembleInternal

각 buildVariants에 맞는 명령어를 적어주시면 됩니다.

예) release 빌드시, ./gradlew assembleRelease ...

Signing Apk

다음으로 빌드해서 나온 결과물을 signing 해줍니다.

먼저 signing하기 위해 keystore를 인코딩해줍니다.

openssl base64 < keystore | tr -d '\n' | tee keystore_base64_encoded.txt

인코딩 해서 나온 텍스트와 Keystore Alias, Password, Key Password를 Github Actions Secret에 저장해줍니다.

- name: Sign APK
        id: sign_apk
        uses: r0adkll/sign-android-release@v1
        with:
          releaseDirectory: app/build/outputs/apk/internal
          signingKeyBase64: ${{ secrets.KEYSTORE }}
          alias: ${{ secrets.SIGNING_KEY_ALIAS }}
          keyStorePassword: ${{ secrets.SIGNING_STORE_PASSWORD }}
          keyPassword: ${{ secrets.SIGNING_KEY_PASSWORD }}

releaseDirectory에는 빌드해서 나오는 결과물의 디렉토리를 적어주면 됩니다.

예) release 빌드시 app/build/outputs/apk/release

Upload Artifact to Firebase App Distribution

최종적으로 Firebase App Distribution에 업로드해줍니다.

- name: upload artifact to Firebase App Distribution
        uses: wzieba/Firebase-Distribution-Github-Action@v1
        with:
          appId: ${{secrets.FIREBASE_INTERNAL_APP_ID}}
          token: ${{secrets.FIREBASE_TOKEN}}
          groups: internal_testers
          file: app/build/outputs/apk/internal/app-internal-unsigned-signed.apk

file directory는 빌드해서 나오는 결과물의 경로와 파일 이름뒤에 -signed를 붙여주면 됩니다.


전체적인 플로우입니다.

on:
  push:
    branches:
      - debug
      - internal

jobs:
  internal_build:
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/internal'

    steps:
      - uses: actions/checkout@v3
      - name: set up JDK 11
        uses: actions/setup-java@v1
        with:
          java-version: 11
      - name: build internal
        run: ./gradlew assembleInternal
      - name: Sign APK
        id: sign_apk
        uses: r0adkll/sign-android-release@v1
        with:
          releaseDirectory: app/build/outputs/apk/internal
          signingKeyBase64: ${{ secrets.KEYSTORE }}
          alias: ${{ secrets.SIGNING_KEY_ALIAS }}
          keyStorePassword: ${{ secrets.SIGNING_STORE_PASSWORD }}
          keyPassword: ${{ secrets.SIGNING_KEY_PASSWORD }}
      - name: upload artifact to Firebase App Distribution
        uses: wzieba/Firebase-Distribution-Github-Action@v1
        with:
          appId: ${{secrets.FIREBASE_INTERNAL_APP_ID}}
          token: ${{secrets.FIREBASE_TOKEN}}
          groups: internal_testers
          file: app/build/outputs/apk/internal/app-internal-unsigned-signed.apk
        
  debug_build:
    runs-on: ubuntu-latest
    if: github.ref == 'refs/heads/debug'
    
    steps:
      - uses: actions/checkout@v3
      - name: set up JDK 11
        uses: actions/setup-java@v1
        with:
          java-version: 11
      - name: build debug
        run: ./gradlew assembleDebug
      - name: Sign APK
        id: sign_apk
        uses: r0adkll/sign-android-release@v1
        with:
          releaseDirectory: app/build/outputs/apk/debug
          signingKeyBase64: ${{ secrets.KEYSTORE }}
          alias: ${{ secrets.SIGNING_KEY_ALIAS }}
          keyStorePassword: ${{ secrets.SIGNING_STORE_PASSWORD }}
          keyPassword: ${{ secrets.SIGNING_KEY_PASSWORD }}
      - name: upload artifact to Firebase App Distribution
        uses: wzieba/Firebase-Distribution-Github-Action@v1
        with:
          appId: ${{secrets.FIREBASE_DEBUG_APP_ID}}
          token: ${{secrets.FIREBASE_TOKEN}}
          groups: debug_testers
          file: app/build/outputs/apk/debug/app-debug-unsigned-signed.apk

References

https://dev.to/supersuman/build-and-sign-android-apps-using-github-actions-54j

profile
https://www.linkedin.com/in/%ED%83%9C%ED%9B%88-%EC%9D%B4-7b9563237

0개의 댓글