TÀna arendatakse enamik tarkvaratooteid meeskondades. Meeskonnatöö edusamme saab kujutada lihtsa skeemina.

PĂ€rast koodi kirjutamist peate veenduma, et see:
- Töötaks.
- Ei rikuks midagi, sealhulgas teie kolleegide kirjutatud koodi.
Kui mÔlemad tingimused on tÀidetud, siis olete edukuse teel. Kui soovite neid tingimusi hÔlpsasti kontrollida ja mitte kasulikult teelt kÔrvale kalduda, leiutati pidev integratsioon.
CI on tööprotsess, kus integreerite oma koodi toote ĂŒldisesse koodi vĂ”imalikult tihti. Ja mitte ainult integreerite, vaid ka pidevalt kontrollite, et kĂ”ik töötaks. Kuna tuleb palju ja tihti kontrollida, tasub mĂ”elda automatiseerimise peale. KĂ”ike saab manuaalselt kontrollida, kuid see ei ole tark, ja siin on miks.
- Inimesed on kallid. Ăhe programmeerija töö tund maksab rohkem kui ĂŒhe serveri töö tund.
- Inimesed eksivad. SeetÔttu vÔivad tekkida olukorrad, kui testid kÀivitatakse vale haru peal vÔi koostatakse vale kommity testijate jaoks.
- Inimesed on laisad. Perioodiliselt, kui lĂ”petan mĂ”ne ĂŒlesande, tuleb mul pĂ€he mĂ”te: âMida siin kontrollida? Kirjutasin kaks rida â kindlasti töötab kĂ”ik!â Arvan, et mĂ”nel teist tulevad sellised mĂ”tted vahel ka meelde. Kuid kontrollida tuleb alati.
Kuidas Rakendati ja Arendati Pidevat Integratsiooni Avito mobiiliarenduse meeskonnas, kuidas jĂ”uti nullist 450 kogumiseni pĂ€evas ja mida kogumismasinad iga pĂ€ev 200 tunni eest teevad, rÀÀgib Nikolai Nesterov () â osaleja kĂ”igis CI/CD Android-rakenduse evolutsioonimuutustes.
Lugu on ĂŒles ehitatud Android meeskonna nĂ€itel, kuid enamik lĂ€henemisi on rakendatavad ka iOS-is.

Kaua aega tagasi töötas Avito Android meeskonnas ĂŒks inimene. Talle ei olnud definitsiooni jĂ€rgi pidev integratsioon vajalik: ei olnud kellegagi integreerida.
Kuid rakendus kasvas, ilmus ĂŒha rohkem uusi ĂŒlesandeid ja vastavalt suurenes meeskond. Ăhel hetkel tuli aeg koodi integreerimise protsess formaalsemaks muuta. Otsustati kasutada Git flow'd.

