Evolucija CI-ja u mobilnom razvojnom timu

Danas se većina softverskih proizvoda razvija u timovima. Uvjeti za uspješan razvoj tima mogu se prikazati u obliku jednostavnog dijagrama.

Evolucija CI-ja u mobilnom razvojnom timu

Nakon što ste napisali svoj kod, morate se uvjeriti da:

  1. Работает.
  2. Ne kvari ništa, uključujući kôd koji su napisali vaši kolege.

Ako su ispunjena oba uvjeta, onda ste na putu uspjeha. Kako bismo jednostavno provjerili te uvjete i ne skrenuli s profitabilnog puta, osmislili smo kontinuiranu integraciju.

CI je tijek rada u kojem svoj kod integrirate u cjelokupni kod proizvoda što je češće moguće. I ne samo da integrirate, već i stalno provjeravate radi li sve. Budući da trebate provjeravati puno i često, vrijedi razmisliti o automatizaciji. Sve možete provjeriti ručno, ali ne biste trebali, a evo i zašto.

  • Dragi ljudi. Sat rada bilo kojeg programera skuplji je od sata rada bilo kojeg servera.
  • Ljudi griješe. Stoga se mogu pojaviti situacije kada su testovi pokrenuti na pogrešnoj grani ili kada je krivo izdavanje sastavljeno za testere.
  • Ljudi su lijeni. S vremena na vrijeme, kad završim neki zadatak, pojavi se misao: “Što tu treba provjeriti? Napisao sam dva retka - sve radi! Mislim da i neki od vas ponekad imaju takve misli. Ali uvijek treba provjeriti.

Kako je kontinuirana integracija implementirana i razvijena u Avito mobilnom razvojnom timu, kako su prešli s 0 na 450 nadogradnji dnevno i da se strojevi za izradu sastavljaju 200 sati dnevno, govori Nikolaj Nesterov (nnesterov) je sudionik svih evolucijskih promjena CI/CD Android aplikacije.

Priča se temelji na primjeru Android naredbe, no većina pristupa primjenjiva je i na iOS-u.


Jednom davno jedna je osoba radila u Avito Android timu. Po definiciji, nije mu trebalo ništa od Kontinuirane integracije: nije se imao s kim integrirati.

No aplikacija je rasla, pojavljivalo se sve više i više novih zadataka, a time je rastao i tim. U nekom trenutku, vrijeme je da se formalnije uspostavi proces integracije koda. Odlučeno je koristiti Git flow.

Evolucija CI-ja u mobilnom razvojnom timu

Koncept Git flowa dobro je poznat: projekt ima jednu zajedničku razvojnu granu, a za svaku novu značajku programeri izrezuju zasebnu granu, obvezuju se na nju, guraju, a kada žele spojiti svoj kod u razvojnu granu, otvaraju zahtjev za povlačenjem. Za razmjenu znanja i raspravu o pristupima, uveli smo code review, odnosno da kolege međusobno provjeravaju i potvrđuju kod.

provjere

Gledanje koda svojim očima je cool, ali nije dovoljno. Stoga se uvode automatske provjere.

  • Prije svega, provjeravamo ARK sklop.
  • Puno Junit testovi.
  • Uzimamo u obzir pokrivenost koda, budući da provodimo testove.

Da bismo razumjeli kako se ove provjere trebaju izvoditi, pogledajmo razvojni proces u Avitu.

Shematski se može prikazati ovako:

  • Programer piše kod na svom laptopu. Ovdje možete pokrenuti integracijske provjere - bilo pomoću kuke za uvrštavanje, ili jednostavno pokrenuti provjere u pozadini.
  • Nakon što je programer gurnuo kod, otvara zahtjev za povlačenjem. Kako bi njegov kod bio uvršten u razvojnu granu, potrebno je proći pregled koda i prikupiti potreban broj potvrda. Ovdje možete omogućiti provjere i nadogradnje: dok sve izgradnje ne budu uspješne, zahtjev za povlačenjem se ne može spojiti.
  • Nakon što se zahtjev za povlačenjem spoji i kod uključi u razvoj, možete odabrati prikladno vrijeme: na primjer, noću, kada su svi poslužitelji slobodni, i pokrenuti onoliko provjera koliko želite.

