Razvoj CI v mobilni razvojni ekipi

Danes se večina programskih izdelkov razvija v skupinah. Pogoje za uspešen razvoj ekipe lahko predstavimo v obliki preprostega diagrama.

Razvoj CI v mobilni razvojni ekipi

Ko napišete kodo, se morate prepričati, da:

  1. Deluje.
  2. Ne pokvari ničesar, vključno s kodo, ki so jo napisali vaši kolegi.

Če sta oba pogoja izpolnjena, potem ste na poti do uspeha. Da bi enostavno preverili te pogoje in ne skrenili z donosne poti, smo se domislili Neprekinjene integracije.

CI je potek dela, kjer svojo kodo čim pogosteje vključite v celotno kodo izdelka. In ne samo integrirate, ampak tudi nenehno preverjate, ali vse deluje. Ker morate veliko in pogosto preverjati, je vredno razmišljati o avtomatizaciji. Vse lahko preverite ročno, vendar ne bi smeli, in tukaj je razlog.

  • Dragi ljudje. Ura dela katerega koli programerja je dražja od ure dela kateregakoli strežnika.
  • Ljudje delamo napake. Zato lahko pride do situacij, ko so bili testi izvedeni na napačni veji ali ko je bila za preizkuševalce prevedena napačna potrditev.
  • Ljudje so leni. Od časa do časa, ko opravim nalogo, se pojavi misel: »Kaj je treba preveriti? Napisal sem dve vrstici - vse deluje! Mislim, da imate tudi nekateri včasih takšne misli. Vendar morate vedno preveriti.

Kako je bila neprekinjena integracija implementirana in razvita v skupini za razvoj mobilnih naprav Avito, kako so šli od 0 do 450 gradenj na dan in da se gradbeni stroji sestavljajo 200 ur na dan, pravi Nikolaj Nesterov (nnesterov) je udeleženec vseh evolucijskih sprememb CI/CD Android aplikacije.

Zgodba temelji na primeru Android ukaza, vendar je večina pristopov uporabnih tudi na iOS.


Nekoč je ena oseba delala v ekipi Avito Android. Po definiciji od Nenehne integracije ni potreboval ničesar: ni bilo nikogar, s katerim bi se povezal.

Toda aplikacija je rasla, pojavljalo se je vedno več novih nalog in temu primerno je rasla tudi ekipa. Na neki točki je čas za bolj formalno vzpostavitev procesa integracije kode. Odločeno je bilo uporabiti Git flow.

Razvoj CI v mobilni razvojni ekipi

Koncept Git flowa je dobro znan: projekt ima eno skupno razvojno vejo in za vsako novo funkcijo razvijalci izrežejo ločeno vejo, se ji zavežejo, potisnejo in ko želijo združiti svojo kodo v razvojno vejo, odprejo povlecite zahtevo. Za izmenjavo znanja in razpravo o pristopih smo uvedli pregled kode, to pomeni, da morajo sodelavci preveriti in potrditi kodo drug drugega.

Pregledi

Videti kodo z očmi je kul, vendar ne dovolj. Zato se uvaja avtomatsko preverjanje.

  • Najprej preverimo montaža ARK.
  • Veliko Junit testi.
  • Upoštevamo pokritost kode, saj izvajamo teste.

Da bi razumeli, kako naj potekajo ta preverjanja, si poglejmo razvojni proces v programu Avito.

Shematično ga lahko predstavimo takole:

  • Razvijalec piše kodo na svojem prenosniku. Preverjanja integracije lahko zaženete kar tukaj - bodisi s kavljem za potrditev ali preprosto zaženete preverjanja v ozadju.
  • Ko je razvijalec potisnil kodo, odpre zahtevo za vlečenje. Da bi bila njegova koda vključena v razvojno vejo, je treba opraviti pregled kode in zbrati potrebno število potrditev. Tukaj lahko omogočite preverjanja in gradnje: dokler vse gradnje niso uspešne, zahteve za vlečenje ni mogoče združiti.
  • Ko je zahteva za vleko združena in je koda vključena v razvoj, lahko izberete primeren čas: na primer ponoči, ko so vsi strežniki prosti, in izvedete poljubno število preverjanj.

Nihče ni maral skeniranja na svojem prenosniku. Ko razvijalec dokonča funkcijo, jo želi hitro potisniti in odpreti zahtevo za vlečenje. Če se v tem trenutku zaženejo dolga preverjanja, to ni samo zelo prijetno, ampak tudi upočasni razvoj: medtem ko prenosnik nekaj preverja, na njem ni mogoče normalno delati.