Git flow kontseptsioon on teada: projektis on ĂŒks ĂŒhine arendusbranch, ja iga uue funktsiooni jaoks lĂ”ikavad arendajad eraldi haru, komiteerivad sellesse, tĂ”ukavad seda ja kui nad tahavad oma koodi arendusbranchi ĂŒhendada, avavad nad pull requesti. Teadmiste vahetamiseks ja lĂ€henemiste arutamiseks oleme sisse viinud koodide ĂŒlevaate, kus kolleegid peavad ĂŒksteise koodi kontrollima ja kinnitama.
Kontrollid
Koodi vaatamine on Àge, kuid sellega ei piisa. SeetÔttu kehtestatakse automaatsed kontrollid.
- Esmalt kontrollime ARKi kogumist.
- Palju Junit teste.
- Arvutame koodi katvuse, kuna kÀivitame testid.
Et aru saada, kuidas neid kontrolle kÀivitada, vaatame arendusprotsessi Avitos.
Skeemiliselt saab seda ette kujutada nii:
- Arendaja kirjutab koodi oma sĂŒlearvutis. Integration checke saab kĂ€ivitada otse siin â kas commit hook'iga vĂ”i lihtsalt testide taustal kĂ€itamisega.
- PĂ€rast seda, kui arendaja on koodi tĂ”uganud, avab ta pull requesti. Selleks, et tema kood pÀÀseks arendusbranchi, peab olema lĂ€bi viidud koodide ĂŒlevaade ja vajalik arv kinnitusi. Siia on vĂ”imalik ĂŒhendata kontrollid ja build'id: kuni kĂ”ik build'id ei ole edukad, ei saa pull requesti ĂŒhendada.
- PĂ€rast seda, kui pull request on ĂŒhendatud ja kood on lĂ€inud arendusbranchi, saab valida sobiva aja: nĂ€iteks öösel, kui kĂ”ik serverid on vabad, ja kĂ€ivitada teste nii palju kui vĂ”imalik.
Kontrollide kĂ€itamine oma sĂŒlearvutis ei meeldinud kellelegi. Kui arendaja on funktsiooni lĂ”petanud, tahab ta selle kiirelt tĂ”ukama ja avada pull requesti. Kui sel hetkel kĂ€ivitatakse pikad kontrollid, pole see mitte ainult ebamugav, vaid aeglustab ka arendust: kuni sĂŒlearvuti kontrollib, ei saa seal normaalselt töötada.
Ăösel kontrolle kĂ€ivitada meeldis meile vĂ€ga, kuna aega ja servere on palju, saab ennast vĂ€lja elada. Kuid kahjuks, kui funktsiooni kood oli lĂ€inud arendusbranchi, oli arendajal juba palju vĂ€hem motivatsiooni parandada vigu, mida CI leidis. Ma vahepeal pĂŒĂŒdsin end korduvalt selle mĂ”ttega, kui vaatasin hommikusel aruandel kĂ”ik leitud vead, et parandan need kunagi hiljem, kuna praegu on Jira's Ă€ge uus ĂŒlesanne, mida tahaks alustada.
Kui kontrollid blokeerivad pull requesti, on motivatsiooni piisavalt, sest seni, kuni build'id ei ole edukad, ei pÀÀse kood arendusbranchi, ja seega ĂŒlesanne ei saa olema lĂ”petatud.
LĂ”puks valisime sellise strateegia: öösel jooksutame maksimaalset kontrollide kogumit, samas kui kĂ”ige kriitilisemad ja, mis kĂ”ige tĂ€htsam, kiiremad neist kĂ€ivitame pull request'i raames. Kuid sellega ei piirdunud â samaaegselt optimeerime kontrollide lĂ€bimise kiirus, et viia need öisest reĆŸiimist pull request'i kontrollideks.
Sel hetkel lĂ€bisid kĂ”ik meie ehitused piisavalt kiiresti, seetĂ”ttu lĂŒlitasime lihtsalt pull request'i blokeerijana sisse ARK'i ehituse, Junit-testid ja code coverage'i arvutamise. LĂŒlitasime sisse, mĂ”tlesime â ja loobusime code coverage'ist, kuna arvutasime, et see ei ole meile vajalik.
Kogu pÔhilise CI seadistamise jaoks lÀks meil kaks pÀeva (siin ja edaspidi on ajahinnang umbkaudne, vajalik mastaabi mÔistmiseks).
PĂ€rast seda hakkasime edasi mĂ”tlema â kas me kontrollime Ă”igesti? Kas me kĂ€ivitame ehitused pull request'i raames Ă”igesti?
Me kÀivitasime ehituse viimase commit'i peal haru, millest pull request avati. Kuid selle commit'i kontrollid vÔivad nÀidata ainult seda, et arendaja kirjutatud kood töötab. Kuid nad ei tÔesta, et ta ei ole midagi rikkunud. Tegelikult tuleb kontrollida develop haru seisundit pÀrast seda, kui feature on sellesse lisatud.

Selleks kirjutasime lihtsa bash-skripti premerge.sh:
#!/usr/bin/env bash
set -e
git fetch origin develop
git merge origin/developSiin tÔmmatakse lihtsalt kÔik uusimad muudatused develop'ist ja lisatakse praegusse haru. Lisame skripti premerge.sh kÔigi ehituste esimeseks sammuks ning hakkame kontrollima tÀpselt seda, mida soovime, ehk siis integreerimist.
Probleemide lokaliseerimise, lahenduse leidmise ja selle skripti kirjutamiseks lÀks kolm pÀeva.
Rakendus arenes, ĂŒlesandeid ilmus ĂŒha rohkem, meeskond kasvas ja premerge.sh hakkas meid mĂ”nikord alt vedama. Develop'isse imbusid konflikti muutused, mis rikkusid ehitust.
NĂ€ide sellest, kuidas see juhtub:

Kaks arendajat alustavad samal ajal feature'ite A ja B loomist. Arendaja feature'ist A leiab projektis kasutamata funktsiooni answer() ja, nagu hea skaut, kustutab selle. Samal ajal lisab arendaja feature'ist B oma harusse uue kutsungi sellele funktsioonile.
Arendajad lĂ”petavad oma töö ja avavad samal ajal pull request'i. Ehitus kĂ€ivitub, premerge.sh kontrollib mĂ”lemat pull request'i vĂ€rske develop'i seisundi suhtes â kĂ”ik kontrollid on rohelised. PĂ€rast seda liidetakse feature A pull request, seejĂ€rel liidetakse feature B pull request... Pomm! Develop puruneb, kuna develop'i koodis on kutsung mitteolevale funktsioonile.

Kui develop ei kogune, siis see kohalik katastroof. Kogu meeskond ei suuda midagi kokku koguda ja testimiseks anda.
Nii juhtus, et ma tegelesin kĂ”ige sagedamini infrastruktuuriĂŒlesannetega: analĂŒĂŒs, vĂ”rk, andmebaasid. Just mina kirjutasin need funktsioonid ja klassid, mida teised arendajad kasutavad. Selle tĂ”ttu sattusin tihti sarnastesse olukordadesse. Mul oli isegi aega, mil selline pilt seisis.

Kuna see meid ei rahuldanud, hakkasime vÀlja töötama variantide, kuidas seda ennetada.
Kuidas mitte developit lÔhkuda
Esimene variant: kÔik pull requestid uuendamisel uuesti kokku panna. Kui meie nÀites pull request funktsiooniga A esimene jÔuab developisse, siis pull request funktsiooniga B pannakse uuesti kokku ja seega ei lÀbene kontrollide tÔttu kompileerimisviga.
Kuna aru saada, kui palju aega see vÔtab, vaatame kahe PR nÀidet. Avame kaks PR: kaks ehitust, kaks kontrolli kÀivitamist. PÀrast seda, kui esimene PR on developisse sulandunud, tuleb teine uuesti kokku panna. Kokku kulub kahe PR jaoks kolme kontrolli kÀivitamist: 2 + 1 = 3.
PĂ”himĂ”tteliselt pole paha. Aga me vaatasime statistikat ja meie meeskonnas oli tĂŒĂŒpiliseks olukorraks 10 avatud PR-i, ja siis on kontrollide arv: aritmeetilise progresseerumise summa: 10 + 9 +⊠+ 1 = 55. See tĂ€hendab, et 10 PR-i aktsepteerimiseks tuleb uuesti kokku panna 55 korda. Ja see on ideaalsetes tingimustes, kui kĂ”ik kontrollid lĂ€hevad esimesel korral lĂ€bi, ja keegi ei ava tĂ€iendavat pull requesti, kuni see kĂŒmme töödeldakse.
Kujutage ette end arendajana, kellele tuleb pingutada, et vajutada nuppu 'merge' esimesena, sest kui seda teeb naaber, tuleb oodata, kuni kÔik koosteprotsessid uuesti lÀhevad... Ei, nii ei saa, see aeglustab tÔsiselt arendust.
Teine vĂ”imalik viis: koguda pull request pĂ€rast koodivaatust. See tĂ€hendab, et avate pull requesti, kogute vajalik arv kinnitusi kolleegidelt, parandate, mis on vajalik, ja seejĂ€rel kĂ€itate ehitused. Kui need on edukad, liidetakse pull request developiga. Sel juhul pole tĂ€iendavaid uuesti kĂ€ivitamisi, kuid tagasiside aeglustub oluliselt. Mina arendajana tahan pull requesti avades kohe nĂ€ha, kas see koostatakse. NĂ€iteks, kui mĂ”ni test kukub, tuleb see kiiresti parandada. EdasilĂŒkatud kooste puhul aeglustub tagasiside, ja seega kogu arendus. See ei rahuldanud ka meid.
KokkuvĂ”ttes jĂ€i ainult kolmas variant â ratast leiutadaKogu meie kood ja kĂ”ik meie lĂ€htekoodid on salvestatud Bitbucket-serveri hoidlas. Seega pidime arendama Bitbucketile pistikprogrammi.

