Evoluce CI v mobilním vývojářském týmu

Dnes se většina softwarových produktů vyvíjí v týmech. Podmínky úspěšného rozvoje týmu lze znázornit formou jednoduchého diagramu.

Evoluce CI v mobilním vývojářském týmu

Po napsání kódu se musíte ujistit, že:

  1. Работает.
  2. Nic to neporušuje, včetně kódu, který napsali vaši kolegové.

Pokud jsou obě podmínky splněny, pak jste na cestě k úspěchu. Abychom tyto podmínky snadno ověřili a neodchýlili se od ziskové cesty, přišli jsme s kontinuální integrací.

CI je pracovní postup, ve kterém integrujete svůj kód do celkového kódu produktu tak často, jak je to možné. A nejen integrujete, ale také neustále kontrolujete, zda vše funguje. Vzhledem k tomu, že potřebujete hodně a často kontrolovat, stojí za to přemýšlet o automatizaci. Vše můžete zkontrolovat ručně, ale neměli byste, a zde je důvod.

  • drazí lidé. Hodina práce jakéhokoli programátora je dražší než hodina práce jakéhokoli serveru.
  • Lidé dělají chyby. Proto mohou nastat situace, kdy byly testy spuštěny na nesprávné větvi nebo byl pro testery zkompilován nesprávný commit.
  • Lidé jsou líní. Čas od času, když dokončím nějaký úkol, vyvstane myšlenka: „Co je třeba zkontrolovat? Napsal jsem dva řádky - vše funguje! Myslím, že někteří z vás také někdy mají takové myšlenky. Ale měli byste vždy zkontrolovat.

Jak byla implementována a vyvíjena nepřetržitá integrace v mobilním vývojovém týmu Avito, jak přešli z 0 na 450 sestavení za den a jak se stavitelské stroje sestavují 200 hodin denně, říká Nikolai Nesterov (nnesterov) je účastníkem všech evolučních změn aplikace CI/CD pro Android.

Příběh je založen na příkladu příkazu Android, ale většina přístupů je použitelná i na iOS.


Kdysi jeden člověk pracoval v týmu Avito Android. Podle definice nepotřeboval nic od kontinuální integrace: nebylo s kým se integrovat.

Aplikace ale rostla, objevovaly se nové a nové úkoly a podle toho se rozrůstal i tým. V určitém okamžiku je čas na formálnější zavedení procesu integrace kódu. Bylo rozhodnuto použít Git flow.

Evoluce CI v mobilním vývojářském týmu

Koncept toku Git je dobře známý: projekt má jednu společnou vývojovou větev a pro každou novou funkci vývojáři odříznou samostatnou větev, zavázají se k ní, tlačí, a když chtějí začlenit svůj kód do vývojové větve, otevřou vytáhnout žádost. Abychom mohli sdílet znalosti a diskutovat o přístupech, zavedli jsme kontrolu kódu, to znamená, že kolegové si musí navzájem kontrolovat a potvrzovat svůj kód.

Kontroly

Vidět kód očima je skvělé, ale nestačí. Proto se zavádějí automatické kontroly.

  • Nejprve zkontrolujeme Montáž ARK.
  • Hodně Junit testy.
  • Zvažujeme pokrytí kódem, protože provádíme testy.

Abychom pochopili, jak by tyto kontroly měly probíhat, podívejme se na proces vývoje v Avitu.

Schematicky to lze znázornit takto:

  • Vývojář píše kód na svém notebooku. Kontroly integrace můžete spouštět přímo zde – buď pomocí háčku odevzdání, nebo jednoduše spouštět kontroly na pozadí.
  • Poté, co vývojář odešle kód, otevře požadavek na stažení. Aby byl jeho kód zařazen do vývojové větve, je nutné projít code review a nasbírat potřebný počet potvrzení. Zde můžete povolit kontroly a sestavení: dokud nebudou všechna sestavení úspěšná, požadavek na stažení nelze sloučit.
  • Po sloučení požadavku na stažení a zahrnutí kódu do vývoje si můžete vybrat vhodný čas: například v noci, kdy jsou všechny servery volné, a spustit tolik kontrol, kolik chcete.

