iOS — 배포 자동화, Fastlane 시작부터 적용까지

Heechan
HcleeDev
Published in
13 min readJul 31, 2021

--

Photo by Sebastian Herrmann on Unsplash

예전부터 회사에서 배포 자동화에 대한 얘기를 나눴었다. iOS 앱 개발의 특성상 그냥 배포는 물론 테스트 배포마저 귀찮다. Xcode를 키고 버튼 눌러야 하는 것도 많고, 배포 전에 실수로 놓치면 안되는 부분도 많은데, 이런 점들을 최대한 간단하게 진행할 수 있는 방법이 있으면 좋겠다고 얘기하곤 했다. 원래 코딩하는데 AppCode를 사용하는지라 Xcode라도 최소한으로 쓰고 싶은 마음… 그러던 중 다른 회사에서는 Fastlane이라는 툴을 사용하고 있다는 점을 알게 되었고, 이게 배포를 조금 더 쉽게 하기 위한 프로그램이라는 점도 알게 되었다.

이번에 프로덕트에 Fastlane을 도입한 기념으로 간단히 Fastlane과 그 적용법에 대해 포스팅하기로 했다.

Fastlane 설치

나는 터미널에서 HomeBrew를 이용해 Fastlane을 컴퓨터에 설치했다.

명령어는 brew install fastlane 이다. 이 명령어 뿐만 아니라 차후 나오는 모든 명령어를 실행하는 도중 권한이 없다 같은 에러가 나오면 명령어 제일 앞에 sudo 를 붙여주면 된다.

그 후 bundler라는 프로그램을 설치해줄건데, 이 bundler는 fastlane을 업데이트할 때 사용해야 할 수 있는 프로그램이다.

이때 명령어는 gem install bundler 다. (나의 경우 컴퓨터에 gem이 이미 깔려있어서 바로 되었는데, 필요할 경우 gem도 따로 설치해줘야 한다)

그 후 fastlane의 업데이트가 필요할 경우 bundle update 만 입력해도 괜찮다.

Fastlane 기본 설정

Fastlane을 설치하고자 하는 프로젝트의 디렉토리로 넘어가주자. 그 후 fastlane을 이 프로젝트에 적용하기 위해 아래 명령어를 입력한다.

fastlane init

fastlane 초기화를 통해 이 디렉토리에서 fastlane 설정을 시작할 수 있다.

요즘 버전은 위 사진처럼 어떤 것을 설정할지 물어봐준다. 처음에는 하나 선택하면 다른건 선택 못하는줄 알고 쫄아서 4번을 눌렀는데, 상관없다. 적혀있는대로 선택한 것을 먼저 얼기설기 세팅해줄 뿐이지 나중에 알아서 추가하면 되기 때문에, 아무거나 눌러도 된다.

4번을 선택하면 fastlane 안내 문구가 몇가지 나오고, 엔터치다보면 초기 설정이 완료된다.

2번이나 3번을 누르면 다짜고짜 Apple ID를 물어볼 것이다. 아이디, 비밀번호를 치고 이중 인증의 경우에는 휴대폰으로 오는 이중인증 6자리도 입력해줘야 한다.

최초 로그인 중에 이런 문구가 나올 가능성이 있다. 처음에는 비밀번호를 치라는 말인가? 싶어서 여러번 쳐봤는데 계속 같은 문구가 나와서 당황했다. 하지만 자세히 보면 Application Specific Password를 입력하라고 되어있다.

이는 위 사진에도 나와있는 appleid.com 링크로 가서 계정에서 ‘앱 암호’를 발급받아 집어넣으면 된다.

이렇게 앱 특정 암호를 만들어서 넣어주면, 차후 애플 서버에 접근할 때도 매번 로그인하고, 비밀번호 적고, 이중인증 체크하는 귀찮은 과정을 반복하는 것이 아니라 fastlane이 알아서 앱 암호를 이용해 바로바로 로그인할 수 있다.

매번 친구가 올 때마다 아파트 1층 출입구 비밀번호랑 집 들어가는 비밀번호를 귀찮게 전화로 말해주는 것이 아니라, 친구한테 프리패스 카드를 하나 쥐어주고 알아서 왔다갔다 하라고 하는 것과 비슷하다.

