تجربة CICD عبر الهاتف المحمول: معيار Fastlane واحد للعديد من تطبيقات الهاتف المحمول

تجربة CICD عبر الهاتف المحمول: معيار Fastlane واحد للعديد من تطبيقات الهاتف المحمول
أود أن أتحدث عن التكامل المستمر والتسليم لتطبيقات الهاتف المحمول باستخدام Fastlane. كيف نقوم بتنفيذ CI/CD على جميع تطبيقات الهاتف المحمول، وكيف وصلنا إلى ذلك وماذا حدث في النهاية.

يوجد بالفعل ما يكفي من المواد على الشبكة حول الأداة، والتي افتقرنا إليها كثيرًا في البداية، لذلك لن أصف الأداة بالتفصيل عمدًا، ولكن سأشير فقط إلى ما كان لدينا في ذلك الوقت:

تتكون المقالة من جزأين:

  • خلفية ظهور CI/CD المحمول في الشركة
  • الحل التقني لطرح CI/CD لتطبيقات N

الجزء الأول هو المزيد من الحنين إلى الأيام الخوالي، والثاني هو تجربة يمكنك تطبيقها على نفسك.

هكذا حدث تاريخيا

سنة 2015

لقد بدأنا للتو في تطوير تطبيقات الهاتف المحمول، ثم لم نكن نعرف شيئًا عن التكامل المستمر وعن DevOps والأشياء العصرية الأخرى. تم نشر كل تحديث للتطبيق بواسطة المطور نفسه من جهازه. وإذا كان الأمر بسيطًا جدًا بالنسبة لنظام Android - يتم تجميعه وتوقيعه .apk وقمنا بتحميله على Google Developer Console، ثم بالنسبة لنظام التشغيل iOS، تركت لنا أداة التوزيع عبر Xcode أمسيات رائعة - غالبًا ما تنتهي محاولات تنزيل الأرشيف بأخطاء وكان علينا المحاولة مرة أخرى. اتضح أن المطور الأكثر تقدما لا يكتب التعليمات البرمجية عدة مرات في الشهر، بل يطلق التطبيق.

سنة 2016

لقد نشأنا، وكان لدينا بالفعل أفكار حول كيفية تحرير المطورين من يوم كامل للإصدار، وظهر أيضًا تطبيق ثانٍ، مما دفعنا أكثر نحو الأتمتة. في نفس العام، قمنا بتثبيت Jenkins لأول مرة وكتبنا مجموعة من النصوص المخيفة، تشبه إلى حد كبير تلك التي يعرضها Fastlane في وثائقه.

$ xcodebuild clean archive -archivePath build/MyApp 
    -scheme MyApp

$ xcodebuild -exportArchive 
                        -exportFormat ipa 
                        -archivePath "build/MyApp.xcarchive" 
                        -exportPath "build/MyApp.ipa" 
                        -exportProvisioningProfile "ProvisioningProfileName"

$ cd /Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/Frameworks/ITunesSoftwareService.framework/Versions/A/Support/

$ ./altool —upload-app 
-f {abs path to your project}/build/{release scheme}.ipa  
-u "[email protected]" 
-p "PASS_APPLE_ID"

لسوء الحظ، حتى الآن لم يكن سوى المطورين لدينا يعرفون كيفية عمل هذه البرامج النصية وسبب الحاجة إلى هذه المجموعة التي لا نهاية لها من المفاتيح، وعندما يتعطل شيء ما مرة أخرى، يحصلون على "أمسيات رائعة" لتحليل السجلات.

سنة 2017

علمنا هذا العام أن هناك شيئًا اسمه الخط السريع. لم يكن هناك الكثير من المعلومات كما هو الحال الآن - كيفية البدء وكيفية استخدامها. وكانت الأداة نفسها لا تزال بدائية في ذلك الوقت: فالأخطاء المستمرة خيبت أملنا وكان من الصعب تصديق الأتمتة السحرية التي وعدوا بها.

ومع ذلك، فإن المرافق الرئيسية المدرجة في Fastlane الأساسية هي gym и pilot، تمكنا من البدء به.

تم تحسين نصوصنا قليلاً.

$ fastlane gym  —-workspace "Example.xcworkspace" 
                --scheme "AppName" 
                —-buildlog_path "/tmp" 
                -—clean

