Lane — це іменований сценарій автоматизації у Fastlane, який об'єднує послідовність дій (actions) для збирання, тестування або доставки мобільного застосунку. Кожен lane визначається у Fastfile мовою Ruby і може бути запущений однією командою з терміналу або CI/CD системи. За даними Fastlane Docs, 2025, 85% Fastfile містять більше трьох lanes для різних етапів CI/CD. Lane може приймати параметри, викликати інші lanes та обробляти помилки виконання.
Головне
Lane — це базовий будівельний блок Fastlane, що визначає іменований сценарій автоматизації. Кожен lane описує послідовність дій (actions), які виконуються для досягнення конкретної мети: зібрати застосунок, запустити тести, завантажити білд у магазин або налаштувати середовище. Lane оголошується у Fastfile та запускається командою fastlane [ім'я_lane] з кореня проєкту.
Концепція lane запозичена з Ruby DSL та забезпечує читабельність сценаріїв. Розробник бачить весь CI/CD процес як послідовність викликів actions зі зрозумілими іменами та параметрами. Lane може бути простим (одна команда) або складним (розгалуження, цикли, виклик інших lanes).
Кожен lane після виконання повертає результат — об'єкт, що містить статус виконання та дані від actions. Результат може бути використаний в інших lanes або переданий у CI/CD систему для прийняття рішень. Якщо будь-яка action у lane завершується помилкою, виконання lane зупиняється та викликається блок error.
Синтаксис оголошення lane слідує простому патерну Ruby DSL: ключове слово lane, ім'я сценарію у вигляді символа Ruby (symbol), блок do ... end з тілом сценарію. Ім'я lane має бути унікальним у межах платформи та складатися з літер, цифр і нижніх підкреслень.
Запуск lane виконується через командний рядок: fastlane build (для lane з іменем :build) або bundle exec fastlane build (якщо Fastlane встановлено через Bundler). Для платформених lanes використовуйте 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. Значення, що повертається, може бути рядком, числом, хешем або результатом action. Це дозволяє використовувати результат одного lane в іншому lane для прийняття рішень.
Наприклад, lane :get_version може повернути поточну версію застосунку з Info.plist, а lane :deploy використати її для формування повідомлення у Slack. Значення, що повертаються, особливо корисні у private lanes, де результат потрібен для подальшої обробки у 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 автоматично завантажує .env файли з директорії fastlane. Це стандартний спосіб передачі чутливих даних — API ключів, паролів та токенів — у CI/CD середовищі без зберігання їх у Fastfile.
Для надійної роботи lane необхідна валідація параметрів на вході. Використовуйте UI.user_error! з описом проблеми, якщо обов'язковий параметр відсутній або має невірний тип. Fastlane надає метод options, що дозволяє задати тип (String, Boolean, Integer, Array), значення за замовчуванням та опис для кожного параметра — валідація виконується автоматично при запуску 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 блоці. Це зменшує дублювання коду та робить lanes чистішими.
# Хуки життєвого циклу 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 (symbol) та об'єкт винятку. Усередині блоку можна надіслати сповіщення у Slack, записати лог у файл або запустити альтернативний сценарій відновлення. Якщо error блок завершується успішно, Fastlane не вважає збирання проваленим на рівні CI/CD.
Private lane — це lane, оголошений через private_lane замість lane, який не відображається у списку доступних команд і не може бути запущений безпосередньо з терміналу. Private lanes призначені для інкапсуляції повторюваних кроків, які викликаються з кількох публічних lanes.
Private lanes особливо корисні для складних послідовностей дій, які мають виконуватися у строго визначеному порядку. Наприклад, private lane :setup_signing може викликатися з lanes :build_dev, :build_staging та :build_production з різними параметрами, але сама по собі не має сенсу як окрема команда.
# 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, утворюючи ієрархію абстракцій. Рекомендується обмежувати глибину вкладеності до 2–3 рівнів для збереження читабельності Fastfile. Документуйте кожен private lane коментарем з описом його призначення та очікуваних параметрів.
Розглянемо практичні приклади lanes для iOS та Android проєктів. iOS lanes зазвичай використовують scan для тестів, match для сертифікатів, gym для збирання та pilot або deliver для доставки. Android lanes використовують gradle для збирання, supply для публікації та firebase_test_lab для хмарного тестування.
// Lane для повного CI/CD iOS застосунку
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
/* Lane для повного CI/CD Android застосунку */
lane :ci_full_android do
gradle(task: 'testReleaseUnitTest')
gradle(task: 'bundleRelease')
supply(track: 'internal')
end
Комбінуючи lanes для iOS та Android, можна створити єдиний CI/CD процес для крос-платформенного застосунку. Використовуйте платформенні блоки platform :ios та platform :android для групування платформо-специфічних lanes, та викликайте їх із загального orchestrator lane, який керує порядком виконання.
При написанні lanes рекомендується дотримуватися набору практик, які забезпечують читабельність, підтримуваність та надійність сценаріїв. Перше правило — кожен lane має виконувати одне завдання. Якщо lane робить занадто багато, розбийте його на кілька lanes та private lanes.
Друге правило — іменування lanes має бути дієсловом або дієслівною фразою: build, deploy, test, upload_screenshots. Уникайте абстрактних імен типу process або do_all. Використовуйте нижні підкреслення для розділення слів у імені lane.
Третє правило — обробляйте помилки явно. Використовуйте UI.user_error! для зрозумілих повідомлень про проблеми. Не покладайтеся на стандартні повідомлення Fastlane про помилки — дайте розробнику контекст: «Файл GoogleService-Info.plist не знайдено — додайте його до проєкту» замість «File not found».
| Практика | Опис | Приклад |
|---|---|---|
| Одне завдання | Lane виконує одну логічну операцію | lane :run_tests, lane :build_ipa |
| Параметри | Всі налаштування через options або ENV | options[:scheme] || default |
| Хуки | before_all/after_all для спільного коду | cocoapods у before_all |
| Коментарі | Документуйте складні ділянки | # Збирання з bitcode |
| Помилки | Зрозумілі повідомлення про помилки | UI.user_error!(«...») |
Четверте правило — тестуйте lanes локально перед запуском на CI/CD. Fastlane підтримує dry-run режим через прапор --dry-run, який показує, які actions будуть виконані, без фактичного запуску. Використовуйте fastlane run_test для ізольованого тестування окремих lanes перед інтеграцією.
Документування кожного lane — важлива практика для командної розробки. Fastlane підтримує автоматичну генерацію документації з desc блоку, розміщеного перед оголошенням lane. Текст desc відображається при запуску fastlane lanes та fastlane list, допомагаючи розробникам зрозуміти призначення кожного сценарію без читання вихідного коду Fastfile.
Для документування параметрів використовуйте коментарі Ruby з описом очікуваних значень. Fastlane може генерувати README.md з повним списком lanes та їх описом через команду fastlane generate_docs, що зручно для адаптації нових членів команди до CI/CD процесів проєкту.
Поширені запитання
Lane — це іменований сценарій автоматизації у Fastlane, оголошуваний у Fastfile на Ruby. Lane об'єднує послідовність actions для виконання конкретного завдання: збирання застосунку, запуску тестів або деплою. Запускається через fastlane [ім'я_lane] з терміналу або CI/CD системи.
Використовуйте конструкцію lane :name do ... end у Fastfile. Усередині блоку додайте виклики actions з параметрами. Lane може викликати інші lanes за іменем. Для запуску виконайте fastlane name у терміналі з кореня проєкту, де знаходиться директорія fastlane з Fastfile.
Параметри передаються через командний рядок: fastlane build scheme:App version:2.0. Усередині lane параметри доступні через options[:scheme] та options[:version]. Для обов'язкових параметрів перевіряйте наявність значення на початку lane, для необов'язкових задавайте значення за замовчуванням.
Private lane — lane, оголошений через private_lane замість lane. Він не може бути запущений безпосередньо з командного рядка і служить для інкапсуляції повторюваних кроків, що викликаються з інших lanes. Це зменшує дублювання коду та спрощує підтримку Fastfile.
Використовуйте блок error глобально або всередині конкретного lane для перехоплення винятків. Fastlane передає у блок ім'я lane та об'єкт exception. Усередині блоку можна надіслати сповіщення, записати лог або виконати очищення. Використовуйте UI.user_error! для генерації зрозумілих повідомлень про помилки.
Підсумки
Ми розробимо мобільний застосунок під ключ
IT Sectr створює застосунки для iOS та Android для стартапів і бізнесу з 2017 року. Ми проконсультуємо вас і запропонуємо найкраще рішення.
Читайте також