Nikdo neměl rád spouštění skenování na svém notebooku. Když vývojář dokončí funkci, chce ji rychle podat a otevřít požadavek na stažení. Pokud jsou v tuto chvíli spuštěny nějaké dlouhé kontroly, není to nejen příliš příjemné, ale také to zpomaluje vývoj: zatímco notebook něco kontroluje, nelze na něm normálně pracovat.

Moc se nám líbilo spouštění kontrol v noci, protože je spousta času a serverů, můžete se toulat. Ale bohužel, když se kód funkce dostane do vývoje, vývojář má mnohem menší motivaci opravovat chyby, které CI našla. Občas jsem se přistihl, že když jsem se podíval na všechny chyby nalezené v ranní zprávě, přemýšlel jsem, že je někdy později opravím, protože teď je v Jirovi skvělý nový úkol, který chci začít dělat.

Pokud kontroly zablokují požadavek na stažení, pak existuje dostatečná motivace, protože dokud sestavení nezačnou zelenat, kód se nedostane do vývoje, což znamená, že úkol nebude dokončen.

V důsledku toho jsme zvolili následující strategii: maximální možnou sadu kontrol spouštíme v noci a nejkritičtější z nich a hlavně ty nejrychlejší spouštíme na žádost o stažení. Tím ale nekončíme – souběžně optimalizujeme rychlost kontrol tak, abychom je přenesli z nočního režimu na kontroly žádostí.

V té době byla všechna naše sestavení dokončena poměrně rychle, takže jsme jednoduše zahrnuli sestavení ARK, testy Junit a výpočty pokrytí kódu jako blokování požadavku na stažení. Zapnuli jsme to, přemýšleli o tom a opustili jsme pokrytí kódem, protože jsme si mysleli, že to nepotřebujeme.

Kompletní nastavení základního CI (dále je časový odhad přibližný, potřebný pro měřítko) nám zabralo dva dny.

Poté jsme začali přemýšlet dále – kontrolujeme vůbec správně? Spouštíme sestavení na žádostech o stažení správně?

Spustili jsme sestavení na posledním potvrzení větve, ze které byl otevřen požadavek na stažení. Ale testy tohoto potvrzení mohou pouze ukázat, že kód, který vývojář napsal, funguje. Neprokazují ale, že nic neporušil. Ve skutečnosti musíte zkontrolovat stav vývojové větve poté, co je do ní sloučena funkce.

Evoluce CI v mobilním vývojářském týmu

K tomu jsme napsali jednoduchý bash skript premerge.sh:

#!/usr/bin/env bash

set -e

git fetch origin develop

git merge origin/develop

Zde jsou všechny nejnovější změny z vývoje jednoduše vytaženy a sloučeny do aktuální větve. Přidali jsme skript premerge.sh jako první krok ve všech sestaveních a začali jsme kontrolovat přesně to, co chceme, tj. integrace.

Lokalizovat problém, najít řešení a napsat tento skript trvalo tři dny.

Aplikace se vyvíjela, objevovaly se další a další úkoly, tým se rozrůstal a premerge.sh nás občas začal zklamat. Develop měl protichůdné změny, které narušily sestavení.

Příklad, jak se to děje:

Evoluce CI v mobilním vývojářském týmu

Dva vývojáři současně začnou pracovat na funkcích A a B. Vývojář funkce A objeví v projektu nevyužitou funkci answer() a jako správný skaut ho odstraní. Vývojář funkce B zároveň ve své pobočce přidává nové volání této funkce.

Vývojáři dokončí svou práci a zároveň otevřou požadavek na stažení. Sestavení jsou spuštěna, premerge.sh kontroluje oba požadavky na stažení týkající se posledního stavu vývoje – všechny kontroly jsou zelené. Poté je sloučen požadavek na stažení funkce A, sloučen požadavek na stažení funkce B... Bum! Přerušení vývoje, protože kód vývoje obsahuje volání neexistující funkce.

Evoluce CI v mobilním vývojářském týmu

Když se to nebude rozvíjet, tak ano místní katastrofa. Celý tým nemůže nic sbírat a předkládat k testování.

