Udvikling af CI i mobiludviklingsteamet

I dag udvikles de fleste softwareprodukter i teams. Betingelserne for succesfuld teamudvikling kan repræsenteres i form af et simpelt diagram.

Udvikling af CI i mobiludviklingsteamet

Når du har skrevet din kode, skal du sikre dig, at den:

  1. Работает.
  2. Det går ikke i stykker, inklusive den kode, dine kolleger skrev.

Hvis begge betingelser er opfyldt, så er du på vej til succes. For nemt at kontrollere disse betingelser og ikke afvige fra den rentable vej, kom vi med Kontinuerlig Integration.

CI er en arbejdsgang, hvor du så ofte som muligt integrerer din kode i den samlede produktkode. Og du integrerer ikke bare, men tjekker også hele tiden, at alt fungerer. Da du skal tjekke meget og ofte, er det værd at tænke på automatisering. Du kan kontrollere alt manuelt, men du bør ikke, og her er hvorfor.

  • Kære mennesker. En times arbejde for enhver programmør er dyrere end en times arbejde for enhver server.
  • Folk laver fejl. Derfor kan der opstå situationer, hvor test blev kørt på den forkerte gren eller den forkerte commit blev kompileret til testere.
  • Folk er dovne. Fra tid til anden, når jeg er færdig med en opgave, dukker tanken op: ”Hvad er der at tjekke? Jeg skrev to linjer - alt virker! Jeg tror, ​​nogle af jer også nogle gange har sådanne tanker. Men du bør altid tjekke.

Hvordan Continuous Integration blev implementeret og udviklet i Avitos mobile udviklingsteam, hvordan de gik fra 0 til 450 builds om dagen, og at byggemaskiner samles 200 timer om dagen, siger Nikolai Nesterov (nesterov) er deltager i alle evolutionære ændringer af CI/CD Android-applikationen.

Historien er baseret på eksemplet med en Android-kommando, men de fleste af tilgangene er også anvendelige på iOS.


Engang arbejdede en person i Avito Android-teamet. Per definition havde han ikke brug for noget fra Continuous Integration: Der var ingen at integrere med.

Men ansøgningen voksede, flere og flere nye opgaver dukkede op, og teamet voksede tilsvarende. På et tidspunkt er det tid til mere formelt at etablere en kodeintegrationsproces. Det blev besluttet at bruge Git flow.

Udvikling af CI i mobiludviklingsteamet

Konceptet med Git flow er velkendt: et projekt har én fælles udviklergren, og for hver ny funktion skærer udviklere en separat gren, forpligter sig til den, pusher, og når de vil flette deres kode ind i udviklergrenen, åbner du en pull anmodning. For at dele viden og diskutere tilgange introducerede vi kodegennemgang, det vil sige, at kollegaer skal tjekke og bekræfte hinandens kode.

kontrol

At se kode med øjnene er fedt, men ikke nok. Derfor indføres automatisk kontrol.

  • Først og fremmest tjekker vi ARK montage.
  • Meget Junit tests.
  • Vi overvejer kodedækning, da vi kører test.

For at forstå, hvordan disse kontroller skal køres, lad os se på udviklingsprocessen i Avito.

Det kan være repræsenteret skematisk således:

  • En udvikler skriver kode på sin bærbare computer. Du kan køre integrationstjek lige her - enten med en commit hook eller blot køre tjek i baggrunden.
  • Efter at udvikleren har skubbet koden, åbner han en pull-anmodning. For at dens kode kan inkluderes i udvikle-grenen, er det nødvendigt at gennemgå en kodegennemgang og indsamle det nødvendige antal bekræftelser. Du kan aktivere checks og builds her: indtil alle builds er lykkedes, kan pull-anmodningen ikke flettes.
  • Efter at pull-anmodningen er slået sammen, og koden er inkluderet i develop, kan du vælge et passende tidspunkt: for eksempel om natten, hvor alle serverne er ledige, og køre så mange kontroller, som du vil.