See pistikprogramm ĂŒletab pull request'ide sulandumismehhanismi. Algus on standardne: avatakse PR, kĂ€ivitatakse kĂ”ik ehitused, toimub koodikontroll. Kuid pĂ€rast koodikontrolli lĂ€bimist, kui arendaja otsustab vajutada 'merge', kontrollib pistikprogramm, millise arenduse oleku suhtes kontrollid kĂ€ivitatakse. Kui pĂ€rast ehitusi arendus on uuendatud, ei luba pistikprogramm sellist pull requesti pĂ”hiharusse sulanduda. See lihtsalt kĂ€ivitab ehitused uuema arenduse suhtes.

Meie konfliktsete muudatuste nÀites ei lÀbinud sellised ehitused kompileerimisvea tÔttu. Seega peab funktsiooni B arendaja koodi parandama, kontrollid uuesti kÀivitama, siis rakendab pistikprogramm automaatselt pull requesti.
Enne selle pistikprogrammi rakendamist oli meil keskmiselt 2,7 kontrolli kĂ€ivitamist ĂŒhe pull requesti kohta. Pistikprogrammi kasutamise jĂ€rel on see kasvanud 3,6 kontrolli kĂ€ivitamiseni. See rahuldab meid.
Tasub mĂ€rkida, et sellel pistikprogrammil on puudus: see kĂ€ivitab ehituse ainult ĂŒks kord. See tĂ€hendab, et jÀÀb vĂ€ike aken, mille kaudu vĂ”ivad konfliktse muudatusega arendusse sattuda. Kuid selle tĂ”enĂ€osus on vĂ€ike ning me lubasime endale selle kompromissi kĂ€ivituste arvu ja tĂ”rgete tĂ”enĂ€osuse vahel. Kahe aasta jooksul juhtus see vaid ĂŒks kord, seega arvatavasti on see Ă”igustatud.
Bitbucket'i pistikprogrammi esimese versiooni kirjutamiseks kulus meil kaks nÀdalat.
Uued kontrollid
Samaanl ajal kasvas meie meeskond. Uusi kontrolli lisandusid.
MĂ”tlesime: miks parandada vigu, kui neid saab ennetada? SeetĂ”ttu rakendasime staatilise koodi analĂŒĂŒsi. Alustasime lint'ist, mis on osa Android SDK-st. Kuid see ei osanud toona ĂŒldse töötada Kotlin'i koodiga, samas kui meie rakendusest oli juba 75% kirjutatud Kotlin-is. Seega lisasime lint'ile sisse ehitatud Android Studio kontrollid.
Selle jaoks pidime tĂ”eliselt vaeva nĂ€gema: vĂ”tma Android Studio, pakendama selle Dockerisse ja kĂ€ivitama CI's virtuaalse monitoriga, et see arvaks, et see kĂ€ivitatakse reaalses sĂŒlearvutis. Kuid see toimis.
Samuti hakkasime sel ajal kirjutama palju instrumentatsiooniteste ja rakendasime ekraanipildistamise testimist.See, kui genereeritakse referentskuva eraldi vÀikese vaate jaoks, ja test seisneb selles, et antud vaates vÔetakse kuvatÔmmis ja vÔrreldakse seda referentsiga otse piksliti. Kui on erinevus, siis kuskil on skeem vale vÔi on stiilides midagi valesti.
Kuid instrumentatsiooni testid ja kuvatĂ”mmise testid tuleb kĂ€ivitada seadmetes: emulaatorites vĂ”i reaalses seadmes. Arvestades, et teste on palju ja neid kĂ€itatakse tihti, on vajalik terve farm. Oma farmi loomine oleks liiga töömahukas, seetĂ”ttu leidsime alternatiivi â Firebase Test Lab.
Firebase Test Lab
Valiti, sest Firebase on Google'i toode, mis tÀhendab, et see peaks olema usaldusvÀÀrne ja ei sure tÔenÀoliselt kunagi vÀlja. Hind on taskukohane: 5 $ tunnis reaalse seadme kasutamise eest, 1 $ tunnis emulaatori kasutamise eest.
Firebase Test Labi rakendamiseks meie CI-s kulus umbes kolm nÀdalat.
Kuid meeskond jĂ€tkas kasvu ning Firebase hakkas meid kahjuks alt vedama. Sel ajal puudus sellel mistahes SLA. MĂ”nikord pidi Firebase ootama, kuni vajalik arv seadmeid teste jaoks on vabastatud, selle asemel, et hakata teste kohe kĂ€ivitama, nagu me soovisime. Ooteaeg oli kuni pool tundi, mis on vĂ€ga pikk. Instrumentatsiooni teste kĂ€idi iga PR-i puhul ning viivitused aeglustasid arendust, seejĂ€rel saime arve kuu kohta, kust tuli ringisumma. ĂhesĂ”naga, otsustasime Firebase'ist loobuda ja teha seda ise, kuna meeskond oli piisavalt kasvanud.
Docker + Python + bash
VĂ”tsime Docker'i, panime emulaatorid sisse, kirjutasime lihtsa programmi Pythonis, mis vajaliku hetke saabudes kĂ€ivitab vajalikul arvu emulaatoreid vajalikus versioonis ja kui vaja, lĂ”petab need. Ja muidugi paar bash-skripti â need on hĂ€davajalikud.
Oma testimiskeskkonna loomisele kulus viis nÀdalat.
KokkuvÔttes tuli igale pull requestile ulatuslik, liitumist blokeeriv kontrollide loetelu:
- ARK-i kogumine;
- Junit-testid;
- Lint;
- Android Studio kontrollid;
- Instrumentatsiooni testid;
- KuvatÔmmise testid.
See takistas palju vÔimalikke rikkeid. Tehniliselt töötab kÔik, kuid arendajad kurtsid, et tulemusi oodati liiga kaua.
Liiga kaua â kui kaua? Me eksportisime andmed Bitbucket'ist ja TeamCity'st analĂŒĂŒsimisse ja mĂ”istsime, et keskmine ooteaeg on 45 minutit. See tĂ€hendab, et arendaja ootab, et avades pull request, keskmiselt 45 minutit tulemusi. Minu arvates on see vĂ€ga palju ja nii ei saa töötada.
Muidugi, me otsustasime kiirendada kÔiki meie ehitusi.
Kiirendame
Kui nĂ€gime, et ehitused seisavad sageli jĂ€rjekorras, siis esimesena ostsime juurde riistvara â ulatuslik areng on kĂ”ige lihtsam. Ehitused ei seisa enam jĂ€rjekorras, kuid ooteaeg vĂ€henes vaid veidi, kuna mĂ”ned kontrollimised kestavad endiselt liiga kaua.
Eemaldame liiga pikad kontrollid
Meie pidev integratsioon suudab tuvastada selliseid vigu ja probleeme.
- Ei kogu. CI suudab leida kompileerimisviga, kui konfliktsete muudatuste tĂ”ttu midagi ei kogu. Nagu ma juba ĂŒtlesin, sel juhul ei saa keegi midagi koguda, arendamine seiskub ja kĂ”ik on nĂ€rvis.
- Viga kĂ€itumises. NĂ€iteks, kui rakendus kogub, kuid nuppu vajutades kukub kokku vĂ”i nupp ei reageeri ĂŒldse. See on halb, sest selline viga vĂ”ib kasutajani jĂ”uda.
- Viga kujunduses. NĂ€iteks, nupp reageerib, kuid on 10 pikslit vasakule nihkunud.
- Tehnilise vÔla suurenemine.
Vaadates seda nimekirja, mĂ”istsime, et kriitilised on ainult esimesed kaks punkti. Selliseid probleeme tahame me esmajĂ€rjekorras avastada. Kujunduse ĂŒlevaate etapis avastatakse kujunduse vead ja neid on lihtne parandada. Tehnilise vĂ”laga tegelemine nĂ”uab eraldi protsessi ja planeerimist, seetĂ”ttu otsustasime seda pull request'is mitte kontrollida.
Selle klassifitseerimise pÔhjal lÀbisime kogu kontrollide nimekirja. TÔmbasime Linti lÀbi ja edastasime selle kÀivitamise öösse: lihtsalt, et see annaks aru, kui palju probleeme projektis on. Tehnilise vÔlaga oleme kokku leppinud, et töötame eraldi, ning Android Studio kontrollidest loobusime tÀielikult. Android Studio Dockeris kontrollide kÀivitamine kÔlab huvitavalt, kuid toob palju ebameeldivusi toetuses. Iga Android Studio versiooni uuendamine - see on vÔitlus arusaamatute vigadega. Samuti oli raske toetada ekraanikuva teste, kuna biblioteka ei töötanud vÀga stabiilselt, esines valehÀireid. Ekraanikuva teste eemaldati kontrollide nimekirjast.
Kokku oli meil jÀÀnud:
- ARK-i kogumine;
- Junit-testid;
- Instrumentatsiooni testid.
Gradle kaugvahend
Ilma raskete kontrollideta on kÔik parem. Kuid tÀiuslikkusel ei ole piire!
Meie rakendus oli juba jagatud umbes 150 gradle mooduliks. TĂŒĂŒpiliselt toimib sellisel juhul Gradle kaugvahend hĂ€sti ja otsustasime seda proovida.
Gradle remote cache on teenus, mis suudab vahemĂ€lu hoida ehitusartefakte eraldi ĂŒlesannete jaoks erinevates moodulites. Gradle, selle asemel et koodi tegelikult kompileerida, kĂŒsib remote cache'ist HTTP kaudu, kas keegi on juba seda ĂŒlesannet tĂ€itnud. Kui jah, laadib ta lihtsalt tulemuse alla.
Gradle remote cache'i kÀivitamine on lihtne, sest Gradle pakub Docker'i kujundust. Suutsime selle teostada kolme tunni jooksul.
Vaja oli lihtsalt kĂ€ivitada Docker ja kirjutada projektis ĂŒks rida. Kuigi see saab kiiresti kĂ€ivituda, et kĂ”ik hĂ€sti töötaks, on vajalikul ajakulul ĂŒsna palju aega.
Allpool on vahekaart cache misses.