لقد تم تحسينها، فقط لأنه ليس كل المعلمات اللازمة xcodebuild، تحتاج إلى الإشارة - gym سوف نفهم بشكل مستقل أين وماذا يكمن. ولمزيد من الضبط الدقيق، يمكنك تحديد نفس المفاتيح كما في xcodebuild، فقط تسمية المفاتيح هي الأكثر وضوحًا.

هذه المرة، بفضل صالة الألعاب الرياضية ومنسق xcpretty المدمج، أصبحت سجلات البناء أكثر وضوحًا. وقد أدى هذا إلى توفير الوقت في إصلاح التجميعات المعطلة، وفي بعض الأحيان كان بإمكان فريق الإصدار اكتشاف الأمر بنفسه.

لسوء الحظ، قياسات سرعة التجميع xcodebuild и gym لم نقم بذلك، لكننا نثق في الوثائق - تسريع يصل إلى 30%.

عملية واحدة لجميع التطبيقات

سنة 2018 وحالياً

بحلول عام 2018، انتقلت عملية إنشاء التطبيقات وطرحها بالكامل إلى Jenkins، وتوقف المطورون عن الإصدار من أجهزتهم، وكان لفريق الإصدار فقط الحق في الإصدار.

لقد أردنا بالفعل تحسين إطلاق الاختبارات والتحليل الثابت، ونمت نصوصنا ونمت. نمت وتغيرت مع تطبيقاتنا. في ذلك الوقت كان هناك حوالي 10 تطبيقات، وبالنظر إلى أن لدينا منصتين، فهذا يعني حوالي 20 نصًا "حيًا".

في كل مرة أردنا إضافة خطوة جديدة إلى البرنامج النصي، كان علينا نسخ ولصق الأجزاء في جميع نصوص shell. ربما كان بإمكاننا العمل بعناية أكبر، ولكن في كثير من الأحيان انتهت مثل هذه التغييرات بأخطاء مطبعية، والتي تحولت إلى أمسيات لفريق الإصدار لإصلاح البرامج النصية ومعرفة الرجل الذكي الذي أضاف هذا الأمر وما يفعله بالفعل. بشكل عام، لا يمكن القول أن البرامج النصية للتجميع لمنصة واحدة كانت متشابهة إلى حد ما على الأقل. على الرغم من أنهم فعلوا الشيء نفسه بالتأكيد.

من أجل بدء عملية تطبيق جديد، كان من الضروري قضاء يوم لاختيار نسخة "حديثة" من هذه البرامج النصية، وتصحيحها والقول "نعم، إنها تعمل".

في صيف عام 2018، نظرنا مرة أخرى نحو الخط السريع الذي لا يزال قيد التطوير.

المهمة رقم 1: تلخيص كافة خطوات البرنامج النصي وإعادة كتابتها في Fastfile

عندما بدأنا، بدت نصوصنا وكأنها قطعة قماش تتكون من جميع الخطوات والعكازات في نص غلاف واحد في جينكينز. لم نتحول بعد إلى خط الأنابيب والتقسيم على مراحل.

لقد نظرنا إلى ما لدينا وحددنا 4 خطوات تناسب وصف CI/CD الخاص بنا:

  • بناء - تثبيت التبعيات، وتجميع الأرشيف،
  • الاختبار - تشغيل اختبارات وحدة المطورين، وحساب التغطية،
  • السونار - يطلق جميع النترات ويرسل التقارير إلى SonarQube،
  • نشر - إرسال قطعة أثرية إلى ألفا (TestFlight).

وإذا لم تدخل في التفاصيل، مع حذف المفاتيح المستخدمة في الإجراءات، فستحصل على هذا الملف السريع:

default_platform(:ios)

platform :ios do
  before_all do
    unlock
  end

  desc "Build stage"
  lane :build do
    match
    prepare_build
    gym
  end

  desc "Prepare build stage: carthage and cocoapods"
  lane :prepare_build do
    pathCartfile = ""
    Dir.chdir("..") do
      pathCartfile = File.join(Dir.pwd, "/Cartfile")
    end
    if File.exist?(pathCartfile)
      carthage
    end
    pathPodfile = ""
    Dir.chdir("..") do
      pathPodfile = File.join(Dir.pwd, "/Podfile")
    end
    if File.exist?(pathPodfile)
      cocoapods
    end
  end

  desc "Test stage"
  lane :test do
    scan
    xcov
  end

  desc "Sonar stage (after run test!)"
  lane :run_sonar do
    slather
    lizard
    swiftlint
    sonar
  end

  desc "Deploy to testflight stage"
  lane :deploy do
    pilot
  end

  desc "Unlock keychain"
  private_lane :unlock do
    pass = ENV['KEYCHAIN_PASSWORD']
    unlock_keychain(
      password: pass
    )
  end
