Evolucija CI u mobilnom razvojnom timu

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

Evolucija CI u mobilnom razvojnom timu

Nakon što napišete svoj kod, morate biti sigurni da je:

  1. Rabotaet.
  2. Ništa ne kvari, uključujući i kod koji su vaše kolege napisale.

Ako su oba uslova ispunjena, onda ste na putu ka uspehu. Kako bismo lako provjerili ove uvjete i ne skrenuli sa profitabilnog puta, osmislili smo Kontinuiranu integraciju.

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

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

Kako je Continuous Integration implementirana i razvijena u Avito mobilnom razvojnom timu, kako su prešli sa 0 na 450 build-ova dnevno i da se mašine za pravljenje sklapaju 200 sati dnevno, kaže Nikolaj Nesterov (nnesterov) je sudionik svih evolucijskih promjena CI/CD Android aplikacije.

Priča je zasnovana na primjeru Android komande, ali većina pristupa je primjenjiva i na iOS-u.


Nekada je jedna osoba radila u Avito Android timu. Po definiciji, nije mu trebalo ništa od kontinuirane integracije: nije bilo s kim da se integriše.

Ali aplikacija je rasla, pojavljivalo se sve više novih zadataka, a tim je rastao u skladu s tim. U nekom trenutku, vrijeme je da se formalnije uspostavi proces integracije koda. Odlučeno je da se koristi Git flow.

Evolucija CI u mobilnom razvojnom timu

Koncept Git toka je dobro poznat: projekat ima jednu zajedničku granu za razvoj, a za svaku novu karakteristiku programeri iseku zasebnu granu, obavežu je na nju, guraju i kada žele da spoje svoj kod u granu za razvoj, otvaraju pull request. Da bismo podijelili znanje i razgovarali o pristupima, uveli smo pregled koda, odnosno kolege moraju međusobno provjeravati i potvrditi kod.

Čekovi

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

  • Prije svega, provjeravamo ARK skupština.
  • Puno Junit testovi.
  • Razmatramo pokrivenost koda, pošto radimo testove.

Da bismo razumjeli kako ove provjere treba pokrenuti, pogledajmo proces razvoja u Avitu.

Može se shematski predstaviti ovako:

  • Programer piše kod na svom laptopu. Možete pokrenuti integracijske provjere upravo ovdje - ili sa zakačicom za urezivanje, ili jednostavno pokrenuti provjere u pozadini.
  • Nakon što programer gurne kod, otvara zahtjev za povlačenjem. Da bi njegov kod bio uključen u granu razvoja, potrebno je proći kroz pregled koda i prikupiti potreban broj potvrda. Ovdje možete omogućiti provjere i gradnje: dok sve izgradnje ne budu uspješne, zahtjev za povlačenjem ne može se spojiti.
  • Nakon što se zahtjev za povlačenjem spoji i kod se uključi u razvoj, možete odabrati pogodno vrijeme: na primjer, noću, kada su svi serveri slobodni, i pokrenuti onoliko provjera koliko želite.

Niko nije volio skeniranje na svom laptopu. Kada programer završi funkciju, ž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 laptop nešto provjerava, nemoguće je normalno raditi na tome.

Zaista nam se svidjelo obavljanje provjera noću, jer ima puno vremena i servera, možete lutati okolo. Ali, nažalost, kada se kod funkcije počne razvijati, programer ima mnogo manje motivacije da popravi greške koje je CI pronašao. Povremeno sam se uhvatio kako razmišljam kada sam pogledao sve greške pronađene u jutarnjem izvještaju da ću ih popraviti jednog dana kasnije, jer je sada u Jira cool novi zadatak koji samo želim početi raditi.

Ako provjere blokiraju zahtjev za povlačenjem, onda postoji dovoljna motivacija, jer dok buildovi ne postanu zeleni, kod neće ući u razvoj, što znači da zadatak neće biti završen.

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

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