Ingen kunne lide at køre scanninger på deres bærbare computer. Når en udvikler har afsluttet en funktion, vil han hurtigt skubbe den og åbne en pull-anmodning. Hvis der i dette øjeblik lanceres nogle lange kontroller, er dette ikke kun ikke særlig behageligt, men bremser også udviklingen: mens den bærbare computer tjekker noget, er det umuligt at arbejde normalt på det.

Vi kunne rigtig godt lide at køre kontrol om natten, for der er meget tid og servere, du kan strejfe rundt. Men desværre, når funktionskoden begynder at udvikle sig, har udvikleren meget mindre motivation til at rette de fejl, som CI fandt. Jeg tog med jævne mellemrum mig selv i at tænke, når jeg kiggede på alle de fejl, der blev fundet i morgenrapporten, at jeg ville rette dem en dag senere, for nu er der en fed ny opgave i Jira, som jeg bare vil i gang med.

Hvis checks blokerer en pull-anmodning, så er der motivation nok, for indtil buildsene bliver grønne, vil koden ikke komme i udvikling, hvilket betyder, at opgaven ikke bliver fuldført.

Som et resultat valgte vi følgende strategi: vi kører det maksimalt mulige sæt af kontroller om natten og starter de mest kritiske af dem og, vigtigst af alt, de hurtigste på en pull-anmodning. Men vi stopper ikke der - parallelt optimerer vi kontrolhastigheden for at overføre dem fra nattilstand til at trække anmodningskontroller.

På det tidspunkt blev alle vores builds færdige ret hurtigt, så vi inkluderede simpelthen ARK-builden, Junit-tests og kodedækningsberegninger som en blokering for pull-anmodningen. Vi tændte det, tænkte over det og opgav kodedækning, fordi vi troede, at vi ikke havde brug for det.

Det tog os to dage at opsætte den grundlæggende CI fuldstændigt (i det følgende er tidsestimatet omtrentligt, nødvendigt for skalering).

Herefter begyndte vi at tænke videre – tjekker vi overhovedet rigtigt? Kører vi builds på pull-anmodninger korrekt?

Vi startede opbygningen på den sidste commit i den filial, hvorfra pull-anmodningen blev åbnet. Men test af denne commit kan kun vise, at koden, som udvikleren skrev, virker. Men de beviser ikke, at han ikke brød noget. Faktisk skal du kontrollere tilstanden for udviklingsgrenen, efter at en funktion er flettet ind i den.

Udvikling af CI i mobiludviklingsteamet

For at gøre dette skrev vi et simpelt bash-script premerge.sh:

#!/usr/bin/env bash

set -e

git fetch origin develop

git merge origin/develop

Her bliver alle de seneste ændringer fra develop blot trukket op og lagt sammen i den nuværende filial. Vi tilføjede premerge.sh scriptet som det første trin i alle builds og begyndte at tjekke præcis, hvad vi vil have, dvs. integration.

Det tog tre dage at lokalisere problemet, finde en løsning og skrive dette script.

Applikationen udviklede sig, flere og flere opgaver dukkede op, teamet voksede, og premerge.sh begyndte nogle gange at svigte os. Develop havde modstridende ændringer, der brød bygningen.

Et eksempel på, hvordan dette sker:

Udvikling af CI i mobiludviklingsteamet

To udviklere begynder samtidigt at arbejde på funktioner A og B. Udvikleren af ​​funktion A opdager en ubrugt funktion i projektet answer() og fjerner den som en god spejder. Samtidig tilføjer udvikleren af ​​funktion B et nyt kald til denne funktion i sin filial.

Udviklere afslutter deres arbejde og åbner en pull-anmodning på samme tid. Bygningerne lanceres, premerge.sh kontrollerer begge pull-anmodninger vedrørende den seneste udviklingstilstand - alle checks er grønne. Derefter er pull-anmodningen for funktion A slået sammen, pull-anmodningen fra feature B er flettet... Bom! Udvikle pauser, fordi udviklingskoden indeholder et kald til en ikke-eksisterende funktion.

Udvikling af CI i mobiludviklingsteamet

Når det ikke kommer til at udvikle sig, er det det lokal katastrofe. Hele teamet kan ikke indsamle noget og sende det til test.

