Skip to content

[20.0][MIG] upgrade_analysis - #3748

Open
hbrunn wants to merge 149 commits into
OCA:20.0from
hbrunn:20.0-mig-upgrade_analysis
Open

hbrunn wants to merge 149 commits into
OCA:20.0from
hbrunn:20.0-mig-upgrade_analysis

Conversation

@hbrunn

@hbrunn hbrunn commented Sep 29, 2026 •

Copy link
Copy Markdown
Member

v20 adds 50k+ res.city records, so I needed to speed up the comparison of xmlids to make this tenable. Also supports jsronrpc2 if the installed version of odoorpc supports it.

Result can be checked at https://github.com/hbrunn/OpenUpgrade/tree/20.0-initialize%2Banalysis/openupgrade_scripts/scripts

@hbrunn hbrunn mentioned this pull request Sep 29, 2026
1 of 6 tasks
@hbrunn
hbrunn force-pushed the 20.0-mig-upgrade_analysis branch 2 times, most recently from ca1e5e3 to 25da561 Compare September 29, 2026 12:31
Comment thread upgrade_analysis/__manifest__.py Resolved
legalsylvain and others added 24 commits October 27, 2026 06:25
… 13.0) to OCA/server-tools

Based on commit 746b7acbd90d62f9ffe6ee17472a1a3533e36597 (Fri Nov 6 17:18:47 2020 +0100)

Co-authored-by: Stefan Rijnhart <stefan@opener.am>
… make the module installable, add readme folders
…y to select some modules, and improve filters, regarding test module with startswith and endswith pattern
Co-authored-by: Stefan Rijnhart <stefan@opener.am>
… (replaced by logger), apply pre-commit rules
[IMP] guess upgrade_path, if config is not set, and openupgrade_scripts is available
Co-authored-by: David Beal <david.beal@akretion.com>
Given that the records need to be managed in the modules that own them rather in the modules that override them, and that we also have the noupdate data xml for every module, then we left out the lines that where indicating the override of records.
hbrunn and others added 16 commits October 27, 2026 06:25
…falsy value

When the previous version set a field explicitly and the new version omits it, _get_xml_diff generated eval="False" using field.falsy_value. This is wrong for fields whose default is truthy (e.g. ir.rule.perm_read/write/create/unlink or active): a fresh install applies the field's default, not its falsy value. The generated noupdate_changes.xml then mismatched a clean install and could even violate model constraints (e.g. ir.rule's _no_access_rights CHECK), breaking the migration.

Use model.default_get() to reset omitted fields to the value a fresh install would give them, falling back to falsy_value when there is no default or it is not a scalar.
…update records

When a noupdate record is moved to another module, its previous definition may set a field declared in a module the new one doesn't depend on (e.g. a module that depends on it). That field is still managed by its own module, so skip it instead of resetting it to its default in the new module's noupdate_changes.xml.
…anged

When a noupdate field set in the previous version is dropped in the current one, only write the reset to noupdate_changes.xml if the value a fresh install would give the field actually differs from the previous value. Otherwise the (noupdate) record already holds the right value and the entry is a no-op.
@hbrunn
hbrunn force-pushed the 20.0-mig-upgrade_analysis branch from 25da561 to efd79f2 Compare October 27, 2026 05:25
@hbrunn

hbrunn commented Oct 27, 2026

Copy link
Copy Markdown
Member Author

test failure fixed in OCA/oca-addons-repo-template#378

@hbrunn hbrunn mentioned this pull request Oct 27, 2026
1 of 3 tasks
"translate",
"required",
"table",
"_order",

@FerDeNetlab FerDeNetlab Oct 27, 2026 •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isproperty isn't in any of the report_fields lists, so the isproperty branch in report_generic never runs and a field that becomes company dependent without changing type isn't reported. In the current 20.0 analysis sale_delay only shows previously in module stock, but it also became company_dependent (integer column → jsonb), and l10n_eg_eta_code on product.product isn't listed at all.

