Mobile CICD experience: isang fastlane standard para sa maraming mobile application

Mobile CICD experience: isang fastlane standard para sa maraming mobile application
Gusto kong pag-usapan ang tungkol sa tuluy-tuloy na pagsasama at paghahatid para sa mga mobile app gamit ang fastlane. Paano namin ipinapatupad ang CI/CD sa lahat ng mobile application, paano kami nakarating doon at kung ano ang nangyari sa huli.

Mayroon nang sapat na materyal sa network sa tool, na kulang sa atin sa simula, kaya't sadyang hindi ko ilalarawan ang tool nang detalyado, ngunit sasangguni lamang sa kung ano ang mayroon tayo noon:

Ang artikulo ay binubuo ng dalawang bahagi:

  • Background sa paglitaw ng mobile CI/CD sa kumpanya
  • Teknikal na solusyon para sa paglulunsad ng CI/CD para sa mga N-application

Ang unang bahagi ay higit na nostalgia para sa mga lumang araw, at ang pangalawa ay isang karanasan na maaari mong ilapat sa iyong sarili.

Ganito ang nangyari sa kasaysayan

2015 year

Nagsimula lang kaming bumuo ng mga mobile application, pagkatapos ay wala kaming alam tungkol sa tuluy-tuloy na pagsasama, tungkol sa DevOps at iba pang mga naka-istilong bagay. Ang bawat pag-update ng application ay inilunsad ng developer mismo mula sa kanyang makina. At kung para sa Android ito ay medyo simple - binuo, nilagdaan .apk at na-upload ito sa Google Developer Console, pagkatapos para sa iOS ang tool sa pamamahagi noon sa pamamagitan ng Xcode ay nag-iwan sa amin ng magagandang gabi - ang mga pagtatangka na i-download ang archive ay kadalasang nauuwi sa mga error at kailangan naming subukang muli. Ito ay lumabas na ang pinaka-advanced na developer ay hindi nagsusulat ng code nang maraming beses sa isang buwan, ngunit sa halip ay naglalabas ng application.

2016 year

Lumaki kami, mayroon na kaming mga iniisip tungkol sa kung paano palayain ang mga developer mula sa isang buong araw para sa isang release, at lumitaw din ang pangalawang application, na nagtulak lamang sa amin nang higit pa patungo sa automation. Sa parehong taon, na-install namin ang Jenkins sa unang pagkakataon at nagsulat ng isang grupo ng mga nakakatakot na script, na halos kapareho sa mga ipinapakita ng fastlane sa dokumentasyon nito.

$ 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"

Sa kasamaang palad, hanggang ngayon ang aming mga developer lang ang nakakaalam kung paano gumagana ang mga script na ito at kung bakit kailangan ang walang katapusang stack ng mga key na ito, at kapag may nasira muli, nakuha nila ang "napakagandang gabi" para sa pagsusuri ng mga log.

2017 year

Sa taong ito natutunan namin na mayroong isang bagay tulad ng fastlane. Walang gaanong impormasyon tulad ng mayroon ngayon - kung paano magsimula ng isa, kung paano ito gamitin. At ang tool mismo ay krudo pa rin sa oras na iyon: ang patuloy na mga pagkakamali ay nabigo lamang sa amin at mahirap paniwalaan ang mahiwagang automation na ipinangako nila.

Gayunpaman, ang mga pangunahing utility na kasama sa fastlane core ay gym ΠΈ pilot, nagawa naming simulan ito.

Ang aming mga script ay napabuti ng kaunti.

$ fastlane gym  β€”-workspace "Example.xcworkspace" 
                --scheme "AppName" 
                β€”-buildlog_path "/tmp" 
                -β€”clean

Ang mga ito ay napabuti, kung dahil lamang sa hindi lahat ng mga parameter na kinakailangan para sa xcodebuild, kailangan mong ipahiwatig - gym ay malayang mauunawaan kung saan at kung ano ang namamalagi. At para sa higit pang fine-tuning, maaari mong tukuyin ang parehong mga key tulad ng sa xcodebuild, ang pagpapangalan lamang ng mga susi ay mas malinaw.

Sa pagkakataong ito, salamat sa gym at sa built-in na xcpretty formatter, ang mga build log ay naging mas nababasa. Nagsimula itong makatipid ng oras sa pag-aayos ng mga sirang asembliya, at kung minsan ay maiisip ito ng pangkat ng pagpapalaya sa kanilang sarili.

Sa kasamaang palad, ang mga sukat ng bilis ng pagpupulong xcodebuild ΠΈ gym Hindi namin ginawa, ngunit magtitiwala kami sa dokumentasyon - hanggang 30% na bilis.

