मोबाइल CICD अनुभव: अनेक मोबाइल अनुप्रयोगांसाठी एक फास्टलेन मानक

मोबाइल CICD अनुभव: अनेक मोबाइल अनुप्रयोगांसाठी एक फास्टलेन मानक
मला फास्टलेन वापरून मोबाइल अॅप्ससाठी सतत एकत्रीकरण आणि वितरणाबद्दल बोलायचे आहे. आम्ही सर्व मोबाईल ऍप्लिकेशन्सवर 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

या वर्षी आम्हाला कळले की फास्टलेनसारखी गोष्ट आहे. आता जितकी माहिती आहे तितकी माहिती नव्हती - एखादी सुरुवात कशी करायची, ती कशी वापरायची. आणि त्या वेळी साधन स्वतःच कच्चे होते: सतत त्रुटींनी आम्हाला निराश केले आणि त्यांनी वचन दिलेल्या जादुई ऑटोमेशनवर विश्वास ठेवणे कठीण होते.

तथापि, फास्टलेन कोरमध्ये समाविष्ट असलेल्या मुख्य उपयुक्तता आहेत gym и pilot, आम्ही ते सुरू करण्यात व्यवस्थापित केले.

आमच्या स्क्रिप्ट्स थोड्या सुधारल्या आहेत.

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

सर्व पॅरामीटर्स आवश्यक नसल्यामुळे ते सुधारले गेले आहेत xcodebuild, तुम्हाला सूचित करणे आवश्यक आहे - gym कुठे आणि काय आहे हे स्वतंत्रपणे समजेल. आणि अधिक फाइन-ट्यूनिंगसाठी, तुम्ही मधील समान की निर्दिष्ट करू शकता xcodebuild, फक्त कळांचे नाव स्पष्ट आहे.

यावेळी, जिम आणि अंगभूत xcpretty फॉरमॅटरचे आभार, बिल्ड लॉग अधिक सुवाच्य झाले आहेत. यामुळे तुटलेली असेंब्ली निश्चित करण्यात वेळ वाचण्यास सुरुवात झाली आणि काहीवेळा रिलीझ टीम स्वतःच ते शोधू शकते.

दुर्दैवाने, असेंबली गती मोजमाप xcodebuild и gym आम्ही ते केले नाही, परंतु आम्ही कागदपत्रांवर विश्वास ठेवू - 30% पर्यंत वेग.

सर्व अर्जांसाठी एकल प्रक्रिया

वर्ष 2018 आणि आत्ताचे

2018 पर्यंत, अॅप्लिकेशन्स तयार करण्याची आणि रोल आउट करण्याची प्रक्रिया पूर्णपणे जेनकिन्सकडे हलवली गेली, विकसकांनी त्यांच्या मशीनमधून रिलीझ करणे थांबवले आणि फक्त रिलीझ टीमला रिलीझ करण्याचा अधिकार होता.

आम्हाला चाचण्यांचे प्रक्षेपण आणि स्थिर विश्लेषण सुधारायचे होते आणि आमच्या स्क्रिप्ट वाढल्या आणि वाढल्या. आमच्या अनुप्रयोगांसह वाढले आणि बदलले. त्यावेळी जवळपास 10 ऍप्लिकेशन्स होते. आमच्याकडे दोन प्लॅटफॉर्म आहेत हे लक्षात घेता, म्हणजे सुमारे 20 “जिवंत” स्क्रिप्ट्स.

प्रत्येक वेळी आम्हाला स्क्रिप्टमध्ये नवीन पायरी जोडायची होती, आम्हाला सर्व शेल स्क्रिप्टमध्ये तुकडे कॉपी-पेस्ट करावे लागायचे. कदाचित आम्ही अधिक काळजीपूर्वक काम करू शकलो असतो, परंतु बर्‍याचदा असे बदल टायपोजमध्ये संपतात, जे रिलीझ टीमसाठी स्क्रिप्ट्स दुरुस्त करण्यासाठी आणि कोणत्या हुशार व्यक्तीने ही कमांड जोडली आणि प्रत्यक्षात काय करते हे शोधण्यासाठी संध्याकाळ झाली. सर्वसाधारणपणे, असे म्हटले जाऊ शकत नाही की एका प्लॅटफॉर्मसाठी असेंब्लीसाठी स्क्रिप्ट किमान काही प्रमाणात समान होत्या. जरी त्यांनी नक्कीच तेच केले.

