Evolució de CI en l'equip de desenvolupament mòbil

Avui dia, la majoria de productes de programari es desenvolupen en equip. Les condicions per al desenvolupament de l'equip amb èxit es poden representar en forma d'un diagrama senzill.

Evolució de CI en l'equip de desenvolupament mòbil

Un cop hàgiu escrit el codi, heu d'assegurar-vos que:

  1. Работает.
  2. No trenca res, inclòs el codi que van escriure els teus companys.

Si es compleixen ambdues condicions, esteu en el camí cap a l'èxit. Per comprovar fàcilment aquestes condicions i no desviar-nos del camí rendible, vam plantejar la Integració Contínua.

CI és un flux de treball on integreu el vostre codi al codi global del producte tan sovint com sigui possible. I no només s'integra, sinó que també comproveu constantment que tot funciona. Com que cal comprovar molt i sovint, val la pena pensar en l'automatització. Podeu comprovar-ho tot manualment, però no ho hauríeu de fer, i aquí teniu el perquè.

  • Benvolguda gent. Una hora de treball de qualsevol programador és més cara que una hora de treball de qualsevol servidor.
  • La gent s'equivoca. Per tant, poden sorgir situacions quan les proves s'executen a la branca equivocada o s'ha compilat la confirmació incorrecta per als provadors.
  • La gent és mandrosa. De tant en tant, quan acabo una tasca, em sorgeix el pensament: “Què hi ha per comprovar? Vaig escriure dues línies: tot funciona! Crec que alguns de vosaltres també teniu de vegades aquests pensaments. Però sempre s'ha de comprovar.

Com es va implementar i desenvolupar la integració contínua a l'equip de desenvolupament mòbil d'Avito, com van passar de 0 a 450 compilacions per dia i que les màquines de construcció es munten 200 hores al dia, diu Nikolai Nesterov (nnesterov) participa en tots els canvis evolutius de l'aplicació d'Android CI/CD.

La història es basa en l'exemple d'una ordre d'Android, però la majoria dels enfocaments també són aplicables a iOS.


Hi havia una vegada una persona que treballava a l'equip d'Avito Android. Per definició, no necessitava res de la Integració Contínua: no hi havia ningú amb qui integrar-se.

Però l'aplicació va créixer, van aparèixer més i més tasques noves i l'equip va créixer en conseqüència. En algun moment, és hora d'establir de manera més formal un procés d'integració de codi. Es va decidir utilitzar Git flow.

Evolució de CI en l'equip de desenvolupament mòbil

El concepte de flux de Git és ben conegut: un projecte té una branca de desenvolupament comuna i, per a cada característica nova, els desenvolupadors tallen una branca separada, es comprometen amb ella, impulsen i, quan volen fusionar el seu codi a la branca de desenvolupament, obren un petició d'extracció. Per compartir coneixements i discutir enfocaments, vam introduir la revisió de codi, és a dir, els companys han de comprovar i confirmar el codi dels altres.

Xecs

Veure el codi amb els ulls és genial, però no suficient. Per tant, s'estan introduint controls automàtics.

  • Primer de tot, comprovem Assemblea ARK.
  • Molt Proves Junit.
  • Considerem la cobertura del codi, ja que estem fent proves.

Per entendre com s'han d'executar aquestes comprovacions, mirem el procés de desenvolupament a Avito.

Es pot representar esquemàticament així:

  • Un desenvolupador escriu codi al seu ordinador portàtil. Podeu executar comprovacions d'integració aquí mateix, ja sigui amb un ganxo de confirmació o simplement executar comprovacions en segon pla.
  • Després que el desenvolupador hagi empès el codi, obre una sol·licitud d'extracció. Perquè el seu codi s'inclogui a la branca de desenvolupament, cal passar per una revisió del codi i recollir el nombre de confirmacions requerits. Podeu activar les comprovacions i les compilacions aquí: fins que totes les compilacions tinguin èxit, la sol·licitud d'extracció no es pot combinar.
  • Després que la sol·licitud d'extracció s'hagi combinat i el codi s'hagi inclòs al desenvolupament, podeu triar un moment convenient: per exemple, a la nit, quan tots els servidors són lliures, i executar tantes comprovacions com vulgueu.