Nitko nije volio pokretanje skeniranja na prijenosnom računalu. Kada programer završi značajku, želi je brzo gurnuti i otvoriti zahtjev za povlačenjem. Ako se u ovom trenutku pokrenu neke duge provjere, to ne samo da nije baš ugodno, već i usporava razvoj: dok prijenosno računalo nešto provjerava, nemoguće je normalno raditi na njemu.

Jako nam se svidjelo provoditi provjere noću, jer ima puno vremena i poslužitelja, možete lutati uokolo. Ali, nažalost, kada kod značajke uđe u razvoj, programer ima mnogo manje motivacije popraviti pogreške koje je CI pronašao. Povremeno sam se uhvatio kako razmišljam kada sam pogledao sve greške pronađene u jutarnjem izvješću da ću ih popraviti jednog dana kasnije, jer sada postoji super novi zadatak u Jiri koji samo želim početi raditi.

Ako provjere blokiraju zahtjev za povlačenjem, onda ima dovoljno motivacije, jer dok buildovi ne pozelene, kod neće ući u development, što znači da zadatak neće biti dovršen.

Kao rezultat toga, odabrali smo sljedeću strategiju: pokrećemo maksimalan mogući skup provjera noću i pokrećemo najkritičnije od njih i, što je najvažnije, one najbrže na zahtjev za povlačenjem. Ali tu ne stajemo - paralelno optimiziramo brzinu provjera kako bismo ih prebacili iz noćnog načina rada u provjere zahtjeva za povlačenjem.

U to su vrijeme sve naše izgradnje bile dovršene prilično brzo, pa smo jednostavno uključili ARK build, Junit testove i izračune pokrivenosti koda kao blokator za zahtjev za povlačenjem. Uključili smo ga, razmislili o tome i napustili pokrivenost kodom jer smo mislili da nam ne treba.

Trebalo nam je dva dana da kompletno postavimo osnovni CI (u daljnjem tekstu procjena vremena je približna, potrebna za mjerilo).

Nakon toga smo počeli dalje razmišljati - provjeravamo li uopće ispravno? Pokrećemo li ispravno nadogradnje na zahtjevima za povlačenje?

Započeli smo izgradnju na posljednjem urezivanju grane iz koje je otvoren zahtjev za povlačenjem. Ali testovi ovog predanja mogu samo pokazati da kod koji je programer napisao radi. Ali ne dokazuju da nije ništa slomio. Zapravo, morate provjeriti stanje razvojne grane nakon što je značajka spojena u nju.

Evolucija CI-ja u mobilnom razvojnom timu

Da bismo to učinili, napisali smo jednostavnu bash skriptu premerge.sh:

#!/usr/bin/env bash

set -e

git fetch origin develop

git merge origin/develop

Ovdje se sve najnovije promjene iz developmenta jednostavno povlače i spajaju u trenutnu granu. Dodali smo skriptu premerge.sh kao prvi korak u svim verzijama i počeli provjeravati točno ono što želimo, tj. integracija.

Trebalo je tri dana da lokaliziramo problem, pronađemo rješenje i napišemo ovu skriptu.

Aplikacija se razvijala, pojavljivalo se sve više zadataka, tim je rastao, a premerge.sh nas je ponekad počeo iznevjeriti. Develop je imao proturječne promjene koje su prekinule izgradnju.

Primjer kako se to događa:

Evolucija CI-ja u mobilnom razvojnom timu

Dva razvojna programera istovremeno počinju raditi na značajkama A i B. Programer značajke A otkriva neiskorištenu značajku u projektu answer() i, poput dobrog izviđača, uklanja ga. U isto vrijeme, programer značajke B dodaje novi poziv ovoj funkciji u svojoj grani.

