iOS/iOS

[iOS] Fastlane 적용해보기

HarryJeonn 2023. 1. 31. 20:26

CI/CD 란?

CI/CD, 개발자라면 한 번 쯤 들어봤을 단어! 하지만 직접 겪어본적은 없다.

실제 회사에서 사용하는 수준까지는 못해보겠지만 개인 앱에 적용하면서 맛을 보려고한다.

그전에 이게 뭔지 먼저 알아보고 시작하자!

CI/CD

애플리케이션 개발 단계부터 배포까지의 모든 단계를 자동화를 통해서 좀 더 효율적이고 빠르게 사용자에게 빈번히 배포할 수 있는 것

CI (Continuous Integration, 지속적 통합)

새로운 코드 변경사항이 정기적으로 빌드 및 테스트 → 공유되는 레포지토리에 통합 → 충돌 감소

  • 코드 검증에 들어가는 시간이 줄어든다.
  • 개발 편의성이 증가한다.
  • 테스트 코드를 통과한 코드만이 레포지토리에 통합되기 때문에 좋은 코드 퀄리티를 유지할 수 있다.

CD (Continuous Deployment, 지속적 배포)

CI 단계에서 빌드 되고 테스트 된 후에 배포 단계에서 문제가 없는지 수정할 곳이 없는지 검증한 후에 이제 배포해도 되겠다! 해서 배포 준비가 완료되면 자동화를 통하여 배포를 하는 것을 말한다.

  • 배포에 들어가는 비용, 시간을 줄일 수 있다.
  • 개발자가 배포보다 개발에 더욱 신경쓸 수 있도록 도와준다.

Fastlane

테스트, 배포, 프로젝트 버전 증분 및 기타 여러가지 고유한 목적을 가진 다양한 기능과 함께 제공되는 CD 도구이다. 모든 과정을 자동화 할 수 있고, 기존의 CI 서비스와도 연동 가능하다. 그래서 많은 기업에서 사용하고 있다.

기존 IPA 추출 과정

  1. info.plist에서 버전과 빌드 올림
  2. 빌드
  3. archive 누른 후 대기
  4. archive 완료 후 배포 누르고 대기
  • 추가로 여러 개발자가 동시에 개발하는 경우 1년에 한번씩 certificate, provisioning profile을 발급받고 공유

Fastlane을 사용한 IPA 추출 과정

  1. 터미널 열기
  2. fastlane beta 명령어 실행

아주 간단하다. 물론 설정은 쉽지않겠지만..

이제 Fastlane을 설치하고 사용해보자!

Fastlane 사용

Fastlane 설치

brew install fastlane

Homebrew를 사용하여 설치했다.

Xcode command line tools 설치

xcode-select --install

Fastlane을 프로젝트에 적용하기

cd 프로젝트 경로

fastlane init

위 처럼 옵션을 선택하는 화면이 나온다.

  1. 4번 매뉴얼로 설정 (다른 옵션으로해도 이후에 수정가능)
  2. 안내문구가 나오고 엔터누르다보면 초기 설정 완료
  3. 생성된 파일 확인 (Gemfile, Gemfile.lock, fastlane 폴더)

Gemfile/Gemfile.lock 파일은 fastlane의 버전관리를 위한 파일이다.

fastlane 폴더 안에 Appfile, Fastfile을 설정하면서 주로 사용한다.

// Appfile

app_identifier("앱 번들 아이디") # The bundle identifier of your app
apple_id("애플 아이디") # Your Apple Developer Portal username

# For more information about the Appfile, see:
#     <https://docs.fastlane.tools/advanced/#appfile>

위와 같이 변경해주자.

apple_id에는 협업을 할 경우 환경변수로 따로 만들어서 협업 시 충돌이 안나게 하는 방법이 있다.

하지만 나는 혼자 하기 때문에 방법만 슬쩍 보고 그냥 아이디 넣어놨다.

// Fastfile

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(
	    scheme: "Bogota"
    )
    pilot(
      api_key_path: "fastlane/APIKey.json",
      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 이다. 하지만 위처럼 미리 플랫폼을 설정해두면 fastlane beta로 사용 가능하다.

lane :beta do
 ...
end

작업을 수행하는 각 메소드들로 구성되어있다. 이 메소드를 순차적으로 실행하며 작업을 진행한다.

cocoapods(use_bundle_exec: false)

코코아팟을 설치하는 pod install 작업이다. 옵션으로는use_bundle_exec: false 을 사용했는데 gem의 버전이 다를 때도 올바르게 작동할 수 있게 하는 옵션이다.

increment_build_number(
  build_number: latest_testflight_build_number + 1
)

빌드 번호를 올린다. 새로운 빌드를 할 때마다 최신 빌드의 숫자를 가져와서 +1 해준다.

build_app(
	    scheme: "Bogota"
    )

빌드할 스킴을 설정해줬다.

// error

Unable to upload archive. Failed to get authorization for username '~' and password.

위 에러가 나와서 1시간은 넘게 삽질한 것 같다.

기존에 사용하려고 했던 테스트플라이트에 올리는 코드 대신 다른 코드를 넣어줬다.

// 기존 사용 코드
upload_to_testflight(
  skip_waiting_for_build_processing: true
)

// API key를 사용했을 때 코드
pilot(
  api_key_path: "fastlane/APIKey.json",
  skip_waiting_for_build_processing: true
)

이렇게 사용하는것이 맞는지는 모르겠지만 테스트 결과 테스트 플라이트에 잘 올라간다.

물론 슬랙 채널에도 알람이 잘 온다!

slack(
  message: "Testflight 배포에 성공했습니다!",
  slack_url: "<https://hooks.slack.com/services/토큰>"
)

error do |lane, exception, options|
    slack(
      message: "에러 발생 : #{exception}",
      success: false,
      slack_url: "<https://hooks.slack.com/services/토큰>",
    )
end

slack으로 결과를 보내주는 메소드다.

배포에 성공했을 때, 에러를 감지 했을 때 보내준다.

13분 걸려서 테스트 플라이트에 배포했다는 것을 알려준다!! 🎉🎉

 

개인 앱에 적용해봤는데 개인 앱 업데이트할 때는 테스트 플라이트가 아닌 스토어에 배포하는 것 까지 해봐야겠다.