A ningú li agradava fer escanejos al seu ordinador portàtil. Quan un desenvolupador ha acabat una funció, vol empènyer-la ràpidament i obrir una sol·licitud d'extracció. Si en aquest moment es llancen algunes comprovacions llargues, això no només no és molt agradable, sinó que també alenteix el desenvolupament: mentre el portàtil està comprovant alguna cosa, és impossible treballar-hi amb normalitat.

Ens va agradar molt fer controls a la nit, perquè hi ha molt de temps i servidors, pots passejar per aquí. Però, malauradament, quan el codi de funció es desenvolupa, el desenvolupador té molta menys motivació per corregir els errors que CI va trobar. Periòdicament, quan mirava tots els errors trobats a l'informe del matí, em vaig quedar pensant que algun dia més tard els arreglaria, perquè ara hi ha una tasca nova a Jira que només vull començar a fer.

Si les comprovacions bloquegen una sol·licitud d'extracció, aleshores hi ha prou motivació, perquè fins que les compilacions es tornin verdes, el codi no es desenvoluparà, la qual cosa significa que la tasca no es completarà.

Com a resultat, hem escollit l'estratègia següent: executem el màxim de controls possibles a la nit i llancem els més crítics d'ells i, el més important, els més ràpids en una sol·licitud d'extracció. Però no ens aturem aquí: en paral·lel, optimitzem la velocitat de les comprovacions per transferir-les del mode nocturn a les comprovacions de sol·licitud.

En aquell moment, totes les nostres compilacions es van completar amb força rapidesa, de manera que només vam incloure la compilació ARK, les proves Junit i els càlculs de cobertura de codi com a bloquejador per a la sol·licitud d'extracció. L'hem activat, ho hem pensat i hem abandonat la cobertura del codi perquè pensàvem que no el necessitàvem.

Vam trigar dos dies a configurar completament el CI bàsic (d'ara endavant el temps estimat és aproximat, necessari per a l'escala).

Després d'això, vam començar a pensar més: estem comprovant correctament? Estem executant les versions de les sol·licituds d'extracció correctament?

Vam començar la construcció a l'últim commit de la branca des de la qual es va obrir la sol·licitud d'extracció. Però les proves d'aquesta confirmació només poden demostrar que el codi que va escriure el desenvolupador funciona. Però no demostren que no hagi trencat res. De fet, heu de comprovar l'estat de la branca de desenvolupament després de fusionar-hi una característica.

Evolució de CI en l'equip de desenvolupament mòbil

Per fer-ho, hem escrit un script bash senzill premerge.sh:

#!/usr/bin/env bash

set -e

git fetch origin develop

git merge origin/develop

Aquí, tots els darrers canvis de desenvolupament simplement es recullen i es fusionen a la branca actual. Hem afegit l'script premerge.sh com a primer pas de totes les compilacions i hem començat a comprovar exactament el que volem, és a dir integració.

Van trigar tres dies a localitzar el problema, trobar una solució i escriure aquest script.

L'aplicació es va desenvolupar, cada cop apareixien més tasques, l'equip va créixer i de vegades premerge.sh va començar a decepcionar-nos. Develop va tenir canvis conflictius que van trencar la construcció.

Un exemple de com passa això:

Evolució de CI en l'equip de desenvolupament mòbil

Dos desenvolupadors simultàniament comencen a treballar en les funcions A i B. El desenvolupador de la funció A descobreix una característica no utilitzada al projecte answer() i, com un bon boy scout, l'elimina. Al mateix temps, el desenvolupador de la característica B afegeix una nova crida a aquesta funció a la seva branca.

Els desenvolupadors acaben la seva feina i obren una sol·licitud d'extracció al mateix temps. Es llancen les compilacions, premerge.sh comprova les dues sol·licituds d'extracció pel que fa a l'últim estat de desenvolupament: totes les comprovacions són verdes. Després d'això, la sol·licitud d'extracció de la característica A es fusiona, la sol·licitud d'extracció de la característica B es fusiona... Boom! Desenvolupa pauses perquè el codi de desenvolupament conté una crida a una funció inexistent.

Evolució de CI en l'equip de desenvolupament mòbil

Quan no es desenvoluparà, sí desastre local. Tot l'equip no pot recollir res i enviar-lo a prova.

Va passar que sovint treballava en tasques d'infraestructura: anàlisi, xarxa, bases de dades. És a dir, vaig ser jo qui va escriure aquelles funcions i classes que utilitzen altres desenvolupadors. Per això, em vaig trobar molt sovint en situacions similars. Fins i tot vaig tenir aquesta imatge penjada durant un temps.