Programeri završavaju svoj posao i otvaraju zahtjev za povlačenje u isto vrijeme. Gradnje su pokrenute, premerge.sh provjerava oba zahtjeva za povlačenje u vezi s najnovijim razvojnim stanjem - sve su provjere zelene. Nakon toga, zahtjev za povlačenje značajke A se spaja, zahtjev za povlačenje značajke B se spaja... Bum! Pauze u razvoju jer kod za razvoj sadrži poziv nepostojeće funkcije.

Evolucija CI-ja u mobilnom razvojnom timu

Kad se neće razvijati, jest lokalna katastrofa. Cijeli tim ne može ništa prikupiti i poslati na testiranje.

Tako se dogodilo da sam najčešće radio na infrastrukturnim poslovima: analitika, mreža, baze podataka. Odnosno, ja sam bio taj koji je napisao te funkcije i klase koje drugi programeri koriste. Zbog toga sam se često našao u sličnim situacijama. Čak sam neko vrijeme držao ovu sliku.

Evolucija CI-ja u mobilnom razvojnom timu

Budući da nam to nije odgovaralo, počeli smo istraživati ​​mogućnosti kako to spriječiti.

Kako ne slomiti razvoj

Prva opcija: ponovno izgradi sve zahtjeve za povlačenjem prilikom ažuriranja razvoja. Ako je, u našem primjeru, zahtjev za povlačenjem sa značajkom A prvi uključen u razvoj, zahtjev za povlačenjem za značajku B bit će ponovno izgrađen i, sukladno tome, provjere neće uspjeti zbog pogreške kompilacije.

Da biste razumjeli koliko će to trajati, razmotrite primjer s dva PR-a. Otvaramo dva PR-a: dva builda, dva rada provjere. Nakon što se prvi PR spoji u development, potrebno je ponovno izgraditi drugi. Ukupno, dva PR-a zahtijevaju tri provjere: 2 + 1 = 3.

U principu je u redu. Ali pogledali smo statistiku i tipična situacija u našem timu bila je 10 otvorenih PR-ova, a tada je broj provjera zbroj progresije: 10 + 9 +... + 1 = 55. To jest, prihvatiti 10 PR-ovi, trebate obnoviti 55 puta. I to u idealnoj situaciji, kada sve provjere prođu prvi put, kada nitko ne otvori dodatni pull request dok se ovih desetak obrađuje.

Zamislite sebe kao programera koji treba prvi kliknuti na gumb "spoji", jer ako susjed to učini, onda ćete morati čekati dok sve građevine ne prođu ponovo... Ne, to neće uspjeti , to će ozbiljno usporiti razvoj.

Drugi mogući način: prikupljanje zahtjeva za povlačenjem nakon pregleda koda. Odnosno, otvorite pull request, prikupite potreban broj odobrenja od kolega, ispravite što je potrebno i onda pokrenete buildove. Ako su uspješni, zahtjev za povlačenje se spaja u development. U ovom slučaju nema dodatnih ponovnih pokretanja, ali je povratna informacija jako usporena. Kao programer, kada otvorim zahtjev za povlačenjem, odmah želim vidjeti hoće li uspjeti. Na primjer, ako test ne uspije, morate to brzo popraviti. U slučaju odgođene izgradnje usporava se povratna sprega, a time i cijeli razvoj. Ni ovo nam nije odgovaralo.

Kao rezultat toga, ostala je samo treća opcija - bicikl. Sav naš kod, svi naši izvori pohranjeni su u repozitoriju na Bitbucket poslužitelju. U skladu s tim, morali smo razviti dodatak za Bitbucket.

Evolucija CI-ja u mobilnom razvojnom timu

