Flutter Fastlane 으로 CICD 구축 [iOS]

석상우·2022년 11월 2일
1
post-thumbnail

Overview

QA 기간만 되면 일주일에 열 두번 씩 수동배포 하는 대참사를 해결하기 위해 Fastlane을 공부해봤습니다.
이 글은 Fastlane 을 이용하여 Firebase Distribution, AppStore 에 자동배포 하는 과정을 기술한 글입니다.


1. Fastlane 설치

brew install fastlane
or
sudo gem install fastlane

homebrewRubyGem 을 통해 Fastlane 을 설치할 수 있습니다. 공식문서 에 따르면, Gem 은 Ruby 환경에 의존하기 때문에 brew 로 설치하는 것을 추천한다고 합니다.!


2. Fastlane init

cd ios/
fastlane init


Init 명령어를 입력하면 Setup 종류를 물어보는 콘솔창이 나옵니다. 저는 Manual Setup을 할 것이기에 4번을 눌렀습니다.
저만 그런건진 모르겠는데, 저는 Fastlane Init 할 때마다 저기 맨 밑에 $ bundle update 에서 멈추더라고요... 그래서 Ctrl + C 눌러서 종료하고 다시 init 하면, 이미 설치되어있다고 합니다.


3. Fastlane Match 설정

Fastlane Match 란, Fastlane 안에 있는 코드 사이닝 방법의 한 종류입니다. 간략히 말하자면, 인증서와 프로파일을 하나의 원격 저장소에 업로드 하고, 팀원들이 해당 인증서와 프로파일을 공유하여 코드 사이닝을 단순화 하는 방법입니다.

Provisioning Profile 에는 앱 ID, 앱 실행이 허용된 Device ID, 애플에서 발급한 인증서 가 포함되어 있으며, 각 개발자의 환경이 다르기 때문에 서로 다른 Profile 이 생성됩니다. 따라서 Match 를 통해 인증서와 프로파일을 공유하면, 코드 사이닝 관리 측면에서 유용하게 사용될 수 있습니다.

3-1. Private 원격 저장소 생성

인증서와 프로파일을 저장 할 원격 저장소를 생성해줍니다. 저는 Bitbucket 을 사용하기 때문에 Repository 를 Bitbucket 에서 생성하였습니다.

3-2. Fastlane Match Init

match init 명령어를 입력하면 Storage mode 로 git 을 선택하고, git 주소를 입력한다. 설정이 다 끝나면 Fastlane 폴더에 MatchFile이 생성됩니다.

3-3. MatchFile 수정

MatchFile 에서 Default Type 을 appstore 로 변경해줍시다.

3-4. 기존의 개발, 배포 인증서 파기

fastlane match nuke development
fastlane match nuke distribution

인증서 파기 명령어를 입력하면, passphase 를 등록하는 화면이 나올 수 있습니다.

3-5. 새로운 개발, 배포 인증서 생성

fastlane match development
fastlane match appstore
팀원들이 공유 할 인증서를 생성합니다. 두 명령어를 모두 입력하면, Matchfile 에 등록된 원격 저장소에 인증서와 프로파일이 올라가게 됩니다.

3-6. Xcode Code Signing 확인

Xcode에 들어가 Provisioning Profile 을 match [...] packageName 으로 변경해줍니다.

4. Fastlane Firebase Distribution 설정

Fastlane 을 이용하여 Firebase App Distribution 에 배포하려면 플러그인 설치, 인증 등을 해야 합니다.

4-1. Firebase Plugin 설치

fastlane add_plugin firebase_app_distribution

Firebase 플러그인을 설치할 때 Your user account isn't allowed... 라는 메세지가 나오면서 Password 를 입력하라고 할 수도 있는데, 그냥 Mac password 입력하고 넘어가도록 합시다.

4-2. Firebase 로그인

fastlane run firebase_app_distribution_login

CLI로 Firebase 에 로그인 하는 과정입니다. 커맨드 입력 시 접속할 수 있는 링크 URL 이 터미널에 보일텐데, 접속해서 Firebase 인증 해주시면 Refresh Token 이 날아옵니다. 해당 토큰은 잘 보관해주세요.


5. 환경변수[ENV] 설정

각 개발자 마다 AppleID, Firebase Refresh Token 등이 환경에 따라 달라질 수 있는데, Fastlane 에서는 .env 파일로 환경변수를 관리하여 서로 다른 환경에서도 동일한 Lane 을 사용할 수 있습니다.

# Appfile
app_identifier("com.blueant.ollacare")
apple_id(ENV["APPLE_ID"])

# .env
APPLE_ID="..."

Fastlane 폴더 안의 Appfile 입니다. app_identifier 는 어느 환경에서나 동일하지만, apple_id 는 개발자 마다 다르기 때문에 환경변수로 치환합니다.



6. Firebase Distribution Lane 생성

Firebase 설정이 끝났으니, 이제 Firebase App Distribution 에 Upload 하는 Lane 을 생성해보겠습니다.

# Firebase Distribution
desc "Push a new beta build with Firebase App Distribution"
lane :firebase do
  match(type:"adhoc")

  increment_build_number(
      build_number: latest_testflight_build_number + 1
  )

  build_app(
    workspace: "Runner.xcworkspace", 
    scheme: "Runner",
  )

  firebase_app_distribution(
    app: ENV["IOS_FIREBASE_APP_DISTRIBUTION_APP"],
    groups: "test",
    release_notes: "안녕난상우야"
  )
end

별다른 설정 없이 간단하게 Firebase App Distribution 에만 올라가도록 lane 을 생성했습니다. lane에 대해서는 따로 공부 후 다른 글에 작성 할 생각입니다.
Action 에 대한 자세한 설명은 공식문서 에 있으니 참조해주시면 될 것 같습니다.

정상적으로 Firebase에 업로드 됐네요!! :)



7. TestFlight Ditribution Lane 생성

이제 마지막으로, TestFlight 에 배포해봅시다!

# TestFlight
desc "build app and upload to testflight"
lane :beta do
  match(type: "appstore")
  increment_version_number(
    version_number: "2.5.1"
  )

  increment_build_number(
      build_number: latest_testflight_build_number + 1
  )
  build_app(
    configuration: "Release"
  )
  upload_to_testflight
end

저는 특정 version_number 를 사용할 것이기에 임의로 상수값을 넣어줬습니다. Lane 에 들어가는 설정값 및 함수들은 아직 깊게 공부를 안했기에 배포가 가능하도록만 설정을 채워넣었습니다. 아마 다음 CICD 포스트에는 Fastlane Action 에 대해 작성해보지 않을까 싶네요 :)



8. 진행하며 생긴 오류


8-1. Firebase lane 실행 중 Missing authentication credentials...

Firebase Lane 을 실행하던 도중 위와 같은 에러메세지가 발생했습니다. IPA 생성까지 마친 후, Firebase 접속 쪽에서 문제가 생긴걸로 봐서 Token 문제인 것 같았습니다. 4-2. Firebase 로그인 과 동일하게 Firebase 로그인 명령어를 통해 Refresh Token 을 재 발급 받으시고, 재 발급 받으신 Token을 환경변수 FIREBASE_TOKEN 에 넣어주면 해결됩니다.

profile
Mobile App Developer

0개의 댓글