Zelo nam je bilo všeč izvajanje pregledov ponoči, ker je veliko časa in strežnikov, lahko se potikaš naokoli. Toda na žalost ima razvijalec veliko manj motivacije, da bi popravil napake, ki jih je našel CI, ko se koda funkcije začne razvijati. Občasno sem se ujel, da sem razmišljal, ko sem pogledal vse napake, najdene v jutranjem poročilu, da jih bom nekega dne kasneje popravil, ker je zdaj v Jiri nova kul naloga, ki jo želim začeti opravljati.

Če preverjanja blokirajo zahtevo po vleki, je dovolj motivacije, ker dokler gradnje ne postanejo zelene, koda ne bo prišla v razvoj, kar pomeni, da naloga ne bo dokončana.

Posledično smo izbrali naslednjo strategijo: ponoči izvajamo največji možni nabor preverjanj, najbolj kritične med njimi in, kar je najpomembneje, najhitrejše izvajamo na zahtevo po vleku. Vendar se ne ustavimo pri tem – vzporedno optimiziramo hitrost preverjanj, tako da jih prenesemo iz nočnega načina v preverjanja zahtevkov za vleko.

Takrat so bile vse naše gradnje dokončane precej hitro, zato smo preprosto vključili gradnjo ARK, teste Junit in izračune pokritosti kode kot blokator za zahtevo po vleku. Vklopili smo ga, razmislili o tem in opustili pokritost kode, ker smo mislili, da je ne potrebujemo.

Za popolno postavitev osnovnega CI smo potrebovali dva dni (v nadaljevanju je časovna ocena približna, potrebna za merilo).

Po tem smo začeli razmišljati naprej - ali sploh preverjamo pravilno? Ali pravilno izvajamo gradnje na podlagi zahtev po vleku?

Začeli smo graditi na zadnji objavi veje, iz katere je bila odprta zahteva za vlečenje. Toda preizkusi te potrditve lahko le pokažejo, da koda, ki jo je napisal razvijalec, deluje. Ne dokazujejo pa, da ni ničesar zlomil. Pravzaprav morate preveriti stanje razvojne veje, potem ko je funkcija združena vanjo.

Razvoj CI v mobilni razvojni ekipi

Da bi to naredili, smo napisali preprost bash skript premerge.sh:

#!/usr/bin/env bash

set -e

git fetch origin develop

git merge origin/develop

Tu so vse najnovejše spremembe iz developmenta preprosto povlečene navzgor in združene v trenutno vejo. Dodali smo skript premerge.sh kot prvi korak pri vseh gradnjah in začeli preverjati, kaj točno želimo, tj. integracija.

Potrebovali smo tri dni, da smo lokalizirali težavo, našli rešitev in napisali ta skript.

Aplikacija se je razvijala, pojavljalo se je vedno več nalog, ekipa je rasla in premerge.sh nas je včasih začel pustiti na cedilu. Develop je imel nasprotujoče si spremembe, ki so prekinile gradnjo.

Primer, kako se to zgodi:

Razvoj CI v mobilni razvojni ekipi

Dva razvijalca istočasno začneta delati na funkcijah A in B. Razvijalec funkcije A odkrije neuporabljeno funkcijo v projektu answer() in ga kot dober skavt odstrani. Istočasno razvijalec funkcije B doda nov klic tej funkciji v svoji veji.

Razvijalci končajo svoje delo in hkrati odprejo zahtevo za vleko. Zgradbe se zaženejo, premerge.sh preveri obe zahtevi za vleko glede zadnjega stanja razvoja – vsa preverjanja so zelena. Po tem se združi zahteva za vlečenje funkcije A, združi se zahteva za vlečenje funkcije B ... Bum! Razvijanje prekine, ker razvojna koda vsebuje klic neobstoječe funkcije.

Razvoj CI v mobilni razvojni ekipi

Ko se ne bo razvilo, se lokalna katastrofa. Celotna ekipa ne more ničesar zbrati in oddati v testiranje.

Tako se je zgodilo, da sem največkrat delal na infrastrukturnih nalogah: analitika, omrežje, baze podatkov. To pomeni, da sem jaz napisal tiste funkcije in razrede, ki jih uporabljajo drugi razvijalci. Zaradi tega sem se zelo pogosto znašel v podobnih situacijah. Nekaj ​​časa sem celo imel to sliko visečo.

