Github Actions + fastlane으로 iOS앱 배포 자동화하기

Munok Kim
7 min readApr 20, 2021

--

무료에 기능도 강력한 두 개의 툴, Github Actions와 fastlane으로 CI/CD를 구축해봅니다

Photo by Alex Knight on Unsplash

워크플로(파이프라인) 순서

  1. 로컬에서 버전/빌드 번호를 변경하고 태그를 푸시하는 lane을 실행‍ 🚘
  2. 앱 버전 태그가 푸시되면 워크플로의 이벤트 실행 🏷
  3. git 코드 체크아웃 ✅
  4. ️SSH key, ruby, fastlane 등의 설치 ‍⚙️
  5. keychain 초기화 🔑
  6. match를 실행하여 인증서 및 프로파일 불러오기 ✍🏼
  7. 빌드 및 내보내기 🏗
  8. 앱스토어 업로드 🎉
  9. 배포 결과 슬랙 노티 🚨

로컬에서 버전/빌드 번호를 변경하고 태그를 푸시하는 lane을 실행‍ 🚘

개발자가 다음과 같이 명령어를 입력하여 set_version lane을 실행합니다.

  • $ fastlane set_version version:2.3.0
  • $ fastlane set_version version:major
  • $ fastlane set_version version:minor
  • $ fastlane set_version version:patch

set_version lane에서 실행하는 액션들은 모두 fastlane 공식문서에서 확인할 수 있습니다. 액션의 이름이나 파라미터의 이름을 검색해보세요.

프로젝트 레포의 “Actions” 탭으로 가서 “new workflow” 를 누르고 appstore.yml 파일을 만들어 봅시다.

1번 순서를 개발자가 실행하면 이 워크플로의 이벤트가 발동되어 지정된 jobs와 steps을 진행합니다. 그 결과로 앱이 앱스토어커넥트에 배포됩니다. 이 워크플로 파일의 내용이 2번 부터 4번 순서 까지에 해당됩니다. 워크플로 파일의 작성요령은 Github Actions 공식문서에 매우 자세히 나와 있습니다.

앱 버전 태그가 푸시되면 워크플로의 이벤트 실행 🏷

on:  
push:
tags:
- "v*"

버전 태그 — 예) “v3.6.0(2021.0417.1453)” — 가 푸시되어 이벤트가 트리거되고 자동 배포가 이어집니다.

git 코드 체크아웃 ✅

- uses: actions/checkout@v2

Github Actions 맥 가상환경에 프로젝트 저장소 코드를 checkout합니다.

SSH key, ruby, fastlane 등의 설치 ‍⚙️

- uses: shimataro/ssh-key-action@v2
with:
key: ${{ secrets.SSH_KEY }}
known_hosts: ${{ secrets.KNOWN_HOSTS }}
- uses: actions/setup-node@v2
with:
node-version: ${{ matrix.node }}
- uses: actions/setup-ruby@v1
with:
ruby-version: §{{ matrix.ruby }}
- run: brew install fastlane
- run: pod install

로컬 맥 디바이스에서 fastlane을 실행하기 위해서 그러하듯이 ruby와 fastlane을 설치합니다. 그리고 정상적인 빌드를 위해 pod을 설치합니다. 그리고 코드사이닝을 위해 fastlane의 match를 이용하려면 SSH key — 로그인 없이 자동으로 레포에 접속 하기 위한 공개&비공개 키 — 를 설치해줘야 합니다. SSH key를 왜 설치해야 하는지 알기 위해서는 먼저 match가 무슨 역할을 하는 것 인지 알아야 합니다.

match란?