Trebalo nam je dva dana da u potpunosti postavimo osnovni CI (u daljem tekstu je procjena vremena približna, potrebna za skalu).

Nakon toga smo počeli dalje razmišljati - da li uopće provjeravamo ispravno? Da li ispravno izvodimo nadgradnje na zahtjevima za povlačenje?

Započeli smo izgradnju na zadnjem urezivanju grane iz koje je otvoren zahtjev za povlačenje. Ali testovi ovog urezivanja mogu samo pokazati da kod koji je programer napisao radi. Ali oni ne dokazuju da nije ništa slomio. U stvari, morate provjeriti stanje grane za razvoj nakon što se funkcija spoji u nju.

Evolucija CI 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 razvoja jednostavno povlače i spajaju u trenutnu granu. Dodali smo premerge.sh skriptu kao prvi korak u svim verzijama i počeli provjeravati šta tačno želimo, tj. integracija.

Trebalo je tri dana da se problem lokalizira, pronađe rješenje i napiše ova skripta.

Aplikacija se razvijala, pojavljivalo se sve više zadataka, tim je rastao, a premerge.sh je ponekad počeo da nas iznevjerava. Razvoj je imao konfliktne promjene koje su pokvarile gradnju.

Primjer kako se to događa:

Evolucija CI u mobilnom razvojnom timu

Dva programera istovremeno počinju raditi na karakteristikama A i B. Programer značajke A otkriva neiskorištenu funkciju u projektu answer() i, kao dobar izviđač, ukloni ga. Istovremeno, programer funkcije B dodaje novi poziv ovoj funkciji u svojoj grani.

Programeri završavaju svoj posao i istovremeno otvaraju zahtjev za povlačenjem. Izgradnje su pokrenute, premerge.sh provjerava oba zahtjeva za povlačenje u vezi sa najnovijim razvojnim stanjem - sve provjere su zelene. Nakon toga se spaja zahtjev za povlačenjem funkcije A, spaja se zahtjev za povlačenjem funkcije B... Bum! Razvijanje se prekida jer razvojni kod sadrži poziv nepostojećoj funkciji.

Evolucija CI u mobilnom razvojnom timu

Kad se neće razviti, hoće lokalna katastrofa. Cijeli tim ne može ništa prikupiti i predati na testiranje.

Desilo se da sam najčešće radio na infrastrukturnim poslovima: analitika, mreža, baze podataka. To jest, ja sam napisao one funkcije i klase koje koriste drugi programeri. Zbog toga sam se vrlo često nalazio u sličnim situacijama. Čak sam neko vrijeme visio i ovu sliku.

Evolucija CI u mobilnom razvojnom timu

Pošto nam to nije odgovaralo, počeli smo da istražujemo opcije kako da to sprečimo.

Kako ne slomiti razvoj

Prva opcija: ponovo izgraditi sve zahtjeve za povlačenje prilikom ažuriranja develop. Ako je, u našem primjeru, zahtjev za povlačenjem sa značajkom A prvi koji će biti uključen u razvoj, zahtjev za povlačenjem značajke B će biti ponovo izgrađen, i, shodno tome, provjere neće uspjeti zbog greške u kompilaciji.

Da biste razumjeli koliko će ovo trajati, razmotrite primjer sa dva PR-a. Otvaramo dva PR-a: dvije izrade, dvije provjere. Nakon što se prvi PR spoji u razvoj, drugi treba ponovo izgraditi. Ukupno, dva PR-a zahtijevaju tri provjere: 2 + 1 = 3.

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

Zamislite sebe kao programera koji prvi treba da klikne na dugme „spajanje“, jer ako to uradi komšija, onda ćete morati da sačekate da sve grade ponovo prođu... Ne, to neće raditi , 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 ono što je potrebno, a zatim pokrenete build. Ako su uspješni, zahtjev za povlačenjem se spaja u razvoj. U ovom slučaju nema dodatnih ponovnih pokretanja, ali je povratna informacija znatno usporena. Kao programer, kada otvorim zahtjev za povlačenjem, odmah želim vidjeti hoće li funkcionirati. Na primjer, ako test ne uspije, morate ga brzo popraviti. U slučaju kašnjenja izgradnje, povratne informacije se usporavaju, a samim tim 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 spremištu na Bitbucket serveru. U skladu s tim, morali smo razviti dodatak za Bitbucket.

