Notice
Recent Posts
Recent Comments
Link
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
Archives
관리 메뉴

Leo

[Android] github actions 배포 자동화 본문

개발 정리/CI·CD

[Android] github actions 배포 자동화

dohyxx 2025. 1. 13. 18:57

 

이번엔 Android 빌드와 App Distribution으로 업로드 되도록 설정한 fastlane을 Github Action에서 사용할 수 있도록 설정한 방법이다.

 

출처: https://blog.mathpresso.com

 

Workflow

1. 브랜치에 관계없이 tag 가 생성된 commit 이 push 되면 자동으로 workflow 실행

- iOS와 동일

# 정규식 패턴을 사용하여 dev/x.x.x 형식의 태그만 허용
on:
  push:
    tags:
      - 'dev/[0-9]+.[0-9]+.[0-9]+'
      - 'qa/[0-9]+.[0-9]+.[0-9]+'
      - 'live/[0-9]+.[0-9]+.[0-9]+'

build를 위한 tag commit

 

2. git 코드 체크아웃

github actions 가상환경에 프로젝트 repo를 설정

// Git Repository Checkout
- uses: actions/checkout@v4

 

3. Flutter Install

action 환경에서 android bundler 관련 오류가 발생해서 빌드 전 프로젝트를 clean 하고 빌드되도록 flutter를 설치했다.

- name: Install Flutter SDK
  uses: subosito/flutter-action@v1.5.1
  with:
    channel: 'stable'
    flutter-version: 3.27.1

 

4. SDK licenses 동의

licenses가 없다는 오류가 발생해서 SDK 동의하는 구문을 추가했다.

- name: Setup Android SDK
  uses: android-actions/setup-android@v2

 

5. Upload Key 복호화

base64로 encode된 key store 파일을 복호화 한 후, 파일을 생성한다.

- name: Generate Android keystore
  id: android_keystore
  uses: timheuer/base64-to-file@v1.1
  with:
    fileName: key.jks
    encodedString: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}

 

5. ignored files 생성

iOS와 비교해서 secret value에 정의해야하는 파일들이 많다.

- name: Create setting file
  run: |
    mkdir -p env
    echo "${{ secrets.ANDROID_GOOGLE_SERVICE_JSON }}" | base64 --decode > $(dirname $GITHUB_WORKSPACE)/vuka-jobs-app/android/app/google-services.json
    echo "${{ secrets.ANDROID_JOBS_SERVICE_ACCOUNT }}" | base64 --decode > $(dirname $GITHUB_WORKSPACE)/vuka-jobs-app/android/app/jobs_service_account.json
    echo "${{ secrets.ENV_QA_CONTENT }}" > env/qa.jobs.app.env
    echo "${{ secrets.ENV_DEV_CONTENT }}" > env/dev.jobs.app.env
    echo "storeFile=${{ steps.android_keystore.outputs.filePath }}" >> android/key.properties
    echo "${{ secrets.ANDROID_KEY_PROPERTIES }}" >> android/key.properties
    echo "${{ secrets.ANDROID_LOCAL_PROPERTIES }}" >> android/local.properties
    echo "sdk.dir=$ANDROID_HOME" >> android/local.properties
    echo "flutter.sdk=$FLUTTER_ROOT" >> android/local.properties
#encode
cat  vuka-jobs-app/vuka_jobs/ios/GoogleService-Info.plist | base64

 

4. Project Clean

- name: Install Dependencies
  run: |
    gem install bundler
    cd android && bundle install
    flutter pub get

 

 

5. fastlane lane 명령어 실행

- name: Deploy App Tester
  run: fastlane build
  working-directory: android
  env:
    ANDROID_FIREBASE_AUTH_TOKEN: ${{ secrets.ANDROID_FIREBASE_AUTH_TOKEN }}
    ANDROID_FIREBASE_DISTRIBUTION_APP_ID: ${{ secrets.ANDROID_FIREBASE_DISTRIBUTION_APP_ID }}

 

전체 Workflow 

    deploy_android:
      runs-on: self-hosted
      steps:
        # 1. Git Repository Checkout
        - uses: actions/checkout@v4

        # 2. Install Flutter
        - name: Install Flutter SDK
          uses: subosito/flutter-action@v1.5.1
          with:
            channel: 'stable'
            flutter-version: 3.22.0

        # 3. Accept SDK licenses
        - name: Setup Android SDK
          uses: android-actions/setup-android@v2

        # 4. upload key 복호화
        - name: Generate Android keystore
          id: android_keystore
          uses: timheuer/base64-to-file@v1.1
          with:
            fileName: key.jks
            encodedString: ${{ secrets.ANDROID_KEYSTORE_BASE64 }}

        # 5. Setting file
        - name: Create setting file
          run: |
            mkdir -p env
            echo "${{ secrets.ANDROID_GOOGLE_SERVICE_JSON }}" | base64 --decode > $(dirname $GITHUB_WORKSPACE)/vuka-jobs-app/android/app/google-services.json
            echo "${{ secrets.ANDROID_JOBS_SERVICE_ACCOUNT }}" | base64 --decode > $(dirname $GITHUB_WORKSPACE)/vuka-jobs-app/android/app/jobs_service_account.json
            echo "${{ secrets.ENV_DEV_CONTENT }}" > env/dev.jobs.app.env
            echo "${{ secrets.ENV_LOCAL_CONTENT }}" > env/local.jobs.app.env
            echo "storeFile=${{ steps.android_keystore.outputs.filePath }}" >> android/key.properties
            echo "${{ secrets.ANDROID_KEY_PROPERTIES }}" >> android/key.properties
            echo "${{ secrets.ANDROID_LOCAL_PROPERTIES }}" >> android/local.properties
            echo "sdk.dir=$ANDROID_HOME" >> android/local.properties
            echo "flutter.sdk=$FLUTTER_ROOT" >> android/local.properties

        # 6. project init
        - name: Install Dependencies
          run: |
            gem install bundler
            cd android && bundle install
            flutter pub get

        # 7. [Android] fastlane build
        - name: Deploy App Tester
          run: fastlane build
          working-directory: android
          env:
            ANDROID_FIREBASE_AUTH_TOKEN: ${{ secrets.ANDROID_FIREBASE_AUTH_TOKEN }}
            ANDROID_FIREBASE_DISTRIBUTION_APP_ID: ${{ secrets.ANDROID_FIREBASE_DISTRIBUTION_APP_ID }}

        # 8. Notification Slack (App Tester)
        - name: Notification Slack
          uses: 8398a7/action-slack@v3
          with:
            status: custom
            fields: repo,author,message
            custom_payload: |
              {
                attachments: [{
                  color: '${{ job.status }}' === 'success' ? 'good' : '${{ job.status }}' === 'failure' ? 'danger' : 'warning',
                  text: '${{ job.status }}' === 'success' ? '✅ Success Upload' : '${{ job.status }}' === 'failure' ? '⛔️ Failed Build' : '⚠️ Canceled Build',
                  fields: [{
                    title: 'repo',
                    value: `${process.env.AS_REPO}`,
                    short: true
                  },
                  {
                    title: 'author',
                    value: `${process.env.AS_AUTHOR}`,
                    short: true
                  },
                  {
                    title: 'message',
                    value: `${process.env.AS_MESSAGE}`,
                    short: true
                  }],
                }]
              }
          env:
            SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL_APPTESTER }}
          if: always()

 

'개발 정리 > CI·CD' 카테고리의 다른 글

[iOS] github actions 배포 자동화  (0) 2025.01.13
fastlane match  (0) 2025.01.06