Alguses oli cache'ist möödalaskmise protsent umbes 65. kolme nĂ€dala pĂ€rast suutsime selle vÀÀrtuse langetada 20%-ni. Selgus, et Android rakenduse ĂŒlesannete kogumine sisaldab kummalisi transitiivseid sĂ”ltuvusi, mille tĂ”ttu Gradle jĂ€i vahemĂ€lu mööda.
Cache'i kasutuselevĂ”tuga kiirus kasvas mĂ€rkimisvÀÀrselt. Kuid peale ehituse kĂ€ivitatakse ka instrumentatsiooni teste, mis vĂ”ivad vĂ”tta kaua aega. VĂ”ib-olla ei ole mĂ”tet kĂ”iki testide kontrollida iga pull request'i korral. Selle vĂ€lja selgitamiseks kasutame mĂ”jude analĂŒĂŒsi.
MĂ”jude analĂŒĂŒs
Pull request'i korral kogume git diff'i ja leiame muudetud Gradle moodulid.

MÔistlik on kÀivitada ainult need instrumentatsiooni testid, mis kontrollivad muudetud mooduleid ja kÔiki mooduleid, mis neist sÔltuvad. Naaber moodulite testide kÀitamine ei ole mÔttekas: seal kood ei muutunud ja midagi ei tohi puruneda.
Instrumentatsiooni testide puhul ei ole kĂ”ik nii lihtne, kuna need peavad olema rakenduse kĂ”ige kĂ”rgemal tasemel moodulis. Kasutasime bait-koodi analĂŒĂŒsile pĂ”hinevat heuristikat, et mĂ”ista, millise mooduliga iga test on seotud.
Instrumentatsiooni testide töö moderniseerimine, et nad kontrolliksid ainult kaasatud mooduleid, vÔttis aega umbes kaheksa nÀdalat.
Kontrollimise kiirendamise meetmed toimisid edukalt. 45 minutist jĂ”udsime umbes 15 minutini. Veerand tundi ootamine build'is on nĂŒĂŒd normaalne.
Aga nĂŒĂŒd on arendajad hakanud kurtma, et neile ei ole selge, millised build'id kĂ€ivitatakse, kust logsid vaadata, miks build on punane, milline test kukkus ja nii edasi.

