GiHub Actions으로 Flutter CI/CD 구축하기 - GitHub Secret 설정
전편에서 깃허브 액션 내에서 활용할 파일들이나 데이터들을 GitHub Secret에 등록하는 작업을 했다.
이제 깃허브 액션이 제공해주는 가상환경에서 이 secret을 활용하여 Workflow를 구성하는 작업을 진행한다.
우선 나의 프로젝트 상황에서는 두개의 workflow가 필요하다.
1. 풀리퀘스트 시 빌드 번호 업데이트, 빌드 그리고 배포 (develop, stage, release 브랜치 각각 작성)
2. develop, stage, release 브랜치에서 풀리퀘스트 시 develop, stage, release 브랜치 모두의 빌드 번호 업데이트
이번 글에서는 먼저 1번(빌드 및 배포 워크플로우)에 대해 기록한다
1, .github/workflows 디렉토리에 yml 파일 생성
해당 브랜치에서 파일을 직접 생성하거나 혹은 Actions탭의 안내 링크를 클릭하여 yml 파일을 생성한다.
직접 생성하거나
Actions탭 페이지에서 set up a workflow yourself 클릭
2, workflow의 이름과 Trigger 설정
# workflow의 이름 : develop 환경의 CICD
name: dev CICD
# workflow의 trigger 설정
on:
# Trogger 조건 : develop 브랜치 pull request할 경우
pull_request:
branches: [ "develop" ]
2-1, 배포 환경 별 트리거
Develop 브랜치에 pull_request 할 경우 빌드 및 배포 진행
on:
pull_request:
branches: [ "develop" ]
3, job 이름과 runner(실행환경) 설정
...
on:
# Trogger 조건 : develop 브랜치 pull request할 경우
pull_request:
branches: [ "develop" ]
jobs:
# job 명명
build and deploy:
# job 실행환경 : github 제공 가상 macos
runs-on: macos-latest
3-1, job 실행 환경 선택 기준
CI/CD를 구성할 때 본인이 소유한 실제 기기 환경에서 작업이 실행되게 할 수도 있고 깃허브에서 제공하는 환경에서 진행할 수도 있다.
- 실제 소유한 기기 환경 : 현재 프로젝트 코딩 작업을 하는 기기에서 진행하게 되면 java, flutter sdk 등을 매번 설치할 필요가 없어 시간을 절약할 수 있으나 해당 기기가 일정 시간 이상 오프라인일 경우 실행 목록에서 제외될 수 있는 단점이 있다.
- GitHub 제공 가상 환경 : 매번 java, flutter sdk 를 설치해야 하기 때문에 빌드 배포시간이 좀 더 소요된다.
시간이 좀 더 걸리더라도 특정 기기나 팀원에 한정되지 않는 CI/CD 환경을 위해 가상 환경으로 선택
4, steps 설정 - 1 : 깃허브 액션 브랜치로 체크아웃
...
# job 실행환경 : github 제공 가상 macos
runs-on: macos-latest
steps:
# 프로젝트 브랜치를 github actions 브랜치로 체크아웃하여 올리는 작업
- name: Checkout
uses: actions/checkout@v3
5, steps 설정 - 2 : 현재 버전 빌드 번호 추출하여 +1 한 값 변수로 선언
- name: 현재 빌드 번호 추출하여 +1을 한 후 $GITHUB_ENV 환경변수로 등록
run: |
version=$(grep 'version:' pubspec.yaml | awk '{print $2}')
echo "Current version: $version"
IFS='+' read -r base_version build_number <<< "$version"
build_number=$((build_number + 1))
new_version="${base_version}+${build_number}"
echo "New version: $new_version"
echo "NEW_VERSION=$new_version" >> $GITHUB_ENV
6, steps 설정 - 3 : ios 빌드 설정 파일 복호화 및 설치
...
steps:
# 프로젝트 브랜치를 github actions 브랜치로 체크아웃하여 올리는 작업
- name: Checkout
uses: actions/checkout@v3
- name: 🔐 ios 빌드 관련 파일 설치
# 깃허브 시크릿에 등록한 값 불러오기
env:
P12_DISTRIBUTION_CERTIFICATE_BASE64: "${{ secrets.IOS_P12_DISTRIBUTION_CERTIFICATE_BASE64 }}"
P12_DISTRIBUTION_CERTIFICATE_PASSWORD: "${{ secrets.IOS_P12_DISTRIBUTION_CERTIFICATE_PASSWORD }}"
DISTRIBUTION_PROVISIONING_PROFILE_BASE64: "${{ secrets.IOS_DISTRIBUTION_PROVISIONING_PROFILE_BASE64 }}"
LOCAL_NOTI_PROVISIONING_PROFILE_BASE64: "${{ secrets.IOS_LOCAL_NOTIFICATION_PROFILE_BASE64 }}"
KEYCHAIN_PASSWORD: "${{ secrets.IOS_RUNNER_LOCAL_KEYCHAIN_PASSWORD }}"
EXPORT_OPTIONS_BASE64: "${{ secrets.IOS_EXPORT_OPTIONS_BASE64 }}"
run: |
# 경로를 가리키는 환경 변수 선언
CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
PROVISIONING_PROFILE_PATH=$RUNNER_TEMP/ios_dist_pp.mobileprovision
LOCAL_NOTIFICATION_PROFILE_PATH=$RUNNER_TEMP/ios_dist_noti_pp.mobileprovision
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
EXPORT_OPTIONS_PATH="${{ github.workspace }}/ios/Runner/ExportOptions.plist"
# base64 복호화 된 파일 생성
echo -n "$P12_DISTRIBUTION_CERTIFICATE_BASE64" | base64 --decode -o $CERTIFICATE_PATH
echo -n "$DISTRIBUTION_PROVISIONING_PROFILE_BASE64" | base64 --decode -o $PROVISIONING_PROFILE_PATH
echo -n "$LOCAL_NOTI_PROVISIONING_PROFILE_BASE64" | base64 --decode -o $LOCAL_NOTIFICATION_PROFILE_PATH
echo -n "$EXPORT_OPTIONS_BASE64" | base64 --decode -o $EXPORT_OPTIONS_PATH
# 임시 키체인 생성 Certificate import
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security import $CERTIFICATE_PATH -P "$P12_DISTRIBUTION_CERTIFICATE_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
security list-keychain -d user -s $KEYCHAIN_PATH
# provisioning profile을 xcode가 인식할 수 있는 디렉토리에 복사
mkdir -p ~/Library/MobileDevice/Provisioning\\ Profiles
cp $PROVISIONING_PROFILE_PATH ~/Library/MobileDevice/Provisioning\\ Profiles
cp $LOCAL_NOTIFICATION_PROFILE_PATH ~/Library/MobileDevice/Provisioning\\ Profiles
7, steps 설정 - 4 : android 빌드 설정 파일 복호화 및 설치
steps:
...
- name: 🔐 android 빌드 관련 파일 설치
run: |
#debug용 keystore 복호화하여 xcode가 인식하는 위치에 생성
echo "${{ secrets.ANDROID_DEBUG_KEYSTORE_BASE64 }}" | base64 --decode > $HOME/.android/debug.keystore
#실제 플레이스토어 배포할 경우 release용 jks 파일 또한 복호화 필요(release 브랜치 yml 파일에만 넣으면 됨)
echo "${{ secrets.ANDROID_RELEASE_KEYSTORE_BASE64 }}" | base64 --decode > "${{ github.workspace }}/android/keystore/key.jks"
8, steps 설정 - 5 : SDK 설치 및 flutter pub get 실행
# SDK 설치를 지원하는 모듈 같은 개념
- uses: actions/setup-java@v2
with:
# 프로젝트 JAVA 버전 맞춰서
java-version: '11'
distribution: 'adopt'
# SDK 설치를 지원하는 모듈 같은 개념
- uses: subosito/flutter-action@v2.3.0
with:
# 프로젝트 Flutter 버전 맞춰서
flutter-version: '3.3.1'
- name: Install packages
run: flutter pub get
9, steps 설정 - 6 : build ipa 및 테스트 플라잇 배포
- name: Build ipa
run: |
flutter build ipa \
--release \
# flavor로 빌드 환경을 관리하는 경우
--flavor dev \
--export-options-plist=ios/Runner/ExportOptions.plist
#이전에 추출했던 ExportOptions.plist의 설정대로 certificate, profile파일 사용
- name: 사용할 app store connect api 키 가져오기
env:
PRIVATE_API_KEY_BASE64: ${{ secrets.APP_STORE_CONNECT_API_PRIVATE_KEY_BASE64 }}
API_KEY: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}
run: |
mkdir -p ~/private_keys
echo -n "$PRIVATE_API_KEY_BASE64" | base64 --decode --output ~/private_keys/AuthKey_$API_KEY.p8
- name: TestFlight에 업로드
env:
API_KEY: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}
API_ISSUER : ${{ secrets.APP_STORE_CONNECT_ISSUER_ID }}
#자신의 프로젝트 빌드 결과물 경로와 프로젝트명으로 수정
run: xcrun altool --output-format xml --upload-app -f ${{ github.workspace }}/build/ios/ipa/pjname.ipa -t ios --apiKey $API_KEY --apiIssuer $API_ISSUER
10, steps 설정 - 7 : build apk 및 구글 드라이브 업로드
- name: Build apk
run: |
flutter build apk \\
--release \\
# flavor로 빌드 환경을 관리하는 경우
--flavor dev
#apk 파일명은 입맛에 맞게
- name: 오늘 날짜에 따라 apk 파일명 설정
run: echo "TODAYS_DATE=$(date +%y%m%d)" >> $GITHUB_ENV
- name: Google Drive에 apk 파일 업로드
uses: willo32/google-drive-upload-action@v1
with:
credentials: ${{ secrets.GOOGLE_SERVICE_ACCOUNT_CREDENTIALS }}
target: ${{ github.workspace }}/build/app/outputs/flutter-apk/app-dev-release.apk
parent_folder_id: ${{ secrets.GOOGLE_DRIVE_DEV_FOLDER_ID }}
name: dev_${{ env.TODAYS_DATE }}.apk
다음에는 브랜치 간 버전 업데이트 및 동기화 워크플로우에 대해 작성하겠다
'Flutter > Flutter CICD' 카테고리의 다른 글
GitHub Actions으로 Flutter CI/CD 구축하기 - workflow 설정 2 (1) | 2024.01.08 |
---|---|
GitHub Actions으로 Flutter CI/CD 구축하기 - GitHub Secret 설정 (3) | 2024.01.02 |