Evolucija CI u mobilnom razvojnom timu

Ovaj dodatak nadjačava mehanizam spajanja zahtjeva za povlačenjem. Početak je standardan: otvara se PR, svi sklopovi se pokreću, pregled koda je završen. Ali nakon što je pregled koda završen i programer odluči kliknuti na „spajanje“, dodatak provjerava u odnosu na koje razvojno stanje su provjere pokrenute. Ako je razvoj ažuriran nakon izgradnje, dodatak neće dozvoliti da se takav zahtjev za povlačenjem spoji u glavnu granu. Jednostavno će ponovo pokrenuti verzije relativno nedavnog razvoja.

Evolucija CI u mobilnom razvojnom timu

U našem primjeru s konfliktnim promjenama, takve gradnje neće uspjeti zbog greške u kompilaciji. U skladu s tim, programer funkcije B će morati ispraviti kod, ponovo pokrenuti provjere, a zatim će dodatak automatski primijeniti zahtjev za povlačenjem.

Prije implementacije ovog dodatka, u prosjeku smo imali 2,7 pokretanja pregleda po zahtjevu za povlačenje. Sa dodatkom je bilo 3,6 pokretanja. Ovo nam je odgovaralo.

Vrijedi napomenuti da ovaj dodatak ima nedostatak: samo jednom ponovo pokreće gradnju. To jest, još uvijek postoji mali prozor kroz koji se konfliktne promjene mogu razviti. Ali vjerovatnoća za to je mala i napravili smo kompromis između broja pokretanja i vjerovatnoće neuspjeha. Za dvije godine je samo jednom opalio, tako da vjerovatno nije bilo uzalud.

Trebale su nam dvije sedmice da napišemo prvu verziju Bitbucket dodatka.

Nove čekove

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

Pomislili smo: zašto praviti greške ako se mogu spriječiti? I zato su implementirali statička analiza koda. Počeli smo sa lintom, koji je uključen u Android SDK. Ali u to vrijeme on uopće nije znao raditi sa Kotlin kodom, a mi smo već imali 75% aplikacije napisane u Kotlinu. Stoga su u lint dodani ugrađeni Android Studio provjerava.

Da bismo to uradili, morali smo da uradimo mnogo izopačenja: uzeti Android Studio, zapakovati ga u Docker i pokrenuti ga na CI sa virtuelnim monitorom, tako da misli da radi na pravom laptopu. Ali upalilo je.

U to vrijeme smo također počeli puno pisati instrumentacijski testovi i implementiran testiranje snimka ekrana. Ovo je kada se generiše referentni snimak ekrana za poseban mali prikaz, a test se sastoji od uzimanja snimka ekrana iz prikaza i poređenja sa standardnim direktno piksel po piksel. Ako postoji neslaganje, to znači da je raspored negdje pogrešio ili nešto nije u redu u stilovima.

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

Firebase Test Lab

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

Trebalo je otprilike tri sedmice da implementiramo Firebase Test Lab u naš CI.

Ali tim je nastavio da raste, a Firebase nas je, nažalost, počeo iznevjeravati. U to vrijeme nije imao SLA. Ponekad nas je Firebase tjerao da čekamo dok se potreban broj uređaja ne oslobodi za testove, a ne počnemo ih izvršavati odmah, kako smo željeli. Čekanje u redu je trajalo i do pola sata, što je jako dugo. Testovi instrumentacije su rađeni na svakom PR-u, kašnjenja su zaista usporila razvoj, a onda je mjesečni račun došao sa okruglim iznosom. Generalno, odlučeno je da se napusti Firebase i radi u kući, pošto je tim dovoljno porastao.