Ovaj dodatak nadjačava mehanizam spajanja zahtjeva za povlačenjem. Početak je standardan: otvara se PR, pokreću se svi sklopovi, dovršava se pregled koda. Ali nakon što je pregled koda dovršen i razvojni programer odluči kliknuti na "spoj", dodatak provjerava prema kojem stanju razvoja su provjere pokrenute. Ako je development ažuriran nakon izgradnje, dodatak neće dopustiti spajanje takvog zahtjeva za povlačenjem u glavnu granu. Jednostavno će ponovno pokrenuti gradnje relativno nedavnog razvoja.

Evolucija CI-ja u mobilnom razvojnom timu

U našem primjeru s proturječnim izmjenama, takve izgradnje neće uspjeti zbog pogreške kompilacije. U skladu s tim, programer značajke B morat će ispraviti kod, ponovno pokrenuti provjere, a zatim će dodatak automatski primijeniti zahtjev za povlačenjem.

Prije implementacije ovog dodatka imali smo prosječno 2,7 pregleda po zahtjevu za povlačenjem. S dodatkom je bilo 3,6 pokretanja. Ovo nam je odgovaralo.

Vrijedno je napomenuti da ovaj dodatak ima nedostatak: samo jednom ponovno pokreće izgradnju. Odnosno, još uvijek postoji mali prozor kroz koji se mogu razviti proturječne promjene. Ali vjerojatnost za to je niska i napravili smo ovaj kompromis između broja pokretanja i vjerojatnosti neuspjeha. U dvije godine pucalo je samo jednom, pa vjerojatno nije bilo uzalud.

Trebalo nam je dva tjedna da napišemo prvu verziju Bitbucket dodatka.

Nove provjere

U međuvremenu, naš tim je nastavio rasti. Dodane su nove provjere.

Pomislili smo: zašto griješiti ako se one mogu spriječiti? I zato su proveli statička analiza koda. Počeli smo s lintom, koji je uključen u Android SDK. Ali tada uopće nije znao raditi s Kotlin kodom, a mi smo već imali 75% aplikacije napisane u Kotlinu. Stoga su vlaknima dodane ugrađene Android Studio provjerava.

Da bismo to učinili, morali smo učiniti mnogo pervertira: uzeti Android Studio, zapakirati ga u Docker i pokrenuti na CI-ju s virtualnim monitorom, tako da misli da radi na stvarnom prijenosnom računalu. Ali uspjelo je.

Također smo u to vrijeme počeli puno pisati ispitivanja instrumentacije i provedeno testiranje snimke zaslona. Tada se generira referentna snimka zaslona za zasebni mali prikaz, a test se sastoji od snimanja snimke zaslona iz prikaza i usporedbe sa standardom izravno piksel po piksel. Ako postoji odstupanje, to znači da je raspored negdje pogriješio ili nešto nije u redu u stilovima.

Ali testovi instrumentacije i testovi snimaka zaslona moraju se izvoditi na uređajima: na emulatorima ili na stvarnim uređajima. S obzirom na to da testova ima puno i često se rade, potrebna je cijela farma. Pokretanje vlastite farme previše je naporno, pa smo pronašli gotovu opciju - Firebase Test Lab.

Firebase Test Lab

Odabran je jer je Firebase Googleov proizvod, što znači da bi trebao biti pouzdan i malo je vjerojatno da će ikada umrijeti. Cijene su prihvatljive: 5$ po satu rada pravog uređaja, 1$ po satu rada emulatora.

Bilo je potrebno otprilike tri tjedna za implementaciju Firebase Test Laba u naš CI.

Ali tim je nastavio rasti, a Firebase nas je, nažalost, počeo iznevjeriti. U to vrijeme nije imao nikakav SLA. Ponekad nas je Firebase tjerao da čekamo dok se potreban broj uređaja ne oslobodi za testove, a nije ih odmah počeo izvršavati, kao što smo željeli. Čekanje u redu trajalo je i do pola sata, što je jako dugo. Na svakom PR-u radili su se instrumentalni testovi, kašnjenja su stvarno usporavala razvoj, a onda je mjesečni račun došao okrugao. Općenito, odlučeno je napustiti Firebase i raditi unutar kuće, budući da je tim dovoljno narastao.

