Per facilitare lo sviluppo tra i progetti, il team che sviluppa la Webmail Infomaniak ha raggruppato il codice delle applicazioni in un unico repository (monorepo). L’obiettivo è migliorare i processi di aggiornamento, facilitare la collaborazione e accelerare lo sviluppo dell’ecosistema. La Webmail è un progetto pilota su larga scala con più applicazioni interconnesse (kDrive, Mail, Calendar, Contacts) e oltre 1 milione di utenti giornalieri. I nostri sviluppatori raccontano questa transizione, i suoi vantaggi, le sfide e anche gli impatti negativi.

La performance delle nostre soluzioni la cercheremo anche nella nostra organizzazione e nei nostri processi. Julien Arnoux, VP of Engineering presso Infomaniak

Perché passare a un’architettura monorepo?

Il ciclo di vita della Webmail richiede l’adattamento della nostra strategia di repository del codice. Finora, le varie parti (progetti, librerie) della Webmail erano sviluppate in repository di codice separati. Un team stava sviluppando il codice di una libreria per il proprio progetto in modo autonomo, senza trasferire in tempo reale le modifiche della versione ad altri progetti in corso. Il follow-up stava diventando complesso:

“Gli sviluppatori che stavano lavorando su modifiche trasversali dovevano sistematicamente individuare e allineare le versioni di ogni libreria e progetto modificati manualmente. Questo poteva comportare molte manipolazioni. L’idea era quella di liberarsi da tutti questi passaggi intermedi per concentrarsi sullo sviluppo vero e proprio.” Zachary Volpi, sviluppatore Webmail presso Infomaniak

I progetti potevano anche desincronizzarsi se un team aveva un ciclo di pubblicazione più veloce di quello delle altre librerie dipendenti. La pesantezza delle operazioni di pubblicazione e aggiornamento manuali in multirepo aumentava inoltre il numero di manipolazioni tediose e il rischio di errori a scapito della creazione di valore. 

I benefici dell’architettura monorepo

Grazie a questa nuova base, il nostro approccio DevOps sta diventando più efficiente. I cicli automatizzati consentono di compilare, testare e distribuire codice senza errori (in particolare lo spettro degli errori umani). Questi progressi consentono di semplificare tutte le fasi di fornitura delle applicazioni.

1. Condivisione e convalida del codice semplificato 

Con un’architettura monorepo, le versioni del codice sorgente sono condivise tra tutte le parti del progetto. Una sola modifica ha effetto ovunque senza rischiare di rompere le funzionalità adiacenti. Non è più necessario puntare alla versione appropriata per ogni dipendenza. I nostri script rilevano i progetti collegati da un aggiornamento e avviano i processi di convalida associati alle aree modificate.

2. Gestione semplificata dei processi DevOps

La centralizzazione del codice consente di creare pipelines per l’intero progetto con un enorme risparmio di tempo. Le nostre pipeline di integrazione continua (CI) e di consegna continua (CD) diventano più rigorose con processi collaudati, predittivi e ripetibili. Tutto ciò, facilita l’aggiunta di nuove porzioni di codice.

Ora possiamo accoppiare le pipeline in base allo stage (build, test, deployment). I processi vengono lanciati in parallelo, cosa che era impossibile o fortemente vincolata in multirepo. Dato che ogni set di test è comune, lo sviluppo delle funzionalità che interessano più applicazioni è molto più veloce.

3. Collaborazione facilitata e migliore visione d’insieme

Gli sviluppatori possono recuperare e integrare tutte le modifiche in corso, rafforzando la comprensione generale. Non è più necessario esaminare più progetti per individuare problemi nascosti, è tutto a portata di mano. Modifichiamo e testiamo in tempi rapidi, abbreviando il ciclo di convalida. Cambiare contesto è anche più facile: uno sviluppatore che lavora a più progetti o che deve integrare il lavoro di un collega può confrontare le differenze molto più velocemente.

4. Miglioramento della qualità del codice

Non abbiamo più bisogno di duplicare, inserire una libreria in un progetto principale e andare continuamente avanti e indietro. Avere tutto il codice a portata di mano consente di identificare i problemi più velocemente. Possiamo anche alleggerire il peso delle applicazioni eliminando il codice morto senza temere che venga utilizzato altrove. Condividere lo stesso ambiente riduce le divergenze tra i team.

Quando modifichiamo una libreria, prima vengono effettuate queste verifiche: il codice è conforme alle norme vigenti? Funziona come previsto? Quindi eseguiamo i test delle applicazioni che lo utilizzano per convalidare la sua corretta integrazione. Si tratta di un approccio a cipolla (a strati), passando dai test più semplici (unitari) a quelli più complessi (end-to-end).

5. Accelerazione dello sviluppo

Il monorepo facilita l’uscita regolare di nuove funzionalità. Recuperiamo le modifiche degli altri sviluppatori molto più velocemente. Con l’automazione dei processi, la produzione diventa più fluida. Con l’accelerazione del ciclo di feedback, possiamo iterare più velocemente.

Passare al monorepo: che cosa cambia?

Non c’è niente di meglio di uno schema che illustri l’impatto del monorepo sulla nostra organizzazione:

Miglioramento che richiede diverse modifiche alle varie librerie utilizzate nel progetto:

Con il monorepo:

Configurazione del monorepo in un ambiente di produzione

Volevamo rendere la transizione completamente trasparente per i nostri clienti e quasi trasparente per i collaboratori che stavano lavorando al progetto. 

“A differenza di un progetto nascente, modificare l’organizzazione del codice della Webmail ha comportato enormi conseguenze, poiché l’applicazione è in produzione. È come aprire un cantiere su una strada principale.” Zachary Volpi, sviluppatore Webmail presso Infomaniak 