Evolució de CI en l'equip de desenvolupament mòbil

Com que això no ens convinia, vam començar a explorar opcions sobre com prevenir-ho.

Com no trencar el desenvolupament

La primera opció: reconstrueix totes les sol·licituds d'extracció quan s'actualitza desenvolupa. Si, en el nostre exemple, la sol·licitud d'extracció amb la característica A és la primera que s'inclou al desenvolupament, la sol·licitud d'extracció de la característica B es reconstruirà i, en conseqüència, les comprovacions fallaran a causa d'un error de compilació.

Per entendre quant de temps trigarà, considereu un exemple amb dos PR. Obrim dos PR: dues compilacions, dues sèries de controls. Després que el primer PR es fusioni amb el desenvolupament, el segon s'ha de reconstruir. En total, dos PR requereixen tres sèries de controls: 2 + 1 = 3.

En principi, està bé. Però vam mirar les estadístiques, i la situació típica del nostre equip era de 10 PR oberts, i després el nombre de controls és la suma de la progressió: 10 + 9 +... + 1 = 55. És a dir, acceptar 10 PRs, heu de reconstruir 55 vegades. I això es troba en una situació ideal, quan totes les comprovacions passen per primera vegada, quan ningú obre una sol·licitud d'extracció addicional mentre s'estan processant aquestes dotzenes.

Imagineu-vos com un desenvolupador que ha de ser el primer a fer clic al botó "fusionar", perquè si un veí ho fa, haureu d'esperar fins que totes les compilacions tornin a passar... No, això no funcionarà. , retardarà seriosament el desenvolupament.

Segona manera possible: recollir les sol·licituds d'extracció després de la revisió del codi. És a dir, obriu una sol·licitud d'extracció, recolliu el nombre necessari d'aprovacions dels companys, corregeu el que cal i, a continuació, inicieu les compilacions. Si tenen èxit, la sol·licitud d'extracció es fusiona amb desenvolupa. En aquest cas, no hi ha reinicis addicionals, però la retroalimentació es ralentitza molt. Com a desenvolupador, quan obro una sol·licitud d'extracció, de seguida vull veure si funcionarà. Per exemple, si una prova falla, cal que la solucioneu ràpidament. En el cas d'una compilació retardada, la retroalimentació s'alenteix i, per tant, tot el desenvolupament. Això tampoc ens va bé.

Com a resultat, només quedava la tercera opció: bicicleta. Tot el nostre codi, totes les nostres fonts s'emmagatzemen en un repositori al servidor Bitbucket. En conseqüència, vam haver de desenvolupar un connector per a Bitbucket.

Evolució de CI en l'equip de desenvolupament mòbil

Aquest connector anul·la el mecanisme de combinació de sol·licituds d'extracció. El principi és estàndard: s'obre el PR, es llancen tots els muntatges, s'acaba la revisió del codi. Però un cop finalitzada la revisió del codi i el desenvolupador decideix fer clic a "fusionar", el connector comprova amb quin estat de desenvolupament s'han executat les comprovacions. Si el desenvolupament s'ha actualitzat després de les compilacions, el connector no permetrà que aquesta sol·licitud d'extracció es fusioni a la branca principal. Simplement reiniciarà les compilacions d'un desenvolupament relativament recent.

Evolució de CI en l'equip de desenvolupament mòbil

En el nostre exemple amb canvis conflictius, aquestes compilacions fallaran a causa d'un error de compilació. En conseqüència, el desenvolupador de la funció B haurà de corregir el codi, reiniciar les comprovacions i, a continuació, el connector aplicarà automàticament la sol·licitud d'extracció.

Abans d'implementar aquest connector, vam fer una mitjana de 2,7 revisions per sol·licitud d'extracció. Amb el connector hi va haver 3,6 llançaments. Això ens va bé.

Val la pena assenyalar que aquest connector té un inconvenient: només reinicia la compilació una vegada. És a dir, encara hi ha una petita finestra a través de la qual es poden desenvolupar canvis conflictius. Però la probabilitat d'això és baixa i vam fer aquest equilibri entre el nombre d'inicis i la probabilitat de fracàs. En dos anys només va disparar una vegada, així que probablement no va ser en va.

Vam trigar dues setmanes a escriure la primera versió del connector Bitbucket.

Nous xecs