Tagasiside probleemid aeglustavad arendust, seega oleme pĂŒĂŒdnud tagada vĂ”imalikult arusaadava ja ĂŒksikasjaliku teabe iga PR ja buildi kohta. Alustasime Bitbucketis PR kommentaaridega, mĂ€rkides, milline build ebaĂ”nnestus ja miks, ning saatsime adresseeritud sĂ”numeid Slackis. LĂ”puks lĂ”ime PR-i juhtpaneeli lehe, kus on kĂ”igi praegu kĂ€imasolevate buildide nimekiri ja nende olek: ootel, kĂ€imas, ebaĂ”nnestunud vĂ”i lĂ”petatud. Saate buildile klĂ”psata ja pÀÀseda selle logisse.

Ăksikasjalikule tagasisidele kulus kuus nĂ€dalat.
Plaane
Liigume edasi viimastele uudistele. Tagasiside probleemide lahendamisega tĂ”stsime oma tegevuse uuele tasemele â otsustasime ehitada oma emulaatorite farmi. Kui teste ja emulaatoreid on palju, on nende haldamine keeruline. LĂ”puks kolisid kĂ”ik meie emulaatorid k8s-klassi, kus ressursside haldamine on paindlik.
Lisaks on veel muid plaane.
- Tagasi Linti (ja muude staatiliste analĂŒĂŒside). Me juba töötame selle suunas.
- KÀivitage PR-i blokeerija kÔik end-to-end testid kÔikide SDK versioonide peal.
Nii et me oleme jĂ€lginud Continuous Integrationi arengu ajalugu Avitos. NĂŒĂŒd tahan anda mĂ”ned nĂ€punĂ€ited kogenud vaatenurgast.
NÔuanded
Kui ma saaksin anda ainult ĂŒhe nĂ”uande, siis see oleks:
Palun olge ettevaatlikud shell-skriptidega!
Bash on vÀga paindlik ja vÔimas tööriist, selle abil on mugav ja kiire skripte kirjutada. Kuid sellega vÔib sattuda lÔksu, ja me, kahjuks, sattusime sellesse.
KÔik algas lihtsatest skriptidest, mis kÀivitati meie build-masinal:
#!/usr/bin/env bash
./gradlew assembleDebugKuid nagu teada, kĂ”ik areneb ja keerukamaks ajaga â laseme ĂŒhel skriptil teisest kĂ€ivituda, laseme sinna mĂ”ned parameetrid â lĂ”puks tuli kirjutada funktsioon, mis mÀÀrab, millisel bashi sisetase me praegu oleme, et sobitada Ă”iged jutumĂ€rgid, nii et see kĂ”ik kĂ€ivituks.

