일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 29 | 30 |
- SWIFT
- Clean Code
- HIG
- tableView
- swift documentation
- map
- Refactoring
- Observable
- rxswift
- collectionview
- Xcode
- uitableview
- UICollectionView
- ribs
- MVVM
- 리펙토링
- Protocol
- combine
- UITextView
- ios
- 리펙터링
- 클린 코드
- 리팩토링
- 스위프트
- 애니메이션
- uiscrollview
- RxCocoa
- clean architecture
- swiftUI
- Human interface guide
- Today
- Total
김종권의 iOS 앱 개발 알아가기
[fastlane] *8. fastlane과 Bitrise를 이용한 자동 배포 구축 방법 본문
1. fastlane이란?
3. fastlane match (certificate, provisioning profile 정보를 git에 저장)
4. fastlane build_app (빌드, firebase에 배포)
5. fastlane 앱 스토어에 배포 (App Store Connect)
6. fastlane register devices, 디바이스 정보(UDID, Name) Apple Developer에 등록 방법 (register_devices)
*7. fastlane 총 정리 및 phase별 configuration 설정, 환경변수 설정
*8. fastlane과 Bitrise를 이용한 자동 배포 구축 방법
cf) fastlane 환경 변수 (.env.default) 사용하여 가장 단순한 match 사용 방법
앱 build를 app store connect에 올리기 전에 준비 사항
- 앱 Icon을 등록하지 않으면 build가 올라가지 않고 아래처럼 이메일을 받으므로 아이콘 등록이 필수
- Assets > AppIcon에 이미지 추가
- Info.plist에 CFBundleIconName 키-밸류 추가
fastlane 내용 수정
- 빌드 번호를 올려주는 기능을 fastlane에서하지 않고 bitrise에서 수행
- fastlane에서 하게되면 아래와같은 빌드 오류 발생
- fastfile 내용 수정 - fastlane 총 정리 및 phase별 configuration 설정에서 정의했던 bump_build_number을 삭제하여, 완성된 아래 fastfile 내용 참고
default_platform(:ios)
ENV["FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD"] = "wzwy-zcxl-xkev-lyft"
platform :ios do
# deploy
lane :deploy_alpha do |options|
sync_codesign_alpha()
build(configuration: "alpha")
upload_to_firebase(appid: "1:773589851865:ios:d1dcae5400c3304acce8c8", tester_group: "tester-first, tester-second" )
end
lane :deploy_beta do |options|
sync_codesign_beta()
build(configuration: "beta")
upload_to_firebase(appid: "1:773589851865:ios:749c1a7bffb649b1cce8c8", tester_group: "tester-first, tester-second" )
end
lane :deploy_real do |options|
sync_codesign_real()
build(configuration: "real")
api_key = app_store_connect_api_key(
key_id: "4KRU955ZYH",
issuer_id: "c2fd1c9b-7e84-42ee-a638-8f1a776042ae",
key_filepath: "fastlane/AuthKey_U4M68Y6BJ3.p8",
duration: 1200,
in_house: false
)
upload_to_testflight(api_key: api_key,
skip_waiting_for_build_processing: true,
ipa: "fastlane/distribute/SavePhoto.ipa")
end
# sync
lane :sync_codesign_alpha do
sync_codesign(type:"development")
sync_codesign(type:"adhoc")
end
lane :sync_codesign_beta do
sync_codesign(type:"development")
sync_codesign(type:"adhoc")
end
lane :sync_codesign_real do
sync_codesign(type:"development")
sync_codesign(type:"appstore")
end
private_lane :sync_codesign do|options|
match(type:options[:type], readonly: true)
end
# renew
lane :renew_codesign_alpha do
renew_codesign(type:"development")
renew_codesign(type:"adhoc")
end
lane :renew_codesign_beta do
renew_codesign(type:"development")
renew_codesign(type:"adhoc")
end
lane :renew_codesign_real do
renew_codesign(type:"development")
renew_codesign(type:"appstore")
end
private_lane :renew_codesign do|options|
match(type:options[:type], force_for_new_devices: true)
end
# register new device
lane :register_new_devices do
register_devices(
devices_file: "./fastlane/devices.txt",
team_id: "SS7U83UJNK"
)
end
# private
private_lane :build do |options|
case options[:configuration]
when "alpha"
scheme = "SavePhoto alpha"
export_type = "ad-hoc"
when "beta"
scheme = "SavePhoto beta"
export_type = "ad-hoc"
when "real"
scheme = "SavePhoto real"
export_type = "app-store"
end
build_app(
scheme: scheme,
export_method: export_type,
output_directory: "./fastlane/distribute",
clean: true
)
end
private_lane :upload_to_firebase do |options|
firebase_app_distribution(
app: options[:appid],
groups: options[:tester_group],
firebase_cli_token: "1//0ePS_knB0VXuOCgYIARAAGA4SNwF-L9IrcIritOpKCIwYh5Mdj288Jgw7euJG_uu6UPVsUgeuQzoIoCuPStvAu2o9qhNYKM_Lv6E",
ipa_path: "./fastlane/distribute/SavePhoto.ipa"
#release_notes: "Lots of amazing new features to test out!"
)
end
end
Bitrise
- webhook과 trigger 기능을 통해 git에 push, tag, merge되었을 때 배포되게끔 가능
- 가입 완료
- Dashboard > Add new app
Project 생성 - git과 연동
- Add new app 클릭하면 아래 화면부터 시작
- private 체크 후 Next
- remote repository 지정
- Connect Github 클릭
- github에서 로그인 완료 시 connect 성공
- 다시 Github을 선택하면 repository를 선택할 수 있고, 해당 배포할 repository 선택
- Add own ssh 선택
- bitrise용도의 ssh키를 생성해야 하므로 명령어 실행
$ ssh-keygen -t rsa -b 4096 -P '' -f ./bitrise-ssh -m PEM
- 생성된 ssh key는 ~/ 디렉토리에 bitrise-ssh로 열어서 복사
- private key: bitrise-ssh > 위 bitrise에 붙여넣기
- public key: bitrise-ssh.pub > github의 ssh키에 등록
- bitrise에서 brach 지정
- 추후 자동 배포 시, 브랜치 설정이 없으면 여기에서 설정한 브랜치 내용으로 배포
- 만약 에러 발생 시, repository가 현재 public으로 설정되어 있어서 에러 발생할수 있으므로, repository를 private으로 access 수정하고 ssh키값이 맞지 않아서 그러므로 ssh키값 확인 필요
- 결과
- 자동으로 xcode에서 만들었던 scheme들과 fastlane 표출
- 옵션을 모두 선택 후 next
- 기타 설정값 선택 후 webhook 설정
- Register a Webhook for me! 클릭
- 완료
- We've kicked off your first test build for you 클릭
Workflow 구현
- 배포되는 하나의 flow를 정의한 것이며, step들로 이루어진 작업흐름단위
ex) alpha, beta, real 워크플로우가 있는 상태,
alpha 워크플로우: alpha버전 배포 용도
- 생성
- Dashboard > ... > workflow 선택
- + Workflow 클릭
- 추가
- Based On은 디폴트로 생성된 primary workflow를 복사하여 만드는 것
- Xcode Archive 스탭 삭제
- Set Xcode Project Build Number 스텝 추가
> xcode에서 Info.plist에 bundle version string 키값 생성
$(CURRENT_PROJECT_VERSION)
> info.plist 경로 입력
력
$BITRISE_SOURCE_DIR/{위에서 확인한 path 붙여넣기}
- fastlane 스탭 생성
- fastlane lane에 fastlane 총 정리 및 phase별 configuration 설정 에서 정의했던 배포 lane 입력
- Save 클릭
cf) 만약 cocoapod을 사용하고 있다면, Certificate and profile 다음 step에 Run cocoapods install 추가
환경 변수 설정
- ssh private key 환경변수 등록 - 위에서 bitrise ssh key 만들었던 private key를 여기에도 입력
- Key 이름은 `SSH_RSA_PRIVATE_KEY`로 입력
- fastlane의 match를 사용할 땐 항상 password가 필요하므로, fastlane 총 정리 및 phase별 configuration 설정 에서 등록했던 password를 설정
- Workflow > Secrets 탭에서 `MATCH_PASSWORD` 키값으로 password 입력
수동 빌드 방법
- bitrise에서 직접 git에 있는 branch 이름을 지정하여 빌드되게 하는 방법
- Dashboard > {user} > {project name} > Start/Schedule a Build 클릭
- 빌드
- Branch 선택
- Message 입력
- Workflow 선택 후 Start Build 클릭
- 성공
trigger 사용 방법
- Workflow Editor 탭에서 Triggers 탭 클릭
- 세 가지 옵션에서 trigger 정의
- PUSH: 연결된 git의 branch와 workflow를 설정하면 해당 branch에 푸시가 될 때 workflow동작
ex) `*` 기호는 모든을 뜻하므로, 아무 branch에 push가 되면 `primary` workflow동작 - PULL REQUEST: Push와 설정 동일
- TAG: 문자열과 workflow를 설정
ex) *alpha* 문자열로 설정해놓으면, alpha-v0.1.1과 같은 tag도 트리거 동작
- PUSH: 연결된 git의 branch와 workflow를 설정하면 해당 branch에 푸시가 될 때 workflow동작
cf) bitrise를 사용하지 않고 로컬에서 fastlane만 사용하는 경우, bump_build_number()를 적용한 fastfile 내용 참고
default_platform(:ios)
ENV["FASTLANE_APPLE_APPLICATION_SPECIFIC_PASSWORD"] = "wzwy-zcxl-xkev-lyft"
platform :ios do
# deploy
lane :deploy_alpha do |options|
sync_codesign_alpha()
bump_build_number()
build(configuration: "alpha")
upload_to_firebase(appid: "1:773589851865:ios:d1dcae5400c3304acce8c8", tester_group: "tester-first, tester-second" )
end
lane :deploy_beta do |options|
sync_codesign_beta()
bump_build_number()
build(configuration: "beta")
upload_to_firebase(appid: "1:773589851865:ios:749c1a7bffb649b1cce8c8", tester_group: "tester-first, tester-second" )
end
lane :deploy_real do |options|
sync_codesign_real()
bump_build_number()
build(configuration: "real")
api_key = app_store_connect_api_key(
key_id: "4KRU955ZYH",
issuer_id: "c2fd1c9b-7e84-42ee-a638-8f1a776042ae",
key_filepath: "fastlane/AuthKey_4KRU955ZYH.p8",
duration: 1200,
in_house: false
)
upload_to_testflight(
api_key: api_key,
skip_waiting_for_build_processing: true,
ipa: "fastlane/distribute/SavePhoto.ipa"
)
end
# sync
lane :sync_codesign_alpha do
sync_codesign(type:"development")
sync_codesign(type:"adhoc")
end
lane :sync_codesign_beta do
sync_codesign(type:"development")
sync_codesign(type:"adhoc")
end
lane :sync_codesign_real do
sync_codesign(type:"development")
sync_codesign(type:"appstore")
end
private_lane :sync_codesign do|options|
match(type:options[:type], readonly: true)
end
# renew
lane :renew_codesign_alpha do
renew_codesign(type:"development")
renew_codesign(type:"adhoc")
end
lane :renew_codesign_beta do
renew_codesign(type:"development")
renew_codesign(type:"adhoc")
end
lane :renew_codesign_real do
renew_codesign(type:"development")
renew_codesign(type:"appstore")
end
private_lane :renew_codesign do|options|
match(type:options[:type], force_for_new_devices: true)
end
# register new device
lane :register_new_devices do
register_devices(
devices_file: "./fastlane/devices.txt",
team_id: "SS7U83UJNK"
)
end
# private
private_lane :build do |options|
case options[:configuration]
when "alpha"
scheme = "SavePhoto alpha"
export_type = "ad-hoc"
when "beta"
scheme = "SavePhoto beta"
export_type = "ad-hoc"
when "real"
scheme = "SavePhoto real"
export_type = "app-store"
end
build_app(
scheme: scheme,
export_method: export_type,
output_directory: "./fastlane/distribute",
clean: true
)
end
private_lane :upload_to_firebase do |options|
firebase_app_distribution(
app: options[:appid],
groups: options[:tester_group],
firebase_cli_token: "1//0ePS_knB0VXuOCgYIARAAGA4SNwF-L9IrcIritOpKCIwYh5Mdj288Jgw7euJG_uu6UPVsUgeuQzoIoCuPStvAu2o9qhNYKM_Lv6E",
ipa_path: "./fastlane/distribute/SavePhoto.ipa"
#release_notes: "Lots of amazing new features to test out!"
)
end
private_lane :bump_build_number do
ensure_git_status_clean
increment_build_number(xcodeproj: "./SavePhoto.xcodeproj")
build_number = get_build_number(xcodeproj: "./SavePhoto.xcodeproj")
commit_version_bump(message: "Bump build number to #{build_number} by fastlane", xcodeproj: "./SavePhoto.xcodeproj")
push_to_git_remote
end
end
- app store connect에서 `빌드 +`버튼을 누르면 업로드된 것 확인 가능
* 전체 소스 코드: https://github.com/JK0369/SavePhoto
* 참고
https://devcenter.bitrise.io/faq/how-to-generate-ssh-keypair/