Det skete sådan, at jeg oftest arbejdede med infrastrukturopgaver: analyse, netværk, databaser. Det vil sige, det var mig, der skrev de funktioner og klasser, som andre udviklere bruger. På grund af dette befandt jeg mig meget ofte i lignende situationer. Jeg havde endda dette billede hængende i et stykke tid.

Udvikling af CI i mobiludviklingsteamet

Da dette ikke passede os, begyndte vi at undersøge mulighederne for at forhindre dette.

Hvordan ikke at bryde udvikle

Den første mulighed: genopbygge alle pull-anmodninger ved opdatering af develop. Hvis, i vores eksempel, pull-anmodningen med feature A er den første, der er inkluderet i udvikling, vil pull-anmodningen for feature B blive genopbygget, og derfor vil kontrollen mislykkes på grund af en kompileringsfejl.

For at forstå, hvor lang tid dette vil tage, kan du overveje et eksempel med to PR'er. Vi åbner to PR'er: to builds, to runs of checks. Efter den første PR er slået sammen til udvikle, skal den anden genopbygges. I alt kræver to PR'er tre kørsler af kontroller: 2 + 1 = 3.

I princippet er det fint. Men vi kiggede på statistikken, og den typiske situation i vores team var 10 åbne PR'er, og så er antallet af kontroller summen af ​​progressionen: 10 + 9 +... + 1 = 55. Det vil sige at acceptere 10 PR'er, du skal genopbygge 55 gange. Og dette er i en ideel situation, når alle checks passerer første gang, når ingen åbner en ekstra pull-anmodning, mens disse dusin behandles.

Forestil dig dig selv som en udvikler, der skal være den første til at klikke på "flet"-knappen, for hvis en nabo gør dette, så skal du vente, indtil alle builds går igennem igen... Nej, det virker ikke , vil det for alvor bremse udviklingen.

Anden mulig måde: indsamle pull-anmodninger efter kodegennemgang. Det vil sige, at du åbner en pull-anmodning, indsamler det nødvendige antal godkendelser fra kollegaer, retter det nødvendige, og starter derefter builds. Hvis de lykkes, bliver pull-anmodningen slået sammen til develop. I dette tilfælde er der ingen yderligere genstarter, men feedbacken er meget langsommere. Som udvikler, når jeg åbner en pull-anmodning, vil jeg straks se, om det kommer til at virke. For eksempel, hvis en test mislykkes, skal du hurtigt rette den. I tilfælde af en forsinket build bremses feedback, og dermed hele udviklingen. Det passede heller ikke os.

Som et resultat var kun den tredje mulighed tilbage - cykel. Al vores kode, alle vores kilder er gemt i et lager på Bitbucket-serveren. Derfor var vi nødt til at udvikle et plugin til Bitbucket.

Udvikling af CI i mobiludviklingsteamet

Dette plugin tilsidesætter pull request-sammenlægningsmekanismen. Begyndelsen er standard: PR'en åbner, alle samlinger lanceres, kodegennemgang er afsluttet. Men efter gennemgangen af ​​koden er afsluttet, og udvikleren beslutter sig for at klikke på "flet", kontrollerer plugin'et, mod hvilken udviklingstilstand kontrollerne blev kørt. Hvis develop er blevet opdateret efter builds, vil plugin ikke tillade en sådan pull-anmodning at blive flettet ind i hovedgrenen. Det vil simpelthen genstarte opbygningen af ​​en relativt ny udvikling.

Udvikling af CI i mobiludviklingsteamet

I vores eksempel med modstridende ændringer vil sådanne builds mislykkes på grund af en kompileringsfejl. Derfor skal udvikleren af ​​funktion B rette koden, genstarte kontrollerne, hvorefter plugin'et automatisk anvender pull-anmodningen.

Før vi implementerede dette plugin, havde vi i gennemsnit 2,7 gennemgangskørsler pr. pull-anmodning. Med plugin var der 3,6 lanceringer. Dette passede os.

Det er værd at bemærke, at dette plugin har en ulempe: det genstarter kun bygningen én gang. Det vil sige, at der stadig er et lille vindue, hvorigennem modstridende ændringer kan udvikle sig. Men sandsynligheden for dette er lav, og vi lavede denne afvejning mellem antallet af starter og sandsynligheden for fiasko. På to år skød den kun én gang, så det var nok ikke forgæves.

