Leo
[Android] github actions 배포 자동화 본문
이번엔 Android 빌드와 App Distribution으로 업로드 되도록 설정한 fastlane을 Github Action에서 사용할 수 있도록 설정한 방법이다.
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]+'
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 |