ABONAMENTE VIDEO REDACȚIA
RO
EN
NOU
Numărul 150
Numărul 149 Numărul 148 Numărul 147 Numărul 146 Numărul 145 Numărul 144 Numărul 143 Numărul 142 Numărul 141 Numărul 140 Numărul 139 Numărul 138 Numărul 137 Numărul 136 Numărul 135 Numărul 134 Numărul 133 Numărul 132 Numărul 131 Numărul 130 Numărul 129 Numărul 128 Numărul 127 Numărul 126 Numărul 125 Numărul 124 Numărul 123 Numărul 122 Numărul 121 Numărul 120 Numărul 119 Numărul 118 Numărul 117 Numărul 116 Numărul 115 Numărul 114 Numărul 113 Numărul 112 Numărul 111 Numărul 110 Numărul 109 Numărul 108 Numărul 107 Numărul 106 Numărul 105 Numărul 104 Numărul 103 Numărul 102 Numărul 101 Numărul 100 Numărul 99 Numărul 98 Numărul 97 Numărul 96 Numărul 95 Numărul 94 Numărul 93 Numărul 92 Numărul 91 Numărul 90 Numărul 89 Numărul 88 Numărul 87 Numărul 86 Numărul 85 Numărul 84 Numărul 83 Numărul 82 Numărul 81 Numărul 80 Numărul 79 Numărul 78 Numărul 77 Numărul 76 Numărul 75 Numărul 74 Numărul 73 Numărul 72 Numărul 71 Numărul 70 Numărul 69 Numărul 68 Numărul 67 Numărul 66 Numărul 65 Numărul 64 Numărul 63 Numărul 62 Numărul 61 Numărul 60 Numărul 59 Numărul 58 Numărul 57 Numărul 56 Numărul 55 Numărul 54 Numărul 53 Numărul 52 Numărul 51 Numărul 50 Numărul 49 Numărul 48 Numărul 47 Numărul 46 Numărul 45 Numărul 44 Numărul 43 Numărul 42 Numărul 41 Numărul 40 Numărul 39 Numărul 38 Numărul 37 Numărul 36 Numărul 35 Numărul 34 Numărul 33 Numărul 32 Numărul 31 Numărul 30 Numărul 29 Numărul 28 Numărul 27 Numărul 26 Numărul 25 Numărul 24 Numărul 23 Numărul 22 Numărul 21 Numărul 20 Numărul 19 Numărul 18 Numărul 17 Numărul 16 Numărul 15 Numărul 14 Numărul 13 Numărul 12 Numărul 11 Numărul 10 Numărul 9 Numărul 8 Numărul 7 Numărul 6 Numărul 5 Numărul 4 Numărul 3 Numărul 2 Numărul 1
×
▼ LISTĂ EDIȚII ▼
Numărul 16
Abonament PDF

Automatizează toate lucrurile!

Attila-Mihaly Balazs
Software Panther @ Synapp.io



PROGRAMARE



Acest articol își propune să ofere un plan de nivel înalt pentru automatizarea unei mare părți a ciclului de viață al software-ului. De asemenea va arăta, pe baza unui exemplu concret, cum poate fi implementat un astfel de plan.

Ideile fundamentale

Mai întâi să menționăm ideile fundamentale pe care se bazează planul. Postulăm că următoarele idei sunt "bune". Pe acestea ar trebui să le implementăm sau să ne străduim să implementăm și care ne ajută să avem un ciclu de viață software lin:

  • revizuire cod (code review),
  • dezvoltare condusă de teste (test driven development),
  • sisteme versionare a surselor (version control systems),
  • analiză statică de cod (static code analysis / linting),
  • metodologii agile / lean,
  • definirea infrastructurii ca și cod (infrastructure as code).