fastlane의 match는 개발 팀 전체에서 하나의 코드사이닝 용 애플계정을 공유하여 코드사이닝 설정을 단순화하고 문제를 방지합니다. CI/CD를 구축할 때, iOS 프로젝트의 코드사이닝을 하는 방법은 여러가지가 있습니다. 인증서와 프로비저닝 프로파일을 암호화하여 프로젝트 디렉토리에 포함하고 가상환경에서 복호화하여 수동으로 엑스코드에 프로파일을 설치, 구성 하는 방법도 있습니다만. 무척이나 귀찮은 방법이고 인증서가 만료되거나 한다면 관리하는 것도 문제입니다. 그래서 제가 선택한 방법은 fastlane의 match 액션을 이용하는 것입니다.

fatlane의 match를 사용하려면 팀의 공동 애플계정을 만들어야 하는데, match가 이 계정을 이용하여 인증서와 프로파일을 코드사이닝 용 레포에 자동으로 암호화하여 생성하고 관리해 줍니다. 개발자 각자에게 흩어져있는 인증서와 프로파일을 더 이상 중구난방하게 관리할 필요가 없습니다. 또한 새로운 개발자가 팀에 합류 하였을 때나 새 맥 로컬 장비, 또는 CI 가상환경에 인증서와 프로비저닝 프로파일을 설치, 구성하기가 매우 쉽습니다. match를 한 번 실행 하기만 하면 됩니다.

일반적인 CI의 가상 macOS 환경에서 match로 코드사이닝을 하려면 SSH key를 만들고 public SSH key를 match 레포의 배포 키로 추가해서 CI가 match 레포에 접근할 수 있도록 하면 됩니다. 그런데 레포의 호스트가 Github인 경우는 동일한 배포 키 만으로는 CI가 또 다른 레포에 접근할 수가 없습니다.

그래서 Github Action의 사용자 제작 action인 shimataro/ssh-key-action을 사용하여 충분한 액세스 권한이 있는 private SSH key를 가상환경에 설치합니다. 이렇게 하면 Github Action이 match 레포에 access가 가능해지므로 match 레포를 클론하고 코드사이닝을 진행할 수 있습니다.

이렇게 코드사이닝과 빌드를 하기 위한 준비가 끝났습니다. Project repo > Settings > secrets에 미리 추가해놓은 환경변수를 env에 넣고 release lane을 실행합니다.

- run: fastlane release
env:
MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
KEYCHAIN_NAME: ${{ secrets.KEYCHAIN_NAME }}
KEYCHAIN_PASSWORD: ${{ secrets.KEYCHAIN_PASSWORD }}
APP_STORE_CONNECT_API_KEY_ID: ${{ secrets.APP_STORE_CONNECT_API_KEY_ID }}
APP_STORE_CONNECT_API_ISSUER_ID: ${{ secrets.APP_STORE_CONNECT_API_ISSUER_ID }}
APP_STORE_CONNECT_API_KEY_CONTENT: ${{ secrets.APP_STORE_CONNECT_API_KEY_CONTENT }}

release lane에서는 5번 부터 마지막 9번 순서까지 진행됩니다.

app_store_connect_api_key 로 2단계 인증을 대신 할 수 있습니다. 이것은 앱스토어커넥트 웹사이트에서 팀의 소유자 만이 얻을 수 있는 api key에 대한 보안 정보입니다. matchdeliver를 실행할 때 이 api key 정보가 제공되어 2단계 인증을 건너뛰게 되므로 워크플로의 진행을 멈추지 않게 됩니다.

마무리

워크플로 성공! 🙌🏼
슬랙 알림 확인! 🎉

무료에 기능도 강력한 두 개의 툴, Github Actions과 fastlane을 모두 사용하여 CI/CD를 구축해 보니 강한 시너지 효과가 나는 것을 느낄 수 있었습니다. 이와 같은 방식으로 QA팀이나 테스터에게 반복적으로 테스트플라이트를 배포하는 일도 자동화 할 수 있습니다. PR이 열리면 테스트를 실행해서 결과를 받아 볼 수도 있을 것입니다. 아직은 여기까지만 생각해봤지만 앞으로 더 무궁무진한 활용 기회를 찾게 되지 않을까 합니다.

--

--

Munok Kim

앱 깎는 장인이 되고 싶은 iOS 개발자입니다