Mobiele CICD-ervaring: een fastlane-standaard vir baie mobiele toepassings

Mobiele CICD-ervaring: een fastlane-standaard vir baie mobiele toepassings
Ek wil graag praat oor deurlopende integrasie en aflewering vir mobiele toepassings wat Fastlane gebruik. Hoe ons CI/CD op alle mobiele toepassings implementeer, hoe ons daar gekom het en wat op die ou end gebeur het.

Daar is reeds genoeg materiaal op die netwerk op die instrument, wat ons aan die begin so kort gehad het, so ek sal doelbewus nie die instrument in detail beskryf nie, maar sal slegs verwys na wat ons toe gehad het:

Die artikel bestaan ​​uit twee dele:

  • Agtergrond tot die opkoms van mobiele CI/CD in die maatskappy
  • Tegniese oplossing vir die uitrol van CI/CD vir N-toepassings

Die eerste deel is meer nostalgie vir die ou dae, en die tweede is 'n ervaring wat jy op jouself kan toepas.

Dit is hoe dit histories gebeur het

Jaar 2015

Ons het pas begin om mobiele toepassings te ontwikkel, toe het ons niks geweet van deurlopende integrasie, van DevOps en ander modieuse dinge nie. Elke toepassingopdatering is deur die ontwikkelaar self vanaf sy masjien ontplooi. En as dit vir Android redelik eenvoudig is - saamgestel, onderteken .apk en dit na die Google Developer Console opgelaai het, dan vir iOS het die destydse verspreidingshulpmiddel via Xcode vir ons wonderlike aande gelaat - pogings om die argief af te laai het dikwels op foute geëindig en ons moes weer probeer. Dit het geblyk dat die mees gevorderde ontwikkelaar nie 'n paar keer per maand kode skryf nie, maar eerder die toepassing vrystel.

Jaar 2016

Ons het grootgeword, ons het reeds gedagtes gehad oor hoe om ontwikkelaars van 'n hele dag vry te maak vir 'n vrystelling, en 'n tweede toepassing het ook verskyn, wat ons net meer na outomatisering gedryf het. Dieselfde jaar het ons Jenkins vir die eerste keer geïnstalleer en 'n klomp skrikwekkende skrifte geskryf, baie soortgelyk aan dié wat Fastlane in sy dokumentasie wys.

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

Ongelukkig het net ons ontwikkelaars tot nou toe geweet hoe hierdie skrifte werk en hoekom hierdie eindelose stapel sleutels nodig is, en toe iets weer gebreek het, het hulle die "pragtige aande" gekry om logs te ontleed.

Jaar 2017

Hierdie jaar het ons geleer dat daar iets soos fastlane is. Daar was nie soveel inligting soos nou nie - hoe om een ​​te begin, hoe om dit te gebruik. En die instrument self was op daardie stadium nog kru: konstante foute het ons net teleurgestel en dit was moeilik om te glo in die magiese outomatisering wat hulle belowe het.

Die belangrikste hulpmiddels wat in die snelbaankern ingesluit is, is egter gym и pilot, het ons daarin geslaag om dit te begin.

Ons skrifte is 'n bietjie verbeter.

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

Hulle is verbeter, al is dit net omdat nie al die parameters wat nodig is vir xcodebuild, moet jy aandui - gym sal onafhanklik verstaan ​​waar en wat lê. En vir meer fyn instel, kan jy dieselfde sleutels spesifiseer as in xcodebuild, net die naam van die sleutels is duideliker.

Hierdie keer, danksy gimnasium en die ingeboude xcpretty formatter, het die boulogboeke baie meer leesbaar geword. Dit het tyd begin spaar om stukkende samestellings reg te maak, en soms kon die vrystellingspan dit op hul eie uitvind.

Ongelukkig, montering spoed metings xcodebuild и gym Ons het dit nie gedoen nie, maar ons sal die dokumentasie vertrou - tot 30% versnel.

Enkele proses vir alle aansoeke

Jaar 2018 en hede