Razvoj CI v mobilni razvojni ekipi

Ker nam to ni ustrezalo, smo začeli raziskovati možnosti, kako to preprečiti.

Kako ne prekiniti razvoja

Prva možnost: obnovi vse zahteve za vleko pri posodabljanju razvoja. Če je v našem primeru zahteva za vlečenje s funkcijo A prva vključena v razvoj, bo zahteva za vlečenje funkcije B ponovno zgrajena in v skladu s tem preverjanja ne bodo uspela zaradi napake pri prevajanju.

Da bi razumeli, kako dolgo bo to trajalo, razmislite o primeru dveh PR-jev. Odpremo dva PR-ja: dve gradnji, dve izvedbi preverjanj. Ko se prvi PR združi v development, je treba drugega ponovno zgraditi. Skupaj dva PR-ja zahtevata tri izvedbe preverjanj: 2 + 1 = 3.

Načeloma je v redu. Toda pogledali smo statistiko in tipična situacija v naši ekipi je bila 10 odprtih PR-jev, nato pa je število preverjanj vsota napredovanja: 10 + 9 +... + 1 = 55. To pomeni, da sprejmemo 10 PR-ji, morate 55-krat obnoviti. In to je v idealni situaciji, ko vsi pregledi minejo prvič, ko nihče ne odpre dodatne zahteve za vleko, medtem ko se ta ducat obdeluje.

Predstavljajte si sebe kot razvijalca, ki mora prvi klikniti na gumb »združi«, kajti če to stori sosed, potem boste morali počakati, da gredo vse gradnje znova skozi ... Ne, to ne bo šlo , bo to resno upočasnilo razvoj.

Drugi možni način: po pregledu kode zbirajte zahteve za vleko. To pomeni, da odprete zahtevo za vlečenje, zberete zahtevano število odobritev kolegov, popravite, kar je potrebno, in nato zaženete gradnje. Če so uspešni, se zahteva za vlečenje združi v development. V tem primeru ni dodatnih ponovnih zagonov, je pa povratna informacija močno upočasnjena. Ko kot razvijalec odprem zahtevo za vlečenje, želim takoj preveriti, ali bo delovala. Na primer, če test ne uspe, ga morate hitro popraviti. V primeru zakasnjene gradnje se povratna informacija upočasni in s tem celoten razvoj. Tudi to nam ni ustrezalo.

Posledično je ostala le tretja možnost - kolo. Vsa naša koda, vsi naši viri so shranjeni v repozitoriju na strežniku Bitbucket. V skladu s tem smo morali razviti vtičnik za Bitbucket.

Razvoj CI v mobilni razvojni ekipi

Ta vtičnik preglasi mehanizem združevanja zahtev za vleko. Začetek je standarden: odpre se PR, zaženejo se vsi sklopi, pregled kode je končan. Ko pa je pregled kode končan in se razvijalec odloči klikniti »združi«, vtičnik preveri, v katerem stanju razvoja so bila izvedena preverjanja. Če je bil development posodobljen po gradnji, vtičnik ne bo dovolil, da se takšna zahteva za vleko združi z glavno vejo. Preprosto bo znova zagnal gradnje relativno nedavnega razvoja.

Razvoj CI v mobilni razvojni ekipi

V našem primeru z nasprotujočimi si spremembami takšne gradnje ne bodo uspele zaradi napake pri prevajanju. V skladu s tem bo moral razvijalec funkcije B popraviti kodo, znova zagnati preverjanja, nato pa bo vtičnik samodejno uporabil zahtevo za vlečenje.

Preden smo uvedli ta vtičnik, smo v povprečju izvedli 2,7 pregleda na zahtevo za vleko. Z dodatkom je bilo 3,6 zagonov. To nam je ustrezalo.

Omeniti velja, da ima ta vtičnik pomanjkljivost: gradnjo znova zažene samo enkrat. To pomeni, da še vedno obstaja majhno okno, skozi katerega se lahko razvijejo nasprotujoče si spremembe. Vendar je verjetnost za to nizka in naredili smo ta kompromis med številom zagonov in verjetnostjo neuspeha. V dveh letih je streljalo le enkrat, tako da verjetno ni bilo zaman.