end

في الواقع، تبين أن Fastfile الأول الخاص بنا كان هائلاً، مع الأخذ في الاعتبار بعض العكازات التي ما زلنا بحاجة إليها وعدد المعلمات التي استبدلناها:

lane :build do
carthage(
  command: "update",
  use_binaries: false,
  platform: "ios",
  cache_builds: true)
cocoapods(
  clean: true,
    podfile: "./Podfile",
    use_bundle_exec: false)

gym(
  workspace: "MyApp.xcworkspace",
  configuration: "Release",
  scheme: "MyApp",
  clean: true,
  output_directory: "/build",
  output_name: "my-app.ipa")
end 

lane :deploy do
 pilot(
  username: "[email protected]",
  app_identifier: "com.example.app",
  dev_portal_team_id: "TEAM_ID_NUMBER_DEV",
  team_id: "ITS_TEAM_ID")
end

في المثال أعلاه، جزء فقط من المعلمات التي نحتاج إلى تحديدها: هذه هي معلمات البناء - المخطط، والتكوين، وأسماء ملفات تعريف التوفير، بالإضافة إلى معلمات التوزيع - معرف Apple لحساب المطور، وكلمة المرور، ومعرف التطبيق، وما إلى ذلك على. كتقريب أولي، نضع كل هذه المفاتيح في ملفات خاصة - Gymfile, Matchfile и Appfile.

يمكنك الآن في Jenkins استدعاء أوامر قصيرة لا تؤدي إلى تشويش الرؤية ويمكن قراءتها بسهولة بالعين المجردة:

# fastlane ios <lane_name>

$ fastlane ios build
$ fastlane ios test
$ fastlane ios run_sonar
$ fastlane ios deploy

مرحى، نحن رائعون

على ماذا حصلت؟ أوامر واضحة لكل خطوة. تنظيف البرامج النصية، وترتيبها بدقة في ملفات Fastlane. ابتهجنا، ركضنا إلى المطورين لنطلب منهم إضافة كل ما يحتاجونه إلى مستودعاتهم.

لكننا أدركنا مع مرور الوقت أننا سنواجه نفس الصعوبات - سيظل لدينا 20 نصًا تجميعيًا سيبدأون بطريقة أو بأخرى في عيش حياتهم الخاصة، وسيكون تحريرها أكثر صعوبة، نظرًا لأن النصوص البرمجية ستنتقل إلى المستودعات، ولم نتمكن من الوصول إلى هناك. وبشكل عام، لن يكون من الممكن حل آلامنا بهذه الطريقة.

تجربة CICD عبر الهاتف المحمول: معيار Fastlane واحد للعديد من تطبيقات الهاتف المحمول

المهمة رقم 2: الحصول على ملف Fastfile واحد لتطبيقات N

الآن يبدو أن حل المشكلة ليس بالأمر الصعب - قم بتعيين المتغيرات، ودعنا نذهب. نعم، في الواقع، هكذا تم حل المشكلة. لكن في اللحظة التي أخفقنا فيها، لم تكن لدينا خبرة في Fastlane نفسه، ولا في Ruby، حيث تمت كتابة Fastlane، ولا أمثلة مفيدة على الشبكة - كل من كتب عن Fastlane حينها كان يقتصر على مثال لتطبيق واحد لـ مطور واحد.

يستطيع Fastlane التعامل مع متغيرات البيئة، وقد جربنا ذلك بالفعل عن طريق تعيين كلمة مرور Keychain:

ENV['KEYCHAIN_PASSWORD']

بعد النظر في النصوص لدينا، حددنا الأجزاء المشتركة:

#for build, test and deploy
APPLICATION_SCHEME_NAME=appScheme
APPLICATION_PROJECT_NAME=app.xcodeproj
APPLICATION_WORKSPACE_NAME=app.xcworkspace
APPLICATION_NAME=appName