Mentrestant, el nostre equip seguia creixent. S'han afegit nous controls.

Vam pensar: per què cometre errors si es poden prevenir? I per això es van implementar anàlisi de codi estàtic. Vam començar amb pelusa, que s'inclou a l'SDK d'Android. Però en aquell moment no sabia com treballar amb codi Kotlin, i ja teníem el 75% de l'aplicació escrita en Kotlin. Per tant, es van afegir els incorporats a la pelusa Comprovacions d'Android Studio.

Per fer-ho, hem hagut de fer moltes perversions: agafar Android Studio, empaquetar-lo a Docker i executar-lo en CI amb un monitor virtual, perquè cregui que s'està executant en un ordinador portàtil real. Però va funcionar.

També va ser durant aquest temps que vam començar a escriure molt proves d'instrumentació i implementat prova de captura de pantalla. És quan es genera una captura de pantalla de referència per a una vista petita independent, i la prova consisteix a fer una captura de pantalla de la vista i comparar-la amb l'estàndard directament píxel per píxel. Si hi ha una discrepància, vol dir que el disseny ha anat malament en algun lloc o que hi ha alguna cosa malament en els estils.

Però les proves d'instrumentació i les proves de captures de pantalla s'han d'executar en dispositius: en emuladors o en dispositius reals. Tenint en compte que hi ha moltes proves i que es fan amb freqüència, cal una granja sencera. Iniciar la vostra pròpia granja requereix massa mà d'obra, així que hem trobat una opció ja feta: Firebase Test Lab.

Laboratori de proves de Firebase

Es va triar perquè Firebase és un producte de Google, és a dir, hauria de ser fiable i poc probable que mori mai. Els preus són raonables: 5 $ per hora de funcionament d'un dispositiu real, 1 $ per hora de funcionament d'un emulador.

Va trigar aproximadament tres setmanes a implementar Firebase Test Lab al nostre CI.

Però l'equip va continuar creixent i Firebase, malauradament, va començar a decepcionar-nos. En aquell moment, no tenia cap SLA. De vegades, Firebase ens feia esperar fins que el nombre requerit de dispositius fos lliure per a les proves i no començava a executar-los immediatament, com volíem. L'espera a la cua va trigar fins a mitja hora, que és molt llarga. Es van fer proves d'instrumentació a cada PR, els retards van frenar realment el desenvolupament i, a continuació, la factura mensual va arribar amb una suma rodona. En general, es va decidir abandonar Firebase i treballar a casa, ja que l'equip havia crescut prou.

Docker + Python + bash

Vam agafar Docker, hi vam introduir emuladors, vam escriure un programa senzill en Python, que en el moment adequat mostra el nombre necessari d'emuladors a la versió requerida i els atura quan cal. I, per descomptat, un parell de scripts bash: on seríem sense ells?

Va trigar cinc setmanes a crear el nostre propi entorn de prova.

Com a resultat, per a cada sol·licitud d'extracció hi havia una extensa llista de comprovacions de bloqueig de combinació:

  • muntatge ARK;
  • proves Junit;
  • Pelusa;
  • comprovacions d'Android Studio;
  • Proves d'instrumentació;
  • Proves de captures de pantalla.

Això va evitar moltes possibles avaries. Tècnicament tot va funcionar, però els desenvolupadors es van queixar que l'espera dels resultats era massa llarga.

Quant de temps és massa? Vam penjar dades de Bitbucket i TeamCity al sistema d'anàlisi i ens vam adonar temps mitjà d'espera 45 minuts. És a dir, un desenvolupador, quan obre una sol·licitud d'extracció, espera de mitjana 45 minuts pels resultats de la compilació. Al meu entendre, això és molt, i no es pot treballar així.

Per descomptat, vam decidir accelerar totes les nostres construccions.

Anem a accelerar

Veient que les compilacions sovint estan a la cua, el primer que fem és comprar més maquinari — El desenvolupament extensiu és el més senzill. Les compilacions van deixar de fer cua, però el temps d'espera només va disminuir lleugerament, perquè algunes comprovacions van trigar molt.

Eliminació de xecs que triguen massa

