Saltar al contenido principal
Odoo.sh · Para partners

Odoo.sh para partners: dev, staging y producción sin romper nada al cliente

El flujo real de un partner en Odoo.sh: ramas por tarea y versión, el build como puerta, qué resuelve la copia de staging y por qué un upgrade ignora parte de tu XML.

Panel de Odoo en un backend real, el destino de cada build que pasa la puerta

La regla que evita la mayoría de los sustos en Odoo.sh cabe en una frase: nada llega a producción sin un build verde sobre una copia real de la base del cliente, con el mismo commit que se va a fusionar. La documentación explica la plataforma, no el flujo de un partner. Aquí está el nuestro.

Esta pieza amplía y sustituye a Odoo.sh para ecommerce; el resumen para tiendas está al final.

Tres etapas, y lo que cada una hace de verdad

Odoo.sh tiene tres etapas: producción (una sola rama), staging y desarrollo. La diferencia está en con qué base arranca cada build:

  • Desarrollo: base nueva con demo, instala los módulos de la rama y ejecuta los tests; dura unos tres días. Es la única etapa que testea: los tests dependen de la demo.
  • Staging: el build duplica la base de producción y la neutraliza. La copia se borra al mes.
  • Producción: el push reinicia el servidor; si has subido la versión del módulo en __manifest__.py, ejecuta el update (equivale a -u) y la instancia queda en mantenimiento. Si falla, revierte a la revisión anterior y restaura la base.

De ahí la consecuencia que casi nadie lee: fusionar lleva el código, nunca lo que tocaste a mano en la base de staging. Lo que quieras que llegue va en XML del módulo, con la versión subida.

Estructura de ramas para un partner

Con un solo cliente basta con dev, staging y producción. Con varios: una rama de desarrollo por tarea; una de staging por cliente y entrega, reconstruida antes de cada validación; la única de producción que impone Odoo.sh; y, si el módulo va al App Store, una por versión de Odoo.

En nuestro repositorio hay hoy 144 ramas, entre ellas 17.0, 18.0, 19.0 y production: 41 llevan sufijo -17, -18 o -19 (un conector, una versión) y 19 son production-pre-<cambio>-<fecha>: el commit que corría producción antes de cada despliegue delicado. Volver atrás es un push.

Trampa comprobada: una rama creada por git se construye con la versión por defecto del proyecto, no con la de la rama que bifurcas. Bifurcamos una -17 desde 17.0 y Odoo.sh la construyó como 19.0: el manifest 17.0.x quedó como no instalable. La versión se asigna en los ajustes, y solo en ramas de desarrollo.

El build como puerta: qué comprueba y qué no

Un build es verde (sin errores ni avisos), amarillo (avisos) o rojo (errores); solo verde se entrega. Uno de desarrollo comprueba que los módulos de la rama se instalan en una base limpia con demo y que sus tests pasan. Lo que no comprueba:

  • Módulos fuera de la rama. Por defecto instala solo los tuyos, sin submódulos. En los ajustes: instalación completa —submódulos y todos los estándar, pero sin tests— o una lista de nombres técnicos por comas, que es la útil.
  • El upgrade. Instala desde cero; nunca ejecuta -u sobre una base con historia.
  • Los datos reales. Eso es staging, que no ejecuta tests.

Por eso la puerta tiene dos hojas: el build de desarrollo ejecuta tests que instalan, no solo unitarios; y la rama de staging ejecuta el upgrade real sobre la copia de producción, leyendo update.log hasta el final. Mira la línea 0 failed, 0 error(s) of N tests con N mayor que cero: un verde de cero tests está vacío. Más causas, en un módulo de Odoo 19 compila pero no se instala.

Staging con datos: qué resuelve la copia y qué no

La neutralización resuelve lo peligroso: no salen correos (se ven en la pestaña Mails), no corren las acciones planificadas, los IAP quedan fuera, transportistas y pasarelas van en modo test, y neutralize.log dice qué se apagó. Lo que no resuelve:

  • Anonimizar sigue siendo tuyo. Apaga procesos, no borra datos personales. Si el equipo no debe ver datos del cliente: Developer no accede ni a staging ni a producción, Tester sí a staging y solo Admin a producción.
  • Las credenciales de APIs externas viajan en la copia. Un conector en staging con las claves de producción habla con Amazon o Mirakl como si lo fuera: activa su modo sandbox o vacía las claves.
  • La base de staging no se refresca sola. Por defecto la rama actualiza el build anterior y la base sobrevive entre pushes, con los datos ya tocados; con New build, cada push parte de una copia fresca. Los crons se disparan a mano, y los backups manuales duran tres días, con un tope de cinco al día.

SSH y psql en producción: qué se toca y qué no

Odoo.sh da shell a producción. Entramos para leer (psql, lnav ~/logs/odoo.log), diagnosticar con odoo-bin shell y ejecutar la suite de un módulo en modo transaccional. Lo que no se hace: un UPDATE a mano ni instalar módulos saltándose el build. Detalles que cuestan una tarde: scp y sftp están bloqueados, el rol de Postgres no puede crear bases y los módulos propios viven bajo ~/src/user. Un alivio: odoo-bin shell hace rollback al salir en 17, 18 y 19 (odoo/cli/shell.py).

Upgrade en producción: noupdate, base.group_system y migraciones

Un upgrade se dispara subiendo la versión en el manifest; Odoo.sh hace un backup marcado como Update —también si cambia requirements.txt— y ejecuta el -u. Aquí vive la trampa más cara que hemos tenido. El idioma habitual para que el administrador herede tu grupo es:

<record id="base.group_system" model="res.groups">
    <field name="implied_ids" eval="[(4, ref('group_mi_manager'))]"/>
</record>

Funciona en una instalación nueva y en un upgrade se ignora en silencio. El motivo está en la base del cliente: noupdate vive en la fila de ir_model_data. Al actualizar, el cargador solo reescribe el registro if not (update and d_noupdate) (odoo/orm/models.py en la 19, odoo/models.py en 17 y 18), y el upsert que mantiene esa tabla refresca modelo y res_id pero nunca la columna noupdate: una vez puesta, no se quita. Y no se deduce del addon: en las tres versiones el record de base.group_system está en un <data> sin noupdate y aun así puede llegar marcado:

select name, noupdate from ir_model_data
 where module='base' and name in ('group_system','group_user');

En nuestra producción de Odoo.sh devuelve t en las dos; en las 69 bases que nuestro banco de pruebas ha creado desde cero, group_user sale t y group_system, f. El mismo XML, dos resultados.

Nos pasó en nuestro conector de Mirakl 16.15.0: las credenciales pasaron a un grupo «Mirakl Manager». En instalaciones nuevas el administrador lo heredaba; en las actualizadas quedó sin miembros y nadie podía tocar las claves. Los tests eran verdes porque una instalación limpia sí aplica el record. El arreglo, en 16.15.1: dejar el XML y añadir migrations/19.0.16.15.1/post-migrate.py, que escribe la implicación en SQL sobre res_groups_implied_rel y res_groups_users_rel con ON CONFLICT DO NOTHING, más un test que falla si el grupo se queda vacío.

Las migraciones: carpeta migrations/<versión>/ con ficheros pre-*.py, post-*.py y end-*.py, cada uno con migrate(cr, version), donde version es la que había instalada. Odoo solo las ejecuta cuando el módulo está marcado para actualizar: en una instalación nueva no corre ninguna, por eso el XML hace falta. Si cambia la versión mayor, el proceso es otro: errores de migración a Odoo 19 y la checklist de go-live.

Trampas que no salen en la documentación

  • Builds que se duermen. Un build de desarrollo sin uso hiberna y sus crons no corren. Si lo usas como banco de pruebas, mantenlo despierto: tenemos un agente de launchd que cada 240 segundos hace curl /web/health y ssh -n … true contra cada build.
  • El build que validas puede ser el viejo. El identificador cambia con cada push y el anterior tarda en reciclarse: por SSH conviven dos. Antes de dar nada por bueno, grep de lo que acabas de cambiar en ~/src/user.
  • La serie del manifest falla distinto en cada sentido. En la 19, un manifest 18.0.x o 17.0.x no revienta: el servidor avisa has an incompatible version, setting installable=False. Al revés, en la 17 o la 18, un 19.0.x.y.z corta la lectura con invalid manifest.

Checklist de entrega al cliente

  1. Build verde (no amarillo) en desarrollo, con tests que instalan y N mayor que cero.
  2. Staging reconstruido hoy desde producción; credenciales externas en sandbox o vacías.
  3. Versión subida en el manifest y update.log leído hasta el final, migraciones incluidas.
  4. Validación del cliente en staging, con los crons a mano y los correos revisados en Mails.
  5. Rama production-pre-<cambio>-<fecha> desde el commit que corre producción, y backup manual si toca datos.
  6. Fusión fuera de horas punta y, después, odoo.log, el grupo de permisos con miembros y los crons activos.

Este flujo lo ofrecemos como ingeniería Odoo para consultorías y lo usamos en cada implantación y migración a Odoo 19. Si eres partner o casa de software, el programa de partners tecnológicos explica cómo trabajamos.

Si lo que tienes es un ecommerce

Tocar un conector de marketplace o una regla de stock en producción es jugar con pedidos reales: etiquetas duplicadas, pedidos importados dos veces, sincronizaciones a medias. Por staging pasan los módulos nuevos, los cambios de stock y las actualizaciones de conectores (Amazon, Mirakl, ManoMano, SEUR, MRW, Correos Express), y ahí transportistas y pasarelas van en modo test: es donde probar una etiqueta sin que salga la furgoneta.

Preguntas frecuentes

¿Odoo.sh ejecuta los tests en staging o en producción?

No. Solo en los builds de desarrollo, sobre una base nueva con demo. Staging valida con datos reales sin tests; producción ni carga demo ni testea.

¿Un build verde garantiza que el módulo se instala en el Odoo del cliente?

Garantiza que se instala en una base limpia de esa versión. No garantiza el upgrade sobre una base con historia ni la convivencia con módulos ajenos a la rama: eso se cubre en el staging del cliente.

Enlaces útiles dentro de FlexigoTech

Programa de partners tecnológicosCómo trabajamos con partners de Odoo y casas de softwareIngeniería Odoo para consultoríasEquipo técnico con banco de pruebas en 19, 18 y 17Un módulo de Odoo 19 compila pero no se instalaLas trampas de API que solo aparecen en un build realTests verdes y el conector falla en producciónPor qué la prueba que vale es la instalación real

Lo que hacemos sobre esto

Conector de Odoo para tu softwareQué hace, capturas, versiones y precio.

¿Entregas proyectos en Odoo.sh y quieres un banco de pruebas que no dependa de la suerte?

Montamos el flujo de ramas, el build como puerta y las migraciones para tus clientes, o revisamos el que ya tienes. Escribe a comercial@flexigobe.com o llama al +34 616 809 504.

Hablar con un ingeniero