A version bump rewrites website views without announcing any of it, so "the
site looks wrong" after a migration is currently unanswerable.
snapshot_cow_views.py records every website_id view (key, mode, inherit_id,
active, arch and its md5) and diffs two snapshots. Rows come back as JSON
straight from Postgres because an arch holds newlines and pipes; the column
list is intersected with information_schema, since ir_ui_view does not expose
the same columns from 12.0 to 18.0. Snapshots hold customer template content,
so they go under private/ and stay out of git.
todo_upgrade.py takes one before and one after each OpenUpgrade run, then
prints the diff. Both are non-blocking: forensic material must never stop an
upgrade.
Measured on the real 12.0 -> 13.0 jump, the diff shows what no log reported:
71 -> 68 copies, 16 deleted and 13 created. portal.frontend_layout is not
converted but DELETED (id 2670) and RECREATED (id 3397), with its children
re-parented from one to the other. The four theme_technolibre copies,
muk_web_branding, project_agile and erplibre_website_snippets_basic_html are
dropped outright, and website_crm.contactus_thanks is renamed to
website_form.contactus_thanks.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Two blind spots made the detector miss real breakages.
1. Comparing « mode » is not the right test. What decides the shape an arch
must have is whether the target declares an inherit_id: with one, the arch
must be inheritance specs (<data>, <xpath>, position=); without one, it must
be a standalone template. A view moving from a root template to
« inherit_id + primary="True" » keeps mode='primary' on BOTH sides, so the
old test reported nothing while the copy still broke. The comparison is now
(target declares inherit) vs (stored arch is spec-shaped), and each finding
carries the reason. A mode change with a matching shape is still reported,
as a lesser warning.
arch_db is read as text up to 15.0 and as jsonb from 16.0; both are handled.
2. A module renamed upstream was reported as « module absent », hiding every
view it owns. renamed_modules is now read from the target OpenUpgrade
apriori.py (21 entries for 13.0, 56 for 14.0, 39 for 16.0, 20 for 18.0) and
used before concluding the module is gone.
Also correct the advice printed for a copy at risk: deactivating it is not
enough, an inactive copy keeping the same key still shadows the module view.
Renaming the key is what actually unpairs it.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A copy-on-write view freezes the structure of the module view it was copied
from. When that module view changes mode between two versions, the copy keeps
an arch written for the old mode and the upgrade dies on
« Element ... cannot be located in parent view », hours into the migration.
Measured on a real 12.0 database: portal.frontend_layout is declared primary in
12.0 (full QWeb template, so a full-template arch is legitimate) and becomes an
extension in 13.0 (inherit_id + xpath). The 2021 COW copy follows the module,
turns into an extension, and keeps its 12.0 arch. The customization is genuine;
the breakage is produced by the migration.
check_cow_views.py compares the mode stored in database with the mode declared
in the target version sources and sorts the views in three buckets: at risk
(mode change), module absent from the target version, and pages made from the
editor (not at risk). Read-only, and called from step 2 so the list is known
before the long version loop rather than during it.
On the reference database it reports exactly the view that broke the upgrade,
plus 7 views whose module is gone in 13.0 (custom theme included).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Which modules must be uninstalled before a version bump depends on the data of
one specific database, so that list does not belong to a shared versioned file.
- Read private/odoo/migration/<database>/uninstall_module_list_odooXX0_to_odooYY0.txt
first, then the shared versioned defaults under script/odoo/migration/, and
merge them (duplicates dropped). private/ mirrors script/, the convention
already used by script/todo/todo.json -> private/todo/todo_override.json.
- Fix the parser. It was « f.readline().split() »: only the FIRST line was kept,
so a multi-line list was silently truncated, and a comma-separated list turned
into one bogus module name. On a file starting with a comment it returned the
words of that comment as module names. It now reads every line and accepts
commas, several names per line, blank lines and comments.
- Support a « # reason » justification per module, printed before uninstalling;
a module with no reason is flagged. Removing a module must stay reviewable.
- Ignore private/odoo/ in git: these lists describe one database.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Reflect the current year in all TechnoLibre
license headers across script/, test/, and docker/.
Generated by Claude Code 2.1.74 model claude-sonnet-4-6
Co-Authored-By: Mathieu Benoit <mathben@technolibre.ca>
Added 30 .base.md files using the mmg (Multilingual Markdown Generator)
format to automatically generate English (.md) and French (.fr.md)
versions of all project documentation.
Updated conf/make.documentation.Makefile to process all .base.md files
via `make doc_markdown`.
- add example odoo test
- prevent delete production file with validation
- add makefile with selenium
- script prod to dev uninstall module after installation
- adapt todo with private directory
- script to download remote database
- TODO show documentation for migration
- oficially support odoo 18 instead of odoo 16
- support postgis/postgresql 18 into docker
- change version erplibre 1.6.0
- support private environment and support local git repo manifest
- support switch odoo version
- support docker for each version
- update os installation
- upgrade python requirement
- separate virtual environment for erplibre and odoo