Mobilioji CICD patirtis: vienas greitosios juostos standartas daugeliui mobiliųjų programų

Mobilioji CICD patirtis: vienas greitosios juostos standartas daugeliui mobiliųjų programų
Norėčiau pakalbėti apie nuolatinį programų mobiliesiems integravimą ir pristatymą naudojant „Fastlane“. Kaip įdiegiame CI/CD visose mobiliosiose programose, kaip mes ten atsidūrėme ir kas galiausiai nutiko.

Tinkle jau yra pakankamai medžiagos apie įrankį, kurios mums taip trūko pradžioje, todėl sąmoningai detaliai neaprašysiu įrankio, o remsiuosi tik tuo, ką tada turėjome:

Straipsnis susideda iš dviejų dalių:

  • Mobiliojo CI/CD atsiradimo įmonėje fonas
  • Techninis sprendimas diegti CI/CD N programoms

Pirmoji dalis labiau nostalgija seniems laikams, o antroji – patirtis, kurią galite pritaikyti sau.

Taip atsitiko istoriškai

Metai 2015

Tik pradėjome kurti mobiliąsias aplikacijas, tada nieko nežinojome apie nuolatinę integraciją, apie DevOps ir kitus madingus dalykus. Kiekvieną programos naujinimą kūrėjas išleido iš savo kompiuterio. O jei „Android“ tai gana paprasta - surinkta, pasirašyta .apk ir įkėlė jį į Google Developer Console, tada iOS atveju tuometinis platinimo įrankis per Xcode mums paliko puikius vakarus – bandymai atsisiųsti archyvą dažnai baigdavosi klaidomis ir tekdavo bandyti dar kartą. Paaiškėjo, kad pažangiausias kūrėjas kelis kartus per mėnesį nerašo kodo, o išleidžia aplikaciją.

Metai 2016

Mes užaugome, jau turėjome minčių, kaip iš visos dienos atlaisvinti kūrėjus leidimui, taip pat atsirado antra programa, kuri tik dar labiau pastūmėjo link automatizavimo. Tais pačiais metais pirmą kartą įdiegėme „Jenkins“ ir parašėme daugybę baisių scenarijų, labai panašių į tuos, kuriuos „Fastlane“ rodo savo dokumentacijoje.

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

Deja, iki šiol tik mūsų kūrėjai žinojo, kaip veikia šie scenarijai ir kam reikalinga ši begalė raktų krūva, o kai vėl kažkas sugedo, gaudavo „puikus vakarus“ žurnalų analizei.

Metai 2017

Šiais metais sužinojome, kad yra toks dalykas kaip greitoji juosta. Informacijos nebuvo tiek daug, kiek dabar – kaip ją pradėti, kaip panaudoti. O pats įrankis tuo metu dar buvo grubus: nuolatinės klaidos mus tik nuvylė ir buvo sunku patikėti jų žadėta magiška automatika.

Tačiau pagrindinės komunalinės paslaugos, įtrauktos į „fastlane“ branduolį, yra gym и pilot, mums pavyko tai pradėti.

Mūsų scenarijai buvo šiek tiek patobulinti.

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

Jie buvo patobulinti, jei tik ne visi reikalingi parametrai xcodebuild, reikia nurodyti - gym savarankiškai supras, kur ir kas slypi. O norėdami tiksliau sureguliuoti, galite nurodyti tuos pačius klavišus kaip ir xcodebuild, tik klavišų pavadinimai aiškesni.

Šį kartą sporto salės ir įmontuoto xcpretty formatuotojo dėka statybos žurnalai tapo daug lengviau įskaitomi. Tai pradėjo taupyti laiką taisant sugedusius mazgus, o kartais išleidimo komanda galėjo tai išsiaiškinti pati.

Deja, surinkimo greičio matavimai xcodebuild и gym Mes to nepadarėme, bet pasitikėsime dokumentais – iki 30 % pagreitis.

Vienas procesas visoms programoms

2018 metai ir dabartis