Docker + Python + bash

Uzeli smo Docker, u njega ugurali emulatore, napisali jednostavan program na Pythonu koji u pravom trenutku podnese potreban broj emulatora u traženoj verziji i po potrebi ih zaustavi. I, naravno, nekoliko bash skripti - gdje bismo bili bez njih?

Bilo je potrebno pet sedmica da stvorimo vlastito testno okruženje.

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

  • ARK skupština;
  • Junit testovi;
  • Lint;
  • Android Studio provjere;
  • Instrumentacijski testovi;
  • Testovi snimka ekrana.

To je spriječilo mnoge moguće kvarove. Tehnički je sve funkcioniralo, ali programeri su se žalili da je čekanje na rezultate predugo.

Koliko dugo je predugo? Prebacili smo podatke iz Bitbucketa i TeamCitya u sistem analize i to shvatili prosječno vrijeme čekanja 45 minuta. To jest, programer, kada otvara zahtjev za povlačenjem, čeka u prosjeku 45 minuta na rezultate izgradnje. Po mom mišljenju, ovo je mnogo, a ne možete tako raditi.

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

Hajde da ubrzamo

S obzirom da zgrade često stoje u redu, prva stvar koju radimo je kupio više hardvera — ekstenzivni razvoj je najjednostavniji. Gradnje su prestale da čekaju u redu, ali se vrijeme čekanja samo neznatno smanjilo, jer su same provjere trajale jako dugo.

Uklanjanje čekova koji predugo traju

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

  • Neću. CI može uhvatiti grešku kompilacije kada se nešto ne izgradi zbog konfliktnih promjena. Kao što sam već rekao, tada niko ne može ništa da sklopi, razvoj staje, i svi postaju nervozni.
  • Greška u ponašanju. Na primjer, kada je aplikacija napravljena, ali se ruši kada pritisnete dugme ili se dugme uopšte ne pritisne. Ovo je loše jer takva greška može doći do korisnika.
  • Greška u rasporedu. Na primjer, dugme je kliknuto, ali se pomaknulo za 10 piksela ulijevo.
  • Povećanje tehničkog duga.

Nakon što smo pogledali ovu listu, shvatili smo da su samo prve dvije tačke kritične. Želimo prvo da uhvatimo takve probleme. Greške u izgledu se otkrivaju u fazi pregleda dizajna i tada se mogu lako ispraviti. Bavljenje tehničkim dugom zahtijeva poseban proces i planiranje, pa smo odlučili da ga ne testiramo na zahtjevu za povlačenje.

Na osnovu ove klasifikacije, uzdrmali smo čitav spisak provjera. Precrtan Lint i odgodio njegovo lansiranje preko noći: samo da bi napravio izvještaj o tome koliko je problema bilo u projektu. Dogovorili smo se da radimo odvojeno sa tehničkim dugom, i Provjere Android Studija su potpuno napuštene. Android Studio u Dockeru za pokretanje inspekcija zvuči zanimljivo, ali izaziva mnogo problema u podršci. Svako ažuriranje verzija Android Studija znači borbu sa neshvatljivim greškama. Takođe je bilo teško podržati testove snimaka ekrana, jer biblioteka nije bila baš stabilna i bilo je lažnih pozitivnih rezultata. Testovi snimka ekrana su uklonjeni sa kontrolne liste.

Kao rezultat, ostali smo sa:

  • ARK skupština;
  • Junit testovi;
  • Instrumentacijski testovi.

Gradle udaljena keš memorija

Bez teških provjera, sve je postalo bolje. Ali ne postoji granica savršenstvu!

Naša aplikacija je već bila podijeljena na oko 150 gradle modula. Gradle udaljeni keš obično dobro radi u ovom slučaju, pa smo odlučili da ga isprobamo.

