Aplicació de sistemes d’integració continua

continuous integration
Aplicació de sistemes d’integració continua

Problemes al moment d’unir grans blocs de codi de diversos desenvolupadors? L’equip de treball no està coordinat i es solapen algunes tasques? Dediquem el tems suficient a revisar el funcionament del nostre codi? O ens assabentem dels errors a través de les queixes dels usuaris? Ens topem amb més dificultats de les que ens agradaria cada cop que volem presentar el nostre software a l’usuari final? Si alguna de les respostes a les preguntes anteriors és un sí, aquest article serà del teu interès.

Per al desenvolupament de projectes de software, a l’inLab seguim el cicle de desenvolupament per iteracions (sprints) o incremental basat en Scrum. Amb aquest mètode es divideix temporalment, normalment en períodes de dues o tres setmanes, el desenvolupament de les funcionalitats requerides pel client podent implementar, comprovar, desplegar i mostrar al client cadascuna d’elles amb independència de les altres, beneficiant així a ambdues parts.

Gràcies a aquesta divisió del bloc de funcionalitats, l’equip de desenvolupament pot centrar-se exclusivament en la mateixa fase de feina, si el client canvia els requisits només afecta la iteració actual i una mala implementació de les funcionalitats no interfereix amb la feina feta a iteracions anteriors.

Aquest mètode de desenvolupament, s’adapta amb resultats molt atractius a algunes de les pràctiques adoptades de l’extreme programming que fem servir a l’inLab, com la integració continua. En poques paraules, aquest model de treball pretén que l’equip de desenvolupament integri el seu codi diàriament, que aquest codi passi una sèrie de proves predefinides pels programadors per verificar el seu correcte funcionament i que el desplegament del producte estigui disponible en qualsevol moment, sigui en un sistema de preproducció o inclús en un de producció.

“Integration is primarily about communication. Integration allows developers to tell other developers about the changes they have made. Frequent communication allows people to know quickly as changes develop.”

– Martin Fowler, 1 May 2006, Continuous Integration

Al dia a dia, abans de començar a programar, cada desenvolupador actualitza el seu entorn baixant els últims canvis del repositori de codi compartit. Si existeix qualsevol conflicte, ha de resoldre’l i a partir d’aquí pot començar a dissenyar una de les noves funcionalitats. Per a això, utilitzem TDD, una altra de les pràctiques de l’extreme programming preparant les proves que validaran el comportament d’aquestes funcionalitats, implementant la funcionalitat i comprovant que els tests definits anteriorment s’executen correctament. Un cop acabada la funcionalitat, el desenvolupador és lliure d’enviar la seva aportació al repositori abans de repetir el mateix procés per una altra funcionalitat. D’aquesta manera, cada dia un sol desenvolupador realitza varis commits amb petits canvis, facilitant la detecció d’errors i la comprensió dels canvis per a altres membres de l’equip. Abans d’acabar la jornada, el desenvolupador ha de compartir els seus canvis, per a això abans ha de descarregar-se les aportacions dels seus companys, resoldre possibles conflictes, verificar que tots els tests funcionen i finalment enviar els seus canvis al repositori.

És en aquest flux de feina on entren en joc els sistemes d’integració continua, automatitzant i facilitant algunes d’aquestes tasques des de la construcció del projecte fins al desplegament d’aquest.

Els sistemes d’integració continua són entorns que pretenen gestionar aquests processos de forma autònoma, alliberant així als programadors d’aquestes labors. Típicament detecten els canvis en el desenvolupament dels projectes, llencen la bateria de test per controlar que el comportament del software és el desitjat i despleguen en una màquina de desenvolupament tot el codi. No obstant això, els processos que acabem de llistar són només alguns dins d’una extensa col·lecció que ens faciliten alguns software d’integració continua.

Les diverses tasques que executen aquests sistemes se solen representar visualment mitjançant targetes ordenades que, en cas de funcionar llencen la tasca següent i en cas de fallar poden arribar a avisar a l’equip de desenvolupament perquè revisin què ha passat. Inclús es pot arribar a configurar algunes targetes perquè la seva execució hagi de ser llançada manualment, podria ser el cas d’un desplegament del software a un entorn de producció, el qual no sempre ens interessarà fer.

