ProHoster > Blog > podávání > Mobilní CICD zážitek: jeden rychlý standard pro mnoho mobilních aplikací
Mobilní CICD zážitek: jeden rychlý standard pro mnoho mobilních aplikací
Chtěl bych mluvit o nepřetržité integraci a poskytování mobilních aplikací pomocí fastlane. Jak implementujeme CI/CD do všech mobilních aplikací, jak jsme se k tomu dostali a co se nakonec stalo.
Na nástroji je již na síti dostatek materiálu, který nám na začátku tak chyběl, takže nástroj schválně nebudu podrobně popisovat, ale pouze odkážu na to, co jsme tehdy měli:
Technické řešení pro zavedení CI/CD pro N-aplikace
První část je spíše nostalgie po starých časech a druhá je zkušenost, kterou na sebe můžete aplikovat.
Tak se to historicky stalo
Rok 2015
Právě jsme začali vyvíjet mobilní aplikace, pak jsme nevěděli nic o průběžné integraci, o DevOps a dalších módních věcech. Každou aktualizaci aplikace spustil sám vývojář ze svého stroje. A pokud je to pro Android docela jednoduché - sestavené, podepsané .apk a nahráli ho do Google Developer Console, pro iOS nám pak tehdejší distribuční nástroj přes Xcode zanechal skvělé večery – pokusy o stažení archivu často končily chybami a museli jsme to zkoušet znovu. Ukázalo se, že nejpokročilejší vývojář nepíše kód několikrát do měsíce, ale aplikaci vydává.
Rok 2016
Vyrostli jsme, už jsme měli myšlenky na to, jak osvobodit vývojáře z celého dne na vydání a objevila se i druhá aplikace, která nás jen více posunula k automatizaci. Ten samý rok jsme poprvé nainstalovali Jenkinse a napsali spoustu děsivých skriptů, velmi podobných těm, které fastlane ukazuje ve své dokumentaci.
Bohužel až doteď věděli jen naši vývojáři, jak tyto skripty fungují a proč je potřeba tato nekonečná hromada klíčů, a když se zase něco pokazilo, dostali „nádherné večery“ na analýzu protokolů.
Rok 2017
Letos jsme se dozvěděli, že existuje něco jako fastlane. Nebylo tolik informací jako nyní – jak je začít, jak je používat. A samotný nástroj byl v té době ještě hrubý: neustálé chyby nás jen zklamaly a bylo těžké uvěřit v magickou automatizaci, kterou slibovaly.
Nicméně hlavní utility zahrnuté v jádru fastlane jsou gym и pilot, podařilo se nám to nastartovat.
Byly vylepšeny, už jen proto, že ne všechny potřebné parametry xcodebuild, musíte uvést - gym nezávisle pochopí, kde a co leží. A pro přesnější doladění můžete zadat stejné klíče jako v xcodebuild, pouze pojmenování kláves je přehlednější.
Tentokrát se díky posilovně a vestavěnému formátovači xcpretty staly protokoly sestavení mnohem čitelnější. To začalo šetřit čas na opravování rozbitých sestav a někdy na to mohl uvolňovací tým přijít sám.
Bohužel měření rychlosti montáže xcodebuild и gym Neudělali jsme to, ale budeme důvěřovat dokumentaci – až 30% zrychlení.
Jediný proces pro všechny aplikace
Rok 2018 a současnost
V roce 2018 se proces vytváření a zavádění aplikací zcela přesunul do Jenkins, vývojáři přestali vydávat ze svých strojů a právo vydávat měl pouze tým pro vydání.
Už jsme chtěli zlepšit spouštění testů a statické analýzy a naše skripty rostly a rostly. Rostl a měnil se spolu s našimi aplikacemi. V té době bylo aplikací asi 10. Když uvážíme, že máme dvě platformy, je to asi 20 „živých“ skriptů.
Pokaždé, když jsme chtěli do skriptu přidat nový krok, museli jsme kousky zkopírovat a vložit do všech skriptů shellu. Možná jsme mohli pracovat opatrněji, ale často takové změny končily překlepy, které se proměnily ve večery, kdy tým pro vydání opravoval skripty a zjišťoval, který chytrák přidal tento příkaz a co vlastně dělá. Obecně se nedá říci, že by skripty pro sestavení pro jednu platformu byly alespoň trochu podobné. I když určitě udělali to samé.
Aby bylo možné zahájit proces pro novou aplikaci, bylo nutné strávit den výběrem „čerstvé“ verze těchto skriptů, odladit ji a říci, že „ano, funguje“.
V létě 2018 jsme se opět podívali na stále se rozvíjející fastlane.
Úkol č. 1: shrňte všechny kroky skriptu a přepište je do Fastfile
Když jsme začínali, naše skripty vypadaly jako šátek skládající se ze všech kroků a berlí v jednom skriptu v Jenkins. Ještě jsme nepřešli na potrubí a rozdělení podle etap.
Podívali jsme se na to, co máme, a identifikovali jsme 4 kroky, které odpovídají popisu našeho CI/CD:
build - instalace závislostí, sestavení archivu,
test — spuštění testů vývojářských jednotek, výpočet pokrytí,
sonar - spouští všechny lintry a odesílá zprávy do SonarQube,
deploy — odeslání artefaktu do alfy (TestFlight).
A pokud nezajdete do podrobností a vynecháte klíče používané v akcích, získáte tento 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
Ve skutečnosti se náš první Fastfile ukázal jako monstrózní, vezmeme-li v úvahu některé berličky, které jsme stále potřebovali, a množství parametrů, které jsme nahradili:
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
Ve výše uvedeném příkladu je pouze část parametrů, které musíme zadat: jedná se o parametry sestavení - schéma, konfigurace, názvy profilů poskytování a také distribuční parametry - Apple ID účtu vývojáře, heslo, ID aplikace atd. na. Jako první aproximaci jsme všechny tyto klíče vložili do speciálních souborů - Gymfile, Matchfile и Appfile.
Nyní v Jenkins můžete volat krátké příkazy, které nerozmazávají pohled a jsou snadno čitelné okem:
Co jsi dostal? Jasné příkazy pro každý krok. Vyčištěné skripty, úhledně uspořádané do rychlých souborů. S radostí jsme běželi za vývojáři a požádali je, aby do svých úložišť přidali vše, co potřebují.
Časem jsme si ale uvědomili, že se setkáme se stejnými potížemi – stále budeme mít 20 skriptů sestavení, které by tak či onak začaly žít svým vlastním životem, bylo by obtížnější je upravovat, protože by se skripty přesunuly do repozitářů, a neměli jsme tam přístup. A obecně, takto nebude možné naši bolest vyřešit.
Úkol #2: získejte jeden Fastfile pro N aplikací
Nyní se zdá, že řešení problému není tak obtížné - nastavte proměnné a jdeme na to. Ano, ve skutečnosti se tím problém vyřešil. Ale ve chvíli, kdy jsme to podělali, jsme neměli ani odborné znalosti v oblasti fastlane, ani v Ruby, ve kterém se fastlane píše, ani užitečné příklady na síti - každý, kdo tehdy psal o fastlane, byl omezen na příklad pro jednu aplikaci pro jeden vývojář.
Fastlane si poradí s proměnnými prostředí a už jsme to vyzkoušeli nastavením hesla Keychain:
ENV['KEYCHAIN_PASSWORD']
Po zhlédnutí našich skriptů jsme identifikovali společné části:
#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
Nyní, abychom mohli začít používat tyto klíče v souborech fastlane, museli jsme přijít na to, jak je tam doručit. Fastlane má na to řešení: načítání proměnných přes dotenv. Dokumentace říká, že pokud je pro vás důležité načíst klíče pro různé účely, vytvořte několik konfiguračních souborů v adresáři fastlane .env, .env.default, .env.development.
A pak jsme se rozhodli tuto knihovnu využít trochu jinak. Neumístěme do úložiště vývojářů rychlé skripty a jejich metainformace, ale jedinečné klíče této aplikace v souboru .env.appName.
Sami Fastfile, Appfile, Matchfile и Gymfile, schovali jsme jej do samostatného úložiště. Byl tam skrytý další soubor s klíči hesel z jiných služeb - .env.
Můžete vidět příklad zde.
Na CI se volání příliš nezměnilo, byl přidán konfigurační klíč pro konkrétní aplikaci:
Toto řešení prozatím opustilo, ačkoli Fastlane má řešení pro stahování Fastfile přes akceimport_from_git, ale funguje pouze pro Fastfile, ale ne pro ostatní soubory. Pokud chcete „opravdu krásné“, můžete si napsat vlastní action.
Podobná sada byla vytvořena pro Android aplikace a ReactNative, soubory jsou ve stejném úložišti, ale v různých větvích iOS, android и react_native.
Když chce release team přidat nějaký nový krok, změny ve skriptu se zaznamenávají přes MR v git, už není třeba hledat viníky nefunkčních skriptů a obecně, teď se to musíte pokusit rozbít.
Teď je to jisté
Dříve jsme trávili čas údržbou všech skriptů, jejich aktualizací a opravou všech důsledků aktualizací. Bylo velkým zklamáním, když důvodem chyb a výpadků ve vydáních byly jednoduché překlepy, které bylo tak těžké udržet ve změti skriptů shellu. Nyní jsou tyto chyby omezeny na minimum. Změny jsou zaváděny do všech aplikací najednou. A vložení nové aplikace do procesu trvá 15 minut – nastavte kanál šablon na CI a přidejte klíče do úložiště vývojáře.
Zdá se, že pointa s Fastfile pro Android a podpisem aplikace zůstává nevysvětlena, pokud bude článek zajímavý, napíšu pokračování. Rád uvidím vaše dotazy nebo návrhy „jak byste tento problém vyřešili“ v komentářích nebo na Telegramu Baškirová.