Din lista de mai sus aș dori să subliniez în mod special importanța revizuirii de cod: conform [CC2nd] revizuirea codului de o altă persoană este de cel puțin de două ori mai eficient în găsirea defectelor comparativ cu testarea (unit-teste sau de altă natură). De asemenea, este un mod excelent de a răspândi cunoștințe despre sistemul aflat sub dezvoltare în interiorul echipei, reducând riscul de eșec în cazul în care cineva devine indisponibil (nu mai există problema că o anumită bucată de cod este cunoscută de o singură persoană).

Din păcate revizuirea codului poate fi foarte lentă (o estimare pune viteză optimă la aproximativ 150 de linii/oră) și consumatoare de timp. Acesta este un alt motiv bun pentru automatizarea proceselor: eliberează timpul dezvoltatorilor în favoarea revizuirii de cod.

Ce este livrarea continua?

Livrare continuă (continuous delivery) înseamnă că organizația are o modalitate relativ automată de a pune software-ul dezvoltat în producție. În termeni mai concreți, dacă avem în vedere procesul de dezvoltare software din figura de mai jos, se poate vorbi despre un proces continuu de livrare dacă domeniile evidențiate sunt automatizate.

Acest plan exemplificativ funcționează în următorul fel:

  • După definirea cerințelor (care ar trebui să fie cât mai mici posibil - conform mentalității Agile) este creat un "loc de muncă" (aceasta poate fi un "feature branch" în cazul în care folosim un DVCS ca și Git sau Mercurial sau o copie separată a codului sursă).
  • Se scriu testele și codul sursă necesare pentru a pune în aplicare cerințele (în această ordine dacă respectăm metodologia TDD).
  • După ce codul este "complet" se "publică" (din nou, în funcție de instrumentele specifice utilizate acest pas poate să ia mai multe forme - de exemplu cu Git acest pas se realizează prin "împingerea" (push) codului într-un repository).
  • Automat atunci când codul este publicat se rulează testele. În cazul oricărui eșec este notificat dezvoltatorul.
  • Automat se efectuează o analiză statică a codului. Dacă sunt detectate posibile probleme se notifică dezvoltatorul.
  • În cazul în care codul trece de teste și de analiza statică, sunt notificați oamenii care pot să revizuie codul. Având în vedere că codul a trecut deja de două controale la acest punct, revizuitorul uman nu este deranjat cu problemele triviale (cum ar fi codul nu este formatat corect) și se poate concentra pe aspectele importante, de nivel de business.
  • Automat, dacă revizuitorul dă undă verde, codul este integrat (aceasta înseamnă fuzionarea - merge - într-o anumită ramură dacă se utilizează un DVCS).
  • Automat după ce codul este integrat, acesta este instalat într-un mediu de pregătire (staging).
  • În mediul de pregătire se poate efectua un proces manual de asigurare a calității (QA).
  • Automat, după verficarea calității, codul poate fi instalat în mediul de producție.

Probabil sunteți deja familiari cu integrarea continuă și vă întrebați: care este diferența? Și, într-adevăr, există foarte puține - livrarea continuă este integrare continuă dusă la concluzia sa logică: automatizarea tuturor etapelor după integrare.

Dacă aveți ezitări în legătură cu răspunsul la întrebrea: "pot să am încredere într-o mașină să aibă aceeași grijă ca un inginer de instalare (deployment engineer) cu experiență?", următoarele idei vă pot oferi unele clarificări:

  • poți cu adevărat încredere că oamenii interacționează întotdeauna cu grijă maximă cu sistemele? Oamenii devin neglijenți în timp, au o zi proastă, pot fi distrași și așa mai departe sau chiar mai rău - ei pot deveni indisponibi, temporar sau permanent, fără avertisment.
  • oamenii nu se scalează - Ce se întâmplă dacă mâine vreți să instalați soft-ul în două medii? Va fi nevoie de două ori mai mult timp sau de două ori mai mulți oameni. Un program poate fi executat foarte simplu de mai multe ori sau chiar rula în paralel.
  • oamenii sunt lenți - sunt întârzieri între momentul în care un e-mail este trimis / un ticket este completat în momentul când inginerul de instalare îl vede. Ce se întâmplă dacă el/ea este în pauză? Un sistem automat va porni în câteva secunde după ce codul devine disponibil
  • oameni nu se scalează, partea a doua - în cazul în care mediul este format din cinci servere, inginerul de instalare trebuie să le modifice pe rând. Un proces automat le poate actualiza pe toate în paralel, terminând procesul într-o cincime de timp.
  • astfel de procese sunt implementate de multe companii care de zeci de ori pe zi pun cod în producție fără ca cineva să observe. Singurul efect este că oamenii văd îmbunătățiri și corecții mai rapid.
  • "Dacă te doare, fă-l mai des" - oameni și organizațiile nu devin mai bune exersând doar punctele lor forte. Ei trebuie să se uite mereu la cea mai slabă verigă a lanțului și să-l îmbunătățească. În cazul în care instalarea este o piedică, trebuie să dedicați efort îmbunătățirii lui.