tareas sistemas integración continua

Entre els avantatges que aporta la inclusió d’aquests sistemes en els projectes, trobem la detecció d’errors a cada iteració del codi, la disponibilitat del projecte construït en tot moment i la seguretat de tenir la implantació a l’entorn de producció ja comprovada.

Hi ha una multitud d’eines d’integració continua: Jenkins, Hudson, Bamboo, Solano, CruiseControl

A l’inLab fem servir aquest tipus d’eines en diversos projectes, prendrem com a exemple un projecte d’aplicacions mòbils format per una API, una aplicació mòbil i una web d’administració gestionades per Jenkins.

ejemplo proyecto

Cada cert temps Jenkins revisa si existeix algun canvi a la branca de desenvolupament del repositori i si és així, inicia el flux de treball. Aquest període de temps és parametritzable, també es pot llançar manualment.

Un cop iniciat el flux, la primera targeta porta l’última versió del codi, construeix el projecte descarregant les seves dependències i preparant l’espai de treball per a l’execució de les targetes següents.

Un cop el projecte està llest, s’inicien dues targetes en paral·lel, són les d’execució de tests unitaris de la API i la de tests de l’aplicació mòbil. En acabar els tests unitaris de la API, una nova targeta s’encarrega de llançar els tests d’integració migrant prèviament els últims canvis produïts a la base de dades.

Executant aquest tipus de proves en un sistema d’integració continua com Jenkins, aconseguim validar el bon funcionament del projecte en un entorn independent del nostre.

Si les targetes de test de la API tenen èxit, la següent targeta desplegarà la API a la màquina de preproducció mentre una altra targeta executa els tests de qualitat de la API.

A la targeta de qualitat hem configurat varis plugins que ens proporcionaran informació sobre el software que estem desenvolupant. Gràcies a un plugin per Jenkins que es diu Clover PHP a la targeta de qualitat obtenim mètriques de la quantitat de codi cobert pels tests. DRY Plugin ens genera una vista on obtenim informació sobre la possible duplicació de codi al projecte. Un altre plugin, PMD Warnings ens mostra alertes sobre el mal funcionament o ús incorrecte del nostre codi, classificant-les en diferents nivells de prioritat. Per últim, JDepend Plugin ensenya les dependències entre classes i possibles cicles en el disseny del software.

Clover PHP coverage reportFigura 1: Exemple d’informe de cobertura de codi de Clover PHP

 

PMD Warnings warning​Figura 2: Exemple d’alerta de PMD Warnings

Un cop estigui llest el desplegament a la màquina de preproducció, podrem llançar manualment la targeta dels tests de càrrega. Aquests permeten comprovar el funcionament correcte del codi a una màquina que serà el més semblant possible a la màquina de producció.

Quan els tests de qualitat hagin acabat de manera satisfactòria, Jenkins ens permetrà llançar de forma manual el desplegament de la API a la màquina de preproducció. Aquest procés ha de ser manual perquè no sempre ens interessarà reemplaçar la API ja existent.

A més, com a punt extra, existeix una última targeta que llança el desplegament de la web d’administració. Aquest punt és posterior al llançament de la API perquè la web en depèn.

Paral·lelament, la compilació de la versió de desenvolupament de l’aplicació es realitza en un servidor extern i els fitxers generats són recuperats per Jenkins per a pujar-los a una web d’ús intern. Tot aquest procés es realitza en una única targeta.

Si la targeta anterior s’ha executat correctament, Jenkins ens permetrà llançar exactament el mateix procés però generant una versió signada per a producció i preparant els arxius APK i IPA llestos per distribuir a la Play Store per a Android i a la App Store per a iOS.

En cas que alguna targeta falli, hem configurat Jenkins a través d’un plugin perquè ens notifiqui via Slack en un canal concret. A més, per a alguns processos que requereixen cert temps o es tracten de desplegaments a producció, Jenkins també ens avisarà en acabar.

No hem d’oblidar que aquest tipus de sistemes pretenen automatitzar processos però no redimeixen al desenvolupador de la programació de proves ni de la configuració dels desplegaments d’entorns de preproducció i producció.

Si després de llegir aquest article esteu pensant a introduir la integració continua en algun dels vostres projectes, us recomanem aquesta lectura.