VÔite ette kujutada, kui palju ressursse kulus selliste skriptide arendamisele. Soovitan mitte siseneda sellesse lÔksu.
Mida vÔiks selle asemel kasutada?
- Mitsugust skriptimiskeelt. Kirjutamine Pythonis vÔi Kotlin Scriptis on mugavam, sest see on programmeerimine, mitte skriptid.
- VĂ”i kirjeldada kogu buildide loogikat Custom gradle ĂŒlesannetena oma projekti jaoks.
Otsustasime valida teise variandi ja praegu eemaldame jĂ€rk-jĂ€rgult kĂ”ik bash-skriptid ning kirjutame palju kohandatud gradle-ĂŒlesandeid.
NÔuanne nr 2: hoidke infrastruktuuri koodis.
Mugav on, kui Continuous Integration seadistus ei hoiu UI-interfÀÀnis nagu Jenkins vÔi TeamCity, vaid tekstifailidena otse projekti hoidlas. See tagab versioonikontrolli. Ei ole raske tagasi minna vÔi koguda koodi teises harus.
Skripte saab projektis hoida. Aga mis teha keskkonnaga?
NÔuanne nr 3: Docker aitab keskkonna seadistamisel.
Android-arendajatele aitab see kindlasti, iOS-i puhul kahjuks mitte.
See on lihtsa docker-faili nÀide, mis sisaldab jdk ja 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
# Laadige alla 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
# Installige Android Build Tool ja raamatukogud
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
Kirjutasin selle docker-faili (ĂŒtlen saladuseks, et seda ei pea kirjutama, vaid valmis versiooni saab GitHubist) ja pildi kokku panemisega saate virtuaalse masina, millel saate rakendust koguda ja Junit-testimist kĂ€ivitada.
Kaks peamist argumenti, miks see on mĂ”ttekas: skaliseeritavus ja korduvus. Dockeriga saab kiiresti ĂŒles seada tosin ehitustegevust, millel on tĂ€pselt sama keskkond nagu eelmisel. See lihtsustab CI-inseneride elu tohutult. Android-sdk't dockerisse tĂ”ukamine on vĂ€ga lihtne, emulaatoritega on veidi keerulisem: natuke peab pingutama (vĂ”i jĂ€lle GitHubist valmis versiooni alla laadima).
NÔuanne nr 4: Àrge unustage, et kontrollid ei toimu kontrollide pÀrast, vaid inimeste jaoks.
Arendajatele on vÀga tÀhtis kiire ja, mis kÔige tÀhtsam, arusaadav tagasiside: mis neil katki lÀks, milline test kukkus lÀbi, kus build-logi vaadata.
NÔuanne nr 5: olge pragmaatilised Continuous Integration'i arendamisel.
Selgelt mĂ”ista, milliseid vigade tĂŒĂŒpe soovite ennetada, kui palju olete valmis ressursse, aega ja masinasaega kulutama. Liiga pikad kontrollid saab nĂ€iteks ööseks edasi lĂŒkata. Ja nendest, mis avastavad mitte vĂ€ga olulisi vigu, saab ĂŒldse loobuda.
NÔuanne nr 6: kasutage valmis tööriistu.
Praegu on palju ettevÔtteid, mis pakuvad pilvepÔhist CI-d.

