Lane هو سيناريو أتمتة مسمى في Fastlane يجمع تسلسلاً من الإجراءات (actions) لبناء أو اختبار أو تسليم تطبيق محمول. يتم تعريف كل lane في Fastfile بلغة Ruby ويمكن تشغيله بأمر واحد من الطرفية أو نظام CI/CD. وفقاً لـ Fastlane Docs, 2025، 85% من Fastfiles تحتوي على أكثر من ثلاثة lanes لمراحل CI/CD مختلفة. يمكن أن يستقبل lane معلمات، ويستدعي lanes أخرى، ويعالج أخطاء التنفيذ.
النقاط الرئيسية
Lane هو لبنة البناء الأساسية في Fastlane التي تحدد سيناريو أتمتة مسمى. يصف كل lane تسلسلاً من الإجراءات التي يتم تنفيذها لتحقيق هدف محدد: بناء تطبيق، تشغيل اختبارات، رفع build إلى المتجر، أو إعداد البيئة. يتم إعلان lane في Fastfile وتشغيله بأمر fastlane [اسم_lane] من جذر المشروع.
مفهوم lane مستعار من Ruby DSL ويضمن وضوح السيناريوهات. يرى المطور عملية CI/CD بأكملها كسلسلة من استدعاءات الإجراءات بأسماء ومعلمات واضحة. يمكن أن يكون lane بسيطاً (أمر واحد) أو معقداً (تفرعات، حلقات، استدعاء lanes أخرى).
بعد التنفيذ، يعيد كل lane نتيجة — كائن يحتوي على حالة التنفيذ والبيانات من الإجراءات. يمكن استخدام النتيجة في lanes أخرى أو تمريرها إلى نظام CI/CD لاتخاذ القرارات. إذا فشل أي إجراء في lane، يتوقف تنفيذ lane ويتم استدعاء كتلة error.
صيغة إعلان lane تتبع نمطاً بسيطاً من Ruby DSL: الكلمة المفتاحية lane، اسم السيناريو كـ symbol في Ruby، وكتلة 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 قيمة ستكون متاحة للكود المستدعي. لاسترجاع قيمة، استخدم return القياسي في Ruby أو آخر تعبير في كتلة lane. يمكن أن تكون القيمة المعادة سلسلة نصية أو رقماً أو هاشاً أو نتيجة إجراء. هذا يسمح باستخدام نتيجة 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 lanes خاصة أخرى، مشكلة تسلسلاً هرمياً للتجريد. يُوصى بتحديد عمق التداخل إلى 2–3 مستويات للحفاظ على قابلية قراءة Fastfile. وثق كل private lane بتعليق يصف غرضه والمعلمات المتوقعة.
لنلق نظرة على أمثلة عملية لـ lanes لمشاريع iOS وAndroid. تستخدم lanes iOS عادةً scan للاختبارات وmatch للشهادات وgym للبناء وpilot أو deliver للتوزيع. تستخدم lanes Android 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: 'تم إكمال CI/CD لنظام iOS بنجاح')
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 الخاصة بكل منصة، واستدعها من lane منسق مشترك يدير ترتيب التنفيذ.
عند كتابة lanes، يُوصى باتباع مجموعة من الممارسات التي تضمن قابلية القراءة والصيانة والموثوقية للسيناريوهات. القاعدة الأولى هي أن كل lane يجب أن يقوم بمهمة واحدة. إذا كان lane يفعل الكثير، قسمه إلى عدة lanes وprivate lanes.
القاعدة الثانية هي أن تسمية 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 للكود المشترك | cocoapods في before_all |
| التعليقات | وثق الأقسام المعقدة | # بناء مع bitcode |
| الأخطاء | رسائل خطأ واضحة | UI.user_error!(«...») |
القاعدة الرابعة هي اختبار lanes محلياً قبل التشغيل على CI/CD. يدعم Fastlane وضع dry-run عبر العلم --dry-run، الذي يعرض الإجراءات التي سيتم تنفيذها دون تشغيلها فعلياً. استخدم 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 تسلسلاً من الإجراءات لتنفيذ مهمة محددة: بناء تطبيق أو تشغيل اختبارات أو نشر. يتم تشغيله عبر fastlane [اسم_lane] من الطرفية أو نظام CI/CD.
استخدم البناء lane :name do ... end في Fastfile. داخل الكتلة، أضف استدعاءات الإجراءات مع المعلمات. يمكن أن يستدعي 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. سوف نقدم لك النصح ونقترح أفضل حل.
اقرأ أيضًا