Fastlane 소개 및 시작하기

박형석·2021년 11월 25일
2

CI / CD

목록 보기
5/7
post-thumbnail
post-custom-banner

Fastlane?

현재 Google에서 유지 관리하는 Fastlane은 테스트, 배포, 프로젝트 버전 증분 및 기타 여러 가지 고유한 목적을 가진 다양한 기능과 함께 제공되는 CD도구다. 예전에는 프로젝트 빌드 및 배포 프로세스를 자동화할 수 있으려면 고유한 솔루션을 만들거나 다른 사람들로부터 여러 스크립트를 가져와야 했다. 하지만 fastlane은 이 모든 과정을 자동화 할 수 있을 뿐만 아니라 기존의 CI 서비스와 페어링도 가능하다. 그렇기 때문에 현재 많은 기업에서 사용하고 있다.

기존 IPA 추출 과정

  1. info.plist에서 버전과 빌드 올리는 작업
  2. 타겟이 여러 개인 경우, 모든 타겟이 버전과 빌드가 동일한지 체크
  3. 빌드
  4. 3인 이상의 개발자가 동시에 개발하는 경우, 1년에 한 번 씩 certificate, provisioning profile을 발급받고 공유
  5. archive를 누른 후 끝날 때까지 대기
  6. archive가 완료되면 배포 버튼 누르고, 배포가 될 때 까지 대기
  7. 노티

Fastlane을 이용한 IPA 추출 과정

  1. 터미널 열기
  2. 명령어 입력 fastlane beta
  3. 기다리기

위에서 설명했듯이 fastlane에는 아주 다양한 설정과 기능이 존재한다. 니드에 맞게 적절한 기능을 찾아보고 사용해보자. 아래는 fastlane을 소개하는 차원에서 Testflight 배포해보고자 한다. 참고로 코드 사이닝 과정은 fastlane에서 기본적으로 처리해주는 것 외에 다른 작업은 다른 글에서 다루려 한다.

Fastlane 설치

Homebrew 사용

brew install fastlane
(권한이 없을 시) prefix로 sudo

Bundler 설치

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

Fastlane 기본 설정 및 적용

fastlane을 프로젝트에 적용하기

// 설치하려는 디렉토리로 이동
// 아래 init 작업 뿐만 아니라 실행 작업도 해당 디렉토리에서 해야 한다.
cd Desktop/Cookid

// fastlane을 적용
fastlane init
  1. init 후에 4번 메뉴얼(수동)로 설정 (다른 옵션으로 해도 이후에 수정 가능)
  2. 로그인 및 자동 로그인을 위한 sign in 및 apple connect를 요청 = fastlane에서 자동으로 로그인
  3. 이후 프로젝트 디렉토리에 다음 파일들이 생성
  • Gemfile / Gemfile.lock : fastlane 버전 관리 파일, 신경 X
  • fastlane 폴더 안의 Appfile / Fastfile : App 및 lane 설정 → 주로 사용

App Store 인증 : Cert, Sign 환경 변수 설정 (feat. Appfile)

  1. fastlane에서 인증하는 두 가지 방법
  • Cert, Sign 이용 : 특별히 유저가 뭔가 설정해줄 필요는 없음. 애플 계정을 입력해뒀고, 인증서를 로컬 Keychain에 넣어뒀다면 알아서 인증을 진행해주는 방식이다. 심지어 로컬에 인증서가 따로 없더라도 Cert, Sigh가 알아서 인증서와 프로필을 다운받아 진행해준다.

  • Match 이용 : 조금 더 대규모 팀일 때 사용하는 인증 방식. Match는 하나의 인증서를 github private 저장소에 넣어두고, 팀원들이 해당 저장소에 접근해서 매번 인증서를 가져와 사용하는 방식이다. Cert, Sigh이 각자의 인증서를 각자의 로컬에 저장, 인증서가 만료되는 시점도 제각각. 하지만 Match를 사용하면 중앙에 있는 인증서만 교체 → 갱신 문제X, 계정 문제X

  1. 개인 프로젝트니 Cert, Sigh 방식을 사용

    Appfile
    fastlane은 Appfile에 기입된 내용을 보고 환경을 세팅한 후 Fastfile을 참고하여 특정 기능을 수행하도록 진행한다.

  • Appfile → git 작업시 conflict 예방을 위해 'apple_id' 환경변수(ENV["APPLE_ID"])로 설정
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
  • fastlane 폴더 안에서 .env 파일 만들기 & 애플 아이디 작성
// 이 디렉토리 안에서 환경변수 설정
vim ./fastlane/.env
APP_IDENTIFIER="your.app.identifier"
APPLE_ID="my-apple-id@email.com"
...

Fastfile: Testflight에 앱 올리기

이제 명령을 직접 커스텀해서 Testflight에 올려보자. 명령은 fastlane 폴더 안에 있는 Fastfile에 작성.

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을 넣어준다.

Fastlane의 장단점

개인적인 의견을 덧붙여본다. 일단 다른 CI의 트리거 없이 fastlane만 사용해도 너무 좋을 정도다. 특히 CLI를 사용하는 것은 정말 좋은 장점 같다. (극초보일 때는 이게 왜 장점인가 했는데...) 자동화 과정이 생각보다 잘 되어있고 개인적으로 빌드 시간도 빠른 것 같다. Bitrise에서는 빌드 시간이 대략 20분가까이 걸렸는데 fastlane은 10분 내외가 걸렸다. 아쉬운 점은 로컬로 작업한다는 점이다. 물론 장단점 둘 다 될 수 있지만 Bitrise의 클라우드 플랫폼이 팀 단위에서 사용하기 더 쉬워보였다.

다음 글에서는 fastlane을 사용해서 다음 버전을 release 해보려고 한다. 일단 testflight로 보낸 앱이 심사를 마치고 외부테스터에서 테스팅을 받은 뒤에 올려보겠다.

profile
IOS Developer
post-custom-banner

0개의 댓글