Github Action으로 Android 앱 github Release에 배포하기

개요

사이드 프로젝트 compose-cocktail-recipes 앱을 제작하던 중, github actions를 통해 CI 뿐만 아니라 CD까지 자동화로 진행 가능 하도록 구성하기로 했습니다. 따라서 이 글에서는 github actions에서 서명된 APK를 빌드하고 릴리즈하는 과정을 소개합니다.

CI/CD 구성하기

제가 CI/CD를 구성하는데에 필요했던 기능은 다음과 같습니다.

  • main branch의 push 이벤트, pull-request 이벤트 발생 시 debug 빌드
  • main branch에서 태그 생성 시 서명된 APK를 생성
  • 앱의 versionCode, versionName도 자동화하여 생성
  • 자동으로 github releases에 서명된 APK를 업로드

main branch의 push 이벤트, pull-request 이벤트 발생 시 debug 빌드

해당 작업은 github actions에서 제공하는 기본 Android CI 템플릿을 적용하여 쉽게 작업할 수 있었다.

아래처럼 github actions가 구성되지 않은 상태에서 Actions 탭을 선택하면 workflow를 검색할 수 있는데, 여기 android라고 검색하면 제일 먼저나오는 ”Android CI”를 configure 하면된다.

Untitled

선택했다면 아래와 같이 기본적인 빌드를 수행하는 workflow 템플릿이 나오는데, 나는 여기서 태그 생성 이벤트 감지와 릴리즈 빌드를 수행하는 job을 추가로 구성했다.

github releases에 서명된 APK를 업로드

많은 사람들이 이미 시도했던 내용이었으며, 생성한 keystore 정보를 github secret으로 생성하여 저장하고, keystore 파일 자체는 base64 인코딩한 정보를 저장한 후 github actions 수행 중 다시 파일로 변환하는 방법이 있었다.

자세한 내용은 수빈박님의 블로그를 참고했다.

앱의 versionCode, versionName도 자동화하여 생성

chkfung 개발자님의 [android-version-actions@v1.2.1](https://github.com/chkfung/android-version-actions) 라는 커스텀 액션을 발견하여 그대로 적용했고, 남은 자동으로 github releases에 서명된 APK를 업로드 기능을 커스텀 액션으로 개발하여 MarketPlace에 배포하기로 결정했다.

완성된 workflow 파일은 아래와 같다.

name: Android CI

on:
  push:
    branches:
      - main
    tags:
      - 'v*.*.*'
  pull_request:
    branches:
      - main

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: 'temurin'
          cache: gradle

      - name: Grant execute permission for gradlew // gradlew 사용권한 주기
        run: chmod +x gradlew

      - name: Set output // tag 이름을 버전정보 변수에 저장
        id: vars
        run: echo "tag=${GITHUB_REF#refs/*/}" >> $GITHUB_OUTPUT
      - name: Check output
        env:
          RELEASE_VERSION: ${{ steps.vars.outputs.tag }}
        run: |
          echo $RELEASE_VERSION
          echo ${{ steps.vars.outputs.tag }}

      - name: Bump version // 앱의 versionCode, versionName 설정
        uses: chkfung/android-version-actions@v1.2.1
        with:
          gradlePath: app/build.gradle # or app/build.gradle.kts
          versionCode: ${{github.run_number}}
          versionName: ${{env.RELEASE_VERSION}}

      - name: Build Debug APK // debug 빌드
        run: ./gradlew assembleDebug

      - name: Upload artifact Debug APK // github action artifact에 apk 업로드
        uses: actions/upload-artifact@v3
        with:
          name: apk
          path: app/build/outputs/apk/debug/*.apk

  release:
    permissions: // github releases 쓰기 권한 얻기
      contents: write
    needs: build
    if: startsWith(github.ref, 'refs/tags/v') // 태그 생성 되었다면
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3 # Necessary to access local action
      - name: github-action-release-apk // release 빌드 및 github Releases 배포
        uses: gogoadl/github-action-release-apk@v1.0.0-alpha09
        with:
          asset-name: 'Cocktails.apk'
          github-token: ${{ secrets.GITHUB_TOKEN }}
          base64-keystore: ${{ secrets.APP_KEYSTORE_BASE64 }}
          key-file: ${{ secrets.APP_KEY_FILE }}
          keystore-password: ${{ secrets.APP_KEYSTORE_PASSWORD }}
          keystore-alias: ${{ secrets.APP_KEYSTORE_ALIAS }}
          key-password: ${{ secrets.APP_KEY_PASSWORD }}

위 작업을 통해 위에서 내가 언급했던 작업들을 자동화 할 수 있었다.

해당 커스텀액션의 내부구현이 궁금하다면 github-action-release-apk 레포지토리에서 확인할 수 있다!

+ Recent posts