# The Wanderer's Guide

Your Odoo module can travel across many versions, like a traveler visits many places.
Polytropos means "the one of many paths" - your companion on this journey.

In this tutorial, you'll build a multi-version Odoo module from scratch.

## What You Need

-   Python 3.11+
-   [uv](https://github.com/astral-sh/uv) installed

## Create Your Module

Make a folder for your addon:

```bash
uvx polytropos init myproject/addons/travel_inventory
```

This creates a basic `pyproject.toml` file (and some others that help).

## Set Up Multiple Versions

Edit the generated `pyproject.toml` to support different Odoo releases:

```toml title="myproject/addons/travel_inventory/pyproject.toml"
[build-system]
requires = ["polytropos[build]"]
build-backend = "polytropos.build"

[project]
name = "odoo-addon-travel-inventory"
version = "1.0.0"
description = "The paths I have traveled"
requires-python = ">=3.11"

[tool.polytropos]
default_odoo_release = "19.0"

[[tool.polytropos.manifest]]
depends = ["auth_oauth"]
data = [
    "security/ir.model.access.csv",
    "views/res_partner_form.xml",
]

[[tool.polytropos.manifest]]
releases = ">=18"
depends = ["auth_passkey"]
data = [
    "templates/login.xml",
]
```

What this does:

-   Defines an Odoo module named `travel_inventory`
-   Default Odoo release is **19.0**
-   All releases implement OAuth for travelers
-   Odoo 18.0 adds passkey support, so our module also supports that by adding extra
    `auth_passkey` and a new view

## Add Your Code

An exercise for the reader.

## Develop in Editable Mode in Different Integration Environments

Create an Odoo integration environment for Odoo 17:

```toml title="myproject/integrations/odoo17/pyproject.toml"
[project]
name = "odoo17-integrated"
version = "0.1.0"
dependencies = [
    "odoo",
    "odoo-addon-travel-inventory",
]

[tool.uv]
config-settings = { odoo_release = "17.0" }

[tool.uv.sources]
odoo = { url = "https://nightly.odoo.com/17.0/nightly/src/odoo_17.0.20260319.tar.gz" }
odoo-addon-travel-inventory = { path = "../../addons/travel_inventory", editable = true }
```

Build and install everything:

```shell
cd myproject/integrations/odoo17
uv sync
uv run odoo --stop-after-init -i travel_inventory
```

!!! warning

    `uv sync` can fail for missing build dependencies.

    Odoo will fail to install the module if it can't find Postgres.

Of course you can do the same for Odoo 18, 19, etc., each one in a separate folder.

!!! tip

    When
    [uv supports per-project config-settings](https://github.com/astral-sh/uv/issues/3636#issuecomment-4089576523),
    you will be able to manage all integration environments from a single parent
    `pyproject.toml`.

## Build Wheels for Different Releases

Build wheel for Odoo 19.0:

```bash
uv build --wheel --config-setting odoo_release=19.0
```

Build for Odoo 18.0:

```bash
uv build --wheel --config-setting odoo_release=18.0
```

Build for Odoo 17.0:

```bash
uv build --wheel --config-setting odoo_release=17.0
```

Each build creates a wheel with the version in the name:

-   `dist/odoo-addon-travel-inventory-19.0.1.0.0-py3-none-any.whl`
-   `dist/odoo-addon-travel-inventory-18.0.1.0.0-py3-none-any.whl`
-   `dist/odoo-addon-travel-inventory-17.0.1.0.0-py3-none-any.whl`

## Check the Wheel

Look inside a built wheel:

```bash
unzip -l dist/*.whl
```

You'll see the `__manifest__.py` with the right version.

## What You Now Have

A multi-version Odoo module that:

-   Uses **one codebase** for all versions
-   Creates **different manifests** for each Odoo release
-   Builds **version-specific wheels** for each Odoo instance

## See Also

-   [Examples Folder](https://gitlab.com/moduon/polytropos/-/tree/main/examples) -
    Real-world module examples