नवीन ऍप्लिकेशनसाठी प्रक्रिया सुरू करण्यासाठी, या स्क्रिप्टची "ताजी" आवृत्ती निवडण्यासाठी, ती डीबग करण्यासाठी आणि "होय, ते कार्य करते" असे म्हणण्यासाठी एक दिवस घालवणे आवश्यक होते.

2018 च्या उन्हाळ्यात, आम्ही पुन्हा एकदा अजूनही विकसित होत असलेल्या फास्टलेनकडे पाहिले.

Задача №1: обобщить все шаги скриптов и переписать их в Fastfile

Когда мы начинали, наши скрипты выглядели портянкой из всех шагов и костылей в одном shell-скрипте в Jenkins. Мы еще не перешли на pipeline и деление по stage.

Посмотрели на то что есть и выделили 4 шага, подходящих под описание нашего CI/CD:

  • बिल्ड - अवलंबित्व स्थापित करणे, संग्रहण एकत्र करणे,
  • चाचणी — विकसक युनिट चाचण्या चालवणे, कव्हरेजची गणना करणे,
  • sonar — запуск всех линтеров и отправка отчетов в SonarQube,
  • deploy — отправка артефакта в альфу (TestFlight).

И если не вдаваться в подробности, опустить используемые ключи у actions, получится вот такой Fastfile:

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

खरं तर, आमची पहिली फास्टफाइल राक्षसी ठरली, आम्हाला अजूनही आवश्यक असलेल्या काही क्रॅच आणि आम्ही बदललेल्या पॅरामीटर्सची संख्या लक्षात घेऊन:

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

वरील उदाहरणात, पॅरामीटर्सचा फक्त एक भाग आहे जो आम्हाला निर्दिष्ट करणे आवश्यक आहे: हे बिल्ड पॅरामीटर्स आहेत - स्कीमा, कॉन्फिगरेशन, प्रोव्हिजन प्रोफाइल नावे, तसेच वितरण पॅरामीटर्स - डेव्हलपर खात्याचा ऍपल आयडी, पासवर्ड, ऍप्लिकेशन आयडी इ. वर प्रथम अंदाजे म्हणून, आम्ही या सर्व की विशेष फायलींमध्ये ठेवतो - Gymfile, Matchfile и Appfile.

आता जेनकिन्समध्ये तुम्ही लहान कमांड कॉल करू शकता जे दृश्य अस्पष्ट करत नाहीत आणि डोळ्यांनी सहज वाचता येतात:

# fastlane ios <lane_name>

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

हुर्रे, आम्ही छान आहोत

तुम्हाला काय मिळाले? प्रत्येक चरणासाठी आदेश साफ करा. फास्टलेन फाइल्समध्ये सुबकपणे मांडलेल्या स्क्रिप्ट्स साफ केल्या. आनंदाने, आम्ही डेव्हलपरकडे धाव घेतली आणि त्यांना त्यांच्या भांडारांमध्ये आवश्यक असलेली प्रत्येक गोष्ट जोडण्यास सांगितली.

परंतु आम्हाला वेळेत लक्षात आले की आम्हाला त्याच अडचणींना सामोरे जावे लागेल - आमच्याकडे अजूनही 20 असेंब्ली स्क्रिप्ट असतील ज्या एका मार्गाने किंवा दुसर्‍या प्रकारे त्यांचे स्वतःचे जीवन जगू लागतील, त्यांना संपादित करणे अधिक कठीण होईल, कारण स्क्रिप्ट रिपॉझिटरीजमध्ये जातील, आणि आम्हाला तिथे प्रवेश नव्हता. आणि, सर्वसाधारणपणे, अशा प्रकारे आपल्या वेदनांचे निराकरण करणे शक्य होणार नाही.

मोबाइल CICD अनुभव: अनेक मोबाइल अनुप्रयोगांसाठी एक फास्टलेन मानक

कार्य #2: N अनुप्रयोगांसाठी एकच फास्टफाइल मिळवा