È stato necessario suddividere la transizione in più passaggi per evitare modifiche troppo grandi che avrebbero potuto causare un’indisponibilità del servizio senza possibilità di tornare indietro. Abbiamo quindi svolto un lungo lavoro di preparazione e convalida:

  • Suddivisione della migrazione in più fasi integrando il potenziale impatto per i colleghi.
  • Test di ogni passaggio a monte, ove possibile.
  • Dettaglio di ogni passaggio con un elenco di attività “pronto per l’uso” per il grande giorno.
  • Pianificazione delle tappe della migrazione nei periodi di bassa affluenza.
  • Simulazione di scenari di crisi per anticipare i problemi e prevedere le azioni da attuare.

Il nostro team ha anche elaborato delle procedure di documentazione degli incidenti per consentire di fare marcia indietro in una certa misura.

La scelta del PHP

Ciò che è DevOps è spesso scritto in bash o in python, raramente in PHP. Le pipeline DevOps che avremmo messo in atto dovevano essere comprensibili a tutti i nostri colleghi. Anche le nostre applicazioni sono scritte in PHP ed è del tutto possibile utilizzarlo per lo scripting. Inoltre, avevamo già anche degli ambienti di esecuzione configurati e disponibili per ulteriori passaggi. Era quindi più facile riutilizzarli direttamente piuttosto che partire da fogli bianchi.

Trovare il giusto ritmo di transizione

Non dovevamo rimanere in fasi di transizione prolungate. Ogni attività doveva quindi svolgersi in un intervallo sufficientemente lungo da garantire la sicurezza e la stabilità, ma relativamente breve per non creare fragilità nel sistema.

Le principali sfide della migrazione

Una migrazione senza ritorno

Questa procedura ha avuto un impatto sull’intero workflow (strutturazione dei passaggi, estrazione delle porzioni comuni, posizione dei file, cronologia delle modifiche) e su tutti gli ambienti di lavoro del team Webmail (ambiente di produzione, sviluppo, test, release di pacchetti, notifiche, ecc.). Era quindi importante che la fase di transizione non durasse troppo a lungo.

In multirepo, ogni modifica su un componente richiede l’adattamento e la verifica manuale di ogni sua dipendenza. In monorepo, quasi tutto è automatizzato: non appena un componente viene modificato, l’intero sistema si aggiorna automaticamente. È un po’ come passare dal cambio manuale a quello automatico in un’auto. È tutto più semplice! Julien Arnoux, VP of Engineering presso Infomaniak

Pensare e anticipare tutti gli scenari

È paradossale, ma è stato necessario passare attraverso una grande complessità per semplificare tutto. Centralizzare il codice significa ripensare tutto. Per definire le logiche di attivazione delle pipeline, dovevamo comprenderne l’impatto su ogni progetto e sviluppare il rilevamento del contesto correlato, per:

  • gli stage (Continuous Integration + Continuous Development)
  • i processi comuni alle app e alle librerie
  • i diversi stages di build
  • Esecuzione dei test e delle convalide delle parti interessate

La difficoltà principale era che non potevamo testare tutte le fasi in condizioni reali, in particolare quelle relative all’ambiente di produzione. Grazie alle possibilità di concentrazione delle definizioni di gitlab-ci, siamo stati in grado di separare i nostri diversi script per tema e area di impatto. Questo ha ridotto drasticamente la duplicazione di file e altri problemi di copia e incolla.

Esito: monorepo o multirepo? 

È stata una buona idea passare a monorepo? La risposta è sì.

Questa nuova organizzazione porta grandi vantaggi:

  • Recupero semplificato delle modifiche.
  • Condivisione della configurazione di alcuni strumenti.
  • Riduzione della gestione in caso di modifiche su più applicazioni.
  • Semplificazione dello sviluppo: tutto è disponibile in un unico posto ed è molto più facile navigare tra le aree.

Questa evoluzione ha anche degli impatti negativi:

  • È meno facile orientarsi che in un repository classico. La curva di apprendimento di un nuovo arrivato è un po’ più lunga.
  • È necessaria una buona conoscenza degli strumenti CI/CD, in particolare gitlab-ci, per apportare modifiche alle pipeline.

Gli sviluppatori che hanno gestito il passaggio al monorepo

Julien Arnoux, VP of Engineering presso Infomaniak (ma sempre pronto a sporcarsi le mani):

Mi occupo di sviluppo da quando ho 15 anni e mi piace tutto ciò che riguarda l’automazione dei nostri workflow. Quando svolgo attività di sviluppo, a seconda dell’umore, posso ascoltare sia l’hard-rock/metal che il drum’n’bass. A dire il vero, ascolto un po’ di tutto, ma questi due generi mi danno energia 😅

Zachary Volpi, sviluppatore full stack all’interno del team Webmail:

Mi occupo di sviluppo dall’agosto 2014. Mi piace avere la visione (e la comprensione) di tutti gli aspetti dello sviluppo dell’applicazione. Cerco sempre soluzioni per semplificare un processo o ottenere maggiori prestazioni. Per accompagnare le mie sessioni, adatto la musica in base a ciò che voglio fare: dal chill al dub o al metal. Per quanto riguarda i riferimenti, trovo il blog di logrocket molto pertinente. Hanno articoli molto ben concepiti su argomenti molto ampi e specifici. Altrimenti, seguo direttamente i canali degli strumenti che uso (principalmente su X & LinkedIn).

Anche tu dovresti utilizzare un’architettura monorepo?

Vieni a parlare con i nostri sviluppatori su X.