Det tog os to uger at skrive den første version af Bitbucket-pluginet.

Nye checks

I mellemtiden fortsatte vores team med at vokse. Der er tilføjet nye checks.

Vi tænkte: hvorfor lave fejl, hvis de kan forhindres? Og derfor implementerede de statisk kodeanalyse. Vi startede med lint, som er inkluderet i Android SDK. Men på det tidspunkt vidste han slet ikke, hvordan man arbejdede med Kotlin-kode, og vi havde allerede 75 % af ansøgningen skrevet i Kotlin. Derfor blev der tilføjet indbyggede til fnug Android Studio-tjek.

For at gøre dette var vi nødt til at gøre en masse pervertering: Tag Android Studio, pak det i Docker og kør det på CI med en virtuel skærm, så det tror, ​​det kører på en rigtig bærbar. Men det virkede.

Det var også i denne tid, vi begyndte at skrive meget instrumenteringstest og implementeret screenshot test. Det er, når der genereres et referenceskærmbillede til en separat lille visning, og testen består i at tage et skærmbillede fra visningen og sammenligne det med standarden direkte pixel for pixel. Hvis der er uoverensstemmelse, betyder det, at layoutet er gået galt et eller andet sted, eller at der er noget galt i stilene.

Men instrumenteringstest og screenshottest skal køres på enheder: på emulatorer eller på rigtige enheder. I betragtning af at der er mange tests, og de køres ofte, er der brug for en hel gård. At starte din egen gård er for arbejdskrævende, så vi fandt en færdiglavet mulighed - Firebase Test Lab.

Firebase Test Lab

Det blev valgt, fordi Firebase er et Google-produkt, hvilket betyder, at det burde være pålideligt og usandsynligt, at det nogensinde dør. Priserne er rimelige: $5 pr. driftstime af en rigtig enhed, 1$ pr. times drift af en emulator.

Det tog cirka tre uger at implementere Firebase Test Lab i vores CI.

Men holdet fortsatte med at vokse, og Firebase begyndte desværre at svigte os. På det tidspunkt havde han ikke nogen SLA. Nogle gange fik Firebase os til at vente, indtil det nødvendige antal enheder var ledige til test, og begyndte ikke at udføre dem med det samme, som vi ønskede. At vente i kø tog op til en halv time, hvilket er meget lang tid. Instrumenteringstest blev kørt på hver PR, forsinkelser bremsede virkelig udviklingen, og så kom den månedlige regning med en rund sum. Generelt blev det besluttet at opgive Firebase og arbejde internt, da holdet var vokset nok.

Docker + Python + bash

Vi tog Docker, proppede emulatorer ind i det, skrev et simpelt program i Python, som på det rigtige tidspunkt henter det nødvendige antal emulatorer frem i den påkrævede version og stopper dem, når det er nødvendigt. Og selvfølgelig et par bash-manuskripter - hvor ville vi være uden dem?

Det tog fem uger at skabe vores eget testmiljø.

Som følge heraf var der for hver pull-anmodning en omfattende liste over flette-blokerende kontroller:

  • ARK samling;
  • Junit tests;
  • Fnug;
  • Android Studio-tjek;
  • Instrumentering test;
  • Skærmbillede test.

Dette forhindrede mange mulige nedbrud. Teknisk set virkede alt, men udviklerne klagede over, at ventetiden på resultater var for lang.

Hvor lang tid er for lang? Vi uploadede data fra Bitbucket og TeamCity til analysesystemet og indså det gennemsnitlig ventetid 45 minutter. Det vil sige, at en udvikler, når han åbner en pull-anmodning, venter i gennemsnit 45 minutter på byggeresultaterne. Efter min mening er det meget, og sådan kan man ikke arbejde.

Selvfølgelig besluttede vi at fremskynde alle vores builds.

Lad os sætte farten op

