La regola che evita la maggior parte dei guai su Odoo.sh sta in una frase: nulla arriva in produzione senza una build verde su una copia reale del database del cliente, con lo stesso commit che stai per fondere. La documentazione spiega la piattaforma, non il flusso di un partner. Ecco il nostro.
Questo articolo amplia e sostituisce Odoo.sh per ecommerce; il riepilogo per i negozi online è in fondo.
Tre fasi, e cosa fa davvero ciascuna
Odoo.sh ha tre fasi: produzione (un solo ramo), staging e sviluppo. La differenza sta nel database da cui parte ogni build:
- Sviluppo: database nuovo con demo, installa i moduli del ramo ed esegue i test; dura circa tre giorni. È l'unica fase che testa: i test dipendono dalla demo.
- Staging: la build duplica il database di produzione e lo neutralizza. La copia viene eliminata dopo un mese.
- Produzione: il push riavvia il server; se hai alzato la versione del modulo in
__manifest__.py, esegue l'update (equivale a-u) e l'istanza resta in manutenzione. Se fallisce, torna alla revisione precedente e ripristina il database.
Da qui la conseguenza che quasi nessuno legge: il merge porta il codice, mai ciò che hai toccato a mano nel database di staging. Ciò che vuoi che arrivi va nell'XML del modulo, con la versione alzata.
Struttura dei rami per un partner
Con un solo cliente bastano dev, staging e produzione. Con più clienti: un ramo di sviluppo per attività; uno di staging per cliente e consegna, ricostruito prima di ogni validazione; l'unico di produzione che impone Odoo.sh; e, se il modulo va sull'App Store di Odoo, uno per versione di Odoo.
Nel nostro repository ci sono oggi 144 rami, tra cui 17.0, 18.0, 19.0 e production: 41 hanno il suffisso -17, -18 o -19 (un connettore, una versione) e 19 sono production-pre-<cambio>-<fecha>: il commit che girava in produzione prima di ogni rilascio delicato. Tornare indietro è un push.
Trappola verificata: un ramo creato da git viene costruito con la versione predefinita del progetto, non con quella del ramo da cui lo biforchi. Abbiamo biforcato un -17 da 17.0 e Odoo.sh lo ha costruito come 19.0: il manifest 17.0.x è risultato non installabile. La versione si assegna nelle impostazioni, e solo sui rami di sviluppo.
La build come porta: cosa verifica e cosa no
Una build è verde (senza errori né avvisi), gialla (avvisi) o rossa (errori); si consegna solo se è verde. Una build di sviluppo verifica che i moduli del ramo si installino su un database pulito con demo e che i loro test passino. Ciò che non verifica:
- I moduli fuori dal ramo. Per impostazione predefinita installa solo i tuoi, senza sottomoduli. Nelle impostazioni: installazione completa (sottomoduli e tutti quelli standard, ma senza test) oppure un elenco di nomi tecnici separati da virgole, che è l'opzione utile.
- L'upgrade. Installa da zero; non esegue mai
-usu un database con uno storico. - I dati reali. Quello è lo staging, che non esegue test.
Per questo la porta ha due ante: la build di sviluppo esegue test che installano, non solo unitari; e il ramo di staging esegue l'upgrade reale sulla copia di produzione, leggendo update.log fino in fondo. Guarda la riga 0 failed, 0 error(s) of N tests con N maggiore di zero: un verde con zero test è vuoto. Altre cause, in un modulo di Odoo 19 compila ma non si installa.
Staging con dati: cosa risolve la copia e cosa no
La neutralizzazione risolve ciò che è pericoloso: non partono e-mail (si vedono nella scheda Mails), non girano le azioni pianificate, gli IAP restano fuori, vettori e gateway di pagamento vanno in modalità test, e neutralize.log dice cosa è stato spento. Ciò che non risolve:
- L'anonimizzazione resta a tuo carico. Spegne i processi, non cancella i dati personali. Se il team non deve vedere i dati del cliente: Developer non accede né a staging né a produzione, Tester accede allo staging e solo Admin alla produzione.
- Le credenziali delle API esterne viaggiano nella copia. Un connettore in staging con le chiavi di produzione parla con Amazon o Mirakl come se fosse in produzione: attiva la sua modalità sandbox o svuota le chiavi.
- Il database di staging non si aggiorna da solo. Per impostazione predefinita il ramo aggiorna la build precedente e il database sopravvive tra un push e l'altro, con i dati già modificati; con New build, ogni push parte da una copia fresca. I cron si lanciano a mano, e i backup manuali durano tre giorni, con un massimo di cinque al giorno.
SSH e psql in produzione: cosa si tocca e cosa no
Odoo.sh dà una shell sulla produzione. Entriamo per leggere (psql, lnav ~/logs/odoo.log), diagnosticare con odoo-bin shell ed eseguire la suite di un modulo in modalità transazionale. Ciò che non si fa: un UPDATE a mano né installare moduli saltando la build. Dettagli che costano un pomeriggio: scp e sftp sono bloccati, il ruolo di Postgres non può creare database e i moduli propri vivono sotto ~/src/user. Un sollievo: odoo-bin shell fa rollback all'uscita nelle versioni 17, 18 e 19 (odoo/cli/shell.py).
Upgrade in produzione: noupdate, base.group_system e migrazioni
Un upgrade si innesca alzando la versione nel manifest; Odoo.sh crea un backup contrassegnato come Update (anche se cambia requirements.txt) ed esegue il -u. Qui vive la trappola più costosa che abbiamo incontrato. L'idioma abituale per far ereditare all'amministratore il tuo gruppo è:
<record id="base.group_system" model="res.groups">
<field name="implied_ids" eval="[(4, ref('group_mi_manager'))]"/>
</record>Funziona su un'installazione nuova e in un upgrade viene ignorato in silenzio. Il motivo sta nel database del cliente: noupdate vive nella riga di ir_model_data. Durante l'aggiornamento, il caricatore riscrive solo il record if not (update and d_noupdate) (odoo/orm/models.py nella 19, odoo/models.py nella 17 e 18), e l'upsert che mantiene quella tabella aggiorna modello e res_id ma mai la colonna noupdate: una volta impostata, non si toglie. E non si deduce dall'addon: in tutte e tre le versioni il record di base.group_system è in un <data> senza noupdate e può comunque arrivare contrassegnato:
select name, noupdate from ir_model_data
where module='base' and name in ('group_system','group_user');Nella nostra produzione su Odoo.sh restituisce t in entrambe; nei 69 database che il nostro banco di prova ha creato da zero, group_user risulta t e group_system, f. Lo stesso XML, due risultati.
È successo nel nostro connettore Mirakl 16.15.0: le credenziali sono passate a un gruppo «Mirakl Manager». Nelle installazioni nuove l'amministratore lo ereditava; in quelle aggiornate il gruppo è rimasto senza membri e nessuno poteva toccare le chiavi. I test erano verdi perché un'installazione pulita applica il record. La correzione, nella 16.15.1: lasciare l'XML e aggiungere migrations/19.0.16.15.1/post-migrate.py, che scrive l'implicazione in SQL su res_groups_implied_rel e res_groups_users_rel con ON CONFLICT DO NOTHING, più un test che fallisce se il gruppo resta vuoto.
Le migrazioni: cartella migrations/<versión>/ con file pre-*.py, post-*.py e end-*.py, ciascuno con migrate(cr, version), dove version è la versione che era installata. Odoo le esegue solo quando il modulo è contrassegnato per l'aggiornamento: in un'installazione nuova non ne gira nessuna, per questo serve l'XML. Se cambia la versione maggiore, il processo è un altro: errori di migrazione a Odoo 19 e la checklist di go-live.
Trappole che non compaiono nella documentazione
- Build che si addormentano. Una build di sviluppo non usata va in ibernazione e i suoi cron non girano. Se la usi come banco di prova, tienila sveglia: abbiamo un agente di launchd che ogni 240 secondi esegue
curl /web/healthessh -n … truesu ogni build. - La build che convalidi può essere quella vecchia. L'identificativo cambia a ogni push e il precedente impiega tempo a essere riciclato: via SSH ne convivono due. Prima di dare qualcosa per buono, esegui
grepdi ciò che hai appena modificato in~/src/user. - La serie del manifest fallisce in modo diverso a seconda del verso. Nella 19, un manifest
18.0.xo17.0.xnon esplode: il server avvisa has an incompatible version, setting installable=False. Al contrario, nella 17 o nella 18, un19.0.x.y.zinterrompe la lettura con invalid manifest.
Checklist di consegna al cliente
- Build verde (non gialla) in sviluppo, con test che installano e N maggiore di zero.
- Staging ricostruito oggi dalla produzione; credenziali esterne in sandbox o vuote.
- Versione alzata nel manifest e
update.logletto fino in fondo, migrazioni incluse. - Validazione del cliente in staging, con i cron lanciati a mano e le e-mail controllate in Mails.
- Ramo
production-pre-<cambio>-<fecha>dal commit che gira in produzione, e backup manuale se si toccano dati. - Merge fuori dalle ore di punta e, dopo,
odoo.log, il gruppo di permessi con membri e i cron attivi.
Offriamo questo flusso come ingegneria Odoo per società di consulenza e lo usiamo in ogni implementazione e migrazione a Odoo 19. Se sei un partner o una software house, il programma di partner tecnologici spiega come lavoriamo.
Se quello che hai è un ecommerce
Toccare un connettore di marketplace o una regola di giacenza in produzione significa giocare con ordini reali: etichette duplicate, ordini importati due volte, sincronizzazioni a metà. Su staging passano i moduli nuovi, le modifiche di giacenza e gli aggiornamenti dei connettori (Amazon, Mirakl, ManoMano, SEUR, MRW, Correos Express), e lì vettori e gateway di pagamento vanno in modalità test: è il posto dove provare un'etichetta senza che parta il furgone.
Domande frequenti
Odoo.sh esegue i test in staging o in produzione?
No. Solo nelle build di sviluppo, su un database nuovo con demo. Lo staging valida con dati reali senza test; la produzione non carica la demo né testa.
Una build verde garantisce che il modulo si installi nell'Odoo del cliente?
Garantisce che si installa su un database pulito di quella versione. Non garantisce l'upgrade su un database con storico né la convivenza con moduli estranei al ramo: questo si copre nello staging del cliente.
Link utili su FlexigoTech
Cosa facciamo su questo
Consegni progetti su Odoo.sh e vuoi un banco di prova che non dipenda dalla fortuna?
Configuriamo il flusso di rami, la build come porta e le migrazioni per i tuoi clienti, oppure rivediamo quello che hai già. Scrivi a comercial@flexigobe.com o chiama il +34 616 809 504.

