A regra que evita a maioria dos sustos no Odoo.sh cabe numa frase: nada chega à produção sem um build verde sobre uma cópia real da base de dados do cliente, com o mesmo commit que vai ser integrado. A documentação explica a plataforma, não o fluxo de um partner. Aqui está o nosso.
Este artigo amplia e substitui o Odoo.sh para ecommerce; o resumo para lojas está no final.
Três etapas, e o que cada uma faz de verdade
O Odoo.sh tem três etapas: produção (um único ramo), staging e desenvolvimento. A diferença está na base com que arranca cada build:
- Desenvolvimento: base nova com demo, instala os módulos do ramo e executa os testes; dura cerca de três dias. É a única etapa que testa: os testes dependem da demo.
- Staging: o build duplica a base de produção e neutraliza-a. A cópia é apagada ao fim de um mês.
- Produção: o push reinicia o servidor; se tiver subido a versão do módulo em
__manifest__.py, executa o update (equivale a-u) e a instância fica em manutenção. Se falhar, reverte para a revisão anterior e restaura a base.
Daí a consequência que quase ninguém lê: integrar leva o código, nunca o que alterou à mão na base de staging. O que quiser que chegue vai em XML do módulo, com a versão subida.
Estrutura de ramos para um partner
Com um só cliente bastam dev, staging e produção. Com vários: um ramo de desenvolvimento por tarefa; um de staging por cliente e entrega, reconstruído antes de cada validação; o único de produção que o Odoo.sh impõe; e, se o módulo for para a App Store, um por versão do Odoo.
No nosso repositório há hoje 144 ramos, entre eles 17.0, 18.0, 19.0 e production: 41 têm o sufixo -17, -18 ou -19 (um conector, uma versão) e 19 são production-pre-<cambio>-<fecha>: o commit que corria em produção antes de cada implementação delicada. Voltar atrás é um push.
Armadilha comprovada: um ramo criado pelo git é construído com a versão por defeito do projeto, não com a do ramo de que bifurca. Bifurcámos um -17 a partir de 17.0 e o Odoo.sh construiu-o como 19.0: o manifest 17.0.x ficou como não instalável. A versão atribui-se nas definições, e só em ramos de desenvolvimento.
O build como porta: o que verifica e o que não verifica
Um build é verde (sem erros nem avisos), amarelo (avisos) ou vermelho (erros); só o verde se entrega. Um de desenvolvimento verifica que os módulos do ramo se instalam numa base limpa com demo e que os seus testes passam. O que não verifica:
- Módulos fora do ramo. Por defeito instala só os seus, sem submódulos. Nas definições: instalação completa (submódulos e todos os standard, mas sem testes) ou uma lista de nomes técnicos separados por vírgulas, que é a útil.
- O upgrade. Instala de raiz; nunca executa
-usobre uma base com histórico. - Os dados reais. Isso é o staging, que não executa testes.
Por isso a porta tem duas folhas: o build de desenvolvimento executa testes que instalam, não apenas unitários; e o ramo de staging executa o upgrade real sobre a cópia de produção, lendo update.log até ao fim. Veja a linha 0 failed, 0 error(s) of N tests com N maior que zero: um verde com zero testes está vazio. Mais causas, em um módulo do Odoo 19 compila mas não se instala.
Staging com dados: o que resolve a cópia e o que não resolve
A neutralização resolve o que é perigoso: não saem e-mails (vêem-se no separador Mails), não correm as ações agendadas, os IAP ficam de fora, as transportadoras e os gateways de pagamento ficam em modo de teste, e neutralize.log diz o que foi desligado. O que não resolve:
- Anonimizar continua a ser consigo. Desliga processos, não apaga dados pessoais. Se a equipa não deve ver dados do cliente: Developer não acede nem ao staging nem à produção, Tester acede ao staging e só Admin à produção.
- As credenciais de APIs externas viajam na cópia. Um conector em staging com as chaves de produção fala com a Amazon ou o Mirakl como se fosse o de produção: ative o seu modo sandbox ou esvazie as chaves.
- A base de staging não se atualiza sozinha. Por defeito o ramo atualiza o build anterior e a base sobrevive entre pushes, com os dados já alterados; com New build, cada push parte de uma cópia nova. Os crons disparam-se à mão, e os backups manuais duram três dias, com um limite de cinco por dia.
SSH e psql em produção: o que se toca e o que não se toca
O Odoo.sh dá shell à produção. Entramos para ler (psql, lnav ~/logs/odoo.log), diagnosticar com odoo-bin shell e executar a suite de um módulo em modo transacional. O que não se faz: um UPDATE à mão nem instalar módulos saltando o build. Detalhes que custam uma tarde: scp e sftp estão bloqueados, o role do Postgres não pode criar bases e os módulos próprios vivem em ~/src/user. Um alívio: odoo-bin shell faz rollback ao sair nas versões 17, 18 e 19 (odoo/cli/shell.py).
Upgrade em produção: noupdate, base.group_system e migrações
Um upgrade dispara-se subindo a versão no manifest; o Odoo.sh faz um backup marcado como Update (também se mudar requirements.txt) e executa o -u. Aqui vive a armadilha mais cara que tivemos. O idioma habitual para que o administrador herde o seu grupo é:
<record id="base.group_system" model="res.groups">
<field name="implied_ids" eval="[(4, ref('group_mi_manager'))]"/>
</record>Funciona numa instalação nova e num upgrade é ignorado em silêncio. O motivo está na base do cliente: noupdate vive na linha de ir_model_data. Ao atualizar, o carregador só reescreve o registo if not (update and d_noupdate) (odoo/orm/models.py na 19, odoo/models.py na 17 e 18), e o upsert que mantém essa tabela atualiza modelo e res_id mas nunca a coluna noupdate: uma vez definida, não se remove. E não se deduz do addon: nas três versões o record de base.group_system está num <data> sem noupdate e, mesmo assim, pode chegar marcado:
select name, noupdate from ir_model_data
where module='base' and name in ('group_system','group_user');Na nossa produção do Odoo.sh devolve t nas duas; nas 69 bases que o nosso banco de testes criou de raiz, group_user sai t e group_system, f. O mesmo XML, dois resultados.
Aconteceu-nos no nosso conector do Mirakl 16.15.0: as credenciais passaram para um grupo «Mirakl Manager». Em instalações novas o administrador herdava-o; nas atualizadas ficou sem membros e ninguém podia mexer nas chaves. Os testes eram verdes porque uma instalação limpa aplica o record. A correção, na 16.15.1: manter o XML e acrescentar migrations/19.0.16.15.1/post-migrate.py, que escreve a implicação em SQL sobre res_groups_implied_rel e res_groups_users_rel com ON CONFLICT DO NOTHING, mais um teste que falha se o grupo ficar vazio.
As migrações: pasta migrations/<versión>/ com ficheiros pre-*.py, post-*.py e end-*.py, cada um com migrate(cr, version), onde version é a que estava instalada. O Odoo só as executa quando o módulo está marcado para atualizar: numa instalação nova não corre nenhuma, por isso o XML é necessário. Se mudar a versão principal, o processo é outro: erros de migração para o Odoo 19 e a checklist de go-live.
Armadilhas que não aparecem na documentação
- Builds que adormecem. Um build de desenvolvimento sem uso hiberna e os seus crons não correm. Se o usa como banco de testes, mantenha-o acordado: temos um agente do launchd que, a cada 240 segundos, faz
curl /web/healthessh -n … truecontra cada build. - O build que valida pode ser o antigo. O identificador muda a cada push e o anterior demora a ser reciclado: por SSH convivem dois. Antes de dar o que quer que seja por bom, faça
grepdo que acabou de alterar em~/src/user. - A série do manifest falha de forma diferente em cada sentido. Na 19, um manifest
18.0.xou17.0.xnão rebenta: o servidor avisa has an incompatible version, setting installable=False. Ao contrário, na 17 ou na 18, um19.0.x.y.zcorta a leitura com invalid manifest.
Checklist de entrega ao cliente
- Build verde (não amarelo) em desenvolvimento, com testes que instalam e N maior que zero.
- Staging reconstruído hoje a partir da produção; credenciais externas em sandbox ou vazias.
- Versão subida no manifest e
update.loglido até ao fim, migrações incluídas. - Validação do cliente em staging, com os crons à mão e os e-mails revistos em Mails.
- Ramo
production-pre-<cambio>-<fecha>a partir do commit que corre em produção, e backup manual se mexer em dados. - Integração fora das horas de ponta e, depois,
odoo.log, o grupo de permissões com membros e os crons ativos.
Oferecemos este fluxo como engenharia Odoo para consultoras e usamo-lo em cada implementação e migração para o Odoo 19. Se é partner ou software house, o programa de partners tecnológicos explica como trabalhamos.
Se o que tem é um ecommerce
Mexer num conector de marketplace ou numa regra de stock em produção é brincar com encomendas reais: etiquetas duplicadas, encomendas importadas duas vezes, sincronizações a meio. Pelo staging passam os módulos novos, as alterações de stock e as atualizações de conectores (Amazon, Mirakl, ManoMano, SEUR, MRW, Correos Express), e aí transportadoras e gateways de pagamento ficam em modo de teste: é onde se testa uma etiqueta sem que saia a carrinha.
Perguntas frequentes
O Odoo.sh executa os testes em staging ou em produção?
Não. Só nos builds de desenvolvimento, sobre uma base nova com demo. O staging valida com dados reais sem testes; a produção nem carrega demo nem testa.
Um build verde garante que o módulo se instala no Odoo do cliente?
Garante que se instala numa base limpa dessa versão. Não garante o upgrade sobre uma base com histórico nem a convivência com módulos alheios ao ramo: isso cobre-se no staging do cliente.
Ligações úteis na FlexigoTech
O que fazemos sobre isto
Entrega projetos no Odoo.sh e quer um banco de testes que não dependa da sorte?
Montamos o fluxo de ramos, o build como porta e as migrações para os seus clientes, ou revemos o que já tem. Escreva para comercial@flexigobe.com ou ligue para +34 616 809 504.