아무튼 초기화 및 설정이 끝나고 나면 적어도 이 4가지 파일이 생길 것이다.

Gemfile
Gemfile.lock
fastlane/Appfile
fastlane/Fastfile

Gemfile과 Gemfile.lock은 fastlane 프로그램 자체의 버전 등을 관리하는 파일이라 크게 신경 쓸 것은 없고, fastlane 폴더 안에 있는 두 가지가 이제 내가 관리하는 앱 프로젝트, 애플 계정, 그리고 lane 설정에 대한 내용을 담고 있기 때문에 주로 자주 사용하게 될 파일이다.

이 4개 파일은 팀원들과 공유하고 있는 것이 좋아서, 만약 .gitignore 컨트롤을 하더라도 이 4개 파일은 무시하지 않는 것을 추천한다.

App Store 인증: Cert, Sigh와 환경변수 설정

iOS 앱은 배포 뿐만 아니라 개발 과정에서도 꽤나 복잡한 인증이 필요하다. 우리는 지금까지 Xcode에다가도 이 앱을 개발한다는 개발자 프로그램 인증서와 Profile을 등록했고, Appstore connect에 앱을 업로드할 때도 이런 인증 과정이 필요했다.

Fastlane을 사용하더라도 이 인증은 어떻게든 진행해야 할텐데, 어떻게 하는걸까?

크게 두 가지 방법이 있다. 하나는 Cert, Sigh를 이용하는 방법이고, 하나는 Match를 이용하는 방법이다.

Cert, Sigh는 특별히 유저가 뭔가 설정해줄 필요는 없는데, 나의 애플 계정을 제대로 입력해뒀고, 인증서를 내 로컬 Keychain에 넣어뒀다면 알아서 인증을 진행해주는 방식이다. 심지어 로컬에 인증서가 따로 없더라도 Cert, Sigh가 알아서 인증서와 프로필을 다운받아 진행해준다.

Match의 경우 조금 더 대규모 팀일 때 사용하는 인증 방식으로, 최근에 나왔다. Match는 하나의 인증서를 github private 저장소에 넣어두고, 팀원들이 해당 저장소에 접근해서 매번 인증서를 가져와 사용하는 방식이다. Cert, Sigh가 각자의 인증서를 각자의 로컬에 저장하고 있어, 인증서가 만료되는 시점도 제각각이라 모두가 조금씩 귀찮을 수 있는데, Match를 사용하면 중앙에 있는 인증서만 한번 갈아주면 되기 때문에 복잡하게 갱신 문제, 계정 문제를 고민할 필요가 없다.

아직 우리 팀은 두 명이기도 하고 Match 설정하기 귀찮기도 해서, Cert, Sigh 방식으로 하기로 했다.

일단 현재 Appfile에 들어가면 아래와 같은 내용이 들어있을 것이다.

app_identifier("자신의 앱 identifier") # The bundle identifier of your app
apple_id("자신의 애플 아이디") # Your Apple email address
# For more information about the Appfile, see:
# https://docs.fastlane.tools/advanced/#appfile

하지만 두 명이 사용하다보니 git 리모트를 통해 파일을 왔다갔다하다보면 계속 apple_id 부분에서 충돌이 날 것이다. 따라서 각자의 애플 아이디를 환경 변수로 설정해서 사용하기로 했다.

(Appfile을 .gitignore 처리하면 되지 않나 싶을 수 있는데, 그렇게 해도 되지만.. 만약 새로 팀에 합류한 멤버가 있을 시 저장소를 clone 받았을 때 받고 굳이 Appfile을 직접 작성하도록 하는 것이 더 귀찮을 것 같아서 환경변수 설정을 하기로 했다.)

우선 Appfile을 아래처럼 변경하자.

app_identifier("자신의 앱 identifier") # The bundle identifier of your app
apple_id(ENV["APPLE_ID"]) # Your Apple email address -> Please Set Env Variable in /fastlane/.env!!
# For more information about the Appfile, see:
# https://docs.fastlane.tools/advanced/#appfile

그 후 fastlane 폴더 안에 .env 파일을 만들어서 자신의 이메일을 작성해주자.