Docker + Python + bash

Uzeli smo Docker, utrpali u njega emulatore, napisali jednostavan program u Pythonu koji u pravom trenutku pokreće potreban broj emulatora u pravoj verziji i zaustavlja ih po potrebi. I, naravno, nekoliko bash skripti - gdje bismo bez njih?

Bilo je potrebno pet tjedana za stvaranje vlastitog testnog okruženja.

Kao rezultat toga, za svaki zahtjev za povlačenjem postojala je opsežna lista provjera za blokiranje spajanja:

  • sklop ARK;
  • Junit testovi;
  • vlakna;
  • Android Studio provjere;
  • Instrumentacijski testovi;
  • Screenshot testovi.

Time su spriječeni mnogi mogući kvarovi. Tehnički je sve funkcioniralo, no programeri su se žalili da se na rezultate čeka predugo.

Koliko dugo je predugo? Učitali smo podatke iz Bitbucketa i TeamCityja u sustav za analizu i to shvatili prosječno vrijeme čekanja 45 minuta. Odnosno, programer, kada otvara zahtjev za povlačenjem, čeka u prosjeku 45 minuta na rezultate izgradnje. Po meni je to puno i ne može se tako raditi.

Naravno, odlučili smo ubrzati sve naše gradnje.

Ubrzajmo

Budući da građevine često stoje u redu čekanja, prvo što radimo je kupio više hardvera — ekstenzivni razvoj je najjednostavniji. Gradnje su prestale čekati u redu, ali se vrijeme čekanja samo malo smanjilo, jer su neke same provjere trajale jako dugo.

Uklanjanje provjera koje predugo traju

Naša kontinuirana integracija mogla bi uhvatiti ove vrste pogrešaka i problema.

  • Neću. CI može uhvatiti pogrešku kompilacije kada se nešto ne izgradi zbog proturječnih promjena. Kao što sam već rekao, tada nitko ništa ne može sastaviti, razvoj staje, svi postaju nervozni.
  • Greška u ponašanju. Na primjer, kada je aplikacija izgrađena, ali se ruši kada pritisnete gumb ili se gumb uopće ne pritisne. To je loše jer takav bug može doći do korisnika.
  • Greška u rasporedu. Na primjer, gumb je kliknut, ali se pomaknuo 10 piksela ulijevo.
  • Povećanje tehničkog duga.

Nakon što smo pogledali ovaj popis, shvatili smo da su samo prve dvije točke kritične. Prvo želimo uhvatiti takve probleme. Greške u izgledu otkrivaju se u fazi pregleda dizajna i tada se mogu lako ispraviti. Suočavanje s tehničkim dugom zahtijeva zaseban proces i planiranje, pa smo odlučili da ga ne testiramo na zahtjevu za povlačenjem.

Na temelju ove klasifikacije protresli smo cijeli popis provjera. Precrtano Lint i preko noći odgodio lansiranje: samo kako bi proizveo izvješće o tome koliko je problema bilo u projektu. Dogovorili smo se da ćemo raditi odvojeno s tehničkim dugom i Provjere Android Studija potpuno su napuštene. Android Studio u Dockeru za pokretanje inspekcija zvuči zanimljivo, ali uzrokuje mnogo problema u podršci. Svako ažuriranje verzija Android Studio znači borbu s nerazumljivim greškama. Također je bilo teško podržati testove snimaka zaslona jer biblioteka nije bila baš stabilna i bilo je lažno pozitivnih rezultata. Testovi snimaka zaslona uklonjeni su s popisa za provjeru.

Kao rezultat toga, ostali smo sa:

  • sklop ARK;
  • Junit testovi;
  • Instrumentalna ispitivanja.

Gradle udaljena predmemorija