Når vi ser, at bygninger ofte står i kø, er det første, vi gør købt mere hardware — omfattende udvikling er det enkleste. Bygninger holdt op med at stå i kø, men ventetiden faldt kun lidt, fordi nogle kontroller i sig selv tog meget lang tid.

Fjernelse af checks, der tager for lang tid

Vores kontinuerlige integration kunne fange disse typer fejl og problemer.

  • Vil ikke. CI kan fange en kompileringsfejl, når noget ikke bygges på grund af modstridende ændringer. Som jeg allerede sagde, så kan ingen samle noget, udviklingen stopper, og alle bliver nervøse.
  • Fejl i adfærd. For eksempel når applikationen er bygget, men går ned, når du trykker på en knap, eller der slet ikke trykkes på knappen. Dette er dårligt, fordi en sådan fejl kan nå brugeren.
  • Fejl i layout. For eksempel klikkes der på en knap, men den er flyttet 10 pixels til venstre.
  • Stigning i teknisk gæld.

Efter at have set på denne liste, indså vi, at kun de to første punkter er kritiske. Vi ønsker at fange sådanne problemer først. Fejl i layoutet opdages på design-review-stadiet og kan let rettes derefter. Håndtering af teknisk gæld kræver en separat proces og planlægning, så vi besluttede ikke at teste det på en pull-anmodning.

Baseret på denne klassifikation rystede vi hele listen af ​​checks op. Overstreget lint og udsatte dets lancering fra den ene dag til den anden: bare for at den skulle lave en rapport om, hvor mange problemer der var i projektet. Vi blev enige om at arbejde separat med den tekniske gæld, og Android Studio-tjek blev fuldstændig opgivet. Android Studio i Docker til at køre inspektioner lyder interessant, men forårsager en masse problemer med support. Enhver opdatering til Android Studio-versioner betyder en kamp med uforståelige fejl. Det var også svært at understøtte screenshot-tests, fordi biblioteket ikke var særlig stabilt, og der var falske positiver. Screenshot-tests er blevet fjernet fra tjeklisten.

Som et resultat stod vi tilbage med:

  • ARK samling;
  • Junit tests;
  • Instrumentering test.

Gradle remote cache

Uden tunge kontroller blev alt bedre. Men der er ingen grænse for perfektion!

Vores ansøgning var allerede opdelt i omkring 150 gradle-moduler. Gradle remote cache fungerer normalt godt i dette tilfælde, så vi besluttede at prøve det.

Gradle remote cache er en tjeneste, der kan cachebygge artefakter til individuelle opgaver i individuelle moduler. Gradle, i stedet for faktisk at kompilere koden, bruger HTTP til at banke på fjerncachen og spørge, om nogen allerede har udført denne opgave. Hvis ja, downloader den blot resultatet.

Det er nemt at køre Gradle-fjerncache, fordi Gradle giver et Docker-billede. Det lykkedes os på tre timer.

Alt du skulle gøre var at starte Docker og skrive en linje i projektet. Men selvom det kan lanceres hurtigt, vil det tage ret lang tid, før alt fungerer godt.

Nedenfor er grafen for cache-misser.

Udvikling af CI i mobiludviklingsteamet

I begyndelsen var procentdelen af ​​cache-misser omkring 65. Efter tre uger lykkedes det os at øge denne værdi til 20%. Det viste sig, at de opgaver, som Android-applikationen indsamler, har mærkelige transitive afhængigheder, på grund af hvilke Gradle savnede cachen.

Ved at forbinde cachen har vi fremskyndet opbygningen betydeligt. Men udover montering er der også instrumenteringstest, og de tager lang tid. Det er måske ikke alle test, der skal køres for hver pull-anmodning. For at finde ud af det bruger vi konsekvensanalyse.

Effektanalyse

På en pull-anmodning indsamler vi git diff og finder de modificerede Gradle-moduler.

Udvikling af CI i mobiludviklingsteamet

Det giver mening kun at køre instrumenteringstest, der kontrollerer de ændrede moduler og alle moduler, der er afhængige af dem. Det nytter ikke at køre test for nabomoduler: koden der er ikke ændret, og intet kan gå i stykker.

