{"id":93885,"date":"2020-09-10T19:42:23","date_gmt":"2020-09-10T17:42:23","guid":{"rendered":"https:\/\/prohoster.info\/blog\/administrirovanie\/continuous-integration-kak-praktika-a-ne-jenkins-andrej-aleksandrov"},"modified":"2020-09-10T19:42:23","modified_gmt":"2020-09-10T17:42:23","slug":"continuous-integration-kak-praktika-a-ne-jenkins-andrej-aleksandrov","status":"publish","type":"post","link":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/continuous-integration-kak-praktika-a-ne-jenkins-andrej-aleksandrov","title":{"rendered":"Continuous Integration come pratica, non Jenkins. Andrey Alexandrov","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p><img decoding=\"async\" alt=\"Continuous Integration come pratica, non Jenkins. Andrey Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/ed8a32ae63b8dccfc8b4893ab27f1527.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Discutiamo perch\u00e9 gli strumenti CI e CI siano davvero due cose diverse.<\/p>\n<p><\/p>\n<p>Quale problema il CI mira a risolvere, da dove \u00e8 nata l'idea, quali sono le ultime conferme che funziona, come capire se avete davvero una pratica e non solo un Jenkins installato.<\/p>\n<p><noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><\/p>\n<p>L'idea di fare una presentazione sul Continuous Integration \u00e8 nata un anno fa, quando andavo a colloqui per cercare lavoro. Ho parlato con 10-15 aziende, e solo una \u00e8 riuscita a rispondere chiaramente a cosa sia il CI e a spiegare come hanno capito di non averlo. Le altre dicevano delle sciocchezze incomprensibili su Jenkins \ud83d\ude42 'Beh, abbiamo Jenkins, fa delle build, quindi \u00e8 CI!' Nella presentazione cercher\u00f2 di spiegare cosa sia davvero il Continuous Integration e perch\u00e9 Jenkins e strumenti simili hanno una relazione molto debole con questo.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Continuous Integration come pratica, non Jenkins. Andrey Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/a57813a652c0d788e5a927dc8a7130ba.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Quindi, cosa viene normalmente in mente quando si parla di CI? La maggior parte delle persone penser\u00e0 a Jenkins, Gitlab CI, Travis, ecc.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Continuous Integration come pratica, non Jenkins. Andrey Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/c9799c11ba7bb7bbdb2048c2f314b22a.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Anche se facciamo una ricerca su Google, ci verranno mostrati questi strumenti.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Continuous Integration come pratica, non Jenkins. Andrey Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/028ef088b28b73e7905b1666d9d53d1b.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Se chiedi se sono familiari, subito dopo aver elencato gli strumenti ti diranno che il CI \u00e8 quando in un Pull Request la build e i test vengono eseguiti su un commit.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Continuous Integration come pratica, non Jenkins. Andrey Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/f37ba8f985c10900f669540e063c5e43.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>L'integrazione continua non riguarda gli strumenti, n\u00e9 le build con test nei branch! L'integrazione continua \u00e8 una pratica di integrazione molto frequente del nuovo codice e non \u00e8 affatto necessario costruire Jenkins, GitLab, ecc.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Continuous Integration come pratica, non Jenkins. Andrey Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/c3a12b4a875050550b42714607e787c7.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Prima di capire come appare un CI completo, immergiamoci nel contesto delle persone che lo hanno inventato e nelle difficolt\u00e0 che cercavano di risolvere.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Continuous Integration come pratica, non Jenkins. Andrey Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/2ab9c0f4dba2887fed5744c8b021b424.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E la difficolt\u00e0 che volevano risolvere era la collaborazione all'interno del team!<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Continuous Integration come pratica, non Jenkins. Andrey Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/11a5f3b1075f8b8d0f169fe07adf6c91.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Diamo un'occhiata a esempi di quali difficolt\u00e0 affrontano gli sviluppatori durante lo sviluppo in team. Abbiamo un progetto, un branch master in git e due sviluppatori.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Continuous Integration come pratica, non Jenkins. Andrey Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/8138a52376e87239ff5f7b0af5cd8fee.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E iniziarono a lavorare come tutti sono abituati a fare. Prendono un compito in Jira, creano un branch di funzionalit\u00e0 e scrivono codice.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Continuous Integration come pratica, non Jenkins. Andrey Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/54720c40d9bbd9631b411a2a26c4083f.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Uno ha completato la funzionalit\u00e0 pi\u00f9 velocemente e ha fatto il merge nel master.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Continuous Integration come pratica, non Jenkins. Andrey Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/4593dc3cf33a44bf3a4d8166be9bc5da.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>L'altro ha impiegato pi\u00f9 tempo, ha fatto il merge dopo e ha ottenuto un conflitto. Ora, invece di scrivere le funzionalit\u00e0 necessarie per il business, lo sviluppatore spende il suo tempo e le sue energie a risolvere conflitti.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Continuous Integration come pratica, non Jenkins. Andrey Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/c947601fb1dd3b3dd64bac455dc6691a.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Pi\u00f9 \u00e8 complicato integrare la tua funzione con il master generale, pi\u00f9 tempo ci impieghiamo. E questo \u00e8 solo un esempio piuttosto semplice. \u00c8 un caso in cui ci sono solo 2 sviluppatori. E immagina se 10, 15 o 100 persone in un'azienda scrivono in un unico repository. Andresti fuori di testa a risolvere tutti questi conflitti. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Continuous Integration come pratica, non Jenkins. Andrey Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/16c6b8b51ae462f1e0acb966a93c0ae5.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>C'\u00e8 un caso leggermente diverso. Abbiamo un master e diversi sviluppatori che stanno lavorando su qualcosa.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Continuous Integration come pratica, non Jenkins. Andrey Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/21b78ad8d0cb7cb5bded6ef9d49707c5.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Hanno creato un branch ciascuno.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Continuous Integration come pratica, non Jenkins. Andrey Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/b85d8aa0080f08c1ad8ad83f3a9ab084.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Uno si \u00e8 fuso, tutto bene, ha completato il compito.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Continuous Integration come pratica, non Jenkins. Andrey Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/e96d4fd52c39089e3377ed85adeeb591.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Nel frattempo, il secondo sviluppatore ha completato il suo compito. Supponiamo che lo abbia inviato per una revisione. In molte aziende c'\u00e8 la pratica della revisione. Da un lato, \u00e8 una buona e utile pratica, dall'altro, ci rallenta in molti aspetti. Non approfondiamo questo, ma ecco un ottimo esempio di come una storia complicata riguardo alla revisione possa portare a problemi. Hai inviato una pull request per la revisione. Lo sviluppatore non ha altro da fare. Cosa inizia a fare? Inizia a prendere altri compiti. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Continuous Integration come pratica, non Jenkins. Andrey Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/7b8e121be99432606056acf11e20f518.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Nel frattempo, il secondo sviluppatore ha fatto qualcos'altro. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Continuous Integration come pratica, non Jenkins. Andrey Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/ceaa5ba5b3b5014fad527362f5794e94.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Il primo ha completato il terzo compito. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Continuous Integration come pratica, non Jenkins. Andrey Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/9c27663e63bb9489ecffc5a1f73abb87.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>E dopo un certo periodo di tempo, la sua revisione \u00e8 stata provata e sta cercando di unirsi. E cosa succede? Incontra un enorme numero di conflitti. Perch\u00e9? Perch\u00e9 mentre la sua pull request era in revisione, nel codice erano gi\u00e0 avvenuti molti cambiamenti. <\/p>\n<p><\/p>\n<p>Oltre alla questione dei conflitti, c'\u00e8 anche la questione della comunicazione. Mentre la vostra branch \u00e8 in revisione, mentre aspetta qualcosa, mentre avete impiegato molto tempo a sviluppare una funzionalit\u00e0, smettete di monitorare cosa sta cambiando nella base di codice del vostro servizio. \u00c8 possibile che quello che state cercando di risolvere sia gi\u00e0 stato risolto ieri, e potreste riprendere e riutilizzare qualche metodo. Ma non lo vedrete, perch\u00e9 state sempre lavorando con una branch obsoleta. E questa branch obsoleta porta sempre al fatto che dovrete risolvere conflitti di merging. <\/p>\n<p><\/p>\n<p>Quindi, se lavoriamo in team, cio\u00e8 se non \u00e8 una sola persona a lavorare nel repository, ma 5-10 persone, quanto pi\u00f9 a lungo aspettiamo a aggiungere il nostro codice nel master, tanto pi\u00f9 soffriamo nel dover unire qualcosa alla fine. E quanto pi\u00f9 conflitti abbiamo, e con una versione pi\u00f9 vecchia stiamo lavorando, tanto pi\u00f9 problemi abbiamo.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Continuous Integration come pratica, non Jenkins. Andrey Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/55c070f65a4d3838fb8c02bb9684c76b.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Collaborare pu\u00f2 essere doloroso! Ci intralciamo sempre a vicenda. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Continuous Integration come pratica, non Jenkins. Andrey Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/b914c50aad6f3c9f97edcad7e71ba627.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Questo problema \u00e8 stato notato pi\u00f9 di 20 anni fa. Il primo riferimento alla pratica della Continuous Integration l'ho trovato nell'Extreme Programming.<\/p>\n<p><\/p>\n<p>L'Extreme Programming \u00e8 il primo framework agile. La pagina \u00e8 apparsa nel 1996. L'idea era di utilizzare alcune pratiche di programmazione, pianificazione e altro, affinch\u00e9 lo sviluppo fosse il pi\u00f9 flessibile possibile, cos\u00ec da poter reagire pi\u00f9 rapidamente ai cambiamenti e alle richieste dei nostri clienti. E 24 anni fa hanno iniziato a riscontrare che se si fa qualcosa per molto tempo in modo isolato, si spende pi\u00f9 tempo a causa dei conflitti. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Continuous Integration come pratica, non Jenkins. Andrey Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/93a80838bdb3b297557dbf2ac7587965.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Ora analizzeremo l'espressione 'Continuous Integration' parola per parola. Se tradotta letteralmente, si ottiene 'integrazione continua'. Ma non \u00e8 chiaro quanto sia continua, \u00e8 piuttosto intermittente. E quanto sia 'integrazione' non \u00e8 molto ovvio. <\/p>\n<p><\/p>\n<p>Ecco perch\u00e9 vi mostro ora citazioni dall'Extreme Programming. Analizzeremo entrambe le parole separatamente. <\/p>\n<p><\/p>\n<p>Integrazione \u2014 Come ho gi\u00e0 detto, puntiamo a far s\u00ec che ogni ingegnere lavori con l'ultima versione del codice, cercando di integrare il proprio codice nel branch principale il pi\u00f9 frequentemente possibile, in modo che siano piccoli branch. Questo perch\u00e9 se sono grandi, possiamo facilmente rimanere bloccati per una settimana a causa di conflitti di merge. Soprattutto se abbiamo un lungo ciclo di sviluppo come il waterfall, dove un sviluppatore \u00e8 assente per un mese a lavorare su una grande funzionalit\u00e0. E nella fase di integrazione pu\u00f2 rimanere bloccato a lungo. <\/p>\n<p><\/p>\n<p>L'integrazione \u00e8 quando prendiamo il nostro branch e lo integriamo con il master, lo uniamo. C'\u00e8 una versione ultimativa, quando siamo transbase developer, dove puntiamo a scrivere direttamente nel master senza rami superflui.<\/p>\n<p><\/p>\n<p>In generale, l'integrazione significa prendere il proprio codice e portarlo nel master. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Continuous Integration come pratica, non Jenkins. Andrey Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/8950103e6a59ed7132ec321ac6abe600.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Cosa si intende per \u00abcontinuous\u00bb e cosa significa continuit\u00e0? La pratica implica che lo sviluppatore cerca di integrare il proprio codice il prima possibile. Questo \u00e8 il suo obiettivo in ogni attivit\u00e0: fare in modo che il suo codice arrivi nel master il pi\u00f9 rapidamente possibile. In un mondo ideale, gli sviluppatori lo farebbero ogni poche ore. Cio\u00e8, prendi un piccolo compito e lo unisci al master. Tutto va alla grande. Questo \u00e8 ci\u00f2 a cui aspiri. E deve essere fatto in modo continuo. Non appena hai fatto qualcosa, la metti subito nel master. <\/p>\n<p><\/p>\n<p>E lo sviluppatore che fa qualcosa \u00e8 responsabile di ci\u00f2 che ha fatto affinch\u00e9 funzionasse e non rompesse nulla. Qui emerge solitamente la questione dei test. Vogliamo eseguire alcuni test sul nostro commit, sul nostro merge, per assicurarci che funzioni. E qui Jenkins pu\u00f2 davvero aiutarti.<\/p>\n<p><\/p>\n<p>Ma con le storie: perch\u00e9 non facciamo cambiamenti piccoli? E perch\u00e9 non affrontiamo piccole sfide? E perch\u00e9 non portiamo subito una sfida nel master? Qui, nessun Jenkins pu\u00f2 aiutarti. Perch\u00e9 Jenkins ti aiuter\u00e0 solo a eseguire i test. <\/p>\n<p><\/p>\n<p>Puoi farne a meno. Non ti dar\u00e0 alcun fastidio. Perch\u00e9 l'obiettivo della pratica \u00e8 quello di unirsi il pi\u00f9 spesso possibile, per non perdere moltissimo tempo su eventuali conflitti in futuro. <\/p>\n<p><\/p>\n<p>Immagina che nel 2020 per qualche motivo non ci sia internet. E stiamo lavorando localmente. Non abbiamo Jenkins. Va bene. Puoi comunque creare un ramo locale. Hai scritto del codice in questo ramo. Hai completato una sfida in 3-4 ore. Sei tornato al master, hai eseguito un git pull e hai unito il tuo ramo l\u00ec. Fatto. Se lo fai spesso, congratulazioni, hai l'integrazione continua!<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Continuous Integration come pratica, non Jenkins. Andrey Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/1f2117b65994b940edb04e0e119f6e8a.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Quali prove esistono oggi nel mondo moderno che giustifichino di investire energie in questo? Perch\u00e9 in generale \u00e8 una cosa difficile. Se provi a lavorare in questo modo, capirai che dovrai affrontare una pianificazione, dovrai dedicare pi\u00f9 tempo alla scomposizione delle attivit\u00e0. Se continui a lavorare come man..., non potrai fondere rapidamente e, di conseguenza, ti ritroverai nei guai. Non avrai pi\u00f9 pratiche. <\/p>\n<p><\/p>\n<p>E questo sar\u00e0 costoso. Non sar\u00e0 possibile iniziare a lavorare con Continuous Integration da domani. Tutti voi impiegherete molto tempo ad abituarvi, molto tempo a imparare a scomporre le attivit\u00e0, e molto tempo a rivedere la pratica del review, se ne avete una. Perch\u00e9 il nostro obiettivo \u00e8 di fonderlo oggi. Se passi tre giorni per fare la revisione, hai dei problemi e non riuscirai a implementare Continuous Integration. <\/p>\n<p><\/p>\n<p>Ma abbiamo alcune prove attuali ora stesso che ci dicono che investire in questa pratica ha senso?<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Continuous Integration come pratica, non Jenkins. Andrey Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/2026a8f1d72fb05613511e7bab57e8ec.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>La prima cosa che mi \u00e8 venuta in mente \u00e8 il State of DevOps. \u00c8 uno studio che i ragazzi conducono da 7 anni. Adesso lo fanno come organizzazione indipendente, ma sotto Google.<\/p>\n<p><\/p>\n<p>E la loro ricerca nel 2018 ha mostrato una correlazione tra le aziende che cercano di utilizzare rami a breve termine, che si integrano rapidamente e frequentemente, e che presentano performance IT migliori.<\/p>\n<p><\/p>\n<p>Quali sono queste metriche? Sono 4 metriche che raccolgono da tutte le aziende nei loro questionari: frequenza di distribuzione, tempo necessario per le modifiche, tempo per il ripristino del servizio, tasso di failure delle modifiche.<\/p>\n<p><\/p>\n<p>Innanzitutto, c'\u00e8 questa correlazione: sappiamo che le aziende che effettuano merge frequentemente hanno queste metriche significativamente migliori. Inoltre, esiste una suddivisione delle aziende in diverse categorie: ci sono le aziende lente, quelle a performance media, le alte performer e l'\u00e9lite. L'\u00e9lite include Netflix e Amazon, che sono superveloci, fanno tutto in modo rapido, elegante e di qualit\u00e0.<\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Continuous Integration come pratica, non Jenkins. Andrey Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/4fd98ef48a5cffdd6ae2ceea93dbb0bf.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>La seconda storia \u00e8 avvenuta solo un mese fa. Nel Technology Radar \u00e8 apparso un interessante articolo su Gitflow. Gitflow si distingue da tutti gli altri perch\u00e9 i suoi rami vivono a lungo. Ci sono rami di rilascio che vivono a lungo e rami di funzionalit\u00e0 che vivono anch'essi a lungo. Questa pratica nel Technology Radar \u00e8 stata spostata in HOLD. Perch\u00e9? Perch\u00e9 le persone incontrano difficolt\u00e0 nell'integrazione. <\/p>\n<p><\/p>\n<p>Se una tua branch rimane attiva a lungo, si inceppa, marcisce e iniziamo a spendere pi\u00f9 tempo per apportare modifiche. <\/p>\n<p><\/p>\n<p>Di recente l'autore di Gitflow ha detto che se miri al Continuous Integration e vuoi rilasciare nuove versioni il pi\u00f9 spesso possibile, allora Gitflow \u00e8 una cattiva idea. Ha anche aggiunto in un articolo che, se hai un backend che ti permette di aspirare a questo, allora Gitflow \u00e8 superfluo, perch\u00e9 ti rallenter\u00e0 e ti creer\u00e0 problemi di integrazione. <\/p>\n<p><\/p>\n<p>Questo non significa che Gitflow sia cattivo e che tu non debba usarlo. \u00c8 utile in altri casi. Ad esempio, quando hai bisogno di supportare pi\u00f9 versioni di un servizio o di un'applicazione, ovvero quando devi mantenere il supporto per un lungo periodo di tempo. <\/p>\n<p><\/p>\n<p>Ma se parli con persone che supportano questi servizi, sentirai molte lamentele riguardo al fatto che la versione 3.2 \u00e8 stata rilasciata 4 mesi fa e che non includeva questa correzione, e ora, per apportarla, \u00e8 necessario fare un sacco di modifiche. Cos\u00ec, di nuovo, si sono bloccati e ci stanno lavorando da una settimana per cercare di fondere una nuova funzionalit\u00e0. <\/p>\n<p><\/p>\n<p>Come ha giustamente osservato Aleksandr Kovalev in chat, la correlazione non \u00e8 la stessa cosa della causalit\u00e0. \u00c8 cos\u00ec. Cio\u00e8, non c'\u00e8 una connessione diretta che se hai Continuous Integration, allora tutte le metriche saranno eccellenti. Ma c'\u00e8 una correlazione positiva: se una cosa vale, \u00e8 probabile che valga anche l'altra. Non \u00e8 un dato certo, ma \u00e8 probabile. Questa \u00e8 solo una correlazione. <\/p>\n<p><\/p>\n<p><img decoding=\"async\" alt=\"Continuous Integration come pratica, non Jenkins. Andrey Alexandrov\" src=\"\/wp-content\/uploads\/2020\/09\/d5fc050550b0e9f86a1fdf85fff32fa5.jpg\" style=\"display:block;margin: 0 auto;\" \/><\/p>\n<p><\/p>\n<p>Sembra che stiamo gi\u00e0 facendo qualcosa, sembra che stiamo gi\u00e0 facendo merge, ma come possiamo capire se abbiamo veramente Continuous Integration e se facciamo merge con sufficiente frequenza?<\/p>\n<p><\/p>\n<p>Jez Humble \u00e8 l'autore del Handbook, Accelerate, del sito Continuous Delivery e del libro \"Continuous Delivery\". Propone un test del genere:<\/p>\n<p><\/p>\n<ul>\n<li>Il codice dell'ingegnere viene inserito nel master ogni giorno. <\/li>\n<li>Per ogni commit si eseguono i test unitari.<\/li>\n<li>Se il build nel master fallisce, viene riparato in circa 10 minuti.<\/li>\n<\/ul>\n<p><\/p>\n<p>Propone di utilizzare questo test per assicurarsi che la pratica esista realmente nel tuo processo. <\/p>\n<p><\/p>\n<p>L'ultima parte mi sembra un po' controversa. Cio\u00e8, se puoi risolvere il problema in 10 minuti, significa che hai una Continuous Integration, il che suona un po' strano a mio avviso, ma ha un senso. Perch\u00e9? Perch\u00e9 se fai merge frequentemente, significa che le tue modifiche sono piccole. Se un piccolo cambiamento causa un malfunzionamento della build principale, sarai in grado di trovare l'errore rapidamente, perch\u00e9 la modifica \u00e8 piccola. Hai fatto un piccolo merge, dove hai cambiato 20-30 righe. E, di conseguenza, puoi rapidamente capire qual \u00e8 stato il problema, poich\u00e9 le modifiche sono minime e la tua area di ricerca \u00e8 molto ristretta. <\/p>\n<p><\/p>\n<p>E anche se dopo il rilascio il nostro ambiente di produzione si rompe, se abbiamo la pratica della Continuous Integration, \u00e8 molto pi\u00f9 facile agire, perch\u00e9 le modifiche sono piccole. S\u00ec, questo influenzer\u00e0 la pianificazione. Sar\u00e0 difficile. E probabilmente, la parte pi\u00f9 difficile di questa pratica \u00e8 abituarsi a suddividere i compiti, cio\u00e8 come fare per prendere qualcosa e realizzarlo in poche ore e allo stesso tempo superare la revisione, se la hai. La revisione \u00e8 un dolore a parte. <\/p>\n<p><\/p>\n<p>I test unitari sono solo un supporto che ti aiuta a capire se la tua integrazione \u00e8 andata a buon fine e se non si \u00e8 rotto nulla. A mio avviso, non \u00e8 nemmeno un punto obbligatorio, perch\u00e9 il senso della pratica non \u00e8 questo. <\/p>\n<p><\/p>\n<p>Questo \u00e8 un breve riepilogo dell'Integrazione Continua. \u00c8 tutto ci\u00f2 che c'\u00e8 in questa pratica. Sono pronto per le domande. <\/p>\n<p><\/p>\n<p>Ricapitolo brevemente:<\/p>\n<p><\/p>\n<ul>\n<li>L'Integrazione Continua non \u00e8 Jenkins, non \u00e8 Gitlab.<\/li>\n<li>Non \u00e8 uno strumento, \u00e8 una pratica che implica unire il nostro codice nel master il pi\u00f9 spesso possibile. <\/li>\n<li>Lo facciamo per evitare il grande dolore che si verifica con le fusioni in futuro, cio\u00e8 proviamo un piccolo dolore ora per evitare un grande dolore in seguito. Questo \u00e8 il senso. <\/li>\n<li>Dalla parte si verifica comunicazione attraverso il codice, ma lo vedo molto raramente, ma \u00e8 stato anche ideato per questo.<\/li>\n<\/ul>\n<p><\/p>\n<p><strong>Domande<\/strong><\/p>\n<p><\/p>\n<p><em>Cosa fare con i compiti non decostruiti?<\/em><\/p>\n<p><\/p>\n<p>Decostruirli. Qual \u00e8 il problema? Puoi fare un esempio, che c'\u00e8 un compito e non si decostruisce?<\/p>\n<p><\/p>\n<p><em>Ci sono compiti che non possono essere decomposti, come quelli che richiedono una profonda expertise e possono richiedere mesi prima di raggiungere un risultato accettabile.<\/em> <\/p>\n<p><\/p>\n<p>Se ho capito bene, c'\u00e8 un compito grande e complesso il cui risultato sar\u00e0 visibile solo fra un mese?<\/p>\n<p><\/p>\n<p><em>S\u00ec, corretto. Il risultato potr\u00e0 essere valutato non prima di un mese.<\/em> <\/p>\n<p><\/p>\n<p>Va bene. In generale non \u00e8 un problema. Perch\u00e9? Perch\u00e9 in questo caso, quando parliamo di rami, non ci riferiamo a un ramo con una funzionalit\u00e0. Le funzionalit\u00e0 possono essere grandi e complesse. Possono coinvolgere molti componenti. Ed \u00e8 possibile che non possiamo completarle in un solo ramo. Va bene cos\u00ec. Dobbiamo semplicemente scomporre questa storia. Se la funzionalit\u00e0 non \u00e8 completamente pronta, questo non significa che alcuni pezzi del suo codice non possano essere uniti. Hai aggiunto, ad esempio, una migrazione e all'interno della funzionalit\u00e0 ci sono alcuni passaggi. Hai, ad esempio, un passaggio: fare la migrazione, aggiungere un nuovo metodo. E puoi gi\u00e0 unire queste cose quotidianamente. <\/p>\n<p><\/p>\n<p><em>Va bene. Qual \u00e8 dunque il senso di tutto ci\u00f2?<\/em><\/p>\n<p><\/p>\n<p>Qual \u00e8 il senso di unire piccole parti ogni giorno?<\/p>\n<p><\/p>\n<p><em>S\u00ec.<\/em><\/p>\n<p><\/p>\n<p>Se hanno rotto qualcosa, lo vedi subito. Hai un piccolo pezzo che ha causato un problema, quindi \u00e8 pi\u00f9 facile da risolvere. Il senso \u00e8 che unire un piccolo pezzo ora \u00e8 molto pi\u00f9 semplice che unire qualcosa di grande tra qualche settimana. E un terzo motivo \u00e8 che altri ingegneri lavoreranno gi\u00e0 con la versione attuale del codice. Vedranno che ci sono alcune migrazioni aggiunte e che \u00e8 apparso un metodo che potrebbero voler utilizzare. Tutti vedranno cosa sta succedendo nel tuo codice. \u00c8 proprio per queste tre cose che si fa questa pratica. <\/p>\n<p><\/p>\n<p><em>Grazie, la questione \u00e8 chiusa!<\/em><\/p>\n<p><\/p>\n<p><em>(Oleg Soroka) Posso aggiungere qualcosa? Hai detto tutto giustamente, voglio solo aggiungere una frase.<\/em><\/p>\n<p><\/p>\n<p>Va bene.<\/p>\n<p><\/p>\n<p><em>Con Continuous Integration, il codice viene inserito nel ramo principale non quando una caratteristica \u00e8 completamente pronta, ma quando il build smette di rompersi. Puoi fare commit nel master quante volte vuoi al giorno. Il secondo aspetto \u00e8 che se per qualche motivo non riesci a dividere un compito mensile in attivit\u00e0 di almeno tre giorni, senza parlare di tre ore, allora hai un enorme problema. Il fatto che non hai Continuous Integration \u00e8 il minore di questi problemi. Significa che hai problemi con l'architettura e le pratiche ingegneristiche sono ai minimi storici. Anche se si tratta di ricerca, in ogni caso deve essere formulato sotto forma di ipotesi o cicli.<\/em> <\/p>\n<p><\/p>\n<p><em>Abbiamo parlato di 4 metriche che distinguono le aziende di successo da quelle in ritardo. Prima di arrivare a queste 4 metriche, bisogna sopravvivere. Se una tua attivit\u00e0 richiede un mese, mi concentrei prima su questa metrica. La ridurrei a 3 giorni. Solo allora inizierei a pensare al Continuous.<\/em><\/p>\n<p><\/p>\n<p>Ho capito correttamente che pensi che non abbia senso investire in pratiche ingegneristiche se qualsiasi attivit\u00e0 richiede un mese?<\/p>\n<p><\/p>\n<p><em>Hai a disposizione l'integrazione continua. C'\u00e8 un aspetto per cui in 10 minuti puoi riparare un problema oppure fare il rollback. Immagina di averlo rilasciato. In pi\u00f9 hai anche il continuous deployment, l'hai rilasciato in produzione e solo dopo ti rendi conto che qualcosa \u00e8 andato storto. Devi fare il rollback, ma a quel punto hai gi\u00e0 eseguito la migrazione del database. Hai gi\u00e0 la struttura del database della versione successiva, e inoltre \u00e8 passato anche un backup, e sono stati registrati dei dati.<\/em><\/p>\n<p><\/p>\n<p><em>Qual \u00e8 la tua alternativa? Se fai il rollback del codice, non pu\u00f2 pi\u00f9 funzionare con questo database aggiornato.<\/em><\/p>\n<p><\/p>\n<p>Il database avanza solo in avanti, s\u00ec. <\/p>\n<p><\/p>\n<p><em>Le persone con una scarsa pratica ingegneristica probabilmente non hanno nemmeno letto un grosso libro su ... Cosa fare con il backup? Se ti ripristini da un backup, significa che perdi i dati accumulati nel frattempo. Ad esempio, hai lavorato per tre ore con la nuova versione del database e gli utenti si sono registrati. Torni a un vecchio backup perch\u00e9 con la nuova versione la struttura non funziona, quindi hai perso quegli utenti. E loro sono scontenti, si lamentano.<\/em><\/p>\n<p><\/p>\n<p><em>Per padroneggiare l'intera gamma di pratiche che supportano il Continuous Integration e il Continuous Delivery, non basta imparare a scrivere semplicemente... Innanzitutto, potrebbero diventare troppe, risultando cos\u00ec poco pratiche. Inoltre, ci sono molte altre pratiche come Scientific. Ce n'\u00e8 una che GitHub ha popolarizzato un po' di tempo fa. \u00c8 un approccio in cui il vecchio codice e il nuovo codice vengono eseguiti contemporaneamente. Significa che realizzi una funzionalit\u00e0 incompleta, ma che pu\u00f2 restituire un valore: sia come funzione, sia come Rest API. Esegui sia il nuovo che il vecchio codice, e confronti la differenza tra di essi. Se c'\u00e8 una differenza, la registri come evento. In questo modo, sai che la tua nuova funzionalit\u00e0 \u00e8 pronta per essere implementata sopra la vecchia, a patto che non ci siano stati scostamenti tra questi due nel corso di un determinato periodo di tempo.<\/em> <\/p>\n<p><\/p>\n<p><em>Ci sono centinaia di tali pratiche. Ti suggerirei di iniziare con lo sviluppo transbase. Non \u00e8 al 100% su Continuous Integration, ma le pratiche sono le stesse; uno vive male senza l'altro.<\/em> <\/p>\n<p><\/p>\n<p>Hai citato lo sviluppo transbase come esempio per dove si possono vedere le pratiche, o stai suggerendo alle persone di iniziare a utilizzare lo sviluppo transbase?<\/p>\n<p><\/p>\n<p><em>Guarda, poich\u00e9 non riusciranno a utilizzarli. Per poterli utilizzare, \u00e8 necessario leggere molto. E quando una persona si chiede: \u00abCosa fare con una funzionalit\u00e0 che richiede un mese?\u00bb, significa che non ha letto nulla riguardo allo sviluppo di transbase. Non lo consiglierei ancora. Suggerirei di concentrarsi esclusivamente sul tema di come suddividere architettonicamente compiti complessi in compiti pi\u00f9 piccoli. Questa \u00e8 l'essenza della decomposizione.<\/em><\/p>\n<p><\/p>\n<p><em>La decomposizione \u00e8 uno degli strumenti dell'architetto. Prima facciamo un'analisi, poi la decomposizione, quindi la sintesi, e infine l'integrazione. In questo modo, tutto si compone. E per arrivare alla Continuous Integration, dobbiamo prima passare attraverso la decomposizione. Durante la prima fase sorgono domande, e noi gi\u00e0 parliamo della quarta fase, cio\u00e8, pi\u00f9 frequentemente facciamo integrazioni, meglio \u00e8. \u00c8 ancora presto per farlo; sarebbe opportuno prima migliorare il proprio monolite.<\/em> <\/p>\n<p><\/p>\n<p><em>\u00c8 necessario disegnare alcune frecce e quadrati su un diagramma. Non puoi dire che ora mostrer\u00f2 lo schema architettonico della nuova applicazione e far vedere solo un quadrato con all'interno un pulsante verde per l'app. In ogni caso, ci saranno pi\u00f9 quadrati e frecce. In qualsiasi schema io abbia visto, ce ne erano pi\u00f9 di uno. E la decomposizione, anche a livello di rappresentazione grafica, \u00e8 gi\u00e0 in atto. Pertanto, i quadrati possono essere indipendenti. Se non lo sono, ho molte domande per l'architetto.<\/em> <\/p>\n<p><\/p>\n<p>C'\u00e8 una domanda dalla chat: \u00abSe la revisione \u00e8 obbligatoria e richiede tempo, quindi un giorno o pi\u00f9?\u00bb.<\/p>\n<p><\/p>\n<p>Hai problemi con la pratica. Non dovrebbe passare un giorno o pi\u00f9 per una revisione. \u00c8 la stessa storia della domanda precedente, solo un po' pi\u00f9 morbida. Se la revisione dura un giorno, significa che probabilmente si tratta di una revisione di un cambiamento molto grande. Dobbiamo quindi ridurlo. Nel transbase development, che Oleg ha raccomandato, c'\u00e8 un concetto chiamato revisione continua. L'idea \u00e8 che facciamo pull request cos\u00ec piccoli intenzionalmente, perch\u00e9 puntiamo a fondere costantemente e poco alla volta. E quindi il pull request cambia una sola astrazione o 10 righe. Grazie a questo, la revisione ci richiede solo qualche minuto. <\/p>\n<p><\/p>\n<p>Se una revisione richiede un giorno o pi\u00f9, significa che c'\u00e8 qualcosa che non va. Innanzitutto, potrebbe esserci un problema con l'architettura. Potrebbe anche essere un grande blocco di codice, per esempio, di 1.000 righe. Oppure hai un'architettura cos\u00ec complessa che nessuno riesce a comprenderla. Questo \u00e8 un problema secondario, ma anche quello dovr\u00e0 essere affrontato. Forse non \u00e8 neanche necessaria una revisione. \u00c8 qualcosa su cui riflettere. La revisione \u00e8 un freno. Porta dei benefici nel complesso, ma bisogna capire perch\u00e9 la stai facendo. \u00c8 un modo per trasferire informazioni rapidamente? \u00c8 un modo per stabilire degli standard interni? Perch\u00e9 hai bisogno di farla? Poich\u00e9 la revisione deve essere fatta molto rapidamente o addirittura annullata. \u00c8 un po' come lo sviluppo di transbase: una storia molto bella, ma adatta solo per chi ha gi\u00e0 esperienza. <\/p>\n<p><\/p>\n<p>Per quanto riguarda le 4 metriche, consiglierei di ottenerle per capire a cosa portano. Dare un'occhiata ai numeri, vedere l'immagine, quanto sia critica la situazione. <\/p>\n<p><\/p>\n<p><em>(Dmitry) Sono pronto a discutere questo argomento con te. Le cifre e le metriche sono tutte fantastiche, le pratiche sono fantastiche. Ma dobbiamo capire se questo \u00e8 necessario per il business. Ci sono aziende che non hanno bisogno di un cambiamento cos\u00ec rapido. Conosco aziende in cui non \u00e8 possibile apportare modifiche ogni 15 minuti. E non perch\u00e9 siano cattive. \u00c8 solo un ciclo di vita. Per realizzare funzionalit\u00e0 come branches e toggle, sono necessarie conoscenze approfondite.<\/em> <\/p>\n<p><\/p>\n<p>\u00c8 complicato. Se vuoi leggere di pi\u00f9 sulla storia del toggle delle funzionalit\u00e0, te lo consiglio vivamente. <noindex><a rel=\"nofollow\" href=\"https:\/\/trunkbaseddevelopment.com\/\">https:\/\/trunkbaseddevelopment.com\/<\/a><\/noindex>. E c'\u00e8 un ottimo articolo di Martin Fowler sul toggle delle funzionalit\u00e0: sui diversi tipi, i cicli di vita, ecc. Il toggle delle funzionalit\u00e0 \u00e8 complesso. <\/p>\n<p><\/p>\n<p><em>E comunque non hai risposto alla domanda: \u00abJenkins \u00e8 necessario o non \u00e8 necessario?\u00bb<\/em><\/p>\n<p><\/p>\n<p>Jenkins non \u00e8 realmente necessario in alcun caso. Seriamente, strumenti come Jenkins e GitLab vi offriranno comodit\u00e0. Potete vedere se la build \u00e8 andata a buon fine o meno. Possono esservi utili, ma non vi forniranno vere pratiche. Possono solo darvi un pallino \u2013 Ok o Non Ok. E questo, se scrivete ancora dei test, perch\u00e9 se non ci sono test, \u00e8 quasi senza senso. Quindi \u00e8 utile, perch\u00e9 \u00e8 pi\u00f9 comodo, ma in generale si pu\u00f2 anche vivere senza, non perderete molto. <\/p>\n<p><\/p>\n<p><em>Cio\u00e8, se avete pratiche, significa che non vi serve?<\/em><\/p>\n<p><\/p>\n<p>Esatto. Raccomando il test di Jez Humble. Ho un atteggiamento ambivalente riguardo all'ultimo punto. Ma in generale, se avete queste tre cose, vi mergeate costantemente, eseguite test sui commit nel master e riparate rapidamente la build nel master, allora forse non avete bisogno di altro. <\/p>\n<p><\/p>\n<p><em>Mentre aspettiamo le domande dei partecipanti, ho una domanda. Abbiamo appena parlato di codice di prodotto. Ma hai utilizzato il codice infrastrutturale? \u00c8 lo stesso tipo di codice, ha gli stessi principi e lo stesso ciclo di vita, oppure ci sono cicli di vita e principi diversi? Di solito, quando si parla di Continuous Integration e Development, si dimentica che c'\u00e8 anche il codice infrastrutturale. E ultimamente, sta diventando sempre pi\u00f9 rilevante. Dobbiamo quindi applicare tutte queste regole anche a quello?<\/em><\/p>\n<p><\/p>\n<p>Non \u00e8 tanto che dobbiamo, sarebbe fantastico, perch\u00e9 semplificherebbe sicuramente le cose. Una volta che lavoriamo con il codice, non con script bash, ma con un codice solido.<\/p>\n<p><\/p>\n<p><em>Aspetta un attimo, lo script bash \u00e8 anche questo un codice. Non toccare il mio vecchio amore.<\/em> <\/p>\n<p><\/p>\n<p>Va bene, non calpester\u00f2 i tuoi ricordi. Io ho una certa avversione per bash. Si rompe in modo brutto e orrendo continuamente. E si guasta spesso in modo imprevedibile, per questo non lo amo molto. Ma va bene, supponiamo che tu abbia codice in bash. Forse non ne capisco abbastanza e ci sono dei buoni framework per il testing. Non sono aggiornato. E otteniamo gli stessi vantaggi.<\/p>\n<p><\/p>\n<p>Quando trattiamo l'infrastruttura come codice, ci troviamo di fronte agli stessi problemi degli sviluppatori. Qualche mese fa, mi sono trovato in una situazione in cui un collega mi ha inviato una pull request di 1.000 righe in bash. E ti fermi a fare la revisione per 4 ore. I problemi sono gli stessi. \u00c8 sempre codice. E sempre collaborazione. Ci troviamo bloccati con la pull request e incontriamo gli stessi conflitti di merge dello stesso bash, per esempio. <\/p>\n<p><\/p>\n<p>Attualmente sto monitorando molto attivamente tutto questo per massimizzare la bellezza della programmazione dell'infrastruttura. Ho appena integrato Pulumi nella mia infrastruttura. \u00c8 programmazione pura. \u00c8 ancora pi\u00f9 affascinante perch\u00e9 ho accesso a tutte le funzionalit\u00e0 del linguaggio di programmazione, cio\u00e8 ho creato toggle belli nello stesso modo con le istruzioni if. Pertanto, la mia modifica \u00e8 gi\u00e0 nel master. Tutti la vedono. Gli altri ingegneri ne sono a conoscenza. Ha gi\u00e0 avuto qualche impatto. Tuttavia, non \u00e8 stato attivato per tutte le infrastrutture. \u00c8 attivo solo per i miei ambienti di test, per esempio. Quindi, rispondendo di nuovo alla tua domanda, \u00e8 necessario. Ci semplifica sicuramente la vita come ingegneri che lavorano con il codice. <\/p>\n<p><\/p>\n<p><em>Ci sono altre domande?<\/em> <\/p>\n<p><\/p>\n<p>Ho una domanda. Voglio continuare la discussione con Oleg. In generale, penso che tu abbia ragione nel dire che se un compito richiede un mese, hai un problema con l'architettura, con l'analisi, la decomposizione, la pianificazione, ecc. Tuttavia, ho la sensazione che se inizi a vivere secondo il Continuous Integration, comincerai a risolvere i problemi di pianificazione, perch\u00e9 non potrai evitarli. <\/p>\n<p><\/p>\n<p><em>(Oleg) S\u00ec, \u00e8 tutto corretto. In termini di lavoro, questa pratica \u00e8 paragonabile a qualsiasi altra seria pratica che modifica la cultura. La parte pi\u00f9 difficile da superare sono le abitudini, specialmente quelle sbagliate. E se per implementare questa pratica \u00e8 necessario un cambiamento significativo nelle abitudini degli altri: sviluppatori, management, responsabile della produzione, allora ti aspettano delle sorprese.<\/em> <\/p>\n<p><\/p>\n<p><em>Quali sorprese potrebbero esserci? Supponiamo che tu abbia deciso di effettuare integrazioni pi\u00f9 frequentemente. E queste integrazioni sono legate ad altre cose, ad esempio, artefatti. E nella tua azienda, ad esempio, esiste una politica secondo cui ogni artefatto deve essere in qualche modo registrato in un sistema di archiviazione degli artefatti. E questo richiede un certo tempo. La persona deve contrassegnare che, come release manager, ha testato questo artefatto per la sua prontezza per il deployment in produzione. Se questo richiede 5-10-15 minuti, ma effettui il deployment una volta alla settimana, allora investire mezz'ora una volta a settimana \u00e8 un piccolo dazio.<\/em> <\/p>\n<p><\/p>\n<p><em>Se stai facendo Continuous Integration 10 volte al giorno, allora devi moltiplicare 10 per 30 minuti. E questo supera il tempo lavorativo di quel release manager. Si stanca semplicemente a farlo. Ci sono costi fissi per alcune pratiche. E basta.<\/em> <\/p>\n<p><\/p>\n<p><em>E devi o annullare questa regola, cos\u00ec non ti occupi pi\u00f9 di queste cose illogiche, cio\u00e8 non assegni manualmente il livello di conformit\u00e0 di qualcosa a qualcos'altro. Ti affidi completamente a un insieme automatizzato di test di prontezza.<\/em> <\/p>\n<p><\/p>\n<p><em>E se hai bisogno di un'approvazione per far firmare il principale, e non entri in produzione senza che qualcuno ti dica che va bene, tutto questo ostacola le pratiche. Perch\u00e9 se ci sono attivit\u00e0 legate a tasse, tutto si amplifica di cento volte. Quindi il cambiamento non sar\u00e0 spesso accolto con gioia da tutti. \u00c8 difficile cambiare le abitudini delle persone.<\/em> <\/p>\n<p><\/p>\n<p><em>Quando una persona svolge un lavoro abituale, lo fa praticamente senza pensarci. Il suo carico cognitivo \u00e8 pari a zero. Lavora seguendo un modello gi\u00e0 pronto, ha una checklist nella mente, l'ha fatto mille volte. E non appena arrivi e gli dici: 'Annulliamo questa pratica e da luned\u00ec implementiamo una nuova', per lui diventa un pesante carico cognitivo. E questo colpisce subito tutti.<\/em> <\/p>\n<p><\/p>\n<p><em>Quindi la cosa pi\u00f9 semplice, anzi, non tutti possono permettersi questo lusso, ma io faccio sempre esattamente cos\u00ec, ed ecco perch\u00e9. Quando inizia un nuovo progetto, generalmente si inseriscono immediatamente in questo progetto tutte le pratiche non testate. Finch\u00e9 il progetto \u00e8 giovane, non rischiamo molto. Non c'\u00e8 ancora un ambiente di produzione, quindi non c'\u00e8 nulla da rovinare. Pertanto, pu\u00f2 essere usato come allenamento. Questo approccio funziona. Ma non tutte le aziende hanno la possibilit\u00e0 di avviare progetti del genere frequentemente. Anche se \u00e8 un po' strano, perch\u00e9 adesso siamo in una continua trasformazione digitale e tutte devono avviare esperimenti per tenere il passo con i concorrenti.<\/em> <\/p>\n<p><\/p>\n<p>Qui ti trovi di fronte al fatto che devi prima avere una comprensione di ci\u00f2 che devi fare. Il mondo non \u00e8 perfetto, nemmeno l'ambiente di produzione \u00e8 perfetto. <\/p>\n<p><\/p>\n<p><em>S\u00ec, queste cose sono collegate.<\/em><\/p>\n<p><\/p>\n<p>Le aziende non hanno sempre chiara l'idea che debbano andare da qualche parte. <\/p>\n<p><\/p>\n<p><em>Esiste una situazione in cui non \u00e8 possibile apportare alcuna modifica. \u00c8 una situazione in cui la pressione sul team \u00e8 maggiore. Il team \u00e8 gi\u00e0 piuttosto bruciato. Non ha alcun margine di tempo per esperimenti. Lavorano dalla mattina alla sera su nuove funzionalit\u00e0. E il management sembra non essere mai soddisfatto delle funzionalit\u00e0. Serve sempre di pi\u00f9. In una tale situazione, non \u00e8 possibile effettuare alcun cambiamento. Al team possono solo dire di continuare a lavorare come ieri, ma con un numero leggermente maggiore di funzionalit\u00e0. Non \u00e8 possibile passare a pratiche diverse in questo senso. \u00c8 una situazione classica in cui non c'\u00e8 tempo per affilare l'ascia, bisogna abbattere gli alberi, di conseguenza si abbattono con un'ascia smussata. Qui non ci sono consigli facili.<\/em> <\/p>\n<p><\/p>\n<p><em>(Dmitriy) Legger\u00f2 un chiarimento dal chat: \u00abMa \u00e8 necessario avere una buona copertura di test a diversi livelli. Quanto tempo viene dedicato ai test? \u00c8 piuttosto costoso e richiede molto tempo\u00bb.<\/em><\/p>\n<p><\/p>\n<p><em>(Oleg) \u00c8 un comune errore. Devono esserci abbastanza test affinch\u00e9 tu stesso sia sicuro. L'integrazione continua non \u00e8 qualcosa dove prima fai il 100% dei test e poi inizi a mettere in pratica. L'integrazione continua riduce il tuo carico cognitivo poich\u00e9 ogni cambiamento che vedi \u00e8 talmente ovvio che capisci se romper\u00e0 qualcosa o meno, anche senza test. Puoi testarlo rapidamente nella tua testa perch\u00e9 le modifiche sono piccole. Anche se hai solo tester manuali, per loro \u00e8 pi\u00f9 semplice. Hai fatto il deployment e hai detto: \u00abGuarda, non si \u00e8 rotto niente?\u00bb. Loro controllano e dicono: \u00abNo, non si \u00e8 rotto niente\u00bb. Perch\u00e9 il tester sa dove guardare. Hai un commit legato a un singolo frammento di codice. E questo esplode in un comportamento specifico.<\/em><\/p>\n<p><\/p>\n<p>Qui hai, ovviamente, un po' esagerato. <\/p>\n<p><\/p>\n<p><em>(Dmitry) Su questo non sono d'accordo. Esiste una pratica \u2013 lo sviluppo attraverso il testing, che ti salver\u00e0 proprio da questo.<\/em> <\/p>\n<p><\/p>\n<p><em>(Oleg) Non ci sono ancora arrivato. La prima illusione \u00e8 che bisogna scrivere il 100% dei test o non occuparsi affatto dell'Integrazione Continua. Non \u00e8 vero. Sono due pratiche parallele e non dipendono direttamente l'una dall'altra. La copertura dei test dovrebbe essere ottimale. Ottimale significa che siete certi che la qualit\u00e0 del master, rimasta dopo il vostro commit, vi permetta di cliccare con fiducia sul pulsante 'Deploy' venerd\u00ec sera, anche se siete un po' brilli. Come si ottiene tutto ci\u00f2? Attraverso le recensioni, la copertura, e un buon monitoraggio.<\/em> <\/p>\n<p><\/p>\n<p><em>Un buon monitoraggio \u00e8 indistinguibile dai test. Se eseguite i test una sola volta in pre-prod, essi controllano tutti i vostri casi d'uso una sola volta e basta. Ma se li eseguite in un ciclo infinito, allora questo diventa il vostro sistema di monitoraggio attivo che testa continuamente \u2013 se \u00e8 andato gi\u00f9 o meno. In questo caso, la differenza sta solo nella singolarit\u00e0 o molteplicit\u00e0. Un insieme di test molto buono ..., eseguito all'infinito, \u00e8 monitoraggio. E il monitoraggio corretto dovrebbe essere proprio cos\u00ec.<\/em> <\/p>\n<p><\/p>\n<p><em>E quindi, come esattamente raggiungerai questo stato, quando venerd\u00ec sera ti deployi e vai a casa, \u00e8 un'altra questione. Forse sei semplicemente un audace trasgressore.<\/em> <\/p>\n<p><\/p>\n<p>Torniamo un attimo indietro all'Integrazione Continua. Ci siamo allontanati verso un'altra pratica complicata. <\/p>\n<p><\/p>\n<p><em>E la seconda illusione \u00e8 che il MVP, dicono, deve essere fatto in fretta, quindi non servono affatto test. Non \u00e8 proprio cos\u00ec. Il fatto \u00e8 che quando scrivi una user story per il MVP, puoi svilupparla in modo casuale, cio\u00e8 ascoltare che c'\u00e8 una user story e correre subito a codificarla, oppure lavorare secondo il TDD. E con il TDD, come dimostra la pratica, non ci si impiega di pi\u00f9, quindi i test sono un effetto collaterale. La pratica del TDD non riguarda il testare. Nonostante si chiami Sviluppo Guidato dai Test, qui non si parla affatto di test. \u00c8 piuttosto un approccio architettonico. \u00c8 un metodo per scrivere precisamente ci\u00f2 di cui hai bisogno e non scrivere ci\u00f2 che non ti serve. Questa pratica si concentra sulla prossima iterazione del tuo pensiero in termini di creazione dell'architettura dell'applicazione.<\/em> <\/p>\n<p><\/p>\n<p><em>Quindi non \u00e8 cos\u00ec facile liberarsi di queste illusioni. MVP e i test non si escludono a vicenda. Anzi, piuttosto il contrario: se realizzi un MVP seguendo la pratica TDD, lo farai meglio e pi\u00f9 velocemente che farlo senza alcuna pratica, e a casaccio.<\/em><\/p>\n<p><\/p>\n<p>\u00c8 un pensiero molto sottile e complesso. Quando senti dire che ora scriver\u00f2 pi\u00f9 test e nello stesso tempo far\u00f2 qualcosa pi\u00f9 velocemente, sembra assolutamente inadeguato. <\/p>\n<p><\/p>\n<p><em>(Dmitrij) Qui molti, quando parlano di MVP, sono semplicemente troppo pigri per scrivere qualcosa di decente. E queste sono comunque cose diverse. Non bisogna trasformare l'MVP in una cosa brutta che non funziona.<\/em> <\/p>\n<p><\/p>\n<p>S\u00ec-s\u00ec, hai ragione.<\/p>\n<p><\/p>\n<p><em>E poi, improvvisamente, MVP in prod.<\/em><\/p>\n<p><\/p>\n<p>Per sempre. <\/p>\n<p><\/p>\n<p>Il TDD pu\u00f2 sembrare insolito quando ascolti che stai scrivendo test e apparentemente stai facendo pi\u00f9 lavoro. Sembra strano, ma in realt\u00e0 consente di ottenere risultati pi\u00f9 rapidi e ordinati. Quando scrivi un test, nella tua mente stai gi\u00e0 pensando molto su quale codice e come verr\u00e0 chiamato, nonch\u00e9 quale comportamento ci aspettiamo da esso. Non stai solo dicendo che hai scritto una funzione e che fa qualcosa. Prima pensi che ha tali condizioni e che verr\u00e0 chiamata in un certo modo. Copri tutto questo con i test e di conseguenza comprendi come appariranno le interfacce all'interno del tuo codice. Questo influisce notevolmente sull'architettura. Il tuo codice diventa automaticamente pi\u00f9 modulare, perch\u00e9 cerchi prima di capire come lo testerai, e solo dopo lo scrivi. <\/p>\n<p><\/p>\n<p>Con TDD ho avuto un'esperienza in cui, a un certo punto, ho assunto un mentore per Ruby, mentre ero ancora un programmatore Ruby. E lui dice: \u00abFacciamo che tu faccia tutto con TDD\u00bb. E io pensavo: \u00abCavolo, adesso devo scrivere qualcosa di aggiuntivo\u00bb. Cos\u00ec abbiamo concordato che per due settimane scriverei tutto il codice funzionale in Python seguendo TDD. Dopo due settimane ho capito che non volevo tornare indietro. Dopo aver cercato di applicarlo ovunque per due settimane, ho realizzato quanto fosse pi\u00f9 semplice anche solo pensare. Ma non \u00e8 ovvio, quindi consiglio a tutti che, se avete la sensazione che TDD sia complicato, lungo e superfluo, provate a seguirlo per sole due settimane. A me sono bastate due per capirlo.<\/p>\n<p><\/p>\n<p><em>(Dmitry) Possiamo sviluppare questo concetto dal punto di vista dell'operativit\u00e0 dell'infrastruttura. Prima di lanciare qualcosa di nuovo, effettuamo un monitoraggio, per poi avviarlo. In questo caso, il monitoraggio diventa un test normale. E c'\u00e8 uno sviluppo attraverso il monitoraggio. Ma quasi tutti dicono che \u00e8 lungo, mi scoccia, ho fatto un bozzetto temporaneo. Se facciamo un monitoraggio corretto, capiamo lo stato del sistema CI. E nel sistema CI c'\u00e8 molto monitoraggio. Comprendiamo lo stato del sistema, capiamo cosa c'\u00e8 all'interno. E durante lo sviluppo, stiamo proprio creando un sistema che raggiunga lo stato desiderato.<\/em> <\/p>\n<p><\/p>\n<p><em>Queste pratiche sono conosciute da tempo. Ne abbiamo parlato circa 4 anni fa. Ma in 4 anni praticamente non \u00e8 cambiato nulla.<\/em> <\/p>\n<p><\/p>\n<p><em>Ma su questa nota propongo di concludere la discussione ufficiale.<\/em><\/p>\n<p><\/p>\n<p>Video (inserito come elemento multimediale, ma chiss\u00e0 per quale motivo non funziona):<\/p>\n<p>\n<noindex><a rel=\"nofollow\" href=\"https:\/\/youtu.be\/zZ3qXVN3Oic\">https:\/\/youtu.be\/zZ3qXVN3Oic<\/a><\/noindex><br \/>\n<br \/>Fonte: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/post\/518406\/\">habr.com<\/a> <\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041e\u0431\u0441\u0443\u0434\u0438\u043c \u043f\u043e\u0447\u0435\u043c\u0443 CI-\u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0438 CI \u2013 \u044d\u0442\u043e \u0441\u043e\u0432\u0441\u0435\u043c \u043f\u0440\u043e \u0440\u0430\u0437\u043d\u043e\u0435. \u041a\u0430\u043a\u0443\u044e \u0431\u043e\u043b\u044c CI \u043f\u0440\u0438\u0437\u0432\u0430\u043d\u043e \u0440\u0435\u0448\u0438\u0442\u044c, \u043e\u0442\u043a\u0443\u0434\u0430 \u0432\u043e\u0437\u043d\u0438\u043a\u043b\u0430 \u0438\u0434\u0435\u044f, \u043a\u0430\u043a\u0438\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f \u0447\u0442\u043e \u043e\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043a\u0430\u043a \u043f\u043e\u043d\u044f\u0442\u044c \u0447\u0442\u043e \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u0438\u043c\u0435\u043d\u043d\u043e \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430, \u0430 \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0439 Jenkins. \u041c\u044b\u0441\u043b\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043e\u043a\u043b\u0430\u0434 \u043f\u0440\u043e Continuous Integration \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u0435\u0449\u0435 \u0433\u043e\u0434 \u043d\u0430\u0437\u0430\u0434, \u043a\u043e\u0433\u0434\u0430 \u044f \u0445\u043e\u0434\u0438\u043b \u043f\u043e \u0441\u043e\u0431\u0435\u0441\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f\u043c \u0438\u0441\u043a\u0430\u043b \u0440\u0430\u0431\u043e\u0442\u0443. \u041f\u043e\u043e\u0431\u0449\u0430\u043b\u0441\u044f [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":93886,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-93885","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 4.9.10 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041e\u0431\u0441\u0443\u0434\u0438\u043c \u043f\u043e\u0447\u0435\u043c\u0443 CI-\u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0438 CI \u2013 \u044d\u0442\u043e \u0441\u043e\u0432\u0441\u0435\u043c \u043f\u0440\u043e \u0440\u0430\u0437\u043d\u043e\u0435. \u041a\u0430\u043a\u0443\u044e \u0431\u043e\u043b\u044c CI \u043f\u0440\u0438\u0437\u0432\u0430\u043d\u043e \u0440\u0435\u0448\u0438\u0442\u044c, \u043e\u0442\u043a\u0443\u0434\u0430 \u0432\u043e\u0437\u043d\u0438\u043a\u043b\u0430 \u0438\u0434\u0435\u044f, \u043a\u0430\u043a\u0438\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f \u0447\u0442\u043e \u043e\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043a\u0430\u043a \u043f\u043e\u043d\u044f\u0442\u044c \u0447\u0442\u043e \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u0438\u043c\u0435\u043d\u043d\u043e \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430, \u0430 \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0439 Jenkins. \u041c\u044b\u0441\u043b\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043e\u043a\u043b\u0430\u0434 \u043f\u0440\u043e Continuous Integration \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u0435\u0449\u0435 \u0433\u043e\u0434 \u043d\u0430\u0437\u0430\u0434, \u043a\u043e\u0433\u0434\u0430 \u044f \u0445\u043e\u0434\u0438\u043b \u043f\u043e \u0441\u043e\u0431\u0435\u0441\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f\u043c \u0438\u0441\u043a\u0430\u043b \u0440\u0430\u0431\u043e\u0442\u0443. \u041f\u043e\u043e\u0431\u0449\u0430\u043b\u0441\u044f\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/continuous-integration-kak-praktika-a-ne-jenkins-andrej-aleksandrov\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 4.9.10\" \/>\n\t\t<meta property=\"og:locale\" content=\"it_IT\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47Continuous Integration \u043a\u0430\u043a \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430, \u0430 \u043d\u0435 Jenkins. \u0410\u043d\u0434\u0440\u0435\u0439 \u0410\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440\u043e\u0432 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041e\u0431\u0441\u0443\u0434\u0438\u043c \u043f\u043e\u0447\u0435\u043c\u0443 CI-\u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0438 CI \u2013 \u044d\u0442\u043e \u0441\u043e\u0432\u0441\u0435\u043c \u043f\u0440\u043e \u0440\u0430\u0437\u043d\u043e\u0435. \u041a\u0430\u043a\u0443\u044e \u0431\u043e\u043b\u044c CI \u043f\u0440\u0438\u0437\u0432\u0430\u043d\u043e \u0440\u0435\u0448\u0438\u0442\u044c, \u043e\u0442\u043a\u0443\u0434\u0430 \u0432\u043e\u0437\u043d\u0438\u043a\u043b\u0430 \u0438\u0434\u0435\u044f, \u043a\u0430\u043a\u0438\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f \u0447\u0442\u043e \u043e\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043a\u0430\u043a \u043f\u043e\u043d\u044f\u0442\u044c \u0447\u0442\u043e \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u0438\u043c\u0435\u043d\u043d\u043e \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430, \u0430 \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0439 Jenkins. \u041c\u044b\u0441\u043b\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043e\u043a\u043b\u0430\u0434 \u043f\u0440\u043e Continuous Integration \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u0435\u0449\u0435 \u0433\u043e\u0434 \u043d\u0430\u0437\u0430\u0434, \u043a\u043e\u0433\u0434\u0430 \u044f \u0445\u043e\u0434\u0438\u043b \u043f\u043e \u0441\u043e\u0431\u0435\u0441\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f\u043c \u0438\u0441\u043a\u0430\u043b \u0440\u0430\u0431\u043e\u0442\u0443. \u041f\u043e\u043e\u0431\u0449\u0430\u043b\u0441\u044f\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/continuous-integration-kak-praktika-a-ne-jenkins-andrej-aleksandrov\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2020-09-10T17:42:23+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2020-09-10T17:42:23+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47Continuous Integration come pratica, non Jenkins. Andrey Alexandrov | ProHoster","description":"Discutiamo perch\u00e9 gli strumenti CI e CI sono due cose completamente diverse. Quale problema il CI \u00e8 destinato a risolvere, da dove \u00e8 nata l'idea, quali sono le ultime conferme che funziona, come capire se hai una vera pratica e non semplicemente un Jenkins installato. L'idea di fare una presentazione su Continuous Integration \u00e8 emersa un anno fa, quando andavo ai colloqui per cercare lavoro. Ho parlato","canonical_url":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/continuous-integration-kak-praktika-a-ne-jenkins-andrej-aleksandrov","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"it_IT","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47Continuous Integration \u043a\u0430\u043a \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430, \u0430 \u043d\u0435 Jenkins. \u0410\u043d\u0434\u0440\u0435\u0439 \u0410\u043b\u0435\u043a\u0441\u0430\u043d\u0434\u0440\u043e\u0432 | ProHoster","og:description":"\u041e\u0431\u0441\u0443\u0434\u0438\u043c \u043f\u043e\u0447\u0435\u043c\u0443 CI-\u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0438 CI \u2013 \u044d\u0442\u043e \u0441\u043e\u0432\u0441\u0435\u043c \u043f\u0440\u043e \u0440\u0430\u0437\u043d\u043e\u0435. \u041a\u0430\u043a\u0443\u044e \u0431\u043e\u043b\u044c CI \u043f\u0440\u0438\u0437\u0432\u0430\u043d\u043e \u0440\u0435\u0448\u0438\u0442\u044c, \u043e\u0442\u043a\u0443\u0434\u0430 \u0432\u043e\u0437\u043d\u0438\u043a\u043b\u0430 \u0438\u0434\u0435\u044f, \u043a\u0430\u043a\u0438\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0435 \u043f\u043e\u0434\u0442\u0432\u0435\u0440\u0436\u0434\u0435\u043d\u0438\u044f \u0447\u0442\u043e \u043e\u043d\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043a\u0430\u043a \u043f\u043e\u043d\u044f\u0442\u044c \u0447\u0442\u043e \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u0438\u043c\u0435\u043d\u043d\u043e \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430, \u0430 \u043d\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u043d\u044b\u0439 Jenkins. \u041c\u044b\u0441\u043b\u044c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043e\u043a\u043b\u0430\u0434 \u043f\u0440\u043e Continuous Integration \u043f\u043e\u044f\u0432\u0438\u043b\u0430\u0441\u044c \u0435\u0449\u0435 \u0433\u043e\u0434 \u043d\u0430\u0437\u0430\u0434, \u043a\u043e\u0433\u0434\u0430 \u044f \u0445\u043e\u0434\u0438\u043b \u043f\u043e \u0441\u043e\u0431\u0435\u0441\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u044f\u043c \u0438\u0441\u043a\u0430\u043b \u0440\u0430\u0431\u043e\u0442\u0443. \u041f\u043e\u043e\u0431\u0449\u0430\u043b\u0441\u044f","og:url":"https:\/\/prohoster.info\/it\/blog\/administrirovanie\/continuous-integration-kak-praktika-a-ne-jenkins-andrej-aleksandrov","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2020-09-10T17:42:23+00:00","article:modified_time":"2020-09-10T17:42:23+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"93885","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":null,"breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-02-28 11:37:31","updated":"2022-09-27 15:57:30"},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/93885","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/comments?post=93885"}],"version-history":[{"count":0,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/posts\/93885\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media\/93886"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/media?parent=93885"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/categories?post=93885"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/it\/wp-json\/wp\/v2\/tags?post=93885"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}