Potrebovali smo dva tedna, da smo napisali prvo različico vtičnika Bitbucket.

Novi čeki

Medtem je naša ekipa še naprej rasla. Dodani so bili novi pregledi.

Pomislili smo: zakaj delati napake, če jih je mogoče preprečiti? In zato so uvedli statična analiza kode. Začeli smo s lintom, ki je vključen v Android SDK. A takrat sploh še ni znal delati s kodo Kotlin, mi pa smo že imeli 75% aplikacije napisane v Kotlinu. Zato so lintu dodali vgrajene Android Studio preverja.

Da bi to naredili, smo morali narediti veliko sprevrženja: vzeti Android Studio, ga zapakirati v Docker in zagnati na CI z virtualnim monitorjem, tako da misli, da deluje na pravem prenosniku. Ampak je delovalo.

V tem času smo tudi začeli veliko pisati instrumentacijski testi in izvajati testiranje posnetkov zaslona. Takrat se ustvari referenčni posnetek zaslona za ločen majhen pogled, preskus pa zajema posnetek zaslona iz pogleda in njegovo primerjavo s standardom neposredno slikovno piko za slikovno piko. Če pride do neskladja, pomeni, da se je postavitev nekje zmotila ali pa je nekaj narobe v slogih.

Vendar je treba preizkuse instrumentov in posnetke zaslona izvajati na napravah: na emulatorjih ali na resničnih napravah. Glede na to, da je testov veliko in se izvajajo pogosto, je potrebna cela farma. Zagon lastne kmetije je preveč delovno intenziven, zato smo našli že pripravljeno možnost – Firebase Test Lab.

Testni laboratorij Firebase

Izbrali so ga, ker je Firebase Googlov izdelek, kar pomeni, da bi moral biti zanesljiv in malo verjetno, da bo kdaj umrl. Cene so razumne: 5 $ na uro delovanja prave naprave, 1 $ na uro delovanja emulatorja.

Trajalo je približno tri tedne, da smo implementirali Firebase Test Lab v naš CI.

Toda ekipa je še naprej rasla in Firebase nas je na žalost začel puščati na cedilu. Takrat še ni imel SLA. Včasih nas je Firebase prisilil, da počakamo, da je zahtevano število naprav prosto za teste, in jih ni začel izvajati takoj, kot smo želeli. Čakanje v vrsti je trajalo tudi do pol ure, kar je zelo dolgo. Na vsakem PR-ju so bili testirani instrumenti, zamude so res upočasnile razvoj, nato pa je mesečni račun prišel okrogel. Na splošno je bilo odločeno, da opustimo Firebase in delamo znotraj podjetja, saj je ekipa dovolj zrasla.

Docker + Python + bash

Vzeli smo Docker, vanj stlačili emulatorje, napisali preprost program v Pythonu, ki v pravem trenutku prikliče zahtevano število emulatorjev v zahtevani verziji in jih po potrebi ustavi. In seveda nekaj bash skriptov - kje bi bili brez njih?

Potrebovali smo pet tednov, da smo ustvarili naše testno okolje.

Posledično je za vsako zahtevo po vleki obstajal obsežen seznam preverjanj za blokiranje spajanja:

  • montaža ARK;
  • testi Junit;
  • vlakna;
  • Android Studio preverja;
  • Instrumentacijski testi;
  • Testi posnetkov zaslona.

S tem smo preprečili številne morebitne okvare. Tehnično je vse delovalo, vendar so se razvijalci pritoževali, da je bilo čakanje na rezultate predolgo.

Koliko časa je predolgo? Podatke iz Bitbucket in TeamCity smo naložili v sistem za analizo in to ugotovili povprečna čakalna doba 45 minut. To pomeni, da razvijalec, ko odpre zahtevo za vleko, v povprečju čaka 45 minut na rezultate gradnje. Po mojem mnenju je to veliko in tako ne moreš delati.

Seveda smo se odločili pospešiti vse naše gradnje.

Pospešimo

Ko vidimo, da zgradbe pogosto stojijo v čakalni vrsti, je prva stvar, ki jo naredimo kupil več strojne opreme — ekstenziven razvoj je najenostavnejši. Zgradbe so prenehale stati v vrsti, vendar se je čakalna doba le malo skrajšala, saj so nekateri pregledi sami trajali zelo dolgo.

Odstranjevanje pregledov, ki trajajo predolgo