Isang proseso para sa lahat ng mga aplikasyon

Taong 2018 at kasalukuyan

Sa pamamagitan ng 2018, ang proseso ng pagbuo at paglulunsad ng mga application ay ganap na inilipat sa Jenkins, ang mga developer ay huminto sa pag-release mula sa kanilang mga machine, at ang release team lamang ang may karapatang mag-release.

Nais na naming pagbutihin ang paglulunsad ng mga pagsubok at static na pagsusuri, at ang aming mga script ay lumago at lumago. Lumaki at nagbago kasama ng aming mga aplikasyon. Sa oras na iyon ay may humigit-kumulang 10 mga aplikasyon na isinasaalang-alang na mayroon kaming dalawang platform, iyon ay tungkol sa 20 "buhay" na mga script.

Sa tuwing gusto naming magdagdag ng bagong hakbang sa script, kailangan naming kopyahin-i-paste ang mga piraso sa lahat ng mga script ng shell. Marahil ay nakapagtrabaho kami nang mas maingat, ngunit kadalasan ang mga ganitong pagbabago ay nauuwi sa mga typo, na naging mga gabi para sa release team upang ayusin ang mga script at malaman kung sinong matalinong tao ang nagdagdag ng command na ito at kung ano talaga ang ginagawa nito. Sa pangkalahatan, hindi masasabi na ang mga script para sa pagpupulong para sa isang platform ay hindi bababa sa medyo magkatulad. Bagaman tiyak na ginawa nila ang parehong bagay.

Upang makapagsimula ng proseso para sa isang bagong aplikasyon, kinailangan na gumugol ng isang araw upang pumili ng "sariwang" bersyon ng mga script na ito, i-debug ito at sabihin na "oo, gumagana ito."

Noong tag-araw ng 2018, muli kaming tumingin sa patuloy na umuunlad na fastlane.

Gawain #1: ibuod ang lahat ng hakbang sa script at muling isulat ang mga ito sa Fastfile

Noong nagsimula kami, ang aming mga script ay mukhang isang footcloth na binubuo ng lahat ng mga hakbang at saklay sa isang shell script sa Jenkins. Hindi pa tayo lumilipat sa pipeline at division by stage.

Tiningnan namin kung ano ang mayroon kami at natukoy ang 4 na hakbang na akma sa paglalarawan ng aming CI/CD:

  • build - pag-install ng mga dependency, pag-assemble ng archive,
  • pagsubok β€” pagpapatakbo ng mga pagsubok sa yunit ng developer, pagkalkula ng saklaw,
  • sonar - inilunsad ang lahat ng linter at nagpapadala ng mga ulat sa SonarQube,
  • deploy β€” pagpapadala ng artifact sa alpha (TestFlight).

At kung hindi ka magsasalaysay ng mga detalye, na tinanggal ang mga key na ginamit sa mga aksyon, makukuha mo ang Fastfile na ito:

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

Sa katunayan, ang aming unang Fastfile ay naging napakapangit, isinasaalang-alang ang ilan sa mga saklay na kailangan pa rin namin at ang bilang ng mga parameter na aming pinalitan:

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

Sa halimbawa sa itaas, bahagi lang ng mga parameter ang kailangan naming tukuyin: ito ang mga build parameter - schema, configuration, Provision Profile name, pati na rin ang distribution parameters - Apple ID ng developer account, password, application ID, at iba pa. sa. Bilang unang pagtataya, inilalagay namin ang lahat ng mga key na ito sa mga espesyal na file - Gymfile, Matchfile ΠΈ Appfile.

Ngayon sa Jenkins maaari kang tumawag ng mga maiikling command na hindi lumalabo ang view at madaling mabasa ng mata:

# fastlane ios <lane_name>

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

Hurray, magaling kami

Ano ang nakuha mo? I-clear ang mga utos para sa bawat hakbang. Nilinis ang mga script, maayos na nakaayos sa mga fastlane file. Nagagalak, tumakbo kami sa mga developer na humihiling sa kanila na idagdag ang lahat ng kailangan nila sa kanilang mga repository.

Ngunit napagtanto namin sa oras na makakaranas kami ng parehong mga paghihirap - magkakaroon pa rin kami ng 20 script ng pagpupulong na sa isang paraan o iba pa ay magsisimulang mamuhay ng kanilang sariling mga buhay, magiging mas mahirap na i-edit ang mga ito, dahil ang mga script ay lilipat sa mga repositoryo, at wala kaming access doon. At, sa pangkalahatan, hindi posible na lutasin ang aming sakit sa ganitong paraan.

