Lane은 모바일 애플리케이션을 빌드, 테스트 또는 배포하기 위한 일련의 작업(actions)을 결합하는 Fastlane의 명명된 자동화 스크립트입니다. 각 lane은 Fastfile에서 Ruby 언어로 정의되며 터미널 또는 CI/CD 시스템에서 하나의 명령으로 실행할 수 있습니다. Fastlane Docs, 2025에 따르면 85%의 Fastfile에는 CI/CD의 다양한 단계에 대해 3개 이상의 lane이 포함되어 있습니다. Lane은 매개변수를 받고, 다른 lane을 호출하며, 실행 오류를 처리할 수 있습니다.
핵심 사항
Lane은 Fastlane의 기본 구성 요소로 명명된 자동화 스크립트를 정의합니다. 각 lane은 특정 목표를 달성하기 위해 실행되는 일련의 작업을 설명합니다: 애플리케이션 빌드, 테스트 실행, 스토어에 빌드 업로드 또는 환경 설정. Lane은 Fastfile에서 선언되며 프로젝트 루트에서 fastlane [lane_name] 명령으로 실행됩니다.
Lane 개념은 Ruby DSL에서 차용되었으며 스크립트 가독성을 보장합니다. 개발자는 전체 CI/CD 프로세스를 명확한 이름과 매개변수가 있는 작업 호출 시퀀스로 볼 수 있습니다. Lane은 단순(하나의 명령)하거나 복잡(분기, 루프, 다른 lane 호출)할 수 있습니다.
실행 후 각 lane은 결과를 반환합니다 — 실행 상태와 작업 데이터를 포함하는 객체입니다. 결과는 다른 lane에서 사용하거나 의사 결정을 위해 CI/CD 시스템에 전달할 수 있습니다. lane의 어떤 작업이 실패하면 lane 실행이 중지되고 error 블록이 호출됩니다.
Lane 선언 구문은 간단한 Ruby DSL 패턴을 따릅니다: lane 키워드, Ruby 심볼(symbol)로서의 스크립트 이름, 그리고 do ... end 블록으로 스크립트 본문을 구성합니다. lane 이름은 플랫폼 내에서 고유해야 하며 문자, 숫자 및 밑줄로 구성될 수 있습니다.
Lane은 명령줄을 통해 실행됩니다: fastlane build(:build라는 lane의 경우) 또는 bundle exec fastlane build(Bundler를 통해 Fastlane이 설치된 경우). 플랫폼별 lane의 경우 fastlane ios build 또는 fastlane android build를 사용합니다.
# 간단한 lane 선언
lane :test do
scan(scheme: 'App', devices: ['iPhone 15'])
end
lane :build_and_deploy do
cocoapods
test
gym(scheme: 'App', export_method: 'app-store')
pilot(skip_waiting_for_build_processing: true)
end
# 실행: fastlane build_and_deploy
Lane에는 매개변수 또는 환경 변수를 기반으로 하는 조건부 로직이 포함될 수 있습니다. 특정 조건에서 단계를 건너뛰려면 if/unless를 사용합니다. 배열 처리를 위한 루프(each)도 사용할 수 있어 하나의 lane에서 여러 대상을 빌드하는 데 편리합니다.
Lane은 호출 코드에서 사용할 수 있는 값을 반환할 수 있습니다. 값을 반환하려면 표준 Ruby return 또는 lane 블록의 마지막 표현식을 사용합니다. 반환 값은 문자열, 숫자, 해시 또는 작업의 결과가 될 수 있습니다. 이를 통해 의사 결정을 위해 한 lane의 결과를 다른 lane에서 사용할 수 있습니다.
예를 들어, :get_version lane은 Info.plist에서 현재 애플리케이션 버전을 반환하고, :deploy lane은 이를 사용하여 Slack 메시지를 작성할 수 있습니다. 반환 값은 호출 lane에서 추가 처리를 위해 결과가 필요한 private lane에서 특히 유용합니다.
Lane 매개변수는 스크립트를 유연하고 재사용 가능하게 만듭니다. Lane은 명령줄에서 실행할 때 전달되는 options 해시를 통해 매개변수를 받습니다: fastlane deploy scheme:AppStore version:2.1.0. lane 내부에서 매개변수는 options[:scheme] 및 options[:version]으로 사용할 수 있습니다.
필수 매개변수의 경우 lane 시작 부분에서 값을 확인하고 명확한 메시지와 함께 UI.user_error!를 호출합니다. 선택적 매개변수의 경우 || 연산자를 통해 기본값을 설정합니다. Fastlane은 options 메서드를 통해 유형, 기본값 및 설명과 함께 유형화된 매개변수도 지원합니다.
# 매개변수 처리가 있는 Lane
lane :deploy do |options|
scheme = options[:scheme]
version = options[:version] || '1.0.0'
beta = options[:beta] || false
UI.user_error!("scheme이 지정되지 않음") unless scheme
match(type: beta ? 'adhoc' : 'appstore')
gym(scheme: scheme, export_method: beta ? 'ad-hoc' : 'app-store')
if beta
pilot(distribute_external: true)
else
deliver(submit_for_review: true)
end
end
# 실행: fastlane deploy scheme:MyApp beta:true version:2.1.0
lane 내에서 환경 변수를 사용하려면 ENV['VARIABLE_NAME']을 사용합니다. Fastlane은 fastlane 디렉토리에서 .env 파일을 자동으로 로드합니다. 이것은 CI/CD 환경에서 API 키, 비밀번호 및 토큰과 같은 민감한 데이터를 Fastfile에 저장하지 않고 전달하는 표준 방법입니다.
안정적인 lane 작동을 위해서는 입력 시 매개변수 유효성 검사가 필요합니다. 필수 매개변수가 누락되었거나 유형이 잘못된 경우 문제 설명과 함께 UI.user_error!를 사용합니다. Fastlane은 각 매개변수에 대해 유형(String, Boolean, Integer, Array), 기본값 및 설명을 지정할 수 있는 options 메서드를 제공합니다 — 유효성 검사는 lane이 시작될 때 자동으로 수행됩니다.
또한 문자열 매개변수의 경우 verify 블록을 통해 검사를 사용할 수 있습니다: verify do |value| value.length > 0 end. 형식이 잘못된 경우 Fastlane은 예상 형식과 전달된 값을 나타내는 명확한 메시지를 출력하여 CI/CD 환경에서 디버깅을 단순화합니다.
Fastlane은 각 lane 전후에 코드를 실행하기 위한 라이프사이클 훅을 제공합니다. before_all 블록은 특정 플랫폼에서 또는 전역적으로 각 lane 전에 실행됩니다. after_all 블록은 lane이 성공적으로 완료된 후 실행됩니다. error 블록은 lane 내에서 오류가 발생하면 실행됩니다.
훅을 사용하면 반복 로직을 중앙 집중화할 수 있습니다: before_all에서 종속성 설정, after_all에서 알림 전송, 임시 파일 정리 및 error 블록에서 오류 알림. 이렇게 하면 코드 중복이 줄어들고 lane이 더 깔끔해집니다.
# Lanes 라이프사이클 훅
default_platform(:ios)
before_all do
cocoapods(try_repo_update_on_error: true)
ensure_git_status_clean
end
after_all do |lane|
slack(message: "Lane #{lane} 성공적으로 완료")
end
error do |lane, exception|
slack(
message: "Lane #{lane} 오류로 실패: #{exception}",
success: false
)
end
lane :deploy do
match(type: 'appstore')
gym(export_method: 'app-store')
deliver
end
Error 블록은 두 개의 인수를 받습니다: lane 이름(심볼)과 예외 객체입니다. 블록 내에서 Slack 알림을 보내거나, 파일에 로그를 쓰거나, 대체 복구 스크립트를 실행할 수 있습니다. error 블록이 성공적으로 완료되면 Fastlane은 CI/CD 수준에서 빌드를 실패한 것으로 간주하지 않습니다.
Private lane은 lane 대신 private_lane로 선언된 lane으로, 사용 가능한 명령 목록에 표시되지 않으며 터미널에서 직접 실행할 수 없습니다. Private lanes는 여러 공개 lane에서 호출되는 반복 단계를 캡슐화하기 위해 설계되었습니다.
Private lanes는 엄격하게 정의된 순서로 실행되어야 하는 복잡한 작업 시퀀스에 특히 유용합니다. 예를 들어, private lane :setup_signing은 다른 매개변수로 :build_dev, :build_staging 및 :build_production lane에서 호출될 수 있지만, 그 자체로는 별도의 명령으로 의미가 없습니다.
# 재사용을 위한 Private lanes
private_lane :setup_environment do |options|
cocoapods(try_repo_update_on_error: true)
match(type: options[:type], readonly: true)
increment_build_number
end
lane :dev_build do
setup_environment(type: 'development')
gym(export_method: 'development')
end
lane :appstore_build do
setup_environment(type: 'appstore')
gym(export_method: 'app-store')
deliver
end
Private lanes는 다른 private lanes를 호출하여 추상화 계층 구조를 형성할 수 있습니다. Fastfile의 가독성을 유지하려면 중첩 깊이를 2~3 수준으로 제한하는 것이 좋습니다. 각 private lane을 목적과 예상 매개변수를 설명하는 주석으로 문서화합니다.
iOS 및 Android 프로젝트를 위한 실용적인 예제를 살펴보겠습니다. iOS lane은 일반적으로 테스트에 scan, 인증서에 match, 빌드에 gym, 배포에 pilot 또는 deliver를 사용합니다. Android lane은 빌드에 gradle, 게시에 supply, 클라우드 테스트에 firebase_test_lab을 사용합니다.
// 전체 CI/CD iOS 앱용 Lane
lane :ci_full_ios do
scan(scheme: 'App', code_coverage: true)
gym(scheme: 'App', export_method: 'app-store')
pilot(distribute_external: true)
slack(message: 'iOS CI/CD가 성공적으로 완료됨')
end
/* 전체 CI/CD Android 앱용 Lane */
lane :ci_full_android do
gradle(task: 'testReleaseUnitTest')
gradle(task: 'bundleRelease')
supply(track: 'internal')
end
iOS 및 Android용 lane을 결합하여 크로스 플랫폼 애플리케이션을 위한 통합 CI/CD 프로세스를 만들 수 있습니다. 플랫폼 블록 platform :ios 및 platform :android를 사용하여 플랫폼별 lane을 그룹화하고 실행 순서를 관리하는 공통 오케스트레이터 lane에서 호출합니다.
Lanes을 작성할 때는 스크립트의 가독성, 유지 관리성 및 신뢰성을 보장하는 일련의 방법을 따르는 것이 좋습니다. 첫 번째 규칙은 각 lane이 하나의 작업을 수행해야 한다는 것입니다. lane이 너무 많은 작업을 수행하는 경우 여러 lane과 private lane으로 분할합니다.
두 번째 규칙은 lane 이름 지정이 동사 또는 동사구(build, deploy, test, upload_screenshots)여야 한다는 것입니다. process나 do_all과 같은 추상적인 이름은 피하십시오. lane 이름에서 단어를 구분하려면 밑줄을 사용합니다.
세 번째 규칙은 오류를 명시적으로 처리하는 것입니다. 명확한 문제 메시지를 위해 UI.user_error!를 사용합니다. Fastlane의 기본 오류 메시지에 의존하지 말고 개발자에게 컨텍스트를 제공하십시오: “GoogleService-Info.plist 파일을 찾을 수 없습니다 — 프로젝트에 추가하십시오” (“파일을 찾을 수 없습니다” 대신).
| 방법 | 설명 | 예제 |
|---|---|---|
| 하나의 작업 | Lane이 하나의 논리적 작업 수행 | lane :run_tests, lane :build_ipa |
| 매개변수 | 모든 설정은 options 또는 ENV를 통해 | options[:scheme] || default |
| 훅 | 공통 코드를 위한 before_all/after_all | before_all의 cocoapods |
| 주석 | 복잡한 섹션 문서화 | # bitcode로 빌드 |
| 오류 | 명확한 오류 메시지 | UI.user_error!(“...”) |
네 번째 규칙은 CI/CD에서 실행하기 전에 로컬에서 lane을 테스트하는 것입니다. Fastlane은 --dry-run 플래그를 통해 드라이 런 모드를 지원하며, 실제로 실행하지 않고 어떤 작업이 실행될지 표시합니다. 통합 전에 개별 lane을 격리 테스트하려면 fastlane run_test를 사용합니다.
각 lane을 문서화하는 것은 팀 개발을 위한 중요한 방법입니다. Fastlane은 lane 선언 전에 배치된 desc 블록에서 자동 문서 생성을 지원합니다. fastlane lanes 및 fastlane list를 실행할 때 desc 텍스트가 표시되어 개발자가 Fastfile의 소스 코드를 읽지 않고도 각 스크립트의 목적을 이해할 수 있습니다.
매개변수를 문서화하려면 예상 값을 설명하는 Ruby 주석을 사용합니다. Fastlane은 fastlane generate_docs 명령을 통해 전체 lane 목록과 설명이 포함된 README.md을 생성할 수 있으며, 이는 프로젝트의 CI/CD 프로세스에 새 팀 구성원을 온보딩하는 데 편리합니다.
자주 묻는 질문
Lane은 Fastlane에서 Ruby로 Fastfile에 선언된 명명된 자동화 스크립트입니다. Lane은 특정 작업(애플리케이션 빌드, 테스트 실행 또는 배포)을 수행하기 위한 일련의 작업을 결합합니다. 터미널 또는 CI/CD 시스템에서 fastlane [lane_name]을 통해 실행됩니다.
Fastfile에서 lane :name do ... end 구문을 사용합니다. 블록 내에 매개변수와 함께 작업 호출을 추가합니다. Lane은 이름으로 다른 lane을 호출할 수 있습니다. 실행하려면 Fastfile이 있는 fastlane 디렉토리가 있는 프로젝트 루트의 터미널에서 fastlane name을 실행합니다.
매개변수는 명령줄을 통해 전달됩니다: fastlane build scheme:App version:2.0. lane 내부에서 매개변수는 options[:scheme] 및 options[:version]을 통해 사용할 수 있습니다. 필수 매개변수의 경우 lane 시작 부분에서 값을 확인하고 선택적 매개변수의 경우 기본값을 설정합니다.
Private lane은 lane 대신 private_lane로 선언된 lane입니다. 명령줄에서 직접 실행할 수 없으며 다른 lane에서 호출되는 반복 단계를 캡슐화하는 역할을 합니다. 이렇게 하면 코드 중복이 줄어들고 Fastfile 유지 관리가 간소화됩니다.
예외를 포착하려면 전역적으로 또는 특정 lane 내에서 error 블록을 사용합니다. Fastlane은 lane 이름과 예외 객체를 블록에 전달합니다. 블록 내에서 알림을 보내거나, 로그를 쓰거나, 정리를 수행할 수 있습니다. 명확한 오류 메시지를 생성하려면 UI.user_error!를 사용합니다.
요약
턴키 방식의 모바일 애플리케이션을 개발해 드립니다
IT Sectr는 2017년부터 스타트업과 기업을 위한 iOS 및 Android 애플리케이션을 만듭니다. 저희가 상담해 드리고 최적의 솔루션을 제안하겠습니다.