Fastlane을 활용한 앱 배포 자동화(1) - with. Firebase App Distribution, Slack

Fastlane & Firebase App Distribution

1. Fastlane이란?

ruby 기반의 클라이언트 자동 빌드 오픈소스 라이브러리로,
Android, iOS, 크로스플랫폼 클라이언트의 배포 과정을 자동화해 주는 도구이다.

이게 Fastlane의 사전적 의미이고, 단어를 조금 쪼개보면 `fast lane`으로 추월 차선을 뜻한다. 흔히 CI/CD에서 사용하는 pipline과 유사한 점이 있는 것 같다.

고속도로에선 1차선이 추월 차선이고 추월 차선을 이용하면 빠르게 나아갈 수 있다.

이러한 관점에서 fastlane을 사용하면 더 빠르게 배포할 수 있다는 컨셉이라고 생각된다.

Fastlane 공식 홈페이지 메인 로고

산정 기준은 모르겠지만 공식 홈페이지에서도 개발자들의 아낀 시간을 카운팅 하고있다.

이 글에서는 `Fastlane``Firebase App Distribution`의 연동 과정 그리고 배포 시 `Slack` 자동 메시지 전달까지 진행한 내용을 정리해 보려고 한다.

2. Fastlane 연동

이 글에서는 macOS 환경에서 Homebrew 기준으로 작성되었다.

Homebrew가 설치 안 되어있다면 여기서 확인할 수 있다.

2-1. Ruby 설치

brew install rbenv ruby-build

우선 brew를 통해 `ruby`를 설치해 준다. (Fastlane은 ruby로 작성되기 때문에)

rbenv install -l
rbenv install 3.2.2

설치 가능한 버전 목록을 확인하여 최신 버전으로 설치한다.

# ruby path
export PATH="$HOME/.rbenv/bin:$PATH"
eval "$(rbenv init -)"

전역에서 사용할 수 있도록 `~/.zshrc` 파일에 환경 변수를 추가해 준다.

2-2. Bundler 설치

gem install bundler

ruby에서 사용하는 패키지인 Gem의 의존성관리를 위해 의존성 관리 도구인 bundler 설치

2-3. Fastlane 설치

fastlane init

Android와 iOS 프로젝트 각각의 root 경로에서 fastlane init을 진행한다.

  • `fastlane` 폴더 하위에 `Fastfile`이 생긴다.
  • 프로젝트 root엔 `Gemfile`을 확인할 수 있다. (생성 안되면 생성해야한다.)
  • `Gemfile`을 열어보면 `gem "fastlane"` 이 명시되어 있는 것을 확인할 수 있다.

3. Fastlane 설정

3-1. Pluginfile

지난 설정들을 통해 Fastlane을 사용할 준비는 완료되었고 ruby로 작성된 `fastfile`을 작성해 주면 된다.

gem 'fastlane-plugin-firebase_app_distribution'

fastlane init 하면서 fastlane 폴더 하위에 Pluginfile이 자동 생성되었을 텐데 여기에 Firebase App Distribution 연동을 위해 플러그인을 추가해 준다.

3-2. Fastfile (Android)

default_platform(:android)

platform :android do
    desc "Deploy STG to Firebase App Distribution"
        lane :stg do |options|
          begin
            UI.message("🚀 Android STG 배포 시작...")

            gradle(
                task: "assembleStg",
                build_type: "Release",
            )
            UI.message("✅ (1/2)Gradle 빌드 완료!")

            firebase_app_distribution(
                app: "{firebase_app_id}",
                groups: "{tester_groups}",
                release_notes: release_notes
            )
            UI.message("✅ (2/2)Firebase 배포 완료!")
          rescue => error
            UI.error("❌ Android STG 배포 실패: #{error.message}")
            raise
        end
    end
 end

크게 2단계로 진행된다.

  1. 앱 빌드
  2. firebase에 앱 업로드

여기서 확인할 포인트는

firebase_app_distribution → app
firebase_app_distribution → groups
firebase_app_distribution → release_notes가 표시된다.
  • `lane :stg do`
    • Task 이름에 해당하는 부분이다.
    • 이렇게 작성된 경우엔 프로젝트 경로에서 `fastlane stg` 커맨드를 보내면 해당 Task가 실행된다.
  • `gradle(task: "", build_type:"")`
    • 빌드할 task와 build_type을 필요에 맞게 입력하면 그에 맞게 앱이 빌드된다.
  • `firebase_app_distribution(app: {}, groups: {}, release_notes: "")`
    • 3-1에서 추가했던 Firebase App Distribution 플러그인이다.
    • `app` Firebase 콘솔에서 해당 id를 확인하여 기입한다. (위 사진 참고)
    • `groups` 대상 테스터 그룹을 작성한다.
    • `release_notes` 출시 메시지를 포함하면 된다.

3-3. Fastfile (iOS)

default_platform(:ios)

platform :ios do
  desc "Deploy STG to Firebase App Distribution"
  lane :stg do |options|
    begin
      UI.message("🚀 iOS STG 배포 시작...")

      sync_code_signing(
        type: "adhoc",
        app_identifier: {bundle_id},
        readonly: true
      )

      build_app(
        scheme: {app_scheme},
        export_method: "ad-hoc"
      )
      UI.message("✅ (1/2)앱 빌드 완료!")

      firebase_app_distribution(
        app: "{firebase_app_id}",
        groups: "{tester_groups}",
        release_notes: release_notes
      )
      UI.message("✅ (2/2)Firebase 배포 완료!")
    rescue => error
      UI.error("❌ iOS STG 배포 실패: #{error.message}")
      raise
    end
  end
end

안드로이드와 마찬가지로 크게 2가지 단계를 거치는데, 여기선 Code Signing 과정까지 포함되어 있다.

여기선 인증서 관리를 위해 `Fastlane match`가 사용되었는데 관련 내용은 여기에서 확인 가능하다.

  1. 앱 사이닝
  2. 앱 빌드
  3. firebase에 앱 업로드

안드로이드와 중복되는 항목은 제외하고 iOS에 있는 설정을 보면,

  • `sync_code_signing`
    • 위에서 언급한대로 `Fastlane match`를 통해 코드 사이닝을 자동화하였다.
    • `type` 배포할 타입이다. 여기선 QA를 위한 배포 앱이므로 adhoc 배포가 적용되었다.
    • `app_identifier` 앱 번들아이디
  • `build_app`
    • 앱을 빌드하는 과정인데 대상 `scheme`을 지정해주면 된다.

4. 슬랙으로 메시지 자동화

def send_slack(message:, note:)
  slack(
    message: message,
    success: true,
    slack_url: {WEBHOOK_URL},
    payload: {
        "Release note": note,
    },
    default_payloads: ["git_branch", "git_author", "last_git_commit"]
  )
end

Fastlane에서 `slack(payload)` 메서드를 제공하기 때문에 별도의 설정 과정 없이 쉽게 구현 가능하다.

다만 `slack_url`에는 슬랙 웹훅 URL 이 필요하다. 이 과정은 되어있다고 가정하여 생략하였다.

위 3번 과정에서 진행한 앱 빌드, 업로드 과정이 모두 끝난 뒤 해당 method를 호출해 주면 된다.

메시지는 커스텀 가능하므로 `payload`와 `default_payloads`를 조정해 주면 된다.

자동화 된 slack 메시지

5. 자동 배포 실행하기

fastlane stg

이제 명령어 한 줄로 빌드, 배포, 알림까지 손쉽게 배포할 수 있게 되었다.

차니님의 😊
글이 좋았다면 응원을 보내주세요!