Stalo se, že jsem nejčastěji pracoval na infrastrukturních úkolech: analytika, síť, databáze. To znamená, že jsem to byl já, kdo napsal ty funkce a třídy, které používají ostatní vývojáři. Kvůli tomu jsem se do podobných situací dostával velmi často. Tento obrázek mi dokonce chvíli visel.

Evoluce CI v mobilním vývojářském týmu

Protože nám to nevyhovovalo, začali jsme zkoumat možnosti, jak tomu předejít.

Jak nezlomit voj

První možnost: znovu sestavit všechny požadavky na stažení při aktualizaci vyvinout. Pokud je v našem příkladu žádost o stažení s funkcí A první, která bude zahrnuta do vývoje, žádost o stažení funkce B bude znovu sestavena, a proto kontroly selžou kvůli chybě kompilace.

Chcete-li pochopit, jak dlouho to bude trvat, zvažte příklad se dvěma PR. Otevíráme dvě PR: dvě sestavení, dvě série kontrol. Po sloučení prvního PR do developmentu je potřeba přestavět druhý. Celkem dvě PR vyžadují tři série kontrol: 2 + 1 = 3.

V zásadě je to v pořádku. Ale podívali jsme se na statistiky a typická situace v našem týmu byla 10 otevřených PR, a pak počet kontrol je součet progrese: 10 + 9 +... + 1 = 55. Tedy přijmout 10 PR, musíte 55krát přestavět. A to v ideální situaci, kdy všechny kontroly projdou napoprvé, kdy nikdo neotevře další požadavek na stažení, zatímco se těchto tucet zpracovává.

Představte si sami sebe jako vývojáře, který musí jako první kliknout na tlačítko „sloučit“, protože pokud to udělá soused, budete muset počkat, až se všechny sestavení znovu projdou... Ne, to nebude fungovat , vážně to zpomalí vývoj.

Druhý možný způsob: shromažďovat žádosti o stažení po kontrole kódu. To znamená, že otevřete žádost o stažení, shromáždíte požadovaný počet schválení od kolegů, opravíte, co je potřeba, a poté spustíte sestavení. Pokud jsou úspěšné, požadavek na stažení je sloučen do vývojového. V tomto případě nedochází k dalším restartům, ale zpětná vazba je značně zpomalena. Když jako vývojář otevřu žádost o stažení, okamžitě chci zjistit, zda to bude fungovat. Pokud například test selže, musíte to rychle opravit. V případě opožděného sestavení se zpomaluje zpětná vazba a tím i celý vývoj. Tohle nám taky nesedlo.

V důsledku toho zůstala pouze třetí možnost - kolo. Veškerý náš kód, všechny naše zdroje jsou uloženy v úložišti na serveru Bitbucket. Proto jsme museli vyvinout plugin pro Bitbucket.

Evoluce CI v mobilním vývojářském týmu

Tento plugin potlačuje mechanismus sloučení požadavků na vyžádání. Začátek je standardní: otevře se PR, spustí se všechna sestavení, dokončí se kontrola kódu. Ale poté, co je kontrola kódu dokončena a vývojář se rozhodne kliknout na „sloučit“, plugin zkontroluje, proti kterému stavu vývoje byly kontroly spuštěny. Pokud byl vývoj aktualizován po sestavení, plugin nedovolí, aby byl takový požadavek na stažení začleněn do hlavní větve. Jednoduše to restartuje sestavení relativně nedávného vývoje.

Evoluce CI v mobilním vývojářském týmu

V našem příkladu s konfliktními změnami taková sestavení selžou kvůli chybě kompilace. V souladu s tím bude muset vývojář funkce B opravit kód, restartovat kontroly, pak plugin automaticky použije požadavek na stažení.

Před implementací tohoto pluginu jsme průměrovali 2,7 spuštění kontroly na žádost o stažení. S pluginem došlo ke spuštění 3,6. Tohle nám vyhovovalo.

Stojí za zmínku, že tento plugin má nevýhodu: pouze jednou restartuje sestavení. To znamená, že stále existuje malé okno, kterým se mohou konfliktní změny dostat do vývoje. Ale pravděpodobnost toho je nízká a udělali jsme tento kompromis mezi počtem spuštění a pravděpodobností selhání. Za dva roky to vystřelilo jen jednou, takže to asi nebylo marné.