La nostra integració contínua podria detectar aquest tipus d'errors i problemes.

  • No hi anirà. CI pot detectar un error de compilació quan alguna cosa no es construeix a causa de canvis conflictius. Com ja he dit, llavors ningú no pot muntar res, el desenvolupament s'atura i tothom es posa nerviós.
  • Error en el comportament. Per exemple, quan l'aplicació està creada, però es bloqueja quan premeu un botó, o el botó no es prem en absolut. Això és dolent perquè aquest error pot arribar a l'usuari.
  • Error en el disseny. Per exemple, es fa clic en un botó, però s'ha mogut 10 píxels cap a l'esquerra.
  • Augment del deute tècnic.

Després de mirar aquesta llista, ens vam adonar que només els dos primers punts són crítics. Volem detectar aquests problemes primer. Els errors en el disseny es descobreixen en l'etapa de revisió del disseny i es poden corregir fàcilment aleshores. Fer front al deute tècnic requereix un procés i una planificació separats, de manera que vam decidir no provar-lo en una sol·licitud d'extracció.

A partir d'aquesta classificació, vam sacsejar tota la llista de controls. Lint ratllada i va ajornar el seu llançament d'un dia per l'altre: només perquè elaborés un informe sobre quants problemes hi havia en el projecte. Vam acordar treballar per separat amb el deute tècnic, i Les comprovacions d'Android Studio es van abandonar completament. Android Studio a Docker per executar inspeccions sembla interessant, però causa molts problemes en el suport. Qualsevol actualització de les versions d'Android Studio significa una lluita amb errors incomprensibles. També era difícil suportar les proves de captures de pantalla, perquè la biblioteca no era molt estable i hi havia falsos positius. Les proves de captures de pantalla s'han eliminat de la llista de verificació.

Com a resultat, ens vam quedar amb:

  • muntatge ARK;
  • proves Junit;
  • Proves d'instrumentació.

Gradle la memòria cau remota

Sense controls pesats, tot va millorar. Però no hi ha límit a la perfecció!

La nostra aplicació ja estava dividida en uns 150 mòduls de grau. La memòria cau remota de Gradle normalment funciona bé en aquest cas, així que vam decidir provar-ho.

La memòria cau remota de Gradle és un servei que pot emmagatzemar a la memòria cau artefactes de creació per a tasques individuals en mòduls individuals. Gradle, en lloc de compilar el codi, utilitza HTTP per trucar a la memòria cau remota i preguntar si algú ja ha realitzat aquesta tasca. En cas afirmatiu, simplement baixa el resultat.

L'execució de la memòria cau remota de Gradle és fàcil perquè Gradle proporciona una imatge de Docker. Ho hem aconseguit en tres hores.

Tot el que havies de fer era llançar Docker i escriure una línia al projecte. Però tot i que es pot llançar ràpidament, es necessitarà molt de temps perquè tot funcioni bé.

A continuació es mostra el gràfic de errors de memòria cau.

Evolució de CI en l'equip de desenvolupament mòbil

Al principi, el percentatge d'errors de memòria cau era d'uns 65. Després de tres setmanes, vam aconseguir augmentar aquest valor fins al 20%. Va resultar que les tasques que recull l'aplicació d'Android tenen estranyes dependències transitives, a causa de les quals Gradle va perdre la memòria cau.

En connectar la memòria cau, vam accelerar molt la compilació. Però, a més del muntatge, també hi ha proves d'instrumentació, i triguen molt de temps. Potser no s'han d'executar totes les proves per a cada sol·licitud d'extracció. Per saber-ho, fem servir l'anàlisi d'impacte.

Anàlisi d'impacte

En una sol·licitud d'extracció, recollim git diff i trobem els mòduls Gradle modificats.

Evolució de CI en l'equip de desenvolupament mòbil

Té sentit executar només proves d'instrumentació que comprovin els mòduls canviats i tots els mòduls que en depenen. No té sentit executar proves per als mòduls veïns: el codi no ha canviat i no es pot trencar res.

Les proves d'instrumentació no són tan senzilles, perquè s'han d'ubicar al mòdul d'aplicació de primer nivell. Hem utilitzat heurístiques amb anàlisi de bytecode per entendre a quin mòdul pertany cada prova.

L'actualització del funcionament de les proves d'instrumentació perquè només provessin els mòduls implicats va durar unes vuit setmanes.

Les mesures per accelerar les inspeccions han funcionat amb èxit. Dels 45 minuts vam pujar a uns 15. Ja és normal esperar un quart d'hora per fer una construcció.

Però ara els desenvolupadors han començat a queixar-se que no entenen quines compilacions s'estan llançant, on veure el registre, per què la compilació és vermella, quina prova ha fallat, etc.