Naša stalna integracija bi lahko ujela tovrstne napake in težave.

  • Ne bom. CI lahko ujame napako pri prevajanju, ko se nekaj ne zgradi zaradi nasprotujočih si sprememb. Kot sem že rekel, potem nihče ne more ničesar sestaviti, razvoj se ustavi in ​​vsi postanejo živčni.
  • Napaka v obnašanju. Na primer, ko je aplikacija zgrajena, vendar se zruši, ko pritisnete gumb, ali pa gumb sploh ni pritisnjen. To je slabo, ker lahko taka napaka pride do uporabnika.
  • Napaka v postavitvi. Na primer, gumb je bil kliknjen, vendar se je premaknil za 10 slikovnih pik v levo.
  • Povečanje tehničnega dolga.

Po ogledu tega seznama smo ugotovili, da sta samo prvi dve točki kritični. Takšne težave želimo najprej ujeti. Napake v postavitvi se odkrijejo v fazi pregleda dizajna in jih je mogoče enostavno popraviti. Ukvarjanje s tehničnim dolgom zahteva ločen postopek in načrtovanje, zato smo se odločili, da ga ne bomo preizkusili na zahtevi za vleko.

Na podlagi te razvrstitve smo pretresli celoten seznam pregledov. Prečrtan Lint in čez noč preložil zagon: samo zato, da bi pripravil poročilo o tem, koliko težav je bilo v projektu. S tehničnim dolgom sva se dogovorila za ločeno delo ter Preverjanja Android Studio so bila popolnoma opuščena. Android Studio v Dockerju za izvajanje pregledov se sliši zanimivo, vendar povzroča veliko težav pri podpori. Vsaka posodobitev različic Android Studio pomeni boj z nerazumljivimi hrošči. Prav tako je bilo težko podpreti preizkuse posnetkov zaslona, ​​ker knjižnica ni bila zelo stabilna in je prihajalo do lažno pozitivnih rezultatov. Testi posnetkov zaslona so bili odstranjeni s kontrolnega seznama.

Posledično nam je ostalo:

  • montaža ARK;
  • testi Junit;
  • Instrumentacijski testi.

Oddaljeni predpomnilnik Gradle

Brez težkih pregledov se je vse izboljšalo. Vendar ni omejitev za popolnost!

Naša aplikacija je bila že razdeljena na približno 150 gradle modulov. Oddaljeni predpomnilnik Gradle običajno dobro deluje v tem primeru, zato smo se odločili, da ga preizkusimo.

Oddaljeni predpomnilnik Gradle je storitev, ki lahko predpomni gradbene artefakte za posamezne naloge v posameznih modulih. Gradle, namesto da bi dejansko prevedel kodo, uporablja HTTP, da potrka na oddaljeni predpomnilnik in vpraša, ali je nekdo že opravil to nalogo. Če da, preprosto prenese rezultat.

Zagon oddaljenega predpomnilnika Gradle je enostaven, ker Gradle ponuja sliko Docker. To nam je uspelo v treh urah.

Vse, kar ste morali storiti, je bilo zagnati Docker in napisati eno vrstico v projekt. Čeprav ga je mogoče hitro zagnati, bo trajalo precej časa, da bo vse dobro delovalo.

Spodaj je graf pogreškov predpomnilnika.

Razvoj CI v mobilni razvojni ekipi

Na samem začetku je bil odstotek zgrešenih predpomnilnikov okoli 65. Po treh tednih nam je uspelo to vrednost povečati na 20 %. Izkazalo se je, da imajo naloge, ki jih zbira Android aplikacija, nenavadne tranzitivne odvisnosti, zaradi katerih je Gradle pogrešal predpomnilnik.

S priklopom predpomnilnika smo gradnjo močno pohitrili. Toda poleg montaže so tu še instrumentalni preizkusi, ki trajajo dolgo. Morda ni treba izvajati vseh testov za vsako zahtevo za vleko. Da bi ugotovili, uporabljamo analizo vpliva.

Analiza vpliva

Na zahtevo po vleki zberemo git diff in poiščemo spremenjene module Gradle.

Razvoj CI v mobilni razvojni ekipi

Smiselno je izvajati le teste instrumentov, ki preverjajo spremenjene module in vse module, ki so odvisni od njih. Nima smisla izvajati testov za sosednje module: tam se koda ni spremenila in nič se ne more zlomiti.

