fastrane의 CircleaCI를 사용하여 ReactNative 애플리케이션을 자동으로 구축하는 이야기
51904 단어 CircleCIReact Nativefastlanetech
이 기사는 airCloset Advent Calendar 2021 6일 만에 투고되었다.
프리랜서 엔지니어로 활동하면서 주식회사 에어클로셋(이하 에어크로)의 일부 개발을 소개할 수 있도록 허락해 주십시오.
개요
항공사에서는 베트남의 해외 시장을 활용해 테스트 인원을 외부로 아웃소싱해 인원 출입이 많았고, PL을 비롯한 비엔지니어들이 프로젝트 단위로 개발해 실기 확인을 앞두고 협업이 까다로워졌다.
그래서
누가 제출했든지 간에 누구든지 즉시 실기로 확인할 수 있다
필요조건으로 하다
fastlane의 CircleaCI를 사용한 ReactNative 애플리케이션 구축 자동화
그래서 내용을 소개합니다.
개발 환경
ReactNative에서 ios/android를 위한 응용 프로그램을 제공하고 CI 환경으로서CircleaCI를 사용합니다.
또 동작 확인 방법으로 디플로이 게이트에서 무대 환경을 목표로 한 애플리케이션을 펼쳐 프로젝트 관계자에게 공유했다.
대응 방침
이용 방법
fastlane.
루비제 도구로 문서 잘 정돈됐고, iOS 앱을 만들 때 간지러운 부분도 충분해 패스트라인을 적용했다.그 가려운 곳에 관해서는 다음과 같이 알기 쉽다.
특히 공중에 있는 블랙은 위에서 말한 바와 같이 해안 소프트웨어를 이용했기 때문에 엔지니어의 출입이 많을 것으로 추정되며, iOS 개발용 증서 발행부터 설치하기가 상당히 번거롭다.
따라서 Giithub Teams의read/write 권한 수여와 Giithub Repository에 암호화된 Provisioning Profile을 설치하면 각자 필요한 인증서를 취득하면 업무 효율이 크게 향상되는 것이 장점이라고 생각합니다.
CircleaCI에 MacOS VM 필요
ios 프로그램을 구축할 때 xcode가 필요하기 때문에 maxOS VM을 사용합니다.
이 경우 CircleaCI계획에 대한 upgrade가 필요합니다.
공기 흐름에 적응하는 작업 절차
Stage용 앱을 DeployGate에 제출하고 사내 구성원 등이 동작을 확인하고 있다.
이에 따라 CircleaCI에서 DeployGate에 업로드될 때까지 구현됐다.
또한 슬랙에서 커뮤니케이션이 이루어졌기 때문에 성공 또는 오류 알림을 올리면 슬랙에게 알립니다.
ReactNative에서 fastlane 가져오기
Gemfile
source "https://rubygems.org"
# setup_circle_ci action was released in 2.107.0
gem 'fastlane', '>= 2.191'
가능한 공동 환경을 위해 Gemfile에서 가져옵니다.ReactNative 응용 프로그램의 root dir 에 배치됩니다.
fastlane
fastlane는 상호작용 모드에서 동작을 지정할 수 있지만,CircleaCI에서 이동하려면 어느 정도의 지정과 간단한 이동task를 OS/android로 각각 표현해야 한다.
android/fastlane
안드로이드는 간단합니다.
건물은fastlane에gradle준비되어있어이용만 한다.
보고 싶은 사람 다 여기를 눌러주세요.
android/fastlane/Fastfile
fastlane_version "2.191.0"
default_platform :android
platform :android do
before_all do
# https://docs.fastlane.tools/best-practices/continuous-integration/circle-ci/
setup_circle_ci
end
desc "Build a new version for release"
lane :build_release do
gradle(
task: "assemble",
build_type: "Release"
)
end
desc "Build a new version to upload to deploygate"
lane :build_for_deploygate do
commit = last_git_commit
build_release
deploygate(
api_token: ENV["DEPLOYGATE_API_TOKEN"],
user: ENV["DEPLOYGATE_USER"],
apk: "./app/build/outputs/apk/release/app-release.apk",
message: "uploaded with fastlane, branch: #{git_branch}, last commit message: #{commit[:message]}, last commit hash: #{commit[:abbreviated_commit_hash]}"
)
slack(
message: "assembleReleaseなandroidアプリビルドとdeploygateへのアップロードに成功しました",
payload: {
"App Name" => "{YOUR_APP_NAME}"",
"Circle Build Url" => ENV["CIRCLE_BUILD_URL"]
}
)
end
desc "Build a new version to upload to beta"
lane :build_for_beta do
build_release
# 省略
end
# error block is executed when a error occurs
error do |lane, exception|
puts exception
slack(
# message with short human friendly message
message: exception.to_s,
success: false,
# Output containing extended log output
payload: {
"Output" => exception.to_s,
"Circle Build Url" => ENV["CIRCLE_BUILD_URL"]
}
)
end
end
ios/fastlane
ios는 상당히 번거롭다.
구축할 때 Provisioning Profile이 필요합니다.
보고 싶은 사람 다 여기를 눌러주세요.
ios/fastlane/Fastfile
fastlane_version "2.191.0"
default_platform :ios
platform :ios do
before_all do
# https://docs.fastlane.tools/best-practices/continuous-integration/circle-ci/
setup_circle_ci
end
desc "Build a new version for adhoc"
lane :build_adhoc do |options|
sync_code_signing(type: "adhoc", readonly: true)
update_code_signing_settings(
path: "{YOUR_APP_NAME}.xcodeproj",
code_sign_identity: ENV["IOS_CODE_SIGN_ID"],
profile_name: ENV["IOS_ADHOC_PROFILE_NAME"],
use_automatic_signing: false,
)
build_ios_app(
export_method: "ad-hoc",
output_directory: "./fastlane/build/adhoc/",
export_options: {
provisioningProfiles: {
"{YOUR_APP_BUNDLE_ID}" => ENV["IOS_ADHOC_PROFILE_NAME"]
}
}
)
update_code_signing_settings(
path: "{YOUR_APP_NAME}.xcodeproj",
code_sign_identity: ENV["IOS_CODE_SIGN_ID"],
profile_name: ENV["IOS_ADHOC_PROFILE_NAME"],
use_automatic_signing: true,
)
end
desc "Build a new version to upload to deploygate"
lane :build_for_deploygate do
commit = last_git_commit
build_adhoc
deploygate(
api_token: ENV["DEPLOYGATE_API_TOKEN"],
user: ENV["DEPLOYGATE_USER"],
ipa: "./fastlane/build/adhoc/aircloset.ipa",
message: "uploaded with fastlane, branch: #{git_branch}, last commit message: #{commit[:message]}, last commit hash: #{commit[:abbreviated_commit_hash]}"
)
slack(
message: "adhoc用のiosアプリビルドとdeploygateへのアップロードに成功しました",
payload: {
"App Name" => "{YOUR_APP_NAME}",
"Circle Build Url" => ENV["CIRCLE_BUILD_URL"]
}
)
end
desc "Build a new version for appstore"
lane :build_appstore do
# 省略
end
desc "Build a new version to upload to testflight"
lane :build_for_testflight do
# 省略
end
# error block is executed when a error occurs
error do |lane, exception|
slack(
# message with short human friendly message
message: exception.to_s,
success: false,
# Output containing extended log output
payload: {
"Output" => exception.to_s,
"Circle Build Url" => ENV["CIRCLE_BUILD_URL"]
}
)
end
end
sync_code_signing(type: "adhoc", readonly: true)
Giithub Repository에 있는 Provisioning Profile에 액세스합니다.readonly
, write 권한이 필요 없고, read 권한이 있는 계정은 Provisioning Profile을 획득할 수 있습니다.따라서 로컬에서 ios 응용 프로그램을 처음 만들기 위해 Provisioning Profile이 필요할 때github 계정에read 권한이 있으면
bundle exec fastlane match { development|adhoc|appstore } --readonly
는 CLI에서 사용할 수 있습니다.편리그나저나 match는
sync_code_signing
의 별명이다.update_code_signing_settings(
path: "{YOUR_APP_NAME}.xcodeproj",
code_sign_identity: ENV["IOS_CODE_SIGN_ID"],
profile_name: ENV["IOS_ADHOC_PROFILE_NAME"],
use_automatic_signing: false,
)
구축 시 Provisioning Profile을 지정하기 위해서는 update_code_signing_settings의use_automatic_signing: false
후build가 필요합니다.use_automatic_signing: true
제자리에 둔 것은 현지에서도 이동할 수 있기 때문이다.)이것은 참고 가치를 띠고 있다.
이상은fastlane측의 설정입니다.
참고로 ENV 지정을 통해CircleaCI Project Settings Environment Variables로 설정하여 호출할 수 있습니다.로컬에서 사용할 때dotenv &direnv를 넣는 것도 괜찮을 것 같아요.
Matchfile을 많이 지정했지만 중요하지 않으니 사랑을 끊는 것을 허락해 주세요.
CircleaCI에서 fastlane 이동
circleaci 설정을 다 보신 분들은 여기를 눌러주세요.
.circleci/config.yml
version: 2.1
orbs:
node: circleci/[email protected]
android: circleci/[email protected]
executors:
ios-build-machine:
macos:
xcode: "12.5.1"
commands:
setup_to_build:
description: "アプリビルドに必要な共通セットアップ処理"
steps:
## 省略 - node_modulesのinstallなどが必要です。##
## install gems ##
- restore_cache:
keys:
- gem-v1-{{ arch }}-{{ .Branch }}-{{ checksum "Gemfile.lock" }}
- run: bundle check || bundle install --path vendor/bundle
- save_cache:
key: gem-v1-{{ arch }}-{{ .Branch }}-{{ checksum "Gemfile.lock" }}
paths:
- vendor/bundle
setup_to_build_ios:
description: "iosビルドに必要な共通セットアップ処理"
steps:
- run:
name: jsbundle init
command: yarn ios-bundle # npx react-native bundle --entry-file index.js --platform ios --dev false --bundle-output ios/main.jsbundle --assets-dest ios
## install cocoapods ##
- restore_cache:
keys:
- cocoapods-v1-{{ checksum "ios/Podfile.lock" }}
- cocoapods-v1
- run:
name: pod install
command: cd ios && bundle exec pod install
- save_cache:
key: cocoapods-v1-{{ checksum "ios/Podfile.lock" }}
paths:
- ios/Pods
setup_to_build_android:
description: "androidビルドに必要な共通セットアップ処理"
steps:
## build ##
- run:
name: yarn android-bundle
command: yarn android-bundle # npx react-native bundle --platform android --dev false --entry-file index.js --bundle-output android /app/src/main/assets/index.android.bundle
no_output_timeout: 30m
setup_env_to_stg:
description: "stgの環境変数をセットする"
steps:
- run:
name: set env stg
command: grep -v '^\s*#' env.staging | grep -v '^\s*$' | while read line; do echo "export ${line}" >> $BASH_ENV; done
- run:
name: reload BASH_ENV
command: |
source $BASH_ENV
echo $AC_API_URL
## setup_env_to_prod: 省略 ##
jobs:
## npm_dependencies: 省略 ##
## test: 省略 ##
build_ios_stg:
executor: ios-build-machine
working_directory: /Users/distiller/project
steps:
- checkout
- setup_env_to_stg
- setup_to_build
- run:
name: set env to staging
command: yarn switch-config:stg
- setup_to_build_ios
## build ##
- run:
name: fastlane ios for staging
command: cd ios && bundle exec fastlane build_for_deploygate
- run:
name: zip
command: cd ios/fastlane/build && zip -r ipa.zip adhoc
when: always
- store_artifacts:
path: /Users/distiller/project/ios/fastlane/build
build_android_stg:
executor:
name: android/android-machine
resource-class: medium
environment:
JVM_OPTS: -Xmx3200m
GRADLE_OPTS: '-Dorg.gradle.daemon=false -Dorg.gradle.jvmargs="-Xmx3200m -XX:+HeapDumpOnOutOfMemoryError"'
working_directory: ~/project
steps:
- checkout
- setup_env_to_stg
- setup_to_build
- run:
name: set env to staging
command: yarn switch-config:stg
- setup_to_build_android
- run:
name: fastlane android for staging
command: cd android && bundle exec fastlane build_for_deploygate
- run:
name: zip
command: cd android/app/build/outputs && zip -r apk.zip apk
when: always
- store_artifacts:
path: /home/circleci/project/android/app/build/outputs
## build_ios_prod: 省略 ##
## build_android_prod: 省略 ##
workflows:
version: 2
build-test:
jobs:
- test:
requires:
- npm_dependencies
- build_ios_stg:
requires:
- test
filters:
branches:
only:
- /feature.*/
- master
- build_ios_prod:
filters:
tags:
only: /.*/
branches:
ignore: /.*/
- build_android_stg:
requires:
- test
filters:
branches:
only:
- /feature.*/
- master
- build_android_prod:
filters:
tags:
only: /.*/
branches:
ignore: /.*/
version: 2.1
orbs:
node: circleci/[email protected]
android: circleci/[email protected]
version을 2.1로 설정하여 orbs를 사용합니다.gradle도circleaci/android를 사용하면default install가 완성됩니다.
commands:
setup_to_build_ios:
description: "iosビルドに必要な共通セットアップ処理"
steps:
- run:
name: jsbundle init
command: yarn ios-bundle # npx react-native bundle --entry-file index.js --platform ios --dev false --bundle-output ios/main.jsbundle --assets-dest ios
## install cocoapods ##
- restore_cache:
keys:
- cocoapods-v1-{{ checksum "ios/Podfile.lock" }}
- cocoapods-v1
- run:
name: pod install
command: cd ios && bundle exec pod install
- save_cache:
key: cocoapods-v1-{{ checksum "ios/Podfile.lock" }}
paths:
- ios/Pods
최종적으로 applstore에 업로드하여ios가 구축한 유니버설 설정 처리로 편집합니다.리액트네이티브로 ios를 구축하기 위해서는
npx react-native bundle
해야 한다.안드로이드 쪽도 마찬가지다.
job:
build_ios_stg:
executor: ios-build-machine
working_directory: /Users/distiller/project
steps:
- checkout
- setup_env_to_stg
- setup_to_build
- run:
name: set env to staging
command: yarn switch-config:stg
- setup_to_build_ios
## build ##
- run:
name: fastlane ios for staging
command: cd ios && bundle exec fastlane build_for_deploygate
- run:
name: zip
command: cd ios/fastlane/build && zip -r ipa.zip adhoc
when: always
- store_artifacts:
path: /Users/distiller/project/ios/fastlane/build
ios 디렉터리bundle exec fastlane build_for_deploygate
에서 하면 이전에 표시된fastlane/Fastlane를 볼 수 있습니다.또 아이파 파일을 ARTIFACTS에 토해냄으로써 디플로이 게이트 계정을 초대하지 않더라도 베트남 이안국으로부터 디플로이 게이트가 공유하는 앱을 간단하게 받을 수 있다.(이것이 가장 환영받는 것이다.)
job:
(省略)
build_android_stg:
executor:
name: android/android-machine
resource-class: medium
environment:
JVM_OPTS: -Xmx3200m
GRADLE_OPTS: '-Dorg.gradle.daemon=false -Dorg.gradle.jvmargs="-Xmx3200m -XX:+HeapDumpOnOutOfMemoryError"'
working_directory: ~/project
steps:
(省略)
android 측에서 주의해야 할 것은 JVM_OPTS
과GRADLE_OPTS
의 지정이다.메모리를 확보하지 않으면 정상적으로 광택을 낼 수 있다.일단 위처럼 설정하면 돼요.
workflows:
version: 2
build-test:
jobs:
- test:
requires:
- npm_dependencies
- build_ios_stg:
requires:
- test
filters:
branches:
only:
- /feature.*/
- master
- build_ios_prod:
filters:
tags:
only: /.*/
branches:
ignore: /.*/
- build_android_stg:
requires:
- test
filters:
branches:
only:
- /feature.*/
- master
- build_android_prod:
filters:
tags:
only: /.*/
branches:
ignore: /.*/
작업 절차로서test가 성공하는 전제에서 동작을 구축한다.이렇게 되면 병렬 빌딩이 이동하기 때문에 상당한 시간이 줄어들 것이다.또한feature 지점, 마스터 지점에 제출된 경우만buildios_stg 및buildandroid_stg 이동.
그리고tapush가 한 일 때문에 이번에 생략한buildios_prood 및buildandroid_프로드를 움직일 수 있게 하다.
총결산
병렬 구축이 가능하고 환경 구축 등 번거로운 일을 줄여 업무 효율을 높이는 데 도움이 된다.
(코드가 공유되면 긴 부분은 아코디언으로 접는데 궁금하시면 접어주세요.)
최후
그나저나 백엔드 엔지니어라서 리액트내티브에 별로 접촉하지 않은 상태에서 개발했습니다.
다행히도 항공사에서는 나처럼 프리랜서 엔지니어도 새로운 경험이 많다.
여러분 관심 있으면 꼭 가세요! ->사이트 축소판 그림
Reference
이 문제에 관하여(fastrane의 CircleaCI를 사용하여 ReactNative 애플리케이션을 자동으로 구축하는 이야기), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://zenn.dev/harashun11/articles/ad4daa2db5431a텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)