Odoo Repository Migration Data

odoo_repository_migration
REPOSITORY
REPOSITORYOCA/module-composition-analysis
GIT
GIThttps://github.com/OCA/module-composition-analysis.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/module-composition-analysis/tree/18.0/odoo_repository_migration
VERSION
VERSION 1.1.0
CATEGORY
CATEGORYTools
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Camptocamp
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Camptocamp
COMMITTERS
COMMITTERSSébastien Alix, Weblate, OCA-git-bot, oca-ci
WEBSITE
WEBSITEhttps://github.com/OCA/module-composition-analysis
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 19:30:20
ODOO DEPENDENCIES
ODOO DEPENDENCIES OCA/connector:
    - component
OCA/module-composition-analysis:
    - odoo_repository
OCA/queue:
    - queue_job
OCA/server-tools:
    - base_time_window
odoo/odoo:
    - base_sparse_field
    - base
    - mail
    - base_setup
    - web
    - bus
    - web_tour
    - html_editor
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES oca-port
gitpython
odoo-addons-parser
pyyaml
requests
cachetools
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
This module collects and records modules migration data from Odoo
repositories.

Thanks to [oca-port](https://github.com/OCA/oca-port/) and data
collected by `odoo_repository`, this module will generate migration data
on each module for declared migration paths (e.g. 16.0 -> 18.0).

Also, for specific cases you can declare what a module became in a given
Odoo version, like OCA `web_domain_field` replaced by standard Odoo module
`web` starting from 17.0 (with an optional explanation that could help
users, like how to use this new module compared to the previous one).

Given a migration path, a module can get one of this migration status:

| Status | Description |
| ------ | ----------- |
| *Fully Ported* | All commits from source version are present in target version |
| *To migrate*   | The module doesn't exist on target version |
| *Ported (missing commits?)* | Some commits from source version are not ported in target version (could be false-positive) |
| *To review* | A migration PR has been detected |
| *Replaced* | The module has been replaced by another one (not sharing the same git history) |
| *Moved to standard?* | The module name has been detected in Odoo standard repositories for target version. High chance this module is or should be replaced by another one instead (by creating a timeline), so it mainly helps to detect such cases. |
| *Moved to OCA* | the module name is available in an OCA repository (could be a false-positive because sharing the same name, in such case a timeline has to be created) |
| *Moved to generic repo* | a specific module (only available in a project) in source version now exists in a generic repository (could be a false-positive if both modules have only their name in common) |

It helps to build a consolidated knowledge database accross different
Odoo versions for everyone: functionals and developers.

Code Analysis

Views touched (11)
XML IDNameModelTypeStatus
odoo_migration_path_view_form odoo.migration.path.form odoo.migration.path form New
odoo_migration_path_view_tree odoo.migration.path.list odoo.migration.path list New
odoo_module_branch_migration_view_form odoo.module.branch.migration.form odoo.module.branch.migration form New
odoo_module_branch_migration_view_search odoo.module.branch.migration.search odoo.module.branch.migration search New
odoo_module_branch_migration_view_tree odoo.module.branch.migration.list odoo.module.branch.migration list New
odoo_module_branch_timeline_view_form odoo.module.branch.timeline.form odoo.module.branch.timeline form New
odoo_module_branch_timeline_view_search odoo.module.branch.timeline.search odoo.module.branch.timeline search New
odoo_module_branch_timeline_view_tree odoo.module.branch.timeline.list odoo.module.branch.timeline list New
odoo_module_branch_view_form odoo.module.branch.form.inherit odoo.module.branch div Inherits odoo_repository.odoo_module_branch_view_form
odoo_module_branch_view_search odoo.module.branch.search.inherit odoo.module.branch filter Inherits odoo_repository.odoo_module_branch_view_search
odoo_repository_view_form odoo.repository.form.inherit odoo.repository group Inherits odoo_repository.odoo_repository_view_form
Models touched (5)

New fields (4)
  • active Boolean
    default=True
  • name Char
    compute='_compute_name' store=True
  • source_branch_id Many2one → odoo.branch
    comodel_name='odoo.branch' ondelete='cascade' required=True
  • target_branch_id Many2one → odoo.branch
    comodel_name='odoo.branch' ondelete='cascade' required=True
Public methods (2)
  • action_scan(self)
    Scan the source+target branches. Scan is done on all related repositories configured to collect migration data.
  • create(self, vals_list)
    @api.model_create_multi

New fields (4)
  • migration_ids One2many → odoo.module.branch.migration
    comodel_name='odoo.module.branch.migration' inverse_name='module_branch_id' string='Migrations'
  • migration_scan Boolean
    compute='_compute_migration_scan' help='Technical field telling if this module is elligible for a migration scan.' store=True
  • next_odoo_version_module_branch_id Many2one → odoo.module.branch
    comodel_name='odoo.module.branch' compute='_compute_next_odoo_version_module_branch_id' string='Next Odoo Version Module Branch'
  • timeline_ids One2many → odoo.module.branch.timeline
    comodel_name='odoo.module.branch.timeline' inverse_name='module_branch_id' string='Timeline'
Public methods (3)
  • create(self, vals_list)
    @api.model_create_multi
  • open_next_module_branches(self)
  • write(self, vals)

New fields (25)
  • active Boolean
    related='migration_path_id.active' store=True
  • author_ids Many2many
    related='module_branch_id.author_ids'
  • display_name Char
    compute='_compute_display_name' store=True
  • last_source_scanned_commit Char
  • last_target_scanned_commit Char
  • maintainer_ids Many2many
    related='module_branch_id.maintainer_ids'
  • migration_path_id Many2one → odoo.migration.path
    comodel_name='odoo.migration.path' index=True ondelete='cascade' required=True
  • migration_scan Boolean
    compute='_compute_migration_scan' help='Technical field telling if this migration path needs a migration scan.' store=True
  • module_branch_id Many2one → odoo.module.branch
    comodel_name='odoo.module.branch' index=True ondelete='cascade' required=True string='Source'
  • module_id Many2one
    index=True related='module_branch_id.module_id' store=True
  • moved_to_generic Boolean
    compute='_compute_moved_to_generic' help="Specific module now available in a generic repository. This module is maybe not exactly the same, and doesn't have the same scope so it deserves a check during a migration." store=True string='Now generic'
  • moved_to_oca Boolean
    compute='_compute_moved_to_oca' help="Module now available in OCA. This module is maybe not exactly the same, and doesn't have the same scope so it deserves a check during a migration." store=True
  • moved_to_standard Boolean
    compute='_compute_moved_to_standard' help="Module now available in Odoo standard code. This module is maybe not exactly the same, and doesn't have the same scope so it deserves a check during a migration." store=True
  • org_id Many2one
    related='module_branch_id.org_id' store=True
  • pr_url Char
    compute='_compute_pr_url' store=True string='PR URL'
  • process Char
    index=True
  • renamed_to_module_id Many2one → odoo.module
    comodel_name='odoo.module' compute='_compute_renamed_to_module_id' index=True store=True string='Renamed to'
  • replaced_by_module_id Many2one → odoo.module
    comodel_name='odoo.module' compute='_compute_replaced_by_module_id' index=True store=True string='Replaced by'
  • repository_id Many2one
    ondelete='cascade' related='module_branch_id.repository_id' store=True
  • results Serialized
  • results_text Text
    compute='_compute_results_text'
  • source_branch_id Many2one
    index=True related='migration_path_id.source_branch_id' store=True
  • state Selection
    compute='_compute_state' index=True selection=[('fully_ported', 'Fully Ported'), ('migrate', 'To migrate'), ('port_commits', 'Ported (missing commits?)'), ('review_migration', 'To review'), ('replaced', 'Replaced'), ('moved_to_standard', 'Moved to standard?'), ('moved_to_oca', 'Moved to OCA'), ('moved_to_generic', 'Moved to generic repo')] store=True string='Migration Status'
  • target_branch_id Many2one
    index=True related='migration_path_id.target_branch_id' store=True
  • target_module_branch_id Many2one → odoo.module.branch
    comodel_name='odoo.module.branch' compute='_compute_target_module_branch_id' index=True ondelete='cascade' store=True string='Target'
Public methods (2)
  • force_update(self)
    Ensure the migration data is updated or will be updated on next scan.
  • push_scanned_data(self, module_branch_id, data)
    @api.model@api.returns('odoo.module.branch.migration')

New fields (13)
  • active Boolean
    default=True
  • last_known_module_branch_id Many2one → odoo.module.branch
    comodel_name='odoo.module.branch' compute='_compute_last_known_module_branch_id' help='Technical field to check if current selected module is the last one.' string='Last Known Module'
  • migration_ids Many2many → odoo.module.branch.migration
    comodel_name='odoo.module.branch.migration' compute='_compute_migration_ids' string='Migrations'
  • migration_scan Boolean
    compute='_compute_migration_scan' help='Technical field telling if this timeline needs a migration scan.'
  • module_branch_id Many2one → odoo.module.branch
    comodel_name='odoo.module.branch' index=True required=True string='Module'
  • next_module_branch_id Many2one
    related='module_branch_id.next_odoo_version_module_branch_id' string='New module'
  • next_module_id Many2one → odoo.module
    comodel_name='odoo.module' index=True ondelete='restrict' string='New module name'
  • note Html
  • odoo_version_id Many2one
    index=True related='module_branch_id.branch_id.next_id' store=True string='Starting from version'
  • odoo_version_sequence Integer
    related='odoo_version_id.sequence' store=True
  • org_id Many2one
    index=True related='module_branch_id.org_id' store=True string='Organization'
  • repository_id Many2one
    index=True related='module_branch_id.repository_id' store=True string='Repository'
  • state Selection
    default='renamed' help='Renamed: modules still share the same Git history (it allows to check commits that could be ported)\nReplaced: module has been replaced (or merged) by another one that fulfill the same feature' index=True required=True selection=[('renamed', 'has been renamed to'), ('replaced', 'has been replaced by')]
Public methods (5)
  • action_scan(self)
  • create(self, vals_list)
    @api.model_create_multi
  • open_migrations(self)
  • unlink(self)
  • write(self, vals)
    @api.model

New fields (1)
  • collect_migration_data Boolean
    default=False help='Collect migration data based on the configured migration paths.' string='Collect migration data'
Public methods (1)
  • action_scan(self, branch_ids=None, force=False, raise_exc=True)
REPOSITORY
REPOSITORYOCA/module-composition-analysis
GIT
GIThttps://github.com/OCA/module-composition-analysis.git
GIT FOLDER
GIT FOLDERhttps://github.com/OCA/module-composition-analysis/tree/16.0/odoo_repository_migration
VERSION
VERSION 1.3.4
CATEGORY
CATEGORYTools
LICENSE
LICENSEAGPL-3
APPLICATION
APPLICATIONNo
AUTO-INSTALLABLE
AUTO-INSTALLABLENo
AUTHORS
AUTHORSOdoo Community Association (OCA), Camptocamp
MAINTAINERS
MAINTAINERSOdoo Community Association (OCA), Camptocamp
COMMITTERS
COMMITTERSGitHub, Sébastien Alix, Weblate, OCA-git-bot, oca-ci
WEBSITE
WEBSITEhttps://github.com/OCA/module-composition-analysis
LAST TRACKING UPDATE
LAST TRACKING UPDATE2026-07-06 19:12:08
ODOO DEPENDENCIES
ODOO DEPENDENCIES OCA/connector:
    - component
OCA/module-composition-analysis:
    - odoo_repository
OCA/queue:
    - queue_job
OCA/server-tools:
    - base_time_window
odoo/odoo:
    - base_sparse_field
    - base
    - mail
    - base_setup
    - web
    - bus
    - web_tour
PYTHON DEPENDENCIES
PYTHON DEPENDENCIES oca-port
gitpython
odoo-addons-parser
pyyaml
requests
cachetools
SYSTEM DEPENDENCIES
SYSTEM DEPENDENCIES Not have
DESCRIPTION
DESCRIPTION
This module collects and records modules migration data from Odoo
repositories.

Thanks to [oca-port](https://github.com/OCA/oca-port/) and data
collected by `odoo_repository`, this module will generate migration data
on each module for declared migration paths (e.g. 16.0 -> 18.0).

Also, for specific cases you can declare what a module became in a given
Odoo version, like OCA `web_domain_field` replaced by standard Odoo module
`web` starting from 17.0 (with an optional explanation that could help
users, like how to use this new module compared to the previous one).

Given a migration path, a module can get one of this migration status:

| Status | Description |
| ------ | ----------- |
| *Fully Ported* | All commits from source version are present in target version |
| *To migrate*   | The module doesn't exist on target version |
| *Ported (missing commits?)* | Some commits from source version are not ported in target version (could be false-positive) |
| *To review* | A migration PR has been detected |
| *Replaced* | The module has been replaced by another one (not sharing the same git history) |
| *Moved to standard?* | The module name has been detected in Odoo standard repositories for target version. High chance this module is or should be replaced by another one instead (by creating a timeline), so it mainly helps to detect such cases. |
| *Moved to OCA* | the module name is available in an OCA repository (could be a false-positive because sharing the same name, in such case a timeline has to be created) |
| *Moved to generic repo* | a specific module (only available in a project) in source version now exists in a generic repository (could be a false-positive if both modules have only their name in common) |

It helps to build a consolidated knowledge database accross different
Odoo versions for everyone: functionals and developers.

Code Analysis

Views touched (11)
XML IDNameModelTypeStatus
odoo_migration_path_view_form odoo.migration.path.form odoo.migration.path form New
odoo_migration_path_view_tree odoo.migration.path.tree odoo.migration.path tree New
odoo_module_branch_migration_view_form odoo.module.branch.migration.form odoo.module.branch.migration form New
odoo_module_branch_migration_view_search odoo.module.branch.migration.search odoo.module.branch.migration search New
odoo_module_branch_migration_view_tree odoo.module.branch.migration.tree odoo.module.branch.migration tree New
odoo_module_branch_timeline_view_form odoo.module.branch.timeline.form odoo.module.branch.timeline form New
odoo_module_branch_timeline_view_search odoo.module.branch.timeline.search odoo.module.branch.timeline search New
odoo_module_branch_timeline_view_tree odoo.module.branch.timeline.tree odoo.module.branch.timeline tree New
odoo_module_branch_view_form odoo.module.branch.form.inherit odoo.module.branch div Inherits odoo_repository.odoo_module_branch_view_form
odoo_module_branch_view_search odoo.module.branch.search.inherit odoo.module.branch filter Inherits odoo_repository.odoo_module_branch_view_search
odoo_repository_view_form odoo.repository.form.inherit odoo.repository group Inherits odoo_repository.odoo_repository_view_form
Models touched (5)

New fields (4)
  • active Boolean
    default=True
  • name Char
    compute='_compute_name' store=True
  • source_branch_id Many2one → odoo.branch
    comodel_name='odoo.branch' ondelete='cascade' required=True
  • target_branch_id Many2one → odoo.branch
    comodel_name='odoo.branch' ondelete='cascade' required=True
Public methods (2)
  • action_scan(self)
    Scan the source+target branches. Scan is done on all related repositories configured to collect migration data.
  • create(self, vals_list)
    @api.model_create_multi

New fields (4)
  • migration_ids One2many → odoo.module.branch.migration
    comodel_name='odoo.module.branch.migration' inverse_name='module_branch_id' string='Migrations'
  • migration_scan Boolean
    compute='_compute_migration_scan' help='Technical field telling if this module is elligible for a migration scan.' store=True
  • next_odoo_version_module_branch_id Many2one → odoo.module.branch
    comodel_name='odoo.module.branch' compute='_compute_next_odoo_version_module_branch_id' string='Next Odoo Version Module Branch'
  • timeline_ids One2many → odoo.module.branch.timeline
    comodel_name='odoo.module.branch.timeline' inverse_name='module_branch_id' string='Timeline'
Public methods (3)
  • create(self, vals_list)
    @api.model_create_multi
  • open_next_module_branches(self)
  • write(self, vals)

New fields (25)
  • active Boolean
    related='migration_path_id.active' store=True
  • author_ids Many2many
    related='module_branch_id.author_ids'
  • display_name Char
    compute='_compute_display_name' store=True
  • last_source_scanned_commit Char
  • last_target_scanned_commit Char
  • maintainer_ids Many2many
    related='module_branch_id.maintainer_ids'
  • migration_path_id Many2one → odoo.migration.path
    comodel_name='odoo.migration.path' index=True ondelete='cascade' required=True
  • migration_scan Boolean
    compute='_compute_migration_scan' help='Technical field telling if this migration path needs a migration scan.' store=True
  • module_branch_id Many2one → odoo.module.branch
    comodel_name='odoo.module.branch' index=True ondelete='cascade' required=True string='Source'
  • module_id Many2one
    index=True related='module_branch_id.module_id' store=True
  • moved_to_generic Boolean
    compute='_compute_moved_to_generic' help="Specific module now available in a generic repository. This module is maybe not exactly the same, and doesn't have the same scope so it deserves a check during a migration." store=True string='Now generic'
  • moved_to_oca Boolean
    compute='_compute_moved_to_oca' help="Module now available in OCA. This module is maybe not exactly the same, and doesn't have the same scope so it deserves a check during a migration." store=True
  • moved_to_standard Boolean
    compute='_compute_moved_to_standard' help="Module now available in Odoo standard code. This module is maybe not exactly the same, and doesn't have the same scope so it deserves a check during a migration." store=True
  • org_id Many2one
    related='module_branch_id.org_id' store=True
  • pr_url Char
    compute='_compute_pr_url' store=True string='PR URL'
  • process Char
    index=True
  • renamed_to_module_id Many2one → odoo.module
    comodel_name='odoo.module' compute='_compute_renamed_to_module_id' index=True store=True string='Renamed to'
  • replaced_by_module_id Many2one → odoo.module
    comodel_name='odoo.module' compute='_compute_replaced_by_module_id' index=True store=True string='Replaced by'
  • repository_id Many2one
    ondelete='cascade' related='module_branch_id.repository_id' store=True
  • results Serialized
  • results_text Text
    compute='_compute_results_text'
  • source_branch_id Many2one
    index=True related='migration_path_id.source_branch_id' store=True
  • state Selection
    compute='_compute_state' index=True selection=[('fully_ported', 'Fully Ported'), ('migrate', 'To migrate'), ('port_commits', 'Ported (missing commits?)'), ('review_migration', 'To review'), ('replaced', 'Replaced'), ('moved_to_standard', 'Moved to standard?'), ('moved_to_oca', 'Moved to OCA'), ('moved_to_generic', 'Moved to generic repo')] store=True string='Migration Status'
  • target_branch_id Many2one
    index=True related='migration_path_id.target_branch_id' store=True
  • target_module_branch_id Many2one → odoo.module.branch
    comodel_name='odoo.module.branch' compute='_compute_target_module_branch_id' index=True ondelete='cascade' store=True string='Target'
Public methods (1)
  • push_scanned_data(self, module_branch_id, data)
    @api.model@api.returns('odoo.module.branch.migration')

New fields (9)
  • module_branch_id Many2one → odoo.module.branch
    comodel_name='odoo.module.branch' index=True required=True string='Module'
  • next_module_branch_id Many2one
    related='module_branch_id.next_odoo_version_module_branch_id' string='New module'
  • next_module_id Many2one → odoo.module
    comodel_name='odoo.module' index=True inverse='_inverse_next_fields' ondelete='restrict' string='New module name'
  • note Html
  • odoo_version_id Many2one
    index=True related='module_branch_id.branch_id.next_id' store=True string='Starting from version'
  • odoo_version_sequence Integer
    related='odoo_version_id.sequence' store=True
  • org_id Many2one
    index=True related='module_branch_id.org_id' store=True string='Organization'
  • repository_id Many2one
    index=True related='module_branch_id.repository_id' store=True string='Repository'
  • state Selection
    default='renamed' help='Renamed: modules still share the same Git history (it allows to check commits that could be ported)\nReplaced: module has been replaced (or merged) by another one that fulfill the same feature' index=True inverse='_inverse_next_fields' required=True selection=[('renamed', 'has been renamed to'), ('replaced', 'has been replaced by')]
Public methods (0)

No public methods.

New fields (1)
  • collect_migration_data Boolean
    default=False help='Collect migration data based on the configured migration paths.' string='Collect migration data'
Public methods (1)
  • action_scan(self, branch_ids=None, force=False, raise_exc=True)