Napsání první verze pluginu Bitbucket nám trvalo dva týdny.

Nové kontroly

Mezitím se náš tým stále rozrůstal. Byly přidány nové kontroly.

Říkali jsme si: proč dělat chyby, když jim lze předejít? A proto je implementovali statická analýza kódu. Začali jsme s lint, který je součástí sady Android SDK. Jenže v té době vůbec neuměl pracovat s kódem Kotlin a to už jsme měli 75 % aplikace napsané v Kotlinu. Proto byly do žmolků přidány vestavěné Android Studio kontroluje.

Abychom toho dosáhli, museli jsme udělat hodně zvrácenosti: vzít Android Studio, zabalit ho do Dockeru a spustit na CI s virtuálním monitorem, aby si myslel, že běží na skutečném notebooku. Ale povedlo se.

V této době jsme si také začali hodně psát přístrojové zkoušky a implementovány testování snímků obrazovky. To je, když je generován referenční snímek obrazovky pro samostatný malý pohled a test spočívá v pořízení snímku obrazovky z pohledu a jeho porovnání se standardem přímo pixel po pixelu. Pokud existuje nesrovnalost, znamená to, že se rozložení někde pokazilo nebo je něco špatně ve stylech.

Testy přístrojového vybavení a screenshotové testy však musí být spuštěny na zařízeních: na emulátorech nebo na skutečných zařízeních. Vzhledem k tomu, že existuje mnoho testů a jsou prováděny často, je potřeba celá farma. Založení vlastní farmy je příliš pracné, a tak jsme našli hotovou možnost – Firebase Test Lab.

Firebase Test Lab

Byl vybrán, protože Firebase je produktem Google, což znamená, že by měl být spolehlivý a pravděpodobně nikdy nezemře. Ceny jsou rozumné: 5 $ za hodinu provozu skutečného zařízení, 1 $ za hodinu provozu emulátoru.

Implementace Firebase Test Lab do naší CI trvalo přibližně tři týdny.

Tým ale rostl a Firebase nás bohužel začala zklamat. V té době neměl žádné SLA. Někdy nás Firebase nechala čekat, až se uvolní požadovaný počet zařízení pro testy, a nezačala je spouštět okamžitě, jak jsme chtěli. Čekání ve frontě trvalo až půl hodiny, což je velmi dlouhá doba. Na každém PR probíhaly přístrojové testy, zpoždění opravdu zpomalila vývoj a pak přišla měsíční faktura s kulatou sumou. Obecně bylo rozhodnuto opustit Firebase a pracovat interně, protože tým se dostatečně rozrostl.

Docker + Python + bash

Vzali jsme Docker, nacpali do něj emulátory, napsali jednoduchý program v Pythonu, který ve správný čas spustí potřebný počet emulátorů ve správné verzi a v případě potřeby je zastaví. A samozřejmě pár bash skriptů – kde bychom bez nich byli?

Vytvoření vlastního testovacího prostředí trvalo pět týdnů.

Výsledkem bylo, že pro každý požadavek na stažení byl k dispozici rozsáhlý seznam kontrol blokujících sloučení:

  • montáž ARK;
  • Junit testy;
  • Lint;
  • kontroly Android Studio;
  • Přístrojové zkoušky;
  • Testy screenshotů.

Tím se zabránilo mnoha možným poruchám. Technicky vše fungovalo, ale vývojáři si stěžovali, že čekání na výsledky bylo příliš dlouhé.

Jak dlouho je příliš dlouho? Nahráli jsme data z Bitbucket a TeamCity do analytického systému a uvědomili jsme si to průměrná čekací doba 45 minut. To znamená, že vývojář při otevření požadavku na stažení čeká v průměru 45 minut na výsledky sestavení. Podle mého názoru je to hodně a takhle se pracovat nedá.

Samozřejmě jsme se rozhodli urychlit všechny naše stavby.

Pojďme zrychlit

Když vidíme, že budovy často stojí ve frontě, první věc, kterou uděláme, je koupil další hardware — extenzivní vývoj je nejjednodušší. Buildy se přestaly řadit do fronty, ale čekací doba se zkrátila jen nepatrně, protože některé kontroly samotné trvaly velmi dlouho.