Bez teških provjera, sve je postalo bolje. Ali nema granice savršenstvu!

Naša je aplikacija već bila podijeljena na oko 150 gradle modula. Gradle udaljena predmemorija obično dobro radi u ovom slučaju, pa smo je odlučili isprobati.

Gradle udaljena predmemorija je usluga koja može predmemorirati artefakte izrade za pojedinačne zadatke u pojedinačnim modulima. Gradle, umjesto da zapravo kompajlira kod, koristi HTTP da pokuca na udaljenu predmemoriju i pita je li netko već izvršio ovaj zadatak. Ako da, jednostavno preuzima rezultat.

Pokretanje Gradle udaljene predmemorije jednostavno je jer Gradle pruža Docker sliku. Uspjeli smo to za tri sata.

Sve što je trebalo učiniti je pokrenuti Docker i napisati jedan redak u projektu. Ali iako se može brzo pokrenuti, trebat će dosta vremena da sve dobro funkcionira.

Ispod je grafikon promašaja predmemorije.

Evolucija CI-ja u mobilnom razvojnom timu

Na samom početku postotak promašaja predmemorije bio je oko 65. Nakon tri tjedna uspjeli smo povećati tu vrijednost na 20%. Ispostavilo se da zadaci koje skuplja Android aplikacija imaju čudne tranzitivne ovisnosti zbog kojih je Gradle promašio cache.

Spajanjem predmemorije uvelike smo ubrzali izgradnju. Ali osim montaže, tu su i ispitivanja instrumentacije, a ona dugo traju. Možda se ne moraju izvoditi svi testovi za svaki zahtjev za povlačenjem. Da bismo to saznali, koristimo analizu utjecaja.

Analiza utjecaja

Na zahtjev za povlačenjem prikupljamo git diff i pronalazimo modificirane Gradle module.

Evolucija CI-ja u mobilnom razvojnom timu

Ima smisla izvoditi samo testove instrumentacije koji provjeravaju promijenjene module i sve module koji o njima ovise. Nema smisla izvoditi testove za susjedne module: tamo se kod nije promijenio i ništa se ne može pokvariti.

Testovi instrumentacije nisu tako jednostavni jer se moraju nalaziti u aplikacijskom modulu najviše razine. Koristili smo heuristiku s analizom bajt koda kako bismo razumjeli kojem modulu svaki test pripada.

Nadogradnja rada testova instrumenata tako da testiraju samo uključene module trajala je oko osam tjedana.

Mjere za ubrzavanje inspekcija uspješno su djelovale. Od 45 minuta smo došli do nekih 15. Već je normalno čekati četvrt sata na izgradnju.

Ali sada su se programeri počeli žaliti da ne razumiju koje se verzije pokreću, gdje vidjeti dnevnik, zašto je verzija crvena, koji test nije uspio, itd.

Evolucija CI-ja u mobilnom razvojnom timu

Problemi s povratnim informacijama usporavaju razvoj, stoga smo nastojali dati što jasnije i detaljnije informacije o svakom PR-u i buildu. Započeli smo s komentarima u Bitbucketu PR-u, naznačujući koja je izgradnja neuspješna i zašto, te smo napisali ciljane poruke u Slacku. Na kraju smo izradili PR nadzornu ploču za stranicu s popisom svih nadogradnji koje su trenutno pokrenute i njihovim statusom: u redu čekanja, pokrenuto, srušeno ili dovršeno. Možete kliknuti na izgradnju i doći do njenog dnevnika.

Evolucija CI-ja u mobilnom razvojnom timu

Šest tjedana potrošeno je na detaljne povratne informacije.

Planovi

Prijeđimo na noviju povijest. Nakon što smo riješili problem povratnih informacija, došli smo do nove razine - odlučili smo izgraditi vlastitu farmu emulatora. Kada postoji mnogo testova i emulatora, njima je teško upravljati. Kao rezultat toga, svi naši emulatori prešli su na k8s klaster s fleksibilnim upravljanjem resursima.