Evolució de CI en l'equip de desenvolupament mòbil

Els problemes amb els comentaris frenen el desenvolupament, de manera que hem intentat proporcionar informació tan clara i detallada sobre cada RP i creació com sigui possible. Vam començar amb comentaris a Bitbucket al PR, indicant quina compilació havia fallat i per què, i vam escriure missatges dirigits a Slack. Al final, vam crear un tauler de PR per a la pàgina amb una llista de totes les compilacions que s'estan executant actualment i el seu estat: en cua, en execució, bloquejada o completada. Podeu fer clic a la construcció i accedir al seu registre.

Evolució de CI en l'equip de desenvolupament mòbil

Es van dedicar sis setmanes a comentaris detallats.

Plans

Passem a la història recent. Després d'haver resolt el problema de comentaris, vam arribar a un nou nivell: vam decidir construir la nostra pròpia granja d'emuladors. Quan hi ha moltes proves i emuladors, són difícils de gestionar. Com a resultat, tots els nostres emuladors es van traslladar al clúster k8s amb una gestió de recursos flexible.

A més, hi ha altres plans.

  • Torna pelusa (i altres anàlisis estàtiques). Ja estem treballant en aquesta direcció.
  • Executeu-ho tot amb un bloquejador de relacions públiques proves de punta a punta en totes les versions de l'SDK.

Així doncs, hem resseguit la història del desenvolupament de la Integració Contínua a Avito. Ara vull donar uns consells des d'un punt de vista experimentat.

Советы

Si pogués donar només un consell seria aquest:

Si us plau, aneu amb compte amb els scripts de shell!

Bash és una eina molt flexible i potent, és molt còmode i ràpid per escriure scripts. Però pots caure en un parany amb ell i, malauradament, hi vam caure.

Tot va començar amb scripts senzills que s'executaven a les nostres màquines de construcció:

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

Però, com sabeu, tot es desenvolupa i es complica amb el pas del temps -executem un script d'un altre, passem-hi alguns paràmetres-, al final hem hagut d'escriure una funció que determini en quin nivell de nidificació de bash estem en ordre. per inserir les cometes necessàries, per començar-ho tot.

Evolució de CI en l'equip de desenvolupament mòbil

Us podeu imaginar els costos laborals per al desenvolupament d'aquests scripts. Us aconsello no caure en aquest parany.

Què es pot substituir?

  • Qualsevol llenguatge de guió. Escriu a Script Python o Kotlin més convenient perquè és programació, no scripts.
  • O descriu tota la lògica de construcció en el formulari Tasques personalitzades de grau pel teu projecte.

Vam decidir triar la segona opció, i ara estem suprimint sistemàticament tots els scripts bash i escrivint moltes tasques de gradle personalitzades.

Consell núm. 2: emmagatzema la infraestructura al codi.

És convenient quan la configuració d'integració contínua no s'emmagatzema a la interfície d'IU de Jenkins o TeamCity, etc., sinó en forma de fitxers de text directament al repositori del projecte. Això dóna versionabilitat. No serà difícil revertir o crear el codi en una altra branca.

Els scripts es poden emmagatzemar en un projecte. Què fer amb el medi ambient?

Consell núm. 3: Docker pot ajudar amb el medi ambient.

Sens dubte, ajudarà els desenvolupadors d'Android; Malauradament, iOS encara no en té cap.

Aquest és un exemple d'un fitxer docker senzill que conté jdk i android-sdk:

FROM openjdk:8

ENV SDK_URL="https://dl.google.com/android/repository/sdk-tools-linux-3859397.zip" 
    ANDROID_HOME="/usr/local/android-sdk" 
    ANDROID_VERSION=26 
    ANDROID_BUILD_TOOLS_VERSION=26.0.2

# Download Android SDK
RUN mkdir "$ANDROID_HOME" .android 
    && cd "$ANDROID_HOME" 
    && curl -o sdk.zip $SDK_URL 
    && unzip sdk.zip 
    && rm sdk.zip 
    && yes | $ANDROID_HOME/tools/bin/sdkmanager --licenses

# Install Android Build Tool and Libraries
RUN $ANDROID_HOME/tools/bin/sdkmanager --update
RUN $ANDROID_HOME/tools/bin/sdkmanager "build-tools;${ANDROID_BUILD_TOOLS_VERSION}" 
    "platforms;android-${ANDROID_VERSION}" 
    "platform-tools"