메인 디렉토리에서 만든다면 vi fastlane/.env 로 파일을 만들면 되겠다.

APPLE_ID="자신의 애플 아이디"

그리고 메인 디렉토리에서 .gitignore 파일을 열고 환경변수 파일을 추가해준다.

/fastlane/.env

이렇게 환경 변수 설정까지 마치면 리모트에서의 혼선도 생각하지 않을 수 있다.

Fastfile: Testflight에 앱을 올려보자

이제 명령을 직접 커스텀해보자. 우선 Testflight에 앱을 올리는 것부터 한번 해볼까 한다.

명령은 fastlane 폴더 안에 있는 Fastfile에 작성한다. Ruby라는 언어로 되어있긴 한데, 그래도 대부분은 그냥 Fastlane에서 제공하는 명령어만 나열해두면 되기 때문에 무리없이 진행할 수 있다.

우리 회사의 세팅을 살짝 변형해 가지고 왔다.

  • Line 2: lane 명을 beta로 지었다. 앞으로 이 lane을 사용하고 싶으면 fastlane beta 를 치면 된다.
  • Line 3, 4: Cert, Sigh 방식으로 인증할 때 사용하는 인증 함수다. get_certificates로 인증서를, get_provisioning_profile로 프로필을 가져온다. 여기서 문제가 생기면 애플 계정 로그인이 뭔가 잘못되었거나, 인증서가 안만들어져있다든가 하는 문제점이 있을 수 있으니 인증 상태가 제대로 되어있는지 확인해보자.
  • Line 5: 내 프로젝트의 빌드넘버를 올려준다. 실제 로컬 파일에 있는 정보도 변경시켜준다. Line 6의 설정은, 최근에 Testflight에 올라온 빌드보다 1을 더해서 올리도록 설정한 것이다.
  • Line 8: 앱을 빌드한다. Line 9의 설정은 어떤 Configuration으로 앱을 빌드할 것인지 체크하는건데, 우리 회사의 경우 Debug와 Release로 나뉘어있고, Testflight에는 주로 Debug 버전을 올린다. 따라서 Debug로 설정해뒀으나, 원하는 버전으로 설정해두면 된다.
  • Line 11: Testflight에 업로드해준다. 업로드하고 appstore connect 빌드 목록에 나타날 때까지 대기를 타고 있는데, 이게 꽤 오래 걸린다. 이걸 기다리고 싶지 않다면 skip_waiting_for_build_processing: true 를 옵션으로 넣어주면 된다.
  • Line 12 ~ 15: Slack 채널에 배포가 잘 되었음을 알려주는 메세지를 보내도록 했다.

이렇게 설정하고 fastlane beta 를 터미널에 입력하면 상기한 일련의 과정들을 굳이 내가 신경쓰지 않고도 자동으로 흘러가도록 할 수 있다.

만약에 에러가 나면 어떻게 할까?

나의 경우에는 에러 처리를 따로 만들어두었다.

이렇게 error 핸들러를 만들어두면, platform :ios 내에 있는 어떤 lane에서든 에러가 터질 때 slack으로 메세지를 보내도록 설정할 수 있다.

Fastfile: AppStore에 앱을 올려보자

이번에는 앱 스토어 심사까지 앱을 제출해보자.

  • Line 2, 3: 이번엔 이름이 release인데, 옵션을 붙여줬다. 개발자는 반드시 이걸 사용하기 위해 fastlane release v:1.0.0 이런 느낌으로 버전 넘버를 붙여줘야 한다. Line 3을 보면 알겠지만 v를 적어주지 않으면 일련의 명령들이 돌아가지 않도록 했다.
  • Line 10: 이번엔 Debug가 아니라 Release로 선택했다. 만약 실수로 Debug가 배포된다면… 간단한 문제로는 안끝날 것 같다.
  • Line 12 ~ 19: 이번엔 testflight가 아니라 upload_to_app_store다. Line 14, 15는 빌드를 업로드한 후 심사를 위해 제출까지 하도록 하는 옵션이다. force는 아마 굳이 우리가 한번 더 터미널에서 체크할 필요없이 바로 진행하도록 하는 것 같다. 그리고 앱 스토어 배포에서 Testflight와 다른 점은 metadata와 screenshot이다. 이 두가지는 원래 앱스토어에 배포할 때 체크하는 내용이다. 주로 전 버전 그대로 가져다 써서 고칠 일은 없다… 일단 Line 17에서는 Screenshot의 경우에는 그냥 이전 버전을 그대로 사용하기 위해 스킵했다. 하지만 metadata는 변경할 수도 있을 것 같아 일단 로컬에서 수정하고 올릴 수 있도록 Line 18에서는 스킵하지 않았다.