Osim toga, postoje i drugi planovi.

  • Vrati lint (i druge statičke analize). Već radimo u tom smjeru.
  • Pokrenite sve na PR blokatoru end-to-end testovi na svim verzijama SDK-a.

Dakle, pratili smo povijest razvoja kontinuirane integracije u Avitu. Sada želim dati nekoliko savjeta s gledišta iskustva.

Советы

Kad bih mogao dati samo jedan savjet, to bi bio sljedeći:

Budite oprezni sa skriptama ljuske!

Bash je vrlo fleksibilan i moćan alat, vrlo je zgodan i brz za pisanje skripti. Ali s njim možete upasti u zamku, a mi smo, nažalost, upali u nju.

Sve je počelo s jednostavnim skriptama koje su se izvodile na našim strojevima za izradu:

#!/usr/bin/env bash
./gradlew assembleDebug

Ali, kao što znate, sve se razvija i postaje kompliciranije s vremenom - pokrenimo jednu skriptu iz druge, prenesimo tamo neke parametre - na kraju smo morali napisati funkciju koja određuje na kojoj smo razini bash ugniježđenja sada kako bi umetnuti potrebne navodnike, kako bi sve počelo.

Evolucija CI-ja u mobilnom razvojnom timu

Možete zamisliti troškove rada za razvoj takvih skripti. Savjetujem vam da ne upadnete u ovu zamku.

Što se može zamijeniti?

  • Bilo koji skriptni jezik. Pišite Python ili Kotlin skripta praktičniji jer je to programiranje, a ne skripte.
  • Ili opišite svu logiku izgradnje u obrascu Prilagođeni gradle zadaci za vaš projekt.

Odlučili smo odabrati drugu opciju, a sada sustavno brišemo sve bash skripte i pišemo mnogo custom gradle zadataka.

Savjet #2: Pohranite infrastrukturu u kodu.

Zgodno je kada se postavka kontinuirane integracije ne pohranjuje u UI sučelje Jenkinsa ili TeamCityja itd., već u obliku tekstualnih datoteka izravno u repozitorij projekta. To daje mogućnost verzije. Neće biti teško vratiti se ili izgraditi kod na drugoj grani.

Skripte se mogu pohraniti u projekt. Što učiniti s okolišem?

Savjet #3: Docker može pomoći u zaštiti okoliša.

Definitivno će pomoći Android programerima; iOS ga nažalost još nema.

Ovo je primjer jednostavne docker datoteke koja sadrži jdk i android-sdk:

FROM openjdk:8

ENV SDK_URL="https://dl.google.com/android/repository/sdk-tools-linux-3859397.zip" 
    ANDROID_HOME="/usr/local/android-sdk" 
    ANDROID_VERSION=26 
    ANDROID_BUILD_TOOLS_VERSION=26.0.2

# Download Android SDK
RUN mkdir "$ANDROID_HOME" .android 
    && cd "$ANDROID_HOME" 
    && curl -o sdk.zip $SDK_URL 
    && unzip sdk.zip 
    && rm sdk.zip 
    && yes | $ANDROID_HOME/tools/bin/sdkmanager --licenses

# Install Android Build Tool and Libraries
RUN $ANDROID_HOME/tools/bin/sdkmanager --update
RUN $ANDROID_HOME/tools/bin/sdkmanager "build-tools;${ANDROID_BUILD_TOOLS_VERSION}" 
    "platforms;android-${ANDROID_VERSION}" 
    "platform-tools"

RUN mkdir /application
WORKDIR /application

Nakon što napišete ovu Docker datoteku (odat ću vam tajnu, ne morate je napisati, već je samo izvučete gotovu s GitHuba) i asemblerate sliku, dobivate virtualni stroj na kojem možete graditi aplikaciju i pokrenuti testove Junit.