Gradle udaljena predmemorija je usluga koja može keširati artefakte izgradnje za pojedinačne zadatke u pojedinačnim modulima. Gradle, umjesto da zapravo kompajlira kod, koristi HTTP da bi udario u udaljenu keš memoriju i pitao da li je neko već izvršio ovaj zadatak. Ako da, jednostavno preuzima rezultat.

Pokretanje Gradle udaljene keš memorije je jednostavno jer Gradle pruža Docker sliku. Uspeli smo to da uradimo za tri sata.

Sve što je trebalo da uradite je da pokrenete Docker i upišete jedan red u projekat. Ali iako se može brzo pokrenuti, trebat će dosta vremena da sve dobro funkcionira.

Ispod je grafikon promašaja keša.

Evolucija CI u mobilnom razvojnom timu

Na samom početku postotak promašaja keša bio je oko 65. Nakon tri sedmice uspjeli smo povećati ovu vrijednost na 20%. Pokazalo se da zadaci koje Android aplikacija prikuplja imaju čudne tranzitivne zavisnosti, zbog čega je Gradle propustio keš memoriju.

Povezivanjem keš memorije uvelike smo ubrzali izgradnju. Ali pored montaže, tu su i testovi instrumentacije, a oni dugo traju. Možda se svi testovi ne moraju izvoditi za svaki zahtjev za povlačenjem. Da bismo saznali, koristimo analizu uticaja.

Analiza uticaja

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

Evolucija CI u mobilnom razvojnom timu

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

Instrumentacijski testovi nisu tako jednostavni, jer moraju biti smješteni u aplikativnom modulu najvišeg nivoa. Koristili smo heuristiku sa analizom bajtkoda da bismo razumjeli kojem modulu pripada svaki test.

Nadogradnja rada testova instrumentacije tako da oni testiraju samo uključene module trajala je oko osam sedmica.

Mjere za ubrzanje inspekcija su uspješno funkcionisale. Od 45 minuta smo se popeli na oko 15. Već je normalno čekati četvrt sata za izgradnju.

Ali sada su programeri počeli da se žale da ne razumiju koje se buildove pokreću, gdje vidjeti dnevnik, zašto je build crven, koji test nije uspio itd.

Evolucija CI u mobilnom razvojnom timu

Problemi sa povratnim informacijama usporavaju razvoj, pa smo se trudili da pružimo što jasnije i detaljnije informacije o svakom PR-u i izgradnji. Počeli smo s komentarima u Bitbucketu PR-u, naznačujući koja je izgradnja propala i zašto, i napisali ciljane poruke u Slack-u. Na kraju smo kreirali PR dashboard za stranicu sa listom svih build-ova koji su trenutno pokrenuti i njihovim statusom: u redu čekanja, pokrenuti, srušeni ili završeni. Možete kliknuti na gradnju i doći do njenog dnevnika.

Evolucija CI u mobilnom razvojnom timu

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

Planovi

Pređimo na noviju istoriju. Nakon što smo riješili problem povratnih informacija, došli smo na novi nivo - 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 sa fleksibilnim upravljanjem resursima.

Osim toga, postoje i drugi planovi.

  • Vratite Lint (i druge statičke analize). Mi već radimo u tom pravcu.
  • Pokreni sve na PR blokeru end-to-end testovi na svim verzijama SDK.

Dakle, pratili smo istoriju razvoja Kontinuirane integracije u Avitu. Sada želim dati nekoliko savjeta iz iskusne tačke gledišta.

Savjeti

Kad bih mogao dati samo jedan savjet to bi bio ovaj:

Budite oprezni sa shell skriptama!

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

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

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

Ali, kao što znate, sve se s vremenom razvija i usložnjava - pokrenimo jednu skriptu od druge, dajmo joj neke parametre - na kraju smo morali napisati funkciju koja određuje na kojem se nivou bash gniježđenja sada nalazimo. da umetnete potrebne citate, da sve započnete.