आता असे दिसते की समस्येचे निराकरण करणे इतके अवघड नाही - व्हेरिएबल्स सेट करा आणि चला जाऊया. होय, खरं तर, अशा प्रकारे समस्या सोडवली गेली. परंतु ज्या क्षणी आम्ही ते खराब केले त्या क्षणी, आमच्याकडे फास्टलेनमध्ये किंवा रुबीमध्ये, ज्यामध्ये फास्टलेन लिहिलेले आहे, किंवा नेटवर्कवर उपयुक्त उदाहरणे नव्हती - तेव्हा फास्टलेनबद्दल लिहिलेल्या प्रत्येकाने एका अनुप्रयोगाच्या उदाहरणापुरते मर्यादित होते. एक विकसक.

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

आता, फास्टलेन फाइल्समध्ये या की वापरणे सुरू करण्यासाठी, आम्हाला त्या तेथे कशा वितरित करायच्या हे शोधून काढावे लागले. फास्टलेनकडे यावर उपाय आहे: dotenv द्वारे चल लोड करत आहे. दस्तऐवजात असे म्हटले आहे की जर तुमच्यासाठी वेगवेगळ्या उद्देशांसाठी की लोड करणे महत्त्वाचे असेल, तर फास्टलेन निर्देशिकेत अनेक कॉन्फिगरेशन फाइल्स तयार करा. .env, .env.default, .env.development.

आणि मग ही लायब्ररी जरा वेगळ्या पद्धतीने वापरायचे ठरवले. डेव्हलपर्सच्या भांडारात फास्टलेन स्क्रिप्ट्स आणि त्याची मेटा माहिती नाही तर फाइलमध्ये या अॅप्लिकेशनच्या अनन्य कीज ठेवू. .env.appName.

स्वत: ला Fastfile, Appfile, Matchfile и Gymfile, आम्ही ते एका वेगळ्या भांडारात लपवले. इतर सेवांकडील पासवर्ड की असलेली अतिरिक्त फाईल तेथे लपविली गेली होती - .env.
आपण एक उदाहरण पाहू शकता येथे.

मोबाइल CICD अनुभव: अनेक मोबाइल अनुप्रयोगांसाठी एक फास्टलेन मानक

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

फास्टलेनकडे फास्टफाइल द्वारे डाउनलोड करण्याचा उपाय असला तरी, हे समाधान आत्तासाठी सोडले कारवाई import_from_git, परंतु ते फक्त फास्टफाइलसाठी कार्य करते, परंतु इतर फायलींसाठी नाही. जर तुम्हाला "खरोखर सुंदर" हवे असेल तर तुम्ही तुमचे स्वतःचे लिहू शकता action.

अँड्रॉइड अॅप्लिकेशन्स आणि रिएक्टनेटिव्हसाठी समान संच तयार करण्यात आला होता, फाइल्स एकाच भांडारात आहेत, परंतु वेगवेगळ्या शाखांमध्ये आहेत iOS, android и react_native.

Когда релиз команда хочет добавить какой-нибудь новый шаг, изменения в скрипте фиксируются через MR в git, больше не надо искать виновников поломанных скриптов, да и в целом — сломать теперь, это надо постараться.

आता ते निश्चित आहे

पूर्वी, आम्ही सर्व स्क्रिप्ट्सची देखभाल करण्यात, त्यांना अद्यतनित करण्यात आणि अद्यतनांचे सर्व परिणाम निश्चित करण्यात वेळ घालवला. रिलीझमधील त्रुटी आणि डाउनटाइमची कारणे ही खूप निराशाजनक होती जेव्हा शेल स्क्रिप्टच्या गोंधळात मागोवा ठेवणे इतके कठीण होते अशा साध्या टायपोज होत्या. आता अशा चुका कमीत कमी झाल्या आहेत. बदल एकाच वेळी सर्व अनुप्रयोगांमध्ये आणले जातात. आणि प्रक्रियेमध्ये नवीन अनुप्रयोग ठेवण्यासाठी 15 मिनिटे लागतात - CI वर टेम्पलेट पाइपलाइन सेट करा आणि विकासकाच्या भांडारात की जोडा.

असे दिसते की Android आणि अनुप्रयोग स्वाक्षरीसाठी फास्टफाइलचा मुद्दा अस्पष्ट राहिला आहे; जर लेख मनोरंजक असेल तर मी पुढे लिहीन. टिप्पण्यांमध्ये किंवा टेलिग्रामवर "तुम्ही या समस्येचे निराकरण कसे कराल" तुमचे प्रश्न किंवा सूचना पाहून मला आनंद होईल बाष्किरोवा.

स्त्रोत: www.habr.com

एक टिप्पणी जोडा