Teen 2018 het die proses van die bou en uitrol van toepassings heeltemal na Jenkins verskuif, ontwikkelaars het opgehou om van hul masjiene vry te stel, en net die vrystellingspan het die reg gehad om vry te stel.

Ons wou reeds die bekendstelling van toetse en statiese ontleding verbeter, en ons skrifte het gegroei en gegroei. Gegroei en verander saam met ons toepassings. Op daardie tydstip was daar ongeveer 10 toepassings. As in ag geneem word dat ons twee platforms het, is dit ongeveer 20 "lewende" skrifte.

Elke keer as ons 'n nuwe stap by die skrif wou voeg, moes ons die stukke in al die dop skrifte kopieer en plak. Miskien kon ons meer versigtig gewerk het, maar sulke veranderinge het dikwels in tikfoute geëindig, wat in aande geword het vir die vrystellingspan om skrifte reg te maak en uit te vind watter slim ou hierdie opdrag bygevoeg het en wat dit eintlik doen. Oor die algemeen kan daar nie gesê word dat die skrifte vir samestelling vir een platform ten minste ietwat soortgelyk was nie. Alhoewel hulle beslis dieselfde ding gedoen het.

Om 'n proses vir 'n nuwe toepassing te begin, was dit nodig om 'n dag te spandeer om 'n "vars" weergawe van hierdie skrifte te kies, dit te ontfout en te sê dat "ja, dit werk."

In die somer van 2018 het ons weer na die vinnig ontwikkelende snellaan gekyk.

Taak #1: som alle skripstappe op en herskryf dit in Fastfile

Toe ons begin het, het ons skrifte gelyk soos 'n voetdoek wat bestaan ​​het uit al die trappe en krukke in een dop skrif in Jenkins. Ons het nog nie oorgeskakel na pypleiding en verdeling vir stadium nie.

Ons het gekyk na wat ons het en 4 stappe geïdentifiseer wat by die beskrywing van ons CI/CD pas:

  • bou - die installering van afhanklikhede, die samestelling van die argief,
  • toets – voer ontwikkelaareenheidtoetse uit, bereken dekking,
  • sonar - stel alle linters bekend en stuur verslae na SonarQube,
  • ontplooi - stuur 'n artefak na alfa (TestFlight).

En as jy nie in besonderhede ingaan nie en die sleutels wat in aksies gebruik word weglaat, sal jy hierdie Fastfile kry:

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

Trouens, ons eerste Fastfile blyk monsteragtig te wees, met inagneming van sommige van die krukke wat ons nog nodig gehad het en die aantal parameters wat ons vervang het:

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

In die voorbeeld hierbo, slegs 'n deel van die parameters wat ons moet spesifiseer: dit is die bou-parameters - skema, konfigurasie, voorsieningsprofielname, sowel as verspreidingsparameters - Apple ID van die ontwikkelaarrekening, wagwoord, toepassing-ID, ensovoorts aan. As 'n eerste benadering, plaas ons al hierdie sleutels in spesiale lêers - Gymfile, Matchfile и Appfile.

Nou in Jenkins kan jy kort opdragte noem wat nie die aansig vervaag nie en maklik leesbaar is vir die oog:

# fastlane ios <lane_name>

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

Hoera, ons is wonderlik

Wat het jy gekry? Duidelike opdragte vir elke stap. Skoongemaakte skrifte, netjies gerangskik in vinnige lêers. Verheugend het ons na die ontwikkelaars gehardloop en hulle gevra om alles wat hulle nodig het by hul bewaarplekke te voeg.

Maar ons het mettertyd besef dat ons dieselfde probleme sou teëkom - ons sou steeds 20 samestellingsskrifte hê wat op een of ander manier hul eie lewens sou begin lei, dit sou moeiliker wees om dit te redigeer, aangesien die skrifte na bewaarplekke sou skuif, en ons het nie toegang daar gehad nie. En oor die algemeen sal dit nie moontlik wees om ons pyn op hierdie manier op te los nie.

Mobiele CICD-ervaring: een fastlane-standaard vir baie mobiele toepassings

Taak #2: kry 'n enkele Fastfile vir N toepassings