Instrumenteringstests er ikke så enkle, fordi de skal placeres i applikationsmodulet på øverste niveau. Vi brugte heuristik med bytekodeanalyse for at forstå, hvilket modul hver test tilhører.

At opgradere driften af ​​instrumenteringstestene, så de kun tester de involverede moduler, tog omkring otte uger.

Foranstaltninger til at fremskynde inspektioner har virket med succes. Fra 45 minutter gik vi op til cirka 15. Det er allerede normalt at vente et kvarter på et byggeri.

Men nu er udviklere begyndt at klage over, at de ikke forstår, hvilke builds der lanceres, hvor man kan se loggen, hvorfor buildet er rødt, hvilken test der mislykkedes osv.

Udvikling af CI i mobiludviklingsteamet

Problemer med feedback bremser udviklingen, så vi forsøgte at give så klar og detaljeret information om hver PR og build som muligt. Vi startede med kommentarer i Bitbucket til PR, der indikerede, hvilken build der var fejlet og hvorfor, og skrev målrettede beskeder i Slack. Til sidst oprettede vi et PR-dashboard til siden med en liste over alle builds, der kører i øjeblikket, og deres status: i kø, kører, går ned eller fuldført. Du kan klikke på build og komme til dens log.

Udvikling af CI i mobiludviklingsteamet

Seks uger blev brugt på detaljeret feedback.

Planer

Lad os gå videre til nyere historie. Efter at have løst feedbackproblemet nåede vi et nyt niveau - vi besluttede at bygge vores egen emulatorfarm. Når der er mange tests og emulatorer, er de svære at administrere. Som et resultat flyttede alle vores emulatorer til k8s-klyngen med fleksibel ressourcestyring.

Derudover er der andre planer.

  • Retur Lint (og anden statisk analyse). Vi arbejder allerede i denne retning.
  • Kør alt på en PR-blokker ende-til-ende tests på alle SDK-versioner.

Så vi har sporet historien om udviklingen af ​​kontinuerlig integration i Avito. Nu vil jeg give nogle råd fra en erfaren synsvinkel.

Советы

Hvis jeg kunne give et enkelt råd, ville det være dette:

Vær forsigtig med shell-scripts!

Bash er et meget fleksibelt og kraftfuldt værktøj, det er meget praktisk og hurtigt at skrive scripts. Men du kan falde i en fælde med den, og desværre faldt vi i den.

Det hele startede med simple scripts, der kørte på vores byggemaskiner:

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

Men som bekendt udvikler alt sig og bliver mere kompliceret over tid - lad os køre et script fra et andet, lad os videregive nogle parametre der - til sidst skulle vi skrive en funktion, der bestemmer, på hvilket niveau af bash-nesting vi nu er i orden at indsætte de nødvendige citater, for at få det hele i gang.

Udvikling af CI i mobiludviklingsteamet

Du kan forestille dig arbejdsomkostningerne for udviklingen af ​​sådanne scripts. Jeg råder dig til ikke at falde i denne fælde.

Hvad kan erstattes?

  • Ethvert scriptsprog. Skrive til Python eller Kotlin Script mere praktisk, fordi det er programmering, ikke scripts.
  • Eller beskriv al byggelogikken i formularen Tilpassede gradueringsopgaver til dit projekt.

Vi besluttede at vælge den anden mulighed, og nu sletter vi systematisk alle bash-scripts og skriver en masse tilpassede gradle-opgaver.

Tip #2: Gem infrastruktur i kode.

Det er praktisk, når indstillingen Continuous Integration ikke er gemt i UI-grænsefladen på Jenkins eller TeamCity osv., men i form af tekstfiler direkte i projektets lager. Dette giver versionerbarhed. Det vil ikke være svært at rulle tilbage eller bygge koden på en anden gren.

Scripts kan gemmes i et projekt. Hvad skal man gøre med miljøet?

Tip #3: Docker kan hjælpe med miljøet.

Det vil helt sikkert hjælpe Android-udviklere; iOS har ikke en endnu, desværre.

Dette er et eksempel på en simpel docker-fil, der indeholder jdk og 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