OUTPUT_IPA_NAME=appName.ipa

#app info
APP_BUNDLE_IDENTIFIER=com.example.appName
[email protected]
TEAM_ID=ABCD1234
FASTLANE_ITC_TEAM_ID=123456789

الآن، من أجل البدء في استخدام هذه المفاتيح في ملفات Fastlane، كان علينا معرفة كيفية تسليمها هناك. Fastlane لديه حل لهذا: تحميل المتغيرات عبر dotenv. تشير الوثائق إلى أنه إذا كان من المهم بالنسبة لك تحميل المفاتيح لأغراض مختلفة، فقم بإنشاء عدة ملفات تكوين في دليل Fastlane .env, .env.default, .env.development.

وبعد ذلك قررنا استخدام هذه المكتبة بشكل مختلف قليلاً. دعونا لا نضع في مستودع المطورين نصوص Fastlane والمعلومات التعريفية الخاصة بها، ولكن المفاتيح الفريدة لهذا التطبيق في الملف .env.appName.

أنفسهم Fastfile, Appfile, Matchfile и Gymfile، قمنا بإخفائها في مستودع منفصل. تم إخفاء ملف إضافي يحتوي على مفاتيح كلمة المرور من خدمات أخرى هناك - .env.
يمكنك رؤية مثال هنا.

تجربة CICD عبر الهاتف المحمول: معيار Fastlane واحد للعديد من تطبيقات الهاتف المحمول

في CI، لم يتغير الاتصال كثيرًا، تمت إضافة مفتاح التكوين لتطبيق معين:

# fastlane ios <lane_name> --env appName

$ fastlane ios build --env appName
$ fastlane ios test --env appName
$ fastlane ios run_sonar --env appName
$ fastlane ios deploy --env appName

قبل تشغيل الأوامر، نقوم بتحميل مستودعنا بالنصوص البرمجية. لا تبدو جميلة جدًا:

git clone [email protected]/FastlaneCICD.git fastlane_temp

cp ./fastlane_temp/fastlane/* ./fastlane/
cp ./fastlane_temp/fastlane/.env fastlane/.env

تركت هذا الحل في الوقت الحالي، على الرغم من أن Fastlane لديه حل لتنزيل Fastfile عبر عمل import_from_git، ولكنه يعمل فقط مع Fastfile، وليس مع الملفات الأخرى. إذا كنت تريد "جميلة حقًا"، فيمكنك كتابة ما تريد action.

تم إنشاء مجموعة مماثلة لتطبيقات Android وReactNative، والملفات موجودة في نفس المستودع، ولكن في فروع مختلفة iOS, android и react_native.

عندما يريد فريق الإصدار إضافة بعض الخطوات الجديدة، يتم تسجيل التغييرات في البرنامج النصي عبر MR في git، ولم تعد هناك حاجة للبحث عن مسببي النصوص البرمجية المعطلة، وبشكل عام، عليك الآن محاولة كسرها.

الآن هذا كل شيء بالتأكيد

في السابق، أمضينا وقتًا في صيانة جميع البرامج النصية وتحديثها وإصلاح جميع عواقب التحديثات. لقد كان الأمر مخيبًا للآمال للغاية عندما كانت أسباب الأخطاء ووقت التوقف عن العمل في الإصدارات عبارة عن أخطاء إملائية بسيطة كان من الصعب جدًا تتبعها في مزيج من نصوص shell البرمجية. الآن يتم تقليل هذه الأخطاء إلى الحد الأدنى. يتم نشر التغييرات على جميع التطبيقات مرة واحدة. ويستغرق الأمر 15 دقيقة لوضع تطبيق جديد في العملية - قم بإعداد مسار القالب على CI وإضافة المفاتيح إلى مستودع المطور.

يبدو أن النقطة مع Fastfile لنظام Android وتوقيع التطبيق لا تزال غير مفسرة، إذا كانت المقالة مثيرة للاهتمام، سأكتب استمرارًا. سأكون سعيدًا برؤية أسئلتك أو اقتراحاتك "كيف يمكنك حل هذه المشكلة" في التعليقات أو على Telegram باشكيروفا.

المصدر: www.habr.com

إضافة تعليق