RUN mkdir /application
WORKDIR /application

Després d'haver escrit aquest fitxer Docker (us diré un secret, no heu d'escriure-lo, sinó que només heu de tirar-lo ja fet des de GitHub) i muntat la imatge, obtindreu una màquina virtual sobre la qual podeu construir l'aplicació. i feu proves Junit.

Les dues raons principals per les quals això té sentit són l'escalabilitat i la repetibilitat. Amb Docker, podeu crear ràpidament una dotzena d'agents de compilació que tindran exactament el mateix entorn que l'anterior. Això fa que la vida dels enginyers CI sigui molt més fàcil. És bastant fàcil empènyer l'android-sdk a Docker, però amb els emuladors és una mica més difícil: haureu de treballar una mica més (o tornar a descarregar-ne l'acabat de GitHub).

Consell número 4: no oblideu que les inspeccions no es fan pel bé de les inspeccions, sinó per a les persones.

Els comentaris ràpids i, sobretot, clars són molt importants per als desenvolupadors: què es va trencar, quina prova va fallar, on puc veure el registre de compilació.

Consell núm. 5: sigueu pragmàtics a l'hora de desenvolupar la integració contínua.

Comprèn clarament quins tipus d'errors vols prevenir, quants recursos, temps i temps d'ordinador estàs disposat a gastar. Els controls que triguen massa, per exemple, es poden ajornar d'un dia per l'altre. I aquells d'ells que capten errors poc importants s'han d'abandonar completament.

Consell núm. 6: Utilitzeu eines ja fetes.

Ara hi ha moltes empreses que proporcionen CI al núvol.

Evolució de CI en l'equip de desenvolupament mòbil

Aquesta és una bona solució per a equips petits. No necessiteu donar suport a res, només pagueu una mica de diners, creeu la vostra aplicació i fins i tot feu proves d'instrumentació.

Consell núm. 7: en un equip gran, les solucions internes són més rendibles.

Però tard o d'hora, a mesura que l'equip creixi, les solucions internes seran més rendibles. Hi ha un problema amb aquestes decisions. Hi ha una llei de rendiments decreixents en economia: en qualsevol projecte, cada millora posterior és cada cop més difícil i requereix cada cop més inversió.

L'economia descriu tota la nostra vida, inclosa la integració contínua. Vaig construir un calendari de costos laborals per a cada etapa de desenvolupament de la nostra Integració Contínua.

Evolució de CI en l'equip de desenvolupament mòbil

És evident que qualsevol millora és cada cop més difícil. Mirant aquest gràfic, podeu entendre que la Integració Contínua s'ha de desenvolupar d'acord amb el creixement de la mida de l'equip. Per a un equip de dues persones, passar 50 dies desenvolupant una granja d'emuladors interna és una idea mediocre. Però al mateix temps, per a un equip gran, no fer gens de Integració Continuada també és una mala idea, perquè problemes d'integració, arreglar la comunicació, etc. trigarà encara més temps.

Vam començar amb la idea que l'automatització és necessària perquè la gent és cara, s'equivoca i és mandra. Però la gent també automatitza. Per tant, tots els mateixos problemes s'apliquen a l'automatització.

  • L'automatització és cara. Recordeu l'horari laboral.
  • Quan es tracta d'automatització, la gent s'equivoca.
  • De vegades és molt mandrós automatitzar, perquè tot funciona així. Per què millorar qualsevol altra cosa, per què tota aquesta Integració Contínua?

Però tinc estadístiques: els errors queden atrapats en el 20% dels muntatges. I això no és perquè els nostres desenvolupadors escriguin el codi malament. Això es deu al fet que els desenvolupadors confien que, si cometen algun error, no s'acabarà desenvolupant, sinó que quedarà atrapat per comprovacions automatitzades. En conseqüència, els desenvolupadors poden passar més temps escrivint codi i coses interessants, en lloc d'executar i provar alguna cosa localment.

Practica la Integració Contínua. Però amb moderació.

Per cert, Nikolai Nesterov no només fa grans informes, sinó que també és membre del comitè del programa. AppsConf i ajuda els altres a preparar discursos significatius per a tu. La integritat i la utilitat del programa de la propera conferència es poden avaluar per temes a horari. I per obtenir més informació, vine a Infospace del 22 al 23 d'abril.

Font: www.habr.com

Afegeix comentari