VÀikestele meeskondadele on see hea lahendus. Ei ole vaja midagi hallata, lihtsalt maksate natuke raha, kogute oma rakenduse ja isegi kÀigate instrumentatsioonitestide.
NÔuanne #7: suurtes meeskondades on kasulikum in-house lahendused.
Kuid ĂŒhel hetkel, koos meeskonna kasvuga, saavad in-house lahendused tasuvamaks. Nende lahendustega on ĂŒks aspekt. Majanduses on seadus kahanemisest: igas projektis muutub iga jĂ€rgmine tĂ€iustamine aina raskemaks ja nĂ”uab ĂŒha rohkem investeeringuid.
Majandus kirjeldab kogu meie elu, sealhulgas pidevat integreerimist. Olen koostanud graafiku tööjÔu kulude kohta igas etapis meie pideva integreerimise arendamisel.

On nĂ€ha, et iga tĂ€iustamine muutub aina keerulisemaks ja keerulisemaks. Vaadates seda graafikut, vĂ”ib mĂ”ista, et pidevat integreerimist tuleb arendada koos meeskonna suuruse kasvuga. Kahe inimese meeskonnale kulutada 50 pĂ€eva sisemise emulaatorite farmi arendamiseks â see pole kĂ”ige parem idee. Kuid samas ei tegutseda suure meeskonnaga pideva integreerimise suunal â ka see on halb idee, kuna integreerimise probleemide lahendamiseks, suhtlemise parandamiseks jne kulub veelgi rohkem aega.
Alustasime sellest, et automatiseerimine on vajalik, sest inimesed on kallid, nad teevad vigu ja on laisad. Kuid automatiseerivad ka inimesed. SeetÔttu kehtivad kÔik need probleemid ka automatiseerimise kohta.
- Automatiseerimine on kallis. Meenutage tööjÔu kulu graafikut.
- Automatiseerimise kÀigus teevad inimesed vigu.
- Automatiseerimine on mĂ”nikord ĂŒsna tĂŒlikas, sest nii vĂ”i naa kĂ”ik töötab. Miks veel midagi parandada, miks kogu see pidev integreerimine?
Aga mul on statistika: 20% kogumistest tuvastatakse vead. Ja see ei juhtu seetÔttu, et meie arendajad kirjutavad halba koodi. See toimub seetÔttu, et arendajad on kindlad, et kui nad teevad vea, ei jÔua see develop'i, vaid tuvastavad selle automatiseeritud kontrollid. Seega saavad arendajad kulutada rohkem aega koodi kirjutamisele ja huvitavatele asjadele, mitte mitte kohapeal midagi kÀima ja kontrollima.
Tegelege pideva integreerimisega. Kuid mÔistlikult.
Muide, Nikolai Nesterov mitte ainult ei tee lahedaid ettekandeid, vaid ta kuulub ka programmikomiteesse ja aitab teistel valmistada teie jaoks sisukaid esitlusi. LĂ€hima konverentsi programmi tĂ€iuslikkust ja kasulikkust saab hinnata teemade kaudu . TĂ€iendavate ĂŒksikasjade saamiseks tulge 22-23 aprillil Infoprostranstvo.
Allikas: habr.com