Nou blyk dit dat dit nie so moeilik is om die probleem op te los nie - stel die veranderlikes in, en laat ons gaan. Ja, om die waarheid te sê, dit is hoe die probleem opgelos is. Maar op die oomblik toe ons dit opgefok het, het ons nie kundigheid in fastlane self gehad nie, nóg in Ruby, waarin fastlane geskryf is, nóg nuttige voorbeelde op die netwerk - almal wat toe oor fastlane geskryf het, was beperk tot 'n voorbeeld vir een aansoek vir een ontwikkelaar.

Fastlane kan omgewingsveranderlikes hanteer, en ons het dit reeds probeer deur die sleutelhanger-wagwoord in te stel:

ENV['KEYCHAIN_PASSWORD']

Nadat ons na ons skrifte gekyk het, het ons die algemene dele geïdentifiseer:

#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

Nou, om hierdie sleutels in fastlane-lêers te begin gebruik, moes ons uitvind hoe om dit daar af te lewer. Fastlane het 'n oplossing hiervoor: laai veranderlikes via dotenv. Die dokumentasie sê dat as dit vir jou belangrik is om sleutels vir verskillende doeleindes te laai, skep verskeie konfigurasielêers in die fastlane-gids .env, .env.default, .env.development.

En toe besluit ons om hierdie biblioteek 'n bietjie anders te gebruik. Kom ons plaas nie die fastlane-skrifte en sy meta-inligting in die ontwikkelaars se bewaarplek nie, maar die unieke sleutels van hierdie toepassing in die lêer .env.appName.

hulself Fastfile, Appfile, Matchfile и Gymfile, het ons dit in 'n aparte bewaarplek versteek. 'n Bykomende lêer met wagwoordsleutels van ander dienste is daar versteek - .env.
Jy kan 'n voorbeeld sien hier.

Mobiele CICD-ervaring: een fastlane-standaard vir baie mobiele toepassings

Op CI het die oproep nie veel verander nie; 'n konfigurasiesleutel vir 'n spesifieke toepassing is bygevoeg:

# 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

Voordat ons die opdragte uitvoer, laai ons ons bewaarplek met skrifte. Lyk nie so lekker nie:

git clone [email protected]/FastlaneCICD.git fastlane_temp

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

Het hierdie oplossing vir eers verlaat, hoewel Fastlane 'n oplossing het om Fastfile via af te laai aksie import_from_git, maar dit werk net vir Fastfile, maar nie vir ander lêers nie. As jy "regtig mooi" wil hê, kan jy jou eie skryf action.

'n Soortgelyke stel is gemaak vir Android-toepassings en ReactNative, die lêers is in dieselfde bewaarplek, maar in verskillende takke iOS, android и react_native.

Wanneer die vrystellingspan 'n nuwe stap wil byvoeg, word veranderinge in die script via MR in git aangeteken, dit is nie meer nodig om na die skuldiges van gebroke scripts te soek nie, en in die algemeen moet jy nou probeer om dit te breek.

Nou is dit vir seker

Voorheen het ons tyd spandeer om al die skrifte te onderhou, dit op te dateer en al die gevolge van opdaterings reg te stel. Dit was baie teleurstellend toe die redes vir foute en stilstand in vrystellings eenvoudige tikfoute was wat so moeilik was om tred te hou in die mengelmoes van dopskrifte. Nou word sulke foute tot die minimum beperk. Veranderinge word gelyktydig na alle toepassings uitgerol. En dit neem 15 minute om 'n nuwe toepassing in die proses te plaas - stel 'n sjabloonpyplyn op CI op en voeg die sleutels by die ontwikkelaar se bewaarplek.

Dit blyk dat die punt met Fastfile vir Android en toepassingshandtekening onverklaarbaar bly; as die artikel interessant is, sal ek 'n voortsetting skryf. Ek sal bly wees om jou vrae of voorstelle te sien "hoe sal jy hierdie probleem oplos" in die kommentaar of op Telegram bashkirova.

Bron: will.com

Voeg 'n opmerking