Odstraňování kontrol, které trvají příliš dlouho

Naše průběžná integrace by mohla zachytit tyto typy chyb a problémů.

  • Nechystat se. CI může zachytit chybu kompilace, když se něco nesestaví kvůli konfliktním změnám. Jak jsem již řekl, pak nikdo nemůže nic sestavit, vývoj se zastaví a všichni znervózní.
  • Chyba v chování. Například když je aplikace sestavena, ale při stisknutí tlačítka se zhroutí, nebo se tlačítko nestiskne vůbec. To je špatné, protože taková chyba se může dostat k uživateli.
  • Chyba v rozložení. Například se kliklo na tlačítko, ale posunulo se o 10 pixelů doleva.
  • Nárůst technického dluhu.

Po zhlédnutí tohoto seznamu jsme si uvědomili, že kritické jsou pouze první dva body. Takové problémy chceme podchytit jako první. Chyby v rozvržení jsou objeveny ve fázi kontroly návrhu a lze je pak snadno opravit. Vypořádání se s technickým dluhem vyžaduje samostatný proces a plánování, proto jsme se rozhodli jej netestovat na vyžádání.

Na základě této klasifikace jsme setřásli celý seznam kontrol. Přeškrtnutý Lint a odložil jeho spuštění přes noc: jen proto, aby vypracoval zprávu o tom, kolik problémů v projektu bylo. Dohodli jsme se na samostatné práci s technickým dluhem a Kontroly Android Studio byly zcela opuštěny. Android Studio v Dockeru pro spouštění inspekcí zní zajímavě, ale způsobuje spoustu problémů s podporou. Jakákoli aktualizace verzí Android Studio znamená boj s nepochopitelnými chybami. Obtížná byla také podpora screenshotových testů, protože knihovna nebyla příliš stabilní a docházelo k falešným pozitivům. Testy snímků obrazovky byly odstraněny z kontrolního seznamu.

V důsledku toho nám zůstalo:

  • montáž ARK;
  • Junit testy;
  • Přístrojové zkoušky.

Vzdálená mezipaměť Gradle

Bez náročných kontrol se vše zlepšilo. Ale k dokonalosti se meze nekladou!

Naše aplikace již byla rozdělena do asi 150 gradle modulů. Gradle remote cache obvykle v tomto případě funguje dobře, tak jsme se rozhodli to vyzkoušet.

Gradle remote cache je služba, která umí ukládat do mezipaměti artefakty sestavení pro jednotlivé úkoly v jednotlivých modulech. Gradle namísto skutečného kompilace kódu používá HTTP k zaklepání na vzdálenou mezipaměť a zeptá se, zda již někdo tento úkol provedl. Pokud ano, jednoduše stáhne výsledek.

Spuštění vzdálené mezipaměti Gradle je snadné, protože Gradle poskytuje obraz Dockeru. Zvládli jsme to za tři hodiny.

Stačilo spustit Docker a napsat jeden řádek do projektu. Ale i když to jde spustit rychle, zabere to docela dost času, aby všechno dobře fungovalo.

Níže je graf chybějících vyrovnávací paměti.

Evoluce CI v mobilním vývojářském týmu

Na samém začátku bylo procento vynechání mezipaměti asi 65. Po třech týdnech se nám podařilo tuto hodnotu zvýšit na 20 %. Ukázalo se, že úkoly, které aplikace pro Android sbírá, mají podivné tranzitivní závislosti, kvůli kterým Gradle vynechal mezipaměť.

Připojením cache jsme výrazně urychlili sestavení. Kromě montáže jsou ale i přístrojové zkoušky a ty trvají dlouho. Možná není nutné spouštět všechny testy pro každý požadavek na stažení. Abychom to zjistili, používáme analýzu dopadů.

Analýza dopadů

Na žádost o stažení shromáždíme git diff a najdeme upravené moduly Gradle.

Evoluce CI v mobilním vývojářském týmu

Má smysl spouštět pouze testy přístrojového vybavení, které zkontrolují změněné moduly a všechny moduly, které jsou na nich závislé. Nemá smysl spouštět testy pro sousední moduly: kód se tam nezměnil a nic nemůže prasknout.