Iki 2018 m. programų kūrimo ir diegimo procesas visiškai persikėlė į „Jenkins“, kūrėjai nustojo leisti iš savo mašinų ir tik leidimų komanda turėjo teisę išleisti.

Jau norėjome patobulinti testų ir statinės analizės paleidimą, o mūsų scenarijai augo ir augo. Augo ir keitėsi kartu su mūsų programomis. Tuo metu programų buvo apie 10. Atsižvelgiant į tai, kad turime dvi platformas, tai yra apie 20 „gyvų“ scenarijų.

Kiekvieną kartą, kai norėjome pridėti naują scenarijaus veiksmą, turėjome nukopijuoti ir įklijuoti dalis į visus apvalkalo scenarijus. Galbūt galėjome dirbti atidžiau, tačiau dažnai tokie pakeitimai baigdavosi rašybos klaidomis, kurios virsdavo vakarais, kai leidėjų komanda taisė scenarijus ir išsiaiškino, kuris išmanusis pridėjo šią komandą ir ką ji iš tikrųjų daro. Apskritai negalima teigti, kad vienos platformos surinkimo scenarijai buvo bent kiek panašūs. Nors jie tikrai padarė tą patį.

Norint pradėti naujos programos procesą, reikėjo praleisti dieną, kad pasirinktumėte „naują“ šių scenarijų versiją, derintumėte ją ir pasakytumėte, kad „taip, tai veikia“.

2018 metų vasarą vėl pažvelgėme į vis dar besivystantį greitkelį.

1 užduotis: apibendrinkite visus scenarijaus veiksmus ir perrašykite juos į Fastfile

Kai pradėjome, mūsų scenarijus atrodė kaip pėdų audeklas, susidedantis iš visų žingsnių ir ramentų viename apvalkalo scenarijuje Jenkins. Dar neperėjome prie vamzdyno ir skirstymo pagal etapus.

Peržiūrėjome, ką turime, ir nustatėme 4 veiksmus, atitinkančius mūsų CI / CD aprašymą:

  • statyti - diegti priklausomybes, surinkti archyvą,
  • bandymas – kūrėjo vieneto testų vykdymas, aprėpties apskaičiavimas,
  • sonaras – paleidžia visus linterius ir siunčia ataskaitas į „SonarQube“,
  • dislokuoti – artefakto siuntimas į alfa (TestFlight).

Ir jei nesigilinsite į detales, praleisdami veiksmuose naudojamus klavišus, gausite šį „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

Tiesą sakant, mūsų pirmasis „Fastfile“ pasirodė siaubingas, atsižvelgiant į kai kuriuos mums vis dar reikalingus ramentus ir pakeistų parametrų skaičių:

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

Aukščiau pateiktame pavyzdyje nurodyta tik dalis parametrų, kuriuos turime nurodyti: tai yra kūrimo parametrai – schema, konfigūracija, teikimo profilio pavadinimai, taip pat platinimo parametrai – kūrėjo paskyros Apple ID, slaptažodis, programos ID ir pan. įjungta. Pirmiausia visus šiuos raktus įdėjome į specialius failus - Gymfile, Matchfile и Appfile.

Dabar Jenkins galite iškviesti trumpas komandas, kurios nesulieja vaizdo ir yra lengvai skaitomos akimis:

# fastlane ios <lane_name>

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

Hurray, mes puikūs

Ką tu gavai? Aiškios komandos kiekvienam žingsniui. Išvalyti scenarijai, tvarkingai išdėstyti „fastlane“ failuose. Apsidžiaugę bėgome pas kūrėjus prašydami, kad jie į savo saugyklas įtrauktų viską, ko reikia.

Tačiau laiku supratome, kad susidursime su tais pačiais sunkumais – vis tiek turėsime 20 surinkimo scenarijų, kurie vienaip ar kitaip pradės gyventi savo gyvenimą, bus sunkiau juos redaguoti, nes scenarijai persikels į saugyklas, ir mes ten neturėjome prieigos. Ir apskritai mūsų skausmo taip išspręsti nepavyks.

Mobilioji CICD patirtis: vienas greitosios juostos standartas daugeliui mobiliųjų programų