Mobile CICD experience: isang fastlane standard para sa maraming mobile application

Gawain #2: kumuha ng isang Fastfile para sa N application

Ngayon tila na ang paglutas ng problema ay hindi napakahirap - itakda ang mga variable, at umalis tayo. Oo, sa katunayan, sa ganoong paraan nalutas ang problema. Ngunit sa sandaling nasira namin ito, wala kaming kadalubhasaan sa fastlane mismo, o sa Ruby, kung saan nakasulat ang fastlane, o mga kapaki-pakinabang na halimbawa sa network - lahat ng sumulat tungkol sa fastlane noon ay limitado sa isang halimbawa para sa isang aplikasyon para sa isang developer.

Kakayanin ng Fastlane ang mga variable ng kapaligiran, at nasubukan na namin ito sa pamamagitan ng pagtatakda ng password ng Keychain:

ENV['KEYCHAIN_PASSWORD']

Pagkatapos tingnan ang aming mga script, natukoy namin ang mga karaniwang bahagi:

#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

Ngayon, para simulang gamitin ang mga key na ito sa mga fastlane na file, kinailangan naming malaman kung paano ihahatid ang mga ito doon. Ang Fastlane ay may solusyon para dito: naglo-load ng mga variable sa pamamagitan ng dotenv. Sinasabi ng dokumentasyon na kung mahalaga para sa iyo na mag-load ng mga susi para sa iba't ibang layunin, lumikha ng ilang configuration file sa direktoryo ng fastlane .env, .env.default, .env.development.

At pagkatapos ay nagpasya kaming gamitin ang library na ito nang medyo naiiba. Ilagay natin sa repository ng mga developer hindi ang mga fastlane script at ang meta information nito, ngunit ang mga natatanging key ng application na ito sa file .env.appName.

Ang kanilang mga sarili Fastfile, Appfile, Matchfile ΠΈ Gymfile, itinago namin ito sa isang hiwalay na imbakan. Ang isang karagdagang file na may mga password key mula sa iba pang mga serbisyo ay nakatago doon - .env.
Makakakita ka ng isang halimbawa dito.

Mobile CICD experience: isang fastlane standard para sa maraming mobile application

Sa CI, ang tawag ay hindi masyadong nagbago ng isang configuration key para sa isang partikular na application ay naidagdag:

# 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

Bago patakbuhin ang mga utos, nilo-load namin ang aming repositoryo ng mga script. Mukhang hindi maganda:

git clone [email protected]/FastlaneCICD.git fastlane_temp

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

Iniwan ang solusyon na ito sa ngayon, kahit na ang Fastlane ay may solusyon para sa pag-download ng Fastfile sa pamamagitan ng aksyon import_from_git, ngunit ito ay gumagana lamang para sa Fastfile, ngunit hindi para sa iba pang mga file. Kung gusto mo ng "talagang maganda", maaari kang sumulat ng iyong sarili action.

Ang isang katulad na hanay ay ginawa para sa mga Android application at ReactNative, ang mga file ay nasa parehong repositoryo, ngunit sa iba't ibang sangay iOS, android ΠΈ react_native.

Kapag gusto ng release team na magdagdag ng ilang bagong hakbang, ang mga pagbabago sa script ay naitala sa pamamagitan ng MR sa git, hindi na kailangan pang hanapin ang mga salarin ng mga sirang script, at sa pangkalahatan, ngayon ay kailangan mong subukang sirain ito.

Ngayon ay iyon na para sigurado

Noong nakaraan, ginugol namin ang oras sa pagpapanatili ng lahat ng mga script, pag-update ng mga ito at pag-aayos ng lahat ng mga kahihinatnan ng mga update. Ito ay napaka-disappointing kapag ang mga dahilan para sa mga error at downtime sa mga release ay simpleng typo na napakahirap subaybayan sa paghalu-haluin ng shell script. Ngayon ang mga ganitong error ay nabawasan sa pinakamaliit. Ang mga pagbabago ay inilunsad sa lahat ng mga application nang sabay-sabay. At tumatagal ng 15 minuto para maglagay ng bagong application sa proseso - mag-set up ng template pipeline sa CI at idagdag ang mga susi sa repository ng developer.

Tila ang punto sa Fastfile para sa Android at lagda ng aplikasyon ay nananatiling hindi maipaliwanag kung ang artikulo ay kawili-wili, magsusulat ako ng isang pagpapatuloy. Natutuwa akong makita ang iyong mga tanong o mungkahi "paano mo malulutas ang problemang ito" sa mga komento o sa Telegram bashkirova.

Pinagmulan: www.habr.com

Magdagdag ng komento