De asemenea v-ați putea simț îngrijorați că procesul de implementare este atât de complicat încât nu se poate automatiza. Relaxați-vă, respirați adânc și faceți următorii pași:

  • creați o listă de pași urmat de persoana care face în mod curent instalarea. Această listă în sine este foarte valorosă: se poate folosi ca să ne asigurăm că pașii nu sunt omiși și poate servi ca material de instruire pentru alte persoane.
  • parcurgeți lista și transformați fiecare pas într-un proces de automatizat.
  • realizați că vor exista cazuri în care procesul automat nu funcționează impecabil (sau chiar eșuează în mod catastrofal)). Când vedeți aceste cazuri, amintiți-vă că și un proces uman poate să eșueze. Păstrați o statistică de genul "X zile de la ultimul eșec" dacă vă ajută. Întroduceți un pas de verificare efectuat de un om după instalare dacă simțiți nevoia - chiar și așa, cel puțin persoana este scutită de munca plictisitoare, automatizabilă. De asemenea, considerați modurile în care puteți detecta (sau chiar mai bine) de a evita data viitoare eșecurile de acel tip într-un mod automat.

Instrumente folosite

"Inima" unui proces de implementare continuă este un sistem care poate reacționa la evenimente externe (cum ar fi disponibilitatea unei noi bucăți de cod sursă) care execută pașii necesari. O soluție frecvent utilizată este Jenkins (cunoscut anterior sub numele de Hudson) care este foarte versatil și poate interacționa cu o mulțime de sisteme prin intermediul plugin-urilor. Câteva sfaturi legate de configurarea Jenkins-ului:

  • Jenkins pot folosi "sclavi" (slaves) pentru a executa procesul de build. Acest lucru înseamnă că Jenkins "maestru" (master) poate rula pe o mașină Linux, în timp ce sclavii pot rula pe diferite platforme (Windows, MacOS X - orice care poate rula Java), făcând posibil rularea procesului de build pe toate platformele suportate
  • Stabiliți limite pentru procesul de build. Specificați timpul maxim care poate să dureze pentru a preveni un build blocat care să consume toate resursele. Specificați numărul maxim de build-uri vechi pe care ar trebui să fie arhivate pentru a evita umplerea spațiului pe disc.
  • Profitați de job-urile parametrizate pentru a evita crearea job-urilor (aproape) identice.
  • Profitați de declanșarea de la distanță (remote triggering) a job-ului. În acest fel un build poate fi declanșat chiar în momentul în care o anumită schimbare a fost comisă să vă informați despre hooks / webhooks pentru VCS-ul vostru.
  • Rupeți build-ul în pași mai mici - de exemplu, un pas ar putea fi rularea unit test-elor, a doua ar fi rularea testelor de integrare și un al treilea pas ar putea să fie rularea analizei statice. Pașii mici oferă feedback mai rapid și fac posibilă rularea mai multor pași în paralel.
  • Când rupeți un proces în pași mici, asigurați-vă că fiecare pas operează pe exact aceleași fișiere sursă. Fiți cât mai specifici. Specificarea unui branch nu este suficient de specific, folosiți identificatorii de commit / changeset.
  • Jenkins te poate notifica în mai multe moduri cu privire la progresele job-ului (build-ul a început / a reusit / a eșuat) - în interfața web, e-mail, chat. Să-l configurați în așa fel încât să fie cât mai convenabil pentru membrii echipei dar să nu le spameze.