Efter at have skrevet denne Docker-fil (jeg skal fortælle dig en hemmelighed, du behøver ikke at skrive den, men bare trække den færdig fra GitHub) og samle billedet, får du en virtuel maskine, som du kan bygge applikationen på og kør Junit-tests.

De to hovedårsager til, at dette giver mening, er skalerbarhed og repeterbarhed. Ved at bruge docker kan du hurtigt rejse et dusin byggeagenter, der vil have nøjagtig det samme miljø som det forrige. Dette gør livet for CI-ingeniører meget lettere. Det er ret nemt at skubbe android-sdk ind i docker, men med emulatorer er det lidt sværere: du bliver nødt til at arbejde lidt hårdere (eller downloade den færdige fra GitHub igen).

Tip nr. 4: glem ikke, at inspektioner ikke udføres for inspektioners skyld, men for mennesker.

Hurtig og, vigtigst af alt, klar feedback er meget vigtig for udviklere: hvad gik i stykker, hvilken test mislykkedes, hvor kan jeg se buildloggen.

Tip #5: Vær pragmatisk, når du udvikler Kontinuerlig Integration.

Forstå klart, hvilke typer fejl du vil forhindre, hvor mange ressourcer, tid og computertid du er villig til at bruge. Kontrol, der tager for lang tid, kan fx udskydes natten over. Og de af dem, der fanger ikke særlig vigtige fejl, bør helt opgives.

Tip #6: Brug færdige værktøjer.

Der er mange virksomheder nu, der leverer cloud CI.

Udvikling af CI i mobiludviklingsteamet

Dette er en god løsning for små teams. Du behøver ikke at støtte noget, bare betal lidt penge, byg din applikation og kør endda instrumenteringstest.

Tip #7: I et stort team er interne løsninger mere rentable.

Men før eller siden, efterhånden som teamet vokser, vil interne løsninger blive mere profitable. Der er et problem med disse beslutninger. Der er en lov om faldende afkast i økonomi: I ethvert projekt er hver efterfølgende forbedring mere og mere vanskelig og kræver flere og flere investeringer.

Økonomi beskriver hele vores liv, inklusive Kontinuerlig Integration. Jeg byggede en tidsplan for lønomkostninger for hvert udviklingstrin af vores kontinuerlige integration.

Udvikling af CI i mobiludviklingsteamet

Det er klart, at enhver forbedring bliver mere og mere vanskelig. Når du ser på denne graf, kan du forstå, at Kontinuerlig Integration skal udvikles i overensstemmelse med væksten i teamstørrelsen. For et team på to personer er det en middelmådig idé at bruge 50 dage på at udvikle en intern emulatorfarm. Men samtidig er det for et stort team ikke at lave Continuous Integration overhovedet også en dårlig idé, fordi integrationsproblemer, fiksering af kommunikation mv. det vil tage endnu længere tid.

Vi startede med tanken om, at automatisering er nødvendig, fordi folk er dyre, de laver fejl og er dovne. Men folk automatiserer også. Derfor gælder alle de samme problemer for automatisering.

  • Automatisering er dyrt. Husk arbejdsskemaet.
  • Når det kommer til automatisering, laver folk fejl.
  • Nogle gange er det meget dovent at automatisere, for alt fungerer på den måde. Hvorfor forbedre noget andet, hvorfor al denne kontinuerlige integration?

Men jeg har statistik: fejl fanges i 20% af samlingerne. Og det er ikke fordi vores udviklere skriver kode dårligt. Dette skyldes, at udviklere er overbeviste om, at hvis de laver en fejl, vil det ikke ende med at udvikle, det vil blive fanget af automatiserede kontroller. Derfor kan udviklere bruge mere tid på at skrive kode og interessante ting i stedet for at køre og teste noget lokalt.

Øv kontinuerlig integration. Men med måde.

Nikolai Nesterov giver i øvrigt ikke kun selv flotte rapporter, men er også medlem af programudvalget AppsConf og hjælper andre med at forberede meningsfulde taler for dig. Fuldstændigheden og anvendeligheden af ​​det næste konferenceprogram kan vurderes efter emner i tidsplan. Og for detaljer, kom til Infospace den 22.-23. april.

Kilde: www.habr.com

Tilføj en kommentar