The same lists in 19.0 don't have it either, so I can send it as a separate fix if you prefer to keep it out of the migration.

Drafted with AI assistance (Claude Opus 5.5), reviewed by me.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, I've added this and removed the v18-specific part in the stored branch.

product.template#sale_delay and product.product#{qty_available,l10n_eg_eta_code} are now correctly rendered as newly company_dependent

Can be cherry-picked to v19.

@mauro2306 mauro2306 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Functional test outside CI, on a real-world module set, at efd79f2.

Setup: the 88 modules installed on three production Community databases (account,
account_peppol, account_edi_ubl_cii, l10n_be, sale_stock, stock_account, project…).
Built on the official odoo:19 and odoo:20 Docker images (builds 20261015) rather
than OCB, with PostgreSQL 17. Fresh v19 and v20 databases with that module set, then
upgrade.generate.record.wizard on both, then upgrade.analysis from v20 against v19
over RPC. This is the same sequence as generate-analysis.yml.

Results:

  • It works end to end. The xmlid comparison took about 30 s here. That is a subset, so
    it says nothing about the 50k res.city case.
  • For the 69 modules we share, the generated files match the ones in
    20.0-initialize+analysis. The remaining differences have two explanations:
    • Our module set is smaller. The "moved from" / "renamed to" lines that point to
      modules we don't install (website, stock_picking_batch, payment providers) differ.
    • Odoo 20 has moved since 2026-09-29. For example, account is now 20.0.1.6:
      account.account._order now ends with id, and there is a new view
      account.account_move_view_list_stock_closing. That is one more reason to merge
      this, so the cron can regenerate the analysis.

One issue, pre-existing and not introduced by this PR (see the line comment).

def _get_remote_model(self, connection, model):
self.ensure_one()
if model == "record":
if float(self.config_id.version) < 14.0:

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pre-existing (the same line is in 19.0 and earlier): with the official Odoo packages or
Docker images, the remote server_version is 19.0-20261015. The analysis then crashes:

ValueError: could not convert string to float: '19.0-20261015'

OCB returns 19.0, so CI never hits this. Suggestion, which also covers saas~19.1:

            if int(self.config_id.version.split("~")[-1].split(".")[0]) < 14:

If you'd rather keep this PR focused, I can open a separate PR against 19.0.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thanks, I'm using odoorpc.tools.v for parsing the version string now. can be cherry-picked to other versions

@hbrunn
hbrunn force-pushed the 20.0-mig-upgrade_analysis branch from efd79f2 to 98536ae Compare November 3, 2026 08:47
@oca-cla-bot

oca-cla-bot Bot commented Nov 3, 2026 •

Copy link
Copy Markdown

The following commit authors need to sign the Contributor License Agreement:

CLA not signed