Přístrojové testy nejsou tak jednoduché, protože musí být umístěny v modulu Aplikace nejvyšší úrovně. Použili jsme heuristiku s analýzou bajtkódu, abychom pochopili, do kterého modulu každý test patří.

Modernizace provozu testů přístrojového vybavení tak, aby testovaly pouze příslušné moduly, trvalo asi osm týdnů.

Opatření k urychlení kontrol se osvědčila. Ze 45 minut jsme se dostali až na asi 15. Už je normální čekat čtvrt hodiny na sestavení.

Nyní si ale vývojáři začali stěžovat, že nechápou, která sestavení se spouštějí, kde vidět protokol, proč je sestavení červené, který test selhal atd.

Evoluce CI v mobilním vývojářském týmu

Problémy se zpětnou vazbou zpomalují vývoj, proto jsme se snažili poskytnout co nejjasnější a nejpodrobnější informace o každém PR a buildu. Začali jsme komentáři v Bitbucket k PR, které uváděly, které sestavení selhalo a proč, a psali jsme cílené zprávy do Slacku. Nakonec jsme pro stránku vytvořili PR dashboard se seznamem všech aktuálně spuštěných sestavení a jejich stavem: ve frontě, běžící, havarovaný nebo dokončený. Můžete kliknout na sestavení a dostat se do jeho protokolu.

Evoluce CI v mobilním vývojářském týmu

Šest týdnů bylo věnováno podrobné zpětné vazbě.

Plány

Přejděme do nedávné historie. Po vyřešení problému se zpětnou vazbou jsme se dostali na novou úroveň - rozhodli jsme se vybudovat vlastní emulátorovou farmu. Když existuje mnoho testů a emulátorů, je obtížné je spravovat. V důsledku toho se všechny naše emulátory přesunuly do clusteru k8s s flexibilní správou zdrojů.

Kromě toho existují další plány.

  • Vrátit Lint (a další statické analýzy). V tomto směru již pracujeme.
  • Spusťte vše na PR blockeru end-to-end testy na všech verzích SDK.

Takže jsme sledovali historii vývoje kontinuální integrace v Avitu. Nyní bych chtěl poradit z pohledu zkušeného.

Советы

Kdybych mohl dát jen jednu radu, byla by to tato:

Buďte opatrní se skripty shellu!

Bash je velmi flexibilní a výkonný nástroj, psaní skriptů je velmi pohodlné a rychlé. Ale můžete se s tím dostat do pasti a my jsme do ní bohužel spadli.

Všechno to začalo jednoduchými skripty, které běžely na našich sestavovacích strojích:

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

Ale jak víte, vše se postupem času vyvíjí a komplikuje – spouštějme jeden skript od druhého, předejme tam nějaké parametry – nakonec jsme museli napsat funkci, která určí, na jaké úrovni bash vnoření jsme nyní v pořádku vložit potřebné uvozovky, aby to všechno začalo.

Evoluce CI v mobilním vývojářském týmu

Umíte si představit mzdové náklady na vývoj takových skriptů. Radím vám, abyste se do této pasti nedostali.

Co lze nahradit?

  • Jakýkoli skriptovací jazyk. Napsat Python nebo Kotlin Script pohodlnější, protože je to programování, ne skripty.
  • Nebo popište veškerou logiku sestavení ve formuláři Vlastní gradle úkoly pro váš projekt.

Rozhodli jsme se zvolit druhou možnost a nyní systematicky mažeme všechny bash skripty a píšeme spoustu vlastních gradle úloh.

Tip č. 2: Uložte infrastrukturu v kódu.

Je vhodné, když nastavení Continuous Integration není uloženo v UI rozhraní Jenkins nebo TeamCity apod., ale ve formě textových souborů přímo v úložišti projektu. To poskytuje verzovatelnost. Nebude těžké vrátit zpět nebo vytvořit kód na jiné větvi.

Skripty mohou být uloženy v projektu. Co dělat s prostředím?

Tip č. 3: Docker může pomoci s životním prostředím.

Rozhodně to pomůže vývojářům Androidu; iOS bohužel zatím žádný nemá.

Toto je příklad jednoduchého souboru docker, který obsahuje jdk a 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

