TL;DR
Fastlane은 iOS와 Android 앱의 빌드, 테스트, 배포 과정을 자동화하는 오픈소스 도구입니다.
Ruby 기반으로 작동하며 간단한 문법으로 복잡한 작업 흐름을 정의할 수 있습니다.
테스트, 빌드, 배포의 과정을 수동으로 진행한다고 하면 할 수는 있지만, 만약 여러 번의 테스트 그리고 배포가 이뤄지는 프로젝트 및 작업 환경이라면 한번의 자동화 처리를 해두면 매우 수월하게 일을 진행하실 수 있으실 겁니다.
저도 CI/CD를 적용하지 않고 앱을 관리해본 적이 있는데 정말 .... 삽질과 노가다의 향연입니다. (나와의 싸움이 시작..)
그렇기에 이렇게 편리하게 모든 걸 자동화해주는 프레임워크가 있다면 바로바로 배워야겠죠.
친해지러 가봅시다.
목차
- Fastlane 소개
- Fastlane 작동 원리
- 기본 문법
- 사용 예제
- 테스트 자동화
- 배포 자동화
- 결론
1. Fastlane 소개
모바일 앱 개발자라면 누구나 알고 있는 골치 아픈 작업들이 있습니다.
앱 빌드하기, 스크린샷 생성, 코드 서명, 프로비저닝 프로파일 관리, 테스트플라이트나 구글 플레이에 업로드하기 등.
이러한 반복적이고 시간 소모적인 작업들은 개발자의 생산성을 떨어뜨리고 실수의 가능성을 높입니다.
Fastlane은 이러한 문제를 해결하기 위해 만들어진 오픈소스 자동화 도구입니다.
Felix Krause가 개발한 이 도구는 현재 모바일 개발 워크플로우의 표준이 되었으며, 지속적 통합(CI) 및 지속적 배포(CD) 파이프라인의 핵심 구성 요소로 자리 잡았습니다.
2. Fastlane 작동 원리
Fastlane은 Ruby 기반의 프레임워크로, 모바일 앱 개발 및 배포 과정의 다양한 단계를 자동화합니다.
Fastlane의 작동 원리를 이해하기 위해서는 몇 가지 핵심 개념을 알아야 합니다.
1. 핵심 구성 요소
(1) Actions : Fastlane의 기본 빌딩 블록으로, 특정 작업을 수행하는 단일 기능입니다.
- iOS actions (https://docs.fastlane.tools/actions/ 참조)
용도 | 액션 | 기능 |
빌드 | build_app (gym) | iOS 앱을 빌드하여 ipa 파일 생성 |
increment_build_number | 빌드 번호 자동 증가 | |
cocoapods | CocoaPods 의존성 설치 | |
배포 | upload_to_testflight | TestFlight에 앱 업로드 |
upload_to_app_store | App Store에 앱 업로드 및 제출 | |
match | 코드 서명 인증서와 프로비저닝 프로파일 관리 | |
테스트 | run_tests | XCTest 자동 실행 |
scan | Xcode 테스트 실행 및 보고서 생성 | |
snapshot | UI 테스트를 통한 스크린샷 자동 생성 |
- Android Actions (https://docs.fastlane.tools/actions/ 참조)
용도 | 액션 | 기능 |
빌드 | gradle | Android 앱 빌드 및 그래들 작업 실행 |
android_app_bundle | Android 앱 번들(AAB) 생성 | |
increment_version_code | 버전 코드 자동 증가 | |
배포 | upload_to_play_store | Google Play Store에 앱 업로드 |
supply | Google Play 콘솔에 메타데이터 업로드 | |
google_play_track_version_codes | 특정 트랙의 버전 코드 조회 | |
테스트 | gradle | Gradle 테스트 작업 실행 |
screengrab | 다양한 기기에서 스크린샷 자동 생성 | |
firebase_app_distribution | Firebase App Distribution에 배포 |
(2) Lanes: 특정 목적(예: 베타 배포, 앱스토어 출시)을 위한 작업 흐름을 정의합니다.
- Lane basic
기본 정의 | 여러 액션을 순차적으로 실행하는 작업 흐름 |
선언 방법 | lane :lane_name do ... end |
플랫폼 지정 | platform :ios do ... end platform :android do ... end |
설명 추가 | desc "설명" |
- Lane advanced
파라미터 | lane :name do |options| | 레인 호출 시 파라미터 전달 (터미널에 명령어 입력 시) |
레인 호출 | other_lane | 다른 레인 호출 |
반환 값 | (마지막 표현식) | 레인의 마지막 표현식이 반환 값이 됨 |
조건부 실행 | next if condition | 조건에 따라 레인 실행 중단 |
프라이빗 레인 | private_lane :name do | 직접 호출 불가능한 레인 |
- Lane special (용도)
before_all | 모든 레인 실행 전에 실행 |
after_all | 모든 레인 실행 후에 실행 (성공 시) |
error | 어떤 레인에서든 오류 발생 시 실행 |
- 참조 : https://docs.fastlane.tools/advanced/lanes/
(3) Plugins: 기본 Fastlane에 추가적인 기능을 제공하는 확장 프로그램입니다.
플러그인 | 용도 |
firebase_app_distribution | Firebase를 통한 테스트 앱 배포 |
versioning | iOS/Android 앱 버전 번호 관리 |
appicon | 앱 아이콘 자동 생성 및 리사이징 |
changelog | 변경 로그 자동 생성 및 관리 |
increment_version_code | Android 버전 코드 자동 증가 |
increment_version_name | Android 버전 이름 자동 증가 |
badge | 앱 아이콘에 뱃지 자동 추가 |
trainer | Xcode 테스트 결과를 JUnit 보고서로 변환 |
appcenter | Microsoft AppCenter에 앱 배포 |
aws_s3 | AWS S3에 앱 및 관련 파일 업로드 |
- 참조 : https://docs.fastlane.tools/plugins/available-plugins/
2. 환경 변수 및 상태 관리
Fastlane의 환경 변수 시스템은 "연결된 파이프라인" 개념으로 생각하면 이해하기 쉽습니다.
각 액션은 실행 후 특정 데이터를 lane_context 라는 공유 저장소에 저장하고, 다음 액션은 이 저장소에서 필요한 데이터를 자동으로 가져옵니다.
예를 들어 아래의 lane 코드를 보겠습니다.
lane :deploy do
# build_app은 IPA_OUTPUT_PATH를 lane_context에 저장
build_app
# upload_to_testflight는 자동으로 lane_context에서 IPA_OUTPUT_PATH를 읽음
upload_to_testflight
end
보통 배포를 위해서는 1. 앱을 빌드 / 2. 앱을 배포의 과정을 가집니다. 이 과정에서 앱을 빌드하면 나오는 결과물을 어딘가에 저장하고, 그 path(환경변수)를 불러와 app store connect 혹은 google play console로 보냅니다.
이렇게 중간 과정에서 환경 변수 및 상태 관리를 자동으로 해준다고 생각하면 될 것 같습니다.
3. 설정 파일
Fastlane 프로젝트는 주로 두 개의 설정 파일로 구성됩니다:
- Appfile: 앱 식별자, Apple 개발자 계정 정보 등 글로벌 구성 정보를 저장합니다.
- Fastfile: 레인과 액션을 정의하는 주요 파일입니다. 개발, 테스트, 배포 워크플로우가 여기에 정의됩니다.
이 파일들은 프로젝트의 소스 코드에 커밋되어 모든 개발자가 동일한 빌드 및 배포 단계를 실행할 수 있도록 합니다.
물론 협업을 위해 개발자들의 인증서도 묶어서 소스코드에 커밋하기 위해선 match 인증서를 작성해야합니다. (이는 내용이 너무 많아 생략)
3. 기본 문법
Fastlane의 문법은 Ruby를 기반으로 하지만, 모바일 개발에 특화된 DSL(Domain Specific Language)을 사용합니다. 기본적인 문법 요소를 살펴보겠습니다.
(1) Fastfile 기본 구조
Fastfile은 다음과 같은 기본 구조를 가집니다:
default_platform(:ios)
platform :ios do
desc "Description of what the lane does"
lane :lane_name do
# Actions go here
end
end
- default_platform: 기본 플랫폼을 설정합니다(ios 또는 android).
- platform 블록: 플랫폼별 레인을 그룹화합니다.
- desc: 레인에 대한 설명을 제공합니다.
- lane: 작업 흐름을 정의하는 레인을 생성합니다.
(2) 액션 호출
액션은 다음과 같이 호출됩니다:
# 기본 액션 호출
lane :basic_example do
# 매개변수 없는 액션 호출
clean_build_artifacts // 이전 빌드 과정에서 나온 임시 파일들을 정리하는 액션
# 매개변수가 있는 액션 호출
build_app(
scheme: "MyApp",
workspace: "MyApp.xcworkspace",
clean: true
)
# 환경 변수 공유 예시
# 1. build_app이 IPA_OUTPUT_PATH 환경 변수 설정
# 2. upload_to_testflight가 자동으로 해당 경로 사용
upload_to_testflight(
username: "user@example.com"
)
# 액션 결과값 직접 사용
version = get_version_number(
xcodeproj: "MyApp.xcodeproj"
)
puts "현재 앱 버전: #{version}"
# 조건부 액션 호출
if is_ci?
sh("echo '이 작업은 CI 환경에서 실행 중입니다'")
end
end
(3) 파라미터 전달
레인에 파라미터를 전달할 수 있습니다:
lane :build do |options|
build_config = options[:release] ? "Release" : "Debug"
build_app(configuration: build_config)
end
이 레인은 다음과 같이 호출할 수 있습니다:
fastlane build release:true
(4) 다른 레인 호출
레인 내에서 다른 레인을 호출할 수 있습니다:
lane :release do
build
upload_to_app_store
end
lane :build do
build_app(scheme: "MyApp")
end
(5) 조건문 및 에러 처리
일반적인 Ruby 조건문과 에러 처리를 사용할 수 있습니다:
lane :deploy do
if is_ci?
# CI 환경에서만 실행되는 코드
else
# 로컬 환경에서만 실행되는 코드
end
begin
upload_to_app_store
rescue => ex
puts "업로드 실패: #{ex}"
end
end
(6) 환경별 구성
환경별로 다른 구성을 사용할 수 있습니다:
lane :deploy do
app_id = ENV["APP_IDENTIFIER"]
api_key = ENV["API_KEY"]
# 환경 변수를 사용한 액션 실행
end
4. 사용 예제
Fastlane을 실제로 어떻게 활용할 수 있는지 두 가지 주요 사례를 살펴보겠습니다.
테스트 자동화
테스트 자동화는 Fastlane의 가장 기본적인 사용 사례 중 하나입니다.
다음은 iOS 앱의 단위 테스트 및 UI 테스트를 자동화하는 예제입니다:
desc "Run all the tests"
lane :test do
# 단위 테스트 실행
run_tests(
scheme: "MyAppTests",
devices: ["iPhone 13"]
)
# UI 테스트 실행
run_tests(
scheme: "MyAppUITests",
devices: ["iPhone 13", "iPad Pro (12.9-inch)"]
)
# 코드 커버리지 보고서 생성
xcov(
scheme: "MyApp",
output_directory: "fastlane/xcov_output"
)
# 슬랙에 테스트 결과 보고
slack(
message: "테스트 완료: 모든 테스트 통과",
success: true
)
end
이 레인은 다음과 같은 작업을 수행합니다:
- 단위 테스트 실행
- UI 테스트 실행 (여러 디바이스에서)
- 코드 커버리지 보고서 생성
- 슬랙에 성공 메시지 전송
CI 시스템에서 이 레인을 실행하면 자동으로 모든 테스트가 실행되고 결과가 보고됩니다.
배포 자동화
앱 배포는 보통 여러 단계로 구성된 복잡한 과정입니다.
Fastlane을 사용하면 이 과정을 크게 단순화할 수 있습니다
iOS 기준으로 작성한 예시입니다 :
desc "Build and submit to TestFlight"
lane :beta do
# 코드 서명 인증서 동기화
match(type: "appstore")
# 빌드 번호 증가
increment_build_number
# 앱 빌드
build_app(
scheme: "MyApp",
workspace: "MyApp.xcworkspace",
clean: true,
output_directory: "builds",
output_name: "MyApp.ipa"
)
# TestFlight에 업로드
upload_to_testflight(
skip_waiting_for_build_processing: true
)
# 변경 사항을 Git에 커밋
commit_version_bump(
message: "Version bump [ci skip]"
)
# 슬랙에 성공 메시지 전송
slack(
message: "새 베타 버전이 TestFlight에 업로드되었습니다!",
success: true
)
end
desc "Build and submit to App Store"
lane :release do
# 베타 레인 실행
beta
# 앱 스토어에 제출
upload_to_app_store(
submit_for_review: true,
automatic_release: true,
force: true
)
# 태그 생성 및 푸시
add_git_tag
push_to_git_remote
# 슬랙에 성공 메시지 전송
slack(
message: "앱이 App Store에 제출되었습니다!",
success: true
)
end
- beta 레인:
- 코드 서명 인증서 동기화
- 빌드 번호 증가
- 앱 빌드
- TestFlight에 업로드
- 변경 사항을 Git에 커밋
- 슬랙 알림
- release 레인:
- 베타 레인의 모든 작업 실행
- 앱 스토어에 제출
- Git 태그 생성 및 푸시
- 슬랙 알림
이 두 레인을 사용하면 베타 테스트와 앱 스토어 출시 과정을 완전히 자동화할 수 있습니다.
마무리
이렇게 fastlane에 대해 처음으로 알아보는 시간을 가졌는데요, 다음에는 실제로 출시된 어플에 적용한 결과 사진들을 바탕으로 fastlane 적용기를 작성해보려고 합니다.
추가 글 작성 목록
- 안드로이드 / iOS fastlane 적용 과정 정리
- Match 인증서 연동
- Github Actions 연동
참고 자료
'Flutter > Basic Knowledge' 카테고리의 다른 글
[Flutter] Riverpod - DI (0) | 2025.05.10 |
---|---|
[Flutter] Riverpod - 상태 관리 (0) | 2025.05.08 |
[Flutter] 앱 개발을 위한 클린 아키텍처 기본기 다지기 - 1단계 (0) | 2025.05.02 |
[Dart] Stream 이란? (3) | 2024.01.22 |
[Dart] Asynchronous & Future (3) | 2024.01.12 |