ProHoster > Blog > uprava > Mobilno CICD iskustvo: jedan brzi standard za mnoge mobilne aplikacije
Mobilno CICD iskustvo: jedan brzi standard za mnoge mobilne aplikacije
Želio bih govoriti o kontinuiranoj integraciji i isporuci mobilnih aplikacija koje koriste Fastlane. Kako implementiramo CI/CD na sve mobilne aplikacije, kako smo do toga došli i što se na kraju dogodilo.
Na mreži već ima dovoljno materijala o alatu koji nam je nedostajao u startu, pa namjerno neću detaljno opisivati alat, već ću se osvrnuti samo na ono što smo tada imali:
Tehničko rješenje za uvođenje CI/CD za N-aplikacije
Prvi dio je više nostalgija za starim danima, a drugi je iskustvo koje možete primijeniti na sebe.
Tako se to povijesno dogodilo
Godina 2015
Tek smo počeli razvijati mobilne aplikacije, tada nismo znali ništa o kontinuiranoj integraciji, o DevOpsu i ostalim pomodnim stvarima. Svako ažuriranje aplikacije uveo je programer sam sa svog računala. A ako je za Android prilično jednostavno - sastavljeno, potpisano .apk i uploadali ga na Google Developer Console, zatim nam je za iOS tadašnji alat za distribuciju preko Xcodea ostavio odlične večeri – pokušaji preuzimanja arhive često su završavali pogreškama i morali smo pokušavati ponovno. Pokazalo se da najnapredniji programer ne piše kod nekoliko puta mjesečno, već izdaje aplikaciju.
Godina 2016
Odrasli smo, već smo razmišljali o tome kako programere osloboditi cijelog dana za izdanje, a pojavila se i druga aplikacija koja nas je samo više gurnula prema automatizaciji. Iste godine smo prvi put instalirali Jenkinsa i napisali hrpu strašnih skripti, vrlo sličnih onima koje fastlane prikazuje u svojoj dokumentaciji.
Nažalost, do sada su samo naši programeri znali kako te skripte rade i zašto je potreban taj beskrajni hrp ključeva, a kad bi se opet nešto pokvarilo, dobili su “prekrasne večeri” za analizu zapisa.
Godina 2017
Ove godine smo saznali da postoji nešto poput fastlanea. Nije bilo toliko informacija kao sada - kako ga pokrenuti, kako ga koristiti. A sam alat je u to vrijeme još bio sirov: stalne greške samo su nas razočarale i bilo je teško povjerovati u čarobnu automatizaciju koju su obećavali.
Međutim, glavni uslužni programi uključeni u jezgru fastlanea su gym и pilot, uspjeli smo ga pokrenuti.
Oni su poboljšani, makar samo zato što nisu svi parametri potrebni za xcodebuild, trebate navesti - gym samostalno će razumjeti gdje i što leži. A za više finog podešavanja, možete navesti iste tipke kao u xcodebuild, samo je imenovanje tipki jasnije.
Ovaj put, zahvaljujući teretani i ugrađenom formateru xcpretty, zapisnici izgradnje postali su mnogo čitljiviji. To je počelo uštedjeti vrijeme na popravljanju pokvarenih sklopova, a ponekad je tim za izdavanje mogao sam to shvatiti.
Nažalost, mjerenja brzine montaže xcodebuild и gym Mi to nismo učinili, ali ćemo vjerovati dokumentaciji - do 30% ubrzanja.
Jedinstveni proces za sve aplikacije
Godina 2018. i danas
Do 2018. proces izgradnje i izvođenja aplikacija potpuno se preselio u Jenkins, programeri su prestali izdavati sa svojih strojeva, a samo je tim za izdavanje imao pravo izdavanja.
Već smo željeli poboljšati pokretanje testova i statičke analize, a naše su skripte rasle i rasle. Rasla je i mijenjala se zajedno s našim aplikacijama. Tada je bilo oko 10 aplikacija, s obzirom da imamo dvije platforme, to je oko 20 “živih” skripti.
Svaki put kad smo htjeli dodati novi korak u skriptu, morali smo kopirati i zalijepiti dijelove u sve skripte ljuske. Možda smo mogli raditi pažljivije, ali često su takve izmjene završavale greškama pri upisu, što se pretvaralo u večeri za tim za izdanje da popravi skripte i otkrije koji je pametnjaković dodao ovu naredbu i što ona zapravo radi. Općenito, ne može se reći da su skripte za montažu za jednu platformu bile barem donekle slične. Iako su sigurno učinili istu stvar.
Da bi se pokrenuo proces za novu aplikaciju, bilo je potrebno potrošiti jedan dan da se izabere “svježa” verzija ovih skripti, ispravi pogreška i kaže da “da, radi”.
U ljeto 2018. ponovno smo se okrenuli prema fastlaneu koji je još uvijek u razvoju.
Zadatak #1: sažeti sve korake skripte i prepisati ih u Fastfile
Kad smo počeli, naše su skripte izgledale kao krpa za noge koja se sastoji od svih stepenica i štaka u jednoj shell skripti u Jenkinsu. Nismo još prešli na cjevovod i podjelu po fazama.
Pogledali smo što imamo i identificirali 4 koraka koji odgovaraju opisu našeg CI/CD-a:
test — izvođenje jediničnih testova programera, izračunavanje pokrivenosti,
sonar - pokreće sve lintere i šalje izvješća SonarQubeu,
deploy — slanje artefakta u alpha (TestFlight).
A ako ne idete u detalje, izostavljajući tipke koje se koriste u akcijama, dobit ćete ovaj 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
Zapravo, naš prvi Fastfile ispao je monstruozan, s obzirom na neke štake koje su nam još trebale i broj parametara koje smo zamijenili:
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
U gornjem primjeru, samo dio parametara koje trebamo specificirati: to su parametri izgradnje - shema, konfiguracija, nazivi Provision Profile, kao i parametri distribucije - Apple ID računa razvojnog programera, lozinka, ID aplikacije itd. na. Kao prvu aproksimaciju, sve ove ključeve stavljamo u posebne datoteke - Gymfile, Matchfile и Appfile.
Sada u Jenkinsu možete pozivati kratke naredbe koje ne zamagljuju pogled i lako su čitljive okom:
Što si dobio? Jasne naredbe za svaki korak. Očišćene skripte, uredno složene u fastlane datoteke. Radujući se, otrčali smo do programera tražeći od njih da dodaju sve što im je potrebno u njihova spremišta.
Ali s vremenom smo shvatili da ćemo se susresti s istim poteškoćama - i dalje bismo imali 20 asemblerskih skripti koje bi na ovaj ili onaj način počele živjeti vlastitim životom, bilo bi ih teže uređivati, jer bi se skripte preselile u repozitorije, a tamo nismo imali pristupa. I, općenito, neće biti moguće riješiti našu bol na ovaj način.
Zadatak #2: dobiti jedan Fastfile za N aplikacija
Sada se čini da rješavanje problema nije tako teško - postavite varijable i idemo. Da, zapravo, tako je problem riješen. No, u trenutku kad smo ga zeznuli, nismo imali ekspertizu ni za sam fastlane, ni za Ruby u kojem piše fastlane, niti korisne primjere na mreži - svi koji su tada pisali o fastlaneu bili su ograničeni na primjer za jednu aplikaciju za jedan programer.
Fastlane može rukovati varijablama okruženja, a to smo već isprobali postavljanjem lozinke za privjesak ključeva:
ENV['KEYCHAIN_PASSWORD']
Nakon što smo pogledali naše skripte, identificirali smo zajedničke dijelove:
#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
Sada, da bismo počeli koristiti te ključeve u datotekama fastlanea, morali smo smisliti kako ih tamo isporučiti. Fastlane ima rješenje za to: učitavanje varijabli preko dotenv. Dokumentacija kaže da ako vam je važno učitati ključeve za različite svrhe, napravite nekoliko konfiguracijskih datoteka u direktoriju fastlane .env, .env.default, .env.development.
A onda smo odlučili ovu knjižnicu koristiti malo drugačije. Postavimo u repozitorij programera ne fastlane skripte i njihove meta informacije, već jedinstvene ključeve ove aplikacije u datoteci .env.appName.
sebe Fastfile, Appfile, Matchfile и Gymfile, sakrili smo ga u zasebno spremište. Tamo je bila skrivena dodatna datoteka s ključevima zaporki s drugih usluga - .env.
Možete vidjeti primjer здесь.
Na CI-ju se poziv nije puno promijenio; dodan je konfiguracijski ključ za određenu aplikaciju:
Za sada sam ostavio ovo rješenje, iako Fastlane ima rješenje za preuzimanje Fastfilea putem akcijskiimport_from_git, ali radi samo za Fastfile, ali ne i za druge datoteke. Ako želite "stvarno lijepo", možete napisati svoje action.
Sličan skup napravljen je za Android aplikacije i ReactNative, datoteke su u istom repozitoriju, ali u različitim granama iOS, android и react_native.
Kada tim za izdanje želi dodati neki novi korak, promjene u skripti se bilježe preko MR-a u git-u, više nema potrebe tražiti krivce za pokvarene skripte i općenito, sada je morate pokušati razbiti.
Sada je to sigurno to
Ranije smo provodili vrijeme održavajući sve skripte, ažurirajući ih i popravljajući sve posljedice ažuriranja. Bilo je vrlo razočaravajuće kada su razlozi za pogreške i zastoje u izdanjima bile jednostavne tipfelere koje je bilo tako teško pratiti u zbrci skripti ljuske. Sada su takve pogreške svedene na minimum. Promjene se uvode u sve aplikacije odjednom. I potrebno je 15 minuta da se nova aplikacija stavi u proces - postavite cjevovod predloška na CI i dodajte ključeve u repozitorij razvojnog programera.
Čini se da je poanta s Fastfileom za Android i potpisom aplikacije ostala nerazjašnjena, ako je članak zanimljiv, napisat ću nastavak. Bit će mi drago vidjeti vaša pitanja ili prijedloge "kako biste vi riješili ovaj problem" u komentarima ili na Telegramu bashkirova.