2 užduotis: gaukite vieną „Fastfile“, skirtą N programoms

Dabar atrodo, kad išspręsti problemą nėra taip sunku – nustatykite kintamuosius, ir pirmyn. Taip, iš tikrųjų taip problema buvo išspręsta. Bet tuo metu, kai jį sugadinome, neturėjome nei paties „fastlane“, nei „Ruby“, kuriame parašyta „fastlane“, nei naudingų pavyzdžių tinkle – visi, kurie tada rašė apie „fastlane“, apsiribojo pavyzdžiu vienai programai. vienas kūrėjas.

„Fastlane“ gali tvarkyti aplinkos kintamuosius, ir mes jau išbandėme tai nustatydami „Keychain“ slaptažodį:

ENV['KEYCHAIN_PASSWORD']

Peržiūrėję scenarijus nustatėme bendras dalis:

#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

Dabar, norėdami pradėti naudoti šiuos raktus „Fastlane“ failuose, turėjome išsiaiškinti, kaip juos ten pristatyti. „Fastlane“ turi tam sprendimą: kintamųjų įkėlimas per dotenv. Dokumentacijoje rašoma, kad jei jums svarbu įkelti raktus įvairiems tikslams, „fastlane“ kataloge sukurkite kelis konfigūracijos failus. .env, .env.default, .env.development.

Tada nusprendėme naudoti šią biblioteką šiek tiek kitaip. Į kūrėjų saugyklą įdėkime ne greitosios juostos scenarijus ir jų meta informaciją, o unikalius šios programos raktus faile .env.appName.

Patys Fastfile, Appfile, Matchfile и Gymfile, paslėpėme jį atskiroje saugykloje. Ten buvo paslėptas papildomas failas su slaptažodžio raktais iš kitų tarnybų - .env.
Galite pamatyti pavyzdį čia.

Mobilioji CICD patirtis: vienas greitosios juostos standartas daugeliui mobiliųjų programų

Naudojant CI, skambutis beveik nepasikeitė; buvo pridėtas konkrečios programos konfigūracijos raktas:

# 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

Prieš paleisdami komandas, į savo saugyklą įkeliame scenarijus. Ne taip gražiai atrodo:

git clone [email protected]/FastlaneCICD.git fastlane_temp

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

Kol kas paliko šį sprendimą, nors „Fastlane“ turi sprendimą, kaip atsisiųsti „Fastfile“ per veiksmas import_from_git, bet jis veikia tik Fastfile, bet ne kitiems failams. Jei norite „tikrai gražaus“, galite parašyti savo action.

Panašus rinkinys buvo sukurtas Android programoms ir ReactNative, failai yra toje pačioje saugykloje, bet skirtingose ​​šakose iOS, android и react_native.

Kai išleidimo komanda nori pridėti kokį nors naują žingsnį, scenarijaus pakeitimai įrašomi per MR į git, nebereikia ieškoti sugedusių scenarijų kaltininkų ir apskritai dabar reikia bandyti jį sulaužyti.

Dabar tai tikrai

Anksčiau praleisdavome laiką prižiūrėdami visus scenarijus, juos atnaujindami ir taisydami visas atnaujinimo pasekmes. Buvo labai apmaudu, kai leidimų klaidų ir prastovų priežastys buvo paprastos rašybos klaidos, kurias buvo taip sunku stebėti apvalkalo scenarijų kratinyje. Dabar tokių klaidų sumažėja iki minimumo. Pakeitimai iš karto išleidžiami visose programose. Naujos programos įtraukimas į procesą užtrunka 15 minučių – sukurkite šablono konvejerį CI ir pridėkite raktus į kūrėjo saugyklą.

Panašu, kad „Fastfile for Android“ ir programos parašo esmė liko nepaaiškinta, jei straipsnis įdomus, parašysiu tęsinį. Man bus malonu matyti jūsų klausimus ar pasiūlymus „kaip išspręstumėte šią problemą“ komentaruose arba „Telegram“. baškirovą.

Šaltinis: www.habr.com

Добавить комментарий