metadata는 fastlane deliver download_metadata , 스크린샷은 fastlane deliver download_screenshots 를 사용해 이미 앱 스토어에 올라가있는 정보를 로컬로 다운받을 수 있다.

스크린 샷이야 거의 변할 일이 없겠지만 릴리즈 노트, 이번 버전에서의 변경사항을 적어주고 싶을 수도 있다.

그럴 경우 fastlane/metadata/ko 폴더에서 release_notes.txt 파일을 열어서 변경 사항 문구를 적어주고 release 레인을 실행하면 된다. 그러면 metadata를 업로드할 때 해당 정보까지 알아서 적어서 올려줄 것이다.

확장 가능성: CI/CD

우선 Testflight와 앱 스토어에 앱을 배포하는 lane을 만들어보는데 집중했지만, Fastlane의 활용 가능성은 무궁무진하다. 일단 위에서는 언급하지 않았지만 build_number 말고 app_version 자체도 자동으로 관리하도록 설정할 수도 있고, slack 메세지에 더 많은 정보를 담을 수도 있다.

하지만 이런 식의 배포 자동화를 구축하는건 CI/CD 관점에서 이득이 많다.

Continuous Integration/Continuous Deployment는 코드의 새로운 변경사항을 지속적으로 프로덕트에 ‘통합’하고, 짧은 주기로 사용자에게 서비스할 수 있도록 지속적으로 프로덕트를 ‘배포’하는 방법을 말한다. 물론 이런 과정을 수동으로 하는게 아니라, 개발자가 크게 신경쓰지 않아도 되도록 파이프라인을 구축하는 것을 목표로 한다.

출처: CI/CD 파이프라인이란? (redhat.com)

여기서 Fastlane과 같은 배포 자동화 툴은 굉장히 중요한 역할을 하는데, 위 사진을 보면 알 수 있듯이 빌드, 테스트, 배포 과정을 모두 Fastlane이 담당할 수 있다. Fastlane 설정을 Bitrise, Jenkins 같은 툴과 함께 연결하면 새로운 테스트 과정, 배포 과정을 자동화시키고, 수 있다.

만약 테스트 코드가 있다면, 테스트도 Fastlane 명령어에 포함시킬 수 있다. run_tests 같은 명령어나, scan 을 이용하면 테스트를 진행하고 그 결과를 slack을 통해 알릴 수 있다.

또한, Fastlane과 다른 CI/CD 프로그램을 함께 사용하면 높은 수준의 CI/CD 구축을 위해 특정 이벤트가 벌어졌을 때 어떤 일련의 과정을 취하도록 설정할 수도 있을 것이다. 예를 들어 리뷰를 마친 커밋이 리모트에 올라오면, 해당 커밋에 대해 자동으로 테스트를 돌리고, 성공할 시 빌드까지 정상적으로 진행되는지 확인한다. 이런 과정을 거쳐 검증된 코드는 release할 준비가 된 걸로 평가되며, 이런 코드 커밋에 버전 태그를 붙인다든가 하는 이벤트를 통해 다시 테스트, 빌드, 그리고 실제 배포까지 자동으로 연결되도록 할 수 있다.

결론

Bitrise까지 공부해서 우리 회사에서 적용해볼 수 있는지, 적용하면 정확히 어떤 점이 좋아질지 고민해봐야 할 것 같다.

Fastlane에 워낙 많은 명령어들이 있기에, 이런 명령어도 있나? 이런 parameter도 있나? 궁금한 분들은 직접 document에 찾아가면 더 많은 정보를 얻을 수 있을 것이다.

참고 한 것

fastlane docs

CI/CD 파이프라인이란? (redhat.com)

--

--

Heechan
HcleeDev

Junior iOS Developer / Front Web Developer, major in Computer Science