현재 Google에서 유지 관리하는 Fastlane은 테스트, 배포, 프로젝트 버전 증분 및 기타 여러 가지 고유한 목적을 가진 다양한 기능과 함께 제공되는 CD도구다. 예전에는 프로젝트 빌드 및 배포 프로세스를 자동화할 수 있으려면 고유한 솔루션을 만들거나 다른 사람들로부터 여러 스크립트를 가져와야 했다. 하지만 fastlane은 이 모든 과정을 자동화 할 수 있을 뿐만 아니라 기존의 CI 서비스와 페어링도 가능하다. 그렇기 때문에 현재 많은 기업에서 사용하고 있다.
fastlane beta
위에서 설명했듯이 fastlane에는 아주 다양한 설정과 기능이 존재한다. 니드에 맞게 적절한 기능을 찾아보고 사용해보자. 아래는 fastlane을 소개하는 차원에서 Testflight 배포해보고자 한다. 참고로 코드 사이닝 과정은 fastlane에서 기본적으로 처리해주는 것 외에 다른 작업은 다른 글에서 다루려 한다.
Homebrew 사용
brew install fastlane
(권한이 없을 시) prefix로 sudo
Bundler?
bundler는 Gem들을 실행, Gem은 ruby의 라이브러리
bundler는 Gemfile, Gemfile.lock에 기재되어 있는 것을 기준으로 RubyGems.org에서 Gem을 찾아 설치, bundler를 이용해서 cocoapods을 설치할 수 있음. 그러면 로컬에 얽메이지 않고 호스팅 서버에서 보내주는 팟을 이용할 수 있는 장점이 있다.
RubyGems.org is the Ruby community’s gem hosting service.
gem install bundler
(권한이 없을 시) prefix로 sudo
// 설치하려는 디렉토리로 이동
// 아래 init 작업 뿐만 아니라 실행 작업도 해당 디렉토리에서 해야 한다.
cd Desktop/Cookid
// fastlane을 적용
fastlane init
Cert, Sign 이용 : 특별히 유저가 뭔가 설정해줄 필요는 없음. 애플 계정을 입력해뒀고, 인증서를 로컬 Keychain에 넣어뒀다면 알아서 인증을 진행해주는 방식이다. 심지어 로컬에 인증서가 따로 없더라도 Cert, Sigh가 알아서 인증서와 프로필을 다운받아 진행해준다.
Match 이용 : 조금 더 대규모 팀일 때 사용하는 인증 방식. Match는 하나의 인증서를 github private 저장소에 넣어두고, 팀원들이 해당 저장소에 접근해서 매번 인증서를 가져와 사용하는 방식이다. Cert, Sigh이 각자의 인증서를 각자의 로컬에 저장, 인증서가 만료되는 시점도 제각각. 하지만 Match를 사용하면 중앙에 있는 인증서만 교체 → 갱신 문제X, 계정 문제X
Appfile
fastlane은 Appfile에 기입된 내용을 보고 환경을 세팅한 후 Fastfile을 참고하여 특정 기능을 수행하도록 진행한다.
app_identifier("여기는 앱 identifier") # The bundle identifier of your app
// 아이디는 환경변수 사용
apple_id(ENV["APPLE_ID"]) # Your Apple email address
itc_team_id("123478503") # App Store Connect Team ID
team_id("여기는 팀 ID") # Developer Portal Team ID
# For more information about the Appfile, see:
# https://docs.fastlane.tools/advanced/#appfile
// 이 디렉토리 안에서 환경변수 설정
vim ./fastlane/.env
APP_IDENTIFIER="your.app.identifier"
APPLE_ID="my-apple-id@email.com"
...
이제 명령을 직접 커스텀해서 Testflight에 올려보자. 명령은 fastlane 폴더 안에 있는 Fastfile에 작성.
fastfile
fastlane의 기능들을 lane으로 정의한 후 그 lane을 실행시키면 인증서 관리, firebase배포, appstore에 업로드하는 기능이 존재
default_platform(:ios)
platform :ios do
desc "build app and upload to TestFlight"
lane :beta do
get_certificates
get_provisioning_profile
cocoapods(use_bundle_exec: false)
increment_build_number(
build_number: latest_testflight_build_number + 1
)
build_app(
configuration: "Debug"
)
upload_to_testflight(
skip_waiting_for_build_processing: true
)
slack(
message: "Testflight 배포에 성공했습니다!",
slack_url: "https://hooks.slack.com/services/토큰"
)
end
error do |lane, exception, options|
slack(
message: "에러 발생 : #{exception}",
success: false,
slack_url: "https://hooks.slack.com/services/토큰",
)
end
end
default_platform(:ios)
platform :ios do
...
end
원래 실행 명령어는 fastlane ios beta
이다. 하지만 위에서 플랫폼을 iOS로 미리 설정해두었기 때문에 fastlane beta
로 사용 가능. platform뒤에 띄워쓰기 저렇게 안하면 오류난다.
lane :beta do
...
end
Bitrise의 workflow라는 개념이 여기는 lane으로 사용된다. lane은 fastlane 작업을 수행하는 각 메소드들로 구성되어 있다. 이 메소드를 순차적으로 실행하며 작업을 진행한다. lane의 이름은 "beta"로 설정했다.
cocoapods(use_bundle_exec: false)
코코아팟을 설치하는 pod install
작업이다. 옵션으로는 use_bundle_exec: false
을 사용했는데 이는 gem의 버전이 다를 때도 올바로 작동할 수 있도록 하는 옵션이다. 같은 버전이라면 문제가 없겠지만 아니라면 false로 설정한다. warning을 받을 수 있다.
increment_build_number(
build_number: latest_testflight_build_number + 1
)
빌드 넘버를 올린다. latest_testflight_build_number
는 새로운 빌드를 할 때마다 최신 빌드의 숫자를 가져오는 변수고 + 1은 한 버전을 더 해준다는 의미다.
build_app(
configuration: "Debug"
)
앱을 빌드하는 메소드인데, Testflight에 올릴 예정이기 때문에 Debug 모드로 올린다
upload_to_testflight(
skip_waiting_for_build_processing: true
)
빌드 후 tesflight에 업로드하는 메소드이다. skip_waiting_for_build_processing
를 true로 해놓으면 일단 testflight에 추가되고 난 후 나머지 작업을 진행한다. 즉 시각적으로 바로 볼 수 있다.
slack(
message: "Testflight 배포에 성공했습니다!",
slack_url: "https://hooks.slack.com/services/토큰"
)
build가 완료되면 slack으로 메시지를 전하는 메소드다. slack_url은 slack API에서 받을 수 있다.
error do |lane, exception, options|
slack(
message: "에러 발생 : #{exception}",
success: false,
slack_url: "https://hooks.slack.com/services/토큰",
)
end
이건 에러를 감지하는 lane이다. 마찬가지로 에러시에 slack으로 메시지를 전하는 hook을 넣어준다.
개인적인 의견을 덧붙여본다. 일단 다른 CI의 트리거 없이 fastlane만 사용해도 너무 좋을 정도다. 특히 CLI를 사용하는 것은 정말 좋은 장점 같다. (극초보일 때는 이게 왜 장점인가 했는데...) 자동화 과정이 생각보다 잘 되어있고 개인적으로 빌드 시간도 빠른 것 같다. Bitrise에서는 빌드 시간이 대략 20분가까이 걸렸는데 fastlane은 10분 내외가 걸렸다. 아쉬운 점은 로컬로 작업한다는 점이다. 물론 장단점 둘 다 될 수 있지만 Bitrise의 클라우드 플랫폼이 팀 단위에서 사용하기 더 쉬워보였다.
다음 글에서는 fastlane을 사용해서 다음 버전을 release 해보려고 한다. 일단 testflight로 보낸 앱이 심사를 마치고 외부테스터에서 테스팅을 받은 뒤에 올려보겠다.