Evolucija CI u mobilnom razvojnom timu

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

Šta se može zamijeniti?

  • Bilo koji skriptni jezik. Pišite na Python ili Kotlin Script zgodnije jer je programiranje, a ne skripte.
  • Ili opišite svu logiku izgradnje u obrascu Prilagođeni gradle zadaci za vaš projekat.

Odlučili smo odabrati drugu opciju, a sada sistematski brišemo sve bash skripte i pišemo mnogo prilagođenih gradle zadataka.

Savjet #2: Pohranite infrastrukturu u kodu.

Zgodno je kada se postavka Continuous Integration ne pohranjuje u korisničkom interfejsu Jenkinsa ili TeamCity-a, itd., već u obliku tekstualnih datoteka direktno u repozitoriju projekta. Ovo daje mogućnost verzije. Neće biti teško vratiti ili napraviti kod na drugoj grani.

Skripte se mogu pohraniti u projekt. Šta učiniti sa okolinom?

Savjet br. 3: Docker može pomoći u okolišu.

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 ste napisali ovaj Docker fajl (odat ću vam tajnu, ne morate ga pisati, već ga samo izvucite gotovu sa GitHub-a) i sastavite sliku, dobijate virtuelnu mašinu na kojoj možete izgraditi aplikaciju i pokrenite Junit testove.

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 čini život CI inženjerima mnogo lakšim. Prilično je lako ugurati android-sdk u docker, ali s emulatorima je to malo teže: morat ćete se malo više potruditi (ili ponovo preuzeti gotov s GitHub-a).

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

Brze i, što je najvažnije, jasne povratne informacije su veoma važne za programere: šta je pokvareno, koji test nije uspeo, gde mogu da vidim buildlog.

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

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

Savjet #6: Koristite gotove alate.

Sada postoji mnogo kompanija koje pružaju CI u oblaku.

Evolucija CI u mobilnom razvojnom timu

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

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

Ali prije ili kasnije, kako tim raste, interna rješenja će postati profitabilnija. Postoji jedan problem sa ovim odlukama. U ekonomiji postoji zakon opadajućeg prinosa: 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 u mobilnom razvojnom timu

Jasno je da svako poboljšanje postaje sve teže. Gledajući ovaj grafikon, možete shvatiti da kontinuiranu integraciju treba razvijati u skladu s rastom veličine tima. Za tim od dvoje ljudi, potrošiti 50 dana na razvoj interne farme emulatora je osrednja ideja. Ali u isto vrijeme, za veliki tim, uopće ne raditi kontinuiranu integraciju je također loša ideja, jer problemi s integracijom, popravljanje komunikacije itd. biće potrebno još više vremena.

Počeli smo sa idejom da je automatizacija potrebna jer su ljudi skupi, greše i lijeni su. Ali ljudi se takođe automatizuju. Stoga se svi isti problemi odnose na automatizaciju.

  • Automatizacija je skupa. Zapamtite raspored rada.
  • Kada je u pitanju automatizacija, ljudi prave greške.
  • Ponekad je vrlo lijeno automatizirati, jer sve tako funkcionira. Zašto poboljšati bilo šta drugo, čemu sva ta kontinuirana integracija?

Ali imam statistiku: greške se hvataju 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 grešku, ona neće završiti u razvoju, već će biti uhvaćena automatskim provjerama. Shodno tome, programeri mogu provesti više vremena u pisanju koda i zanimljivih stvari, umjesto da rade i testiraju nešto lokalno.

Vježbajte kontinuiranu integraciju. Ali u umjerenim količinama.

Inače, Nikolaj Nesterov ne samo da sam daje odlične izveštaje, već je i član programskog odbora AppsConf i pomaže drugima da pripreme značajne govore za vas. Kompletnost i korisnost programa sljedeće konferencije može se ocijeniti po temama u raspored. A za detalje dođite u Infospace od 22. do 23. aprila.

izvor: www.habr.com

Dodajte komentar