Dva glavna razloga zašto ovo ima smisla su skalabilnost i ponovljivost. Koristeći docker, možete brzo podići desetak agenata za izgradnju koji će imati potpuno isto okruženje kao prethodni. To uvelike olakšava život CI inženjerima. Prilično je jednostavno gurnuti android-sdk u docker, ali s emulatorima je to malo teže: morat ćete se malo više potruditi (ili ponovno preuzeti gotov s GitHuba).

Savjet broj 4: ne zaboravite da se inspekcije ne rade radi inspekcije, već radi ljudi.

Brza i, što je najvažnije, jasna povratna informacija vrlo je važna za programere: što se pokvarilo, koji test nije uspio, gdje mogu vidjeti buildlog.

Savjet #5: Budite pragmatični kada razvijate kontinuiranu integraciju.

Jasno shvatite koje vrste grešaka želite spriječiti, koliko ste resursa, vremena i računalnog vremena spremni potrošiti. Provjere koje traju predugo mogu se, primjerice, odgoditi preko noći. A one od njih koji hvataju ne baš važne pogreške treba potpuno napustiti.

Savjet #6: Koristite gotove alate.

Sada postoje mnoge tvrtke koje pružaju CI u oblaku.

Evolucija CI-ja u mobilnom razvojnom timu

Ovo je dobro rješenje za male timove. Ne morate ništa podržavati, samo platite malo novca, izradite svoju aplikaciju i čak pokrenite testove instrumentacije.

Savjet #7: U velikom timu, interna rješenja su isplativija.

Ali prije ili kasnije, kako tim bude rastao, interna rješenja postat će isplativija. Postoji jedan problem s tim odlukama. U ekonomiji postoji zakon opadajućih povrata: u svakom projektu svako sljedeće poboljšanje je sve teže i zahtijeva sve više ulaganja.

Ekonomija opisuje cijeli naš život, uključujući kontinuiranu integraciju. Napravio sam raspored troškova rada za svaku fazu razvoja naše kontinuirane integracije.

Evolucija CI-ja u mobilnom razvojnom timu

Jasno je da je bilo kakvo poboljšanje sve teže. Gledajući ovaj grafikon, možete razumjeti da se kontinuirana integracija mora razvijati u skladu s rastom veličine tima. Za tim od dvoje ljudi, potrošiti 50 dana na razvoj interne farme emulatora osrednja je ideja. Ali u isto vrijeme, za veliki tim, ne raditi kontinuiranu integraciju također je loša ideja, jer problemi integracije, popravljanje komunikacije itd. trebat će još više vremena.

Krenuli smo s idejom da je automatizacija potrebna jer su ljudi skupi, griješe i lijeni su. Ali ljudi također automatiziraju. Stoga se svi isti problemi odnose na automatizaciju.

  • Automatizacija je skupa. Zapamtite raspored rada.
  • Kad je u pitanju automatizacija, ljudi griješe.
  • Ponekad je vrlo lijeno automatizirati, jer sve tako funkcionira. Zašto poboljšati bilo što drugo, čemu sva ova kontinuirana integracija?

Ali imam statistiku: pogreške su uhvaćene u 20% sklopova. I to nije zato što naši programeri loše pišu kod. To je zato što su programeri uvjereni da ako naprave neku pogrešku, ona neće završiti u razvoju, već će biti uhvaćena automatiziranim provjerama. U skladu s tim, programeri mogu potrošiti više vremena na pisanje koda i zanimljivih stvari, umjesto da pokreću i testiraju nešto lokalno.

Vježbajte kontinuiranu integraciju. Ali umjereno.

Inače, Nikolaj Nesterov ne samo da sam daje sjajne reportaže, već je i član programskog odbora AppsConf i pomaže drugima pripremiti smislene govore za vas. Cjelovitost i korisnost sljedećeg programa skupa može se ocijeniti prema temama u raspored. A za detalje dođite u Infospace 22.-23.

Izvor: www.habr.com

Dodajte komentar