[iOS] Fastlane 적용해보기
CI/CD 란?
CI/CD, 개발자라면 한 번 쯤 들어봤을 단어! 하지만 직접 겪어본적은 없다.
실제 회사에서 사용하는 수준까지는 못해보겠지만 개인 앱에 적용하면서 맛을 보려고한다.
그전에 이게 뭔지 먼저 알아보고 시작하자!
CI/CD
애플리케이션 개발 단계부터 배포까지의 모든 단계를 자동화를 통해서 좀 더 효율적이고 빠르게 사용자에게 빈번히 배포할 수 있는 것
CI (Continuous Integration, 지속적 통합)
새로운 코드 변경사항이 정기적으로 빌드 및 테스트 → 공유되는 레포지토리에 통합 → 충돌 감소
- 코드 검증에 들어가는 시간이 줄어든다.
- 개발 편의성이 증가한다.
- 테스트 코드를 통과한 코드만이 레포지토리에 통합되기 때문에 좋은 코드 퀄리티를 유지할 수 있다.
CD (Continuous Deployment, 지속적 배포)
CI 단계에서 빌드 되고 테스트 된 후에 배포 단계에서 문제가 없는지 수정할 곳이 없는지 검증한 후에 이제 배포해도 되겠다! 해서 배포 준비가 완료되면 자동화를 통하여 배포를 하는 것을 말한다.
- 배포에 들어가는 비용, 시간을 줄일 수 있다.
- 개발자가 배포보다 개발에 더욱 신경쓸 수 있도록 도와준다.
Fastlane
테스트, 배포, 프로젝트 버전 증분 및 기타 여러가지 고유한 목적을 가진 다양한 기능과 함께 제공되는 CD 도구이다. 모든 과정을 자동화 할 수 있고, 기존의 CI 서비스와도 연동 가능하다. 그래서 많은 기업에서 사용하고 있다.
기존 IPA 추출 과정
- info.plist에서 버전과 빌드 올림
- 빌드
- archive 누른 후 대기
- archive 완료 후 배포 누르고 대기
- 추가로 여러 개발자가 동시에 개발하는 경우 1년에 한번씩 certificate, provisioning profile을 발급받고 공유
Fastlane을 사용한 IPA 추출 과정
- 터미널 열기
- fastlane beta 명령어 실행
아주 간단하다. 물론 설정은 쉽지않겠지만..
이제 Fastlane을 설치하고 사용해보자!
Fastlane 사용
Fastlane 설치
brew install fastlane
Homebrew를 사용하여 설치했다.
Xcode command line tools 설치
xcode-select --install
Fastlane을 프로젝트에 적용하기
cd 프로젝트 경로
fastlane init
위 처럼 옵션을 선택하는 화면이 나온다.
- 4번 매뉴얼로 설정 (다른 옵션으로해도 이후에 수정가능)
- 안내문구가 나오고 엔터누르다보면 초기 설정 완료
- 생성된 파일 확인 (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분 걸려서 테스트 플라이트에 배포했다는 것을 알려준다!! 🎉🎉
개인 앱에 적용해봤는데 개인 앱 업데이트할 때는 테스트 플라이트가 아닌 스토어에 배포하는 것 까지 해봐야겠다.