Instrumentacijski testi niso tako enostavni, saj se morajo nahajati v aplikacijskem modulu najvišje ravni. Uporabili smo hevristiko z analizo bajtne kode, da bi razumeli, kateremu modulu pripada posamezen test.

Nadgradnja delovanja testov instrumentov, tako da testirajo le vključene module, je trajala približno osem tednov.

Ukrepi za pospešitev inšpekcijskih pregledov so bili uspešni. S 45 minut smo šli na približno 15. Že normalno je, da čakaš četrt ure na gradnjo.

Toda zdaj so se razvijalci začeli pritoževati, da ne razumejo, katere zgradbe se zaženejo, kje videti dnevnik, zakaj je zgradba rdeča, kateri test ni uspel itd.

Razvoj CI v mobilni razvojni ekipi

Težave s povratnimi informacijami upočasnjujejo razvoj, zato smo poskušali podati čim bolj jasne in podrobne informacije o posameznem PR-ju in gradivu. Začeli smo s komentarji v Bitbucketu za PR, ki so navedli, katera zgradba je bila neuspešna in zakaj, ter napisali ciljna sporočila v Slacku. Na koncu smo ustvarili PR nadzorno ploščo za stran s seznamom vseh gradenj, ki se trenutno izvajajo, in njihovim statusom: v čakalni vrsti, v teku, zrušitev ali dokončana. Lahko kliknete gradnjo in pridete do njenega dnevnika.

Razvoj CI v mobilni razvojni ekipi

Šest tednov je bilo porabljenih za podrobne povratne informacije.

Načrti

Preidimo v novejšo zgodovino. Ko smo rešili težavo s povratnimi informacijami, smo dosegli novo raven - odločili smo se zgraditi lastno farmo emulatorjev. Če je testov in emulatorjev veliko, jih je težko upravljati. Posledično so se vsi naši emulatorji preselili v gručo k8s s prilagodljivim upravljanjem virov.

Poleg tega obstajajo še drugi načrti.

  • Vrni lint (in druge statične analize). V tej smeri že delamo.
  • Zaženite vse na PR blokatorju testi od konca do konca na vseh različicah SDK.

Tako smo izsledili zgodovino razvoja neprekinjene integracije v Avitu. Zdaj bi rad dal nekaj nasvetov z izkušenega vidika.

Советы

Če bi lahko dal le en nasvet, bi bil ta:

Prosimo, bodite previdni pri lupinskih skriptih!

Bash je zelo prilagodljivo in zmogljivo orodje, z njim je zelo priročno in hitro pisati skripte. Toda z njim se lahko ujameš v past in na žalost smo padli vanjo.

Vse se je začelo s preprostimi skripti, ki so se izvajali na naših gradbenih strojih:

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

Toda, kot veste, se sčasoma vse razvija in postaja bolj zapleteno - poženimo en skript iz drugega, posredujmo nekaj parametrov tja - na koncu smo morali napisati funkcijo, ki določa, na kateri ravni bash gnezdenja smo zdaj, da bi da vstavite potrebne narekovaje, da se vse skupaj začne.

Razvoj CI v mobilni razvojni ekipi

Lahko si predstavljate stroške dela za razvoj takšnih skript. Svetujem vam, da se ne ujamete v to past.

Kaj je mogoče nadomestiti?

  • Kateri koli skriptni jezik. Pišite Skript Python ali Kotlin bolj priročno, ker gre za programiranje, ne za skripte.
  • Ali opišite vso logiko gradnje v obrazcu Naloge Gradle po meri za vaš projekt.

Odločili smo se za drugo možnost in zdaj sistematično brišemo vse bash skripte in pišemo veliko nalog Gradle po meri.

Nasvet št. 2: Shranite infrastrukturo v kodo.

Primerno je, če nastavitev neprekinjene integracije ni shranjena v uporabniškem vmesniku Jenkins ali TeamCity itd., temveč v obliki besedilnih datotek neposredno v repozitoriju projekta. To daje različico. Ne bo težko vrniti nazaj ali zgraditi kode na drugi veji.

Skripte lahko shranite v projekt. Kaj storiti z okoljem?

Namig #3: Docker lahko pomaga z okoljem.

Vsekakor bo pomagal razvijalcem Androida; iOS ga žal še nima.

To je primer preproste docker datoteke, ki vsebuje jdk in 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