Alte variante în afară de Jenkins ar fi: TeamCity, CruiseControl și Travis-CI.

Cea de-a doua parte a unui astfel de configurări este un loc pentru a ține codul și comentariile legate de revizii. Acest lucru poate fi un sistem sau două sisteme distincte (în cazul în acesta aveți nevoie să le sincronizați - probabil folosind Jenkins). Câteva variante:

  • soluții complete (cod hosting și revizuire): Github, BitBucket, Google Code, hosted TFS
  • Cod hosting pe care le puteți instala pe serverul vostru: RhodeCode, Gitorious, Gitlab, gitweb, hgserv
  • Revizuire de cod: Gerrit, ReviewBoard, Rietveld

A treia piesă a puzzle-ului este un sistem care efectuează analiza statică pe cod pentru a oferi feedback despre problemele care pot fi detectate în mod automat. Pentru aceasta recomand SonarQube (cunoscut anterior sub numele Sonar). Ea nu face analiză statică pe cont propriu, ci consumă rapoartele create de alte instrumente (cum ar fi FindBugs, FxCop, Pylint, etc) și le prezintă într-o interfață web frumoasă, oferind o clasificare a problemelor, statistici, rapoarte cu schimbări și așa mai departe. Câteva sfaturi legate de folosirea SonarQube:

  • are o arhitectură ciudată: analiza se execută pe client care are nevoie de acces direct atât la interfața web cât și la baza de date.
  • analiza unui proiect mare poate să dureze o lungă perioadă de timp și să consume multe resurse (CPU/memorie - puteți găsi sfaturi specifice pentru proiecte mari de Java pe blog-ul Transylvania JUG). Dacă apar astfel de probleme, este un indicator bun că ar trebui să despărțiți proiectul în mai multe module mici.
  • SonarQube are nevoie de o bază de date performantă. Nu rulați cu baza de date încorporată (H2) cu care vine sau cu o instanță MySQL slabă. Recomand să folosiți un PostgreSQL configurat corect.

Concluzii

Existența unui "deployment pipeline" are multe beneficii. Se eliberează timpul pe echipe. Instalarea se face mai repede și garantează rezultate consistente. Asigură că procesul de instalare este definit cu precizie (suficient de precis ca să-l poate executa un calculator). De asemenea, ne învață despre instrumentele de bază și despre linia de comandă, un lucru indispensabil pentru a depana problemele de producție.

Puteți aplica livrarea continuă la toate tipurile de sisteme software, nu doar site-uri sau servicii găzduite (acolo unde este cel mai ușor). Pipeline-ul poate produce installkit-uri sau chiar mașini virtuale complete cu software-ul preinstalat. Livrarea continuă nu înseamnă neapărat că trebuie livrat noul software-ul la client de fiecare dată când se schimbă ceva. Înseamnă doar că aveți opțiunea de a face acest lucru la orice moment în timp.

O carte bună (deși ușor depășită) este "Continuous Delivery: Reliable Software Releases through Build, Test, and Deployment Automation" de Jez Humble și David Farley. De asemenea, puteți arunca o privire asupra unei prezentări cu acest subiect sau puteți să mă contactați pentru întrebări / sfaturi sau chiar să veniți la următoarea întâlnire Cluj.PM unde voi vorbi despre acest subiect.

NUMĂRUL 149 - Development with AI

Sponsori

  • Accenture
  • BT Code Crafters
  • Accesa
  • Bosch
  • Betfair
  • MHP
  • BoatyardX
  • .msg systems
  • P3 group
  • Ing Hubs
  • Cognizant Softvision
  • Colors in projects