Po napsání tohoto souboru Docker (prozradím vám tajemství, nemusíte ho psát, ale stačí jej stáhnout hotový z GitHubu) a sestavit obraz, získáte virtuální stroj, na kterém můžete aplikaci postavit a spusťte testy Junit.

Dva hlavní důvody, proč to dává smysl, jsou škálovatelnost a opakovatelnost. Pomocí dockeru můžete rychle vychovat tucet sestavení agentů, kteří budou mít přesně stejné prostředí jako ten předchozí. To značně usnadňuje život inženýrů CI. Je docela snadné vložit android-sdk do dockeru, ale s emulátory je to trochu obtížnější: budete muset pracovat trochu tvrději (nebo si znovu stáhnout hotový z GitHubu).

Rada č. 4: nezapomeňte, že kontroly se nedělají kvůli kontrolám, ale pro lidi.

Rychlá a hlavně jasná zpětná vazba je pro vývojáře velmi důležitá: co se pokazilo, jaký test selhal, kde mohu vidět buildlog.

Tip č. 5: Při vývoji kontinuální integrace buďte pragmatičtí.

Jasně pochopte, jakým typům chyb chcete předejít, kolik zdrojů, času a počítačového času jste ochotni utratit. Kontroly, které trvají příliš dlouho, mohou být například odloženy přes noc. A ty z nich, které zachycují nepříliš důležité chyby, by měly být zcela opuštěny.

Tip #6: Použijte hotové nástroje.

V současnosti existuje mnoho společností, které poskytují cloudové CI.

Evoluce CI v mobilním vývojářském týmu

Toto je dobré řešení pro malé týmy. Nemusíte nic podporovat, stačí zaplatit trochu peněz, vytvořit aplikaci a dokonce spustit testy přístrojů.

Tip č. 7: Ve velkém týmu jsou in-house řešení ziskovější.

Ale dříve nebo později, jak se tým rozroste, budou interní řešení ziskovější. S těmito rozhodnutími je jeden problém. V ekonomii platí zákon klesající návratnosti: v každém projektu je každé další zlepšení stále obtížnější a vyžaduje stále více investic.

Ekonomie popisuje celý náš život, včetně kontinuální integrace. Sestavil jsem plán mzdových nákladů pro každou fázi vývoje naší kontinuální integrace.

Evoluce CI v mobilním vývojářském týmu

Je jasné, že jakékoliv zlepšování je čím dál tím těžší. Při pohledu na tento graf můžete pochopit, že kontinuální integraci je třeba rozvíjet v souladu s růstem velikosti týmu. Pro tým dvou lidí je strávit 50 dní vývojem interní emulátorové farmy průměrný nápad. Ale zároveň pro velký tým je nedělat kontinuální integraci vůbec špatný nápad, protože problémy s integrací, opravou komunikace atd. zabere to ještě více času.

Začali jsme s myšlenkou, že automatizace je potřeba, protože lidé jsou drazí, dělají chyby a jsou líní. Lidé ale také automatizují. Proto všechny stejné problémy platí pro automatizaci.

  • Automatizace je drahá. Pamatujte na rozvrh práce.
  • Pokud jde o automatizaci, lidé dělají chyby.
  • Někdy je velmi líné automatizovat, protože všechno tak funguje. Proč vylepšovat něco jiného, ​​proč všechna tato kontinuální integrace?

Ale mám statistiku: chyby se chytí u 20% sestav. A není to proto, že by naši vývojáři psal kód špatně. Je to proto, že vývojáři jsou přesvědčeni, že pokud udělají nějakou chybu, neskončí to ve vývoji, ale zachytí ji automatické kontroly. V souladu s tím mohou vývojáři strávit více času psaním kódu a zajímavých věcí, než aby něco spouštěli a testovali lokálně.

Procvičte si kontinuální integraci. Ale s mírou.

Mimochodem, Nikolaj Nesterov nejen sám podává skvělé zprávy, ale je také členem programového výboru AppsConf a pomáhá ostatním připravit pro vás smysluplné projevy. Úplnost a užitečnost dalšího programu konference lze posoudit podle témat v plán. A pro podrobnosti přijďte 22. – 23. dubna do Infospace.

Zdroj: www.habr.com

Přidat komentář