Ko napišete to datoteko Docker (razkril vam bom skrivnost, ni vam je treba napisati, ampak jo preprosto potegnete že pripravljeno iz GitHuba) in sestavite sliko, dobite virtualni stroj, na katerem lahko zgradite aplikacijo in zaženite teste Junit.

Dva glavna razloga, zakaj je to smiselno, sta razširljivost in ponovljivost. Z uporabo dockerja lahko hitro ustvarite ducat gradbenih agentov, ki bodo imeli popolnoma enako okolje kot prejšnji. To močno olajša življenje inženirjev CI. Precej enostavno je potisniti android-sdk v docker, vendar je z emulatorji malo težje: morali se boste malo bolj potruditi (ali znova prenesti končanega iz GitHuba).

Namig št. 4: ne pozabite, da se inšpekcije ne izvajajo zaradi inšpekcij, ampak zaradi ljudi.

Za razvijalce so zelo pomembne hitre in, kar je najpomembneje, jasne povratne informacije: kaj se je pokvarilo, kateri test ni uspel, kje lahko vidim buildlog.

Namig št. 5: Bodite pragmatični, ko razvijate stalno integracijo.

Jasno razumejte, katere vrste napak želite preprečiti, koliko sredstev, časa in računalniškega časa ste pripravljeni porabiti. Preverjanja, ki trajajo predolgo, se lahko na primer preložijo čez noč. In tiste med njimi, ki ujamejo ne zelo pomembne napake, je treba popolnoma opustiti.

Nasvet št. 6: Uporabite že pripravljena orodja.

Zdaj je veliko podjetij, ki ponujajo CI v oblaku.

Razvoj CI v mobilni razvojni ekipi

To je dobra rešitev za majhne ekipe. Ničesar vam ni treba podpirati, samo plačajte malo denarja, zgradite svojo aplikacijo in celo izvajajte teste instrumentov.

Namig #7: V veliki ekipi so interne rešitve bolj donosne.

Toda prej ali slej, ko se bo ekipa povečala, bodo interne rešitve postale donosnejše. S temi odločitvami je en problem. V ekonomiji velja zakon padajočih donosov: pri vsakem projektu je vsaka naslednja izboljšava vedno težja in zahteva vedno več vlaganj.

Ekonomija opisuje naše celotno življenje, vključno s stalno integracijo. Sestavil sem razpored stroškov dela za vsako stopnjo razvoja naše Nenehne integracije.

Razvoj CI v mobilni razvojni ekipi

Jasno je, da je vsako izboljšanje vse težje. Če pogledate ta graf, lahko razumete, da je treba nenehno integracijo razvijati v skladu z rastjo velikosti ekipe. Za ekipo dveh ljudi je porabiti 50 dni za razvoj notranje farme emulatorjev povprečna ideja. Toda hkrati je za veliko ekipo tudi slaba ideja, da sploh ne izvaja neprekinjene integracije, ker težave pri integraciji, popravljanje komunikacije itd. trajalo bo še več časa.

Začeli smo z idejo, da je avtomatizacija potrebna, ker so ljudje dragi, delajo napake in so leni. Toda ljudje se tudi avtomatizirajo. Zato veljajo vse iste težave za avtomatizacijo.

  • Avtomatizacija je draga. Ne pozabite na urnik dela.
  • Ko gre za avtomatizacijo, ljudje delajo napake.
  • Včasih je zelo leno avtomatizirati, ker vse deluje na ta način. Zakaj izboljšati karkoli drugega, zakaj vsa ta neprekinjena integracija?

Imam pa statistiko: napake se odkrijejo v 20% sklopov. In to ne zato, ker naši razvijalci slabo pišejo kodo. To je zato, ker so razvijalci prepričani, da če naredijo kakšno napako, ta ne bo končala v razvoju, ampak jo bodo ujeli avtomatizirani pregledi. V skladu s tem lahko razvijalci porabijo več časa za pisanje kode in zanimivih stvari, namesto da izvajajo in testirajo nekaj lokalno.

Vadite stalno integracijo. Vendar v zmernih količinah.

Mimogrede, Nikolaj Nesterov ne daje le odličnih poročil sam, ampak je tudi član programskega odbora AppsConf in pomaga drugim pripraviti pomembne govore za vas. Popolnost in uporabnost programa naslednje konference lahko ocenimo po temah v urnik. Za podrobnosti pa pridite v Infospace 22. in 23. aprila.

Vir: www.habr.com

Dodaj komentar