@carlosdauden carlosdauden left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed at 98536ae against server-tools origin/20.0 and Odoo origin/20.0 (53270b6147ce), commit by commit from the last merged 19.0 state. Thanks for the port and for the xmlid speed-up, the 20.0 analysis is not usable without it. What I checked:

  • Every odoo_patch target against Odoo 20.0: BaseModel._convert_records, Registry.init_models, xml_import._test_xml_id, stock.pre_init_hook (still resolved by name at load time) and IrModuleModule.button_immediate_install exist and are called as the patches expect. _reflect_constraints/_reflect_table_object log the same xmlids as the 19.0 _reflect_model patch: in 20.0 _reflect_constraint only returns nothing when there is no module, which _reflect_table_object skips before. Dropping the mrp patch is right, _pre_init_mrp is gone in 20.0. depends: web is needed for Form (BaseModel.onchange raises in base).
  • The per-model compare_xml_sets gives the same result as before: compare_records matches models through model_rename_map, so a merged model never matched in the old code either, and none of the merged source models in the 20.0 apriori (ir.model.access, ir.rule, res.bank, stock.scrap, hr.leave.type, crm.lead2opportunity.partner) exists in 20.0.
  • odoorpc.tools.v (0.10.1) parses 19.0-20261015, saas~19.1 and test~19.0-test as expected, so mauro2306's crash is fixed.
  • Tests, in a throwaway container (oca-ci/py3.12-odoo20.0, PostgreSQL 16, Odoo origin/20.0): all green with odoorpc 0.10.1 from PyPI, test_connection_api_key skipped. With odoorpc master and the skipIf removed, test_connection_api_key passes too.
  • CI: the module tests pass (11 tests, 0 failed). The red "test with Odoo/OCB" is only the html_editor SCSS warning, which origin/20.0 already ignores since the copier update to v1.48 (your OCA/oca-addons-repo-template#378).

Changes I would ask for:

  1. Rebase on origin/20.0. requirements.txt conflicts (add/add: origin/20.0 now lists cryptography, paramiko<4.0.0, pysftp), and the rebase brings checklog-odoo.cfg from template v1.48, which turns the test jobs green.

  2. security/ir.access.csv: upgrade.record and upgrade.attribute were read-only in 19.0 (1,0,0,0) and are now cru. The ir.model.access -> ir.access conversion for 1,0,0,0 is r (valid in CRUD_SELECTION, and what odoo/upgrade_code/19.4-00-ir-access.py produces). Nothing in the module writes these records through the ORM as a user (the wizard and upgrade_log use SQL), so admins should not get create/edit rights on generated data. Please use r for both.

  3. test_connection_api_key never runs: odoorpc.__version__ <= "0.10.1" is true for the PyPI release and also for odoorpc master, which already has the JSON-2 support (OCA/odoorpc#109) but still declares 0.10.1. It is also a string comparison ("0.9.0" <= "0.10.1" is false). Checking the feature instead works with every version, e.g. "api_key" in inspect.signature(odoorpc.ODOO.login).parameters. The same check in get_connection would give a clear UserError when an API key is filled with an odoorpc without support; today it fails with login() got an unexpected keyword argument 'api_key'.

  4. The last 19.0 commit is missing: 8960605 "[19.0][FIX] upgrade_analysis: update usage documentation link". readme/USAGE.md still points to analyse.html instead of 070_migration_files.html#generate-the-difference-analysis-files.

  5. models/upgrade_analysis.py:124: _logger.exception("Could not open file {logfile} for writing") lost its f prefix in the migration commit, so the log shows {logfile} literally. _logger.exception("Could not open file %s for writing", logfile).

Not blocking, can be follow-ups:

  1. No test covers the isproperty reporting added in 3fa3f7a (now company_dependent / not company_dependent anymore). A case in test_field_comparison like the selection_keys one would keep it from silently disappearing again, as it did in 19.0.

  2. test_connection searches the remote user with login admin and takes ids[0]. With an API key of another user, or a database without admin, it reports "Connection failed" although the login worked. Reading the name of the connected user (connection.env.uid) avoids that.

  3. api_key is a plain Char shown in clear text in the form. password="True" on the field in the view, as for any secret.

  4. The new test only covers test_connection (search/read) with an API key. The analysis also calls field_dump, list_modules and get_xml_records, which odoorpc turns into JSON-2 keyword calls through the remote /doc-bearer endpoint (api_doc, auto_install in 19.0). Has a full analysis been run with an API key?

  5. Nits: the upgrade_log.log_xml_id docstring still names IrModelConstraint._reflect_model(), and _logger is unused in odoo_patch/odoo/addons/base/models/ir_module.py.

  6. CLA: the bot flags two history commits, abe0291 (roy.le@viindoo.com, the 15.0 template noupdate change) and b68e882 (pkpiyush988@gmail.com, the 19.0 doc link). Both are already merged in 19.0 with the same authors, so it is the maintainers' call.

Once this is merged, OCA/OpenUpgrade#6068 needs its analysis regenerated: its files (1faabaf8698) predate 3fa3f7a, e.g. sale/20.0.1.2/upgrade_analysis.txt still lacks the sale_delay company_dependent line that your 20.0-initialize+analysis branch already has.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.