[공익인간 2.0] 3. 배포 자동화 구현 및 브랜치 workflow 수정
Github Actions와 Fastlane으로 배포 자동화 구현하기
배경
공익인간 1.0 에서는 크게 master, develop, feature 브랜치를 구성하여 개발하였고 배포 또한 메뉴얼하게 진행하였다.
공익인간 2.0 개발을 진행하면서 기존의 브랜치 플로우와 배포 방식에 아래와 같은 불편함이 발생하였다.
- 여러가지 feature 개발을 동시에 진행하고, 각각 테스트할 수 있는 환경 구성이 어렵다.
- 매번 develop 브랜치에 pull request를 한 다음 테스트 배포를 하였기 테스트가 끝나지 않은 브랜치들이 하나로 모일 수 있는 문제가 있었다.
- 안드로이드 또한 RN으로 마이그레이션이 완료되어 매번 테스트, 스토어 배포를 위한 빌드를 진행할 시 OS별로 2번씩 동일한 작업을 반복해야하는 효율성 문제가 있었다.
브랜치 전략
TODO: Feature Branch Workflow에서 Gitflow Workflow로 변경하는 것 설명
release 브랜치
스토어 배포전 테스트를 위한 빌드를 진행할 때 develop에서 따로 release 브랜치로 checkout하는 방식을 추가하였다.
- 개발 완료된
feature브랜치develop브랜치로 pull reqeust & merge develop브랜치에서 “git branch checkout -b release/v${CURRENT_VERSION}”release브랜치에서 Fastlane을 통한 iOS TestFlight, android 내부테스트 빌드
git push origin feature/{branch_name} & pull request into develop branch
git push checkout develop
git pull origin develop
git branch checkout -b release/v{CURRENT_VERSION}
fastlane build beta
hotfix 브랜치
release 브랜치와 마찬가지로 급하게 수정해야하는 사항을 위한 브랜치를 구분하였다.
release브랜치에서 테스트 빌드를 통해 최종적인 테스트 도중 문제가 발생한 경우- 최악의 경우 스토어 배포가 완료된 후 문제가 발생한 경우
master 브랜치에서 배포
release 브랜치에서 테스트 검토 완료 하였을 시,
release브랜치 push to remote repomaster브랜치에서 해당 release 브랜치 pull- 태그 생성 “git tag v{CURRENT_VERSION}”
- 원격 저장소 푸시 “git push origin v{CURRENT_VERSION}”
- Github Actions, Fastlane을 통한 스토어 배포
git push origin release/v{CURRENT_VERSION}
git checkout master
git pull origin release/v{CURRENT_VERSION}
git tag v{CURRENT_VERSION}
git push origin v{CURRENT_VERSION}
<!-- github actions에서 진행 -->
fastlane build prod
배포 자동화
위에서 계획한 테스트 빌드와 스토어 배포 과정을 자동화하기 위해 github actions와 Fastlane을 사용하였다.
Fastlane
- Ruby 기반 클라이언트 자동 빌드 오픈소스 라이브러리이다.
- iOS, android 배포 자동화를 위해 사용하였다.
Github Actions
- Github에서 제공하는 CI/CD 툴로 테스트, 빌드, 배포 등 개발 프로세스를 자동화할 수 있다.
- master branch에 tag와 함께 push 되었을 때 자동으로 fastlane을 실행하기 위해 사용하였다.
Fastlane 설정
default_platform(:ios)
platform :ios do
# TestFlight 배포 및 테스트
desc "Push a new beta build to TestFlight"
lane :beta do
increment_build_number(xcodeproj: "iosAgentApp.xcodeproj")
build_app(workspace: "iosAgentApp.xcworkspace", scheme: "iosAgentApp")
upload_to_testflight(skip_waiting_for_build_processing: true)
end
# 배포 전 빌드, 버전 increament
desc 'Version increament'
lane :version do |options|
updateVersion(options)
increment_build_number(xcodeproj: 'iosAgentApp.xcodeproj')
end
# github actions를 통한 스토어 배포
desc 'GitHub actions release'
lane :github do |_options|
create_keychain(
# name: 'distribution_ios_keychain',
# password: 'Alleyoops1402',
timeout: 1800,
default_keychain: true,
unlock: true,
lock_when_sleeps: false
)
import_certificate(
# certificate_path: '../certifications/distribution_ios_keychain.p12',
# certificate_password: 'Alleyoops1402',
# keychain_name: 'distribution_ios_keychain',
# keychain_password: 'Alleyoops1402'
)
install_provisioning_profile(path: '../certifications/distribution_ios.mobileprovision')
update_project_provisioning(
xcodeproj: 'iosAgentApp.xcodeproj',
target_filter: 'github',
profile: 'distribution_ios.mobileprovision',
build_configuration: 'Release'
)
api_key = app_store_connect_api_key(
# key_id: 'QA9HNUZ732',
# issuer_id: 'e0741a70-9331-49e8-98cc-29086c11df7a',
# key_filepath: '../certifications/distribution_ios_api_key.p8'
)
build_app(workspace: 'iosAgentApp.xcworkspace', scheme: 'iosAgentApp')
upload_to_app_store(
force: true,
reject_if_possible: true,
skip_metadata: false,
skip_screenshots: true,
languages: ['ko'],
release_notes: {
'default' => 'bug fixed',
'ko' => 'bug fixed'
},
submit_for_review: true,
precheck_include_in_app_purchases: false,
automatic_release: true,
submission_information: {
add_id_info_uses_idfa: true,
add_id_info_serves_ads: true,
add_id_info_tracks_install: true,
add_id_info_tracks_action: false,
add_id_info_limits_tracking: true,
export_compliance_encryption_updated: false
},
api_key: api_key
)
end
end
Github Actions 설정
프로젝트 레포지토리의 actions 탭에서 workflow를 생성하면 자동으로 프로젝트에 .github/workflows/build.yml 위치로 yml 파일이 추가된다.
name: build
on:
push:
tags:
- "v*"
jobs:
release-ios:
name: Build and release iOS app
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/setup-node@v1
with:
node-version: "10.x"
- uses: actions/setup-ruby@v1
with:
ruby-version: "2.x"
- name: Install Fastlane
run: cd ios && bundle install && cd ..
- name: Install packages
run: npm install
- name: Install pods
run: cd ios && pod install && cd ..
- name: Execute Fastlane command
run: cd ios && fastlane github
release-android:
...