Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
4c1df64
[IMP] Do not load unecessary `odoo/odoo/addons` in addons-paths
brinkflew Jan 28, 2026
f7c753d
[IMP] Do not change database structure at every startup
brinkflew Jan 28, 2026
fea554e
[IMP] Only check for updates if previous date is older than interval
brinkflew Jan 28, 2026
b952af3
[IMP] Only install plugins requirements on install or update
brinkflew Jan 28, 2026
8a963a9
[IMP] Reorganize imports
brinkflew Jan 28, 2026
379e492
[IMP] Custom TTL cache implementation to avoid repeating heavy ops
brinkflew Jan 28, 2026
622def5
[IMP] Do not print python version in PythonEnv's string representation
brinkflew Jan 28, 2026
b528099
[IMP] Programatically bypass prompts
brinkflew Jan 28, 2026
9802155
[IMP] Group `ps aux` results when fetching for odoo-bin' state
brinkflew Jan 28, 2026
07c2f19
[FIX] Keep all repository worktrees in GitCommand iteration
brinkflew Mar 20, 2026
43aea86
[FIX] Support Python <3.13 in console and fix update and plugin installs
brinkflew Mar 20, 2026
884028f
fix: filter worktrees by version in GitCommand (#137)
sea-odoo Mar 23, 2026
a26146c
[REF] core: support streaming process output and AI CLI integration (…
sea-odoo Mar 27, 2026
3c6d9cc
[FIX] core: support HEAD requests and virtualenv check (#139)
sea-odoo Mar 31, 2026
2ff0ab8
[FEAT] include cycle path in circular dependency error
brinkflew Apr 1, 2026
c4c13fe
[FIX] Harden CI, enforce coverage, and expand tests for stability
brinkflew Apr 1, 2026
fbb2184
[FIX] Various improvements need for AI modules (#140)
sea-odoo Apr 9, 2026
3de30c9
[IMP] database/test: fetch auto-tags from runbot (#141)
sea-odoo Apr 10, 2026
212e036
Fix argparse greedy capture and misleading database warnings (#142)
sea-odoo Apr 16, 2026
3ba23c7
[IMP] core: improve command lifecycle, git operations, and cleanup
brinkflew Apr 17, 2026
c4d121e
[FIX] requirements: update vulnerable dependencies and prune unused
brinkflew Apr 17, 2026
971e42e
[FIX] requirements: resolve paramiko/ssh-crypt dependency conflict by…
brinkflew Apr 17, 2026
6c41331
[REF/FIX] local.py: refactor filestore restoration logic to extractall
lse-odoo Apr 17, 2026
4201fcd
[IMP] common: respect release channel during plugin installation (#145)
sea-odoo Apr 21, 2026
0d59fee
[IMP] various: centralize per-version pull interval logic (#146)
sea-odoo Apr 23, 2026
bd07b3e
[FIX] odoobin: fix AttributeError when addons is a list (#148)
sea-odoo Apr 23, 2026
a71018c
[FIX] common: kill the entire process group when using ctrl+c (#149)
nda-odoo Apr 24, 2026
2886b8b
docs: migrate documentation to wiki and simplify README (#151)
sea-odoo Apr 27, 2026
8a8279f
[IMP] various: implement sandbox log filtering and enhance stability …
sea-odoo Apr 28, 2026
90dfdb9
[FIX] odev: sort help arguments and fix alignment (#152)
sea-odoo Apr 28, 2026
474ef67
[FIX] common: improve python requirements parsing and caching (#153)
sea-odoo Apr 28, 2026
3f4498f
Fix greedy capture of positional arguments when names are identical (…
sea-odoo Apr 28, 2026
39f195e
[FIX] odoobin: improve debugger detection and fix filtering logic (#156)
sea-odoo May 5, 2026
70dadbf
[IMP] browsers: provision specific Chrome version for tours (#155)
sea-odoo May 6, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
[run]
# Trace only odev/ so temp plugin files (e.g. test_16 cycle manifests) are not recorded.
source = odev

[report]
omit = */tests/*
fail_under = 60
show_missing = true
exclude_lines =
pragma: no cover
raise NotImplementedError
Expand Down
84 changes: 50 additions & 34 deletions .github/workflows/odev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ on:
- opened
- reopened
- synchronize
push:
branches:
- beta
workflow_dispatch:

jobs:

Expand Down Expand Up @@ -36,6 +40,14 @@ jobs:
uses: actions/setup-python@v5.0.0
with:
python-version: '3.10'
cache: pip
cache-dependency-path: .pre-commit-config.yaml

- name: cache-pre-commit
uses: actions/cache@v4
with:
path: ~/.cache/pre-commit
key: pre-commit-${{ runner.os }}-${{ hashFiles('.pre-commit-config.yaml') }}

- name: run-pre-commit
uses: pre-commit/action@v3.0.0
Expand All @@ -54,19 +66,33 @@ jobs:
- "3.10"
- "3.11"
- "3.12"
- "3.13"

steps:
- name: checkout-repository
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}

- name: setup-python
id: setup-python
uses: actions/setup-python@v5.0.0
with:
# Matrix Python runs pytest. Extra interpreters are available if tests or
# tooling need them; database command tests mock odoo-bin and do not clone Odoo.
python-version: |
3.10
${{ matrix.python-version }}
3.10
3.12
architecture: x64
cache: pip
cache-dependency-path: |
requirements.txt
requirements-dev.txt

- name: setup-system-dependencies
uses: awalsh128/cache-apt-pkgs-action@latest
uses: awalsh128/cache-apt-pkgs-action@v1.5.3
with:
packages: postgresql postgresql-client python3-pip libldap2-dev libpq-dev libsasl2-dev build-essential python3-dev libffi-dev
version: 1.1
Expand All @@ -75,46 +101,36 @@ jobs:
run: |
sudo service postgresql start
sudo -u postgres createuser -s $USER
for i in {1..10}; do pg_isready -h localhost -p 5432 && exit 0; sleep 1; done
exit 1

- name: checkout-repository
uses: actions/checkout@v4
with:
fetch-depth: 0
ref: ${{ github.event.pull_request.head.sha }}

- name: restore-odoo-repositories
id: restore-odoo-repositories
uses: actions/cache/restore@v4
with:
path: ~/odoo/repositories
key: odoo-repositories-${{ matrix.python-version }}

- name: clone-odoo-repositories
if: steps.restore-odoo-repositories.outputs.cache-hit != 'true'
run: |
git clone --depth 1 https://github.com/odoo/odoo ~/odoo/repositories/odoo/odoo --branch master
cd ~/odoo/repositories/odoo/odoo
git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*"
git fetch --depth 1 origin 18.0

- name: save-odoo-repositories
if: steps.restore-odoo-repositories.outputs.cache-hit != 'true'
id: save-odoo-repositories
uses: actions/cache/save@v4
- name: cache-python-venv
id: cache-venv
uses: actions/cache@v4
with:
path: ~/odoo/repositories
key: odoo-repositories-${{ matrix.python-version }}
path: .venv-ci
key: ${{ runner.os }}-py${{ steps.setup-python.outputs.python-version }}-venv-${{ hashFiles('requirements.txt', 'requirements-dev.txt') }}

- name: setup-python-requirements
run: |
python -m ensurepip --upgrade
if [ -f requirements.txt ]; then pip install -r requirements.txt; fi
if [ -f requirements-dev.txt ]; then pip install -r requirements-dev.txt; fi
if [ "${{ steps.cache-venv.outputs.cache-hit }}" != 'true' ]; then
python -m venv .venv-ci
.venv-ci/bin/python -m pip install --upgrade pip
if [ -f requirements.txt ]; then .venv-ci/bin/pip install -r requirements.txt; fi
if [ -f requirements-dev.txt ]; then .venv-ci/bin/pip install -r requirements-dev.txt; fi
fi
echo "${{ github.workspace }}/.venv-ci/bin" >> "$GITHUB_PATH"

- name: run-unit-tests
id: unit-tests
env:
POSTGRES_HOST: postgres
POSTGRES_HOST: localhost
POSTGRES_PORT: 5432
PYTHONPATH: ${{ github.workspace }}
run: |
coverage run -m pytest ./tests --exitfirst
if [ "${{ matrix.python-version }}" = "3.12" ]; then
coverage run -m pytest
coverage report
else
pytest
fi
7 changes: 7 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,10 @@ tests/plugins/*
# --- Temporary and testing files
_*/
tmp/

# --- AI files
.cursor/
.agents/
.gemini/
GEMINI.md
AGENTS.md
5 changes: 0 additions & 5 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,6 @@ repos:
- id: pretty-format-json
args: [--autofix]

- repo: https://github.com/asottile/pyupgrade
rev: v3.20.0
hooks:
- id: pyupgrade

- repo: https://github.com/codespell-project/codespell
rev: v2.4.1
hooks:
Expand Down
139 changes: 4 additions & 135 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,28 +2,17 @@

Automate common tasks relative to working with Odoo development databases.

<!-- TOC depthFrom:2 -->

- [ODEV](#odev)
- [About](#about)
- [Requirements](#requirements)
- [Installation](#installation)
- [Contributing](#contributing)
- [Features](#features)
- [Commands](#commands)
- [Plugins](#plugins)
- [Known Plugins](#known-plugins)
- [Credentials](#credentials)

<!-- /TOC -->

## About

Odev is a multi-purpose tool designed for making the life of Odoo developers and support analysts easier.

It provides wrapper scripts around common tasks, speeding up the whole process of working with databases and allowing
shortcuts to otherwise lengthy commands.

## Documentation

Full documentation for all commands and features is available in the [Odev Wiki](https://github.com/odoo-odev/odev/wiki).

## Requirements

Before you can run this tool, make sure the below requirements are set on your system:
Expand Down Expand Up @@ -72,123 +61,3 @@ You have ideas to share but you don't want to dive in `odev`'s source code? No w
feature.

Check the [Contribution Guide](./docs/CONTRIBUTING.md) for more details about the contribution process.

## Features

### Commands

Odev works with subcommands, each having specific effects.

**Usage:** `odev <command> <args>`

Arguments in square brackets (`[arg]`) are optional and can be omitted, arguments in curvy brackets (`{arg}`) are
options to choose from, arguments without brackets (`arg`) are required.

To see the list of all commands run `odev help`.

To get help on a specific command and its usage, use `odev help <command>`.

### Plugins

Odev can be extended with plugins that are loaded from external GitHub repositories, they could be public or private to
your organizations and allow to add new features and commands or modify existing ones.

Plugins can be enabled with the predefined command `odev plugin --enable <plugin>`.

#### Known Plugins

[plugin-ai-translation]: https://github.com/odoo-odev/odev-plugin-ai-translation
[plugin-ai-scaffold]: https://github.com/odoo-ps/odev-plugin-ai-scaffold
[plugin-editor-vscode]: https://github.com/odoo-odev/odev-plugin-editor-vscode
[plugin-export]: https://github.com/odoo-odev/odev-plugin-export
[plugin-project]: https://github.com/odoo-odev/odev-plugin-project
[plugin-hosted]: https://github.com/odoo-ps/odev-plugin-hosted

| Name | Description |
| ------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------ |
| [odoo-odev/odev-plugin-ai-translation][plugin-ai-translation] | Generate Odoo module translations using AI. |
| [odoo-odev/odev-plugin-ai-scaffold][plugin-ai-scaffold] | Scaffold Odoo modules using AI, based on a formatted technical specification. |
| [odoo-odev/odev-plugin-editor-vscode][plugin-editor-vscode] | Interact with VSCode, open a debugger session and configure workspaces. |
| [odoo-odev/odev-plugin-export][plugin-export] | Export customizations from a database and convert Studio to code. |
| [odoo-odev/odev-plugin-project][plugin-project] | Follow-up on projects and setup working directories for creating new Odoo modules. |
| [odoo-ps/odev-plugin-hosted][plugin-hosted] | Interact with PaaS (odoo.sh) and SaaS (Odoo Online) databases, requires Odoo Technical Support access level. |

### Credentials

To avoid inputting the credentials every time `odev` is run, symmetric encryption is used to store them. This is done
"automagically" with the help of an [`ssh-agent`](https://esc.sh/blog/ssh-agent-windows10-wsl2/)-loaded key. This means
that `ssh-agent` needs to be available in the shell environment the command is being run from, otherwise a warning will
be logged and credentials will need to be inputted every time. If you don't already have a custom script to launch
`ssh-agent`, we recommend using `keychain`, that's an easy option to do that and manage the different keys available
through `ssh-agent`.

After installing `keychain`, and depending on the shell of your choice, the following lines need to be added to the
`.bashrc`/`.zshrc`:

```sh
/usr/bin/keychain -q --nogui $HOME/.ssh/id_rsa
source $HOME/.keychain/$HOST-sh
```

**Alternatively**, you can save the following script into a new file under `~/.profile.d/start_ssh_agent` and make it
run automatically at startup by adding the line `source ~/.profile.d/start_ssh_agent` to your `~/.bashrc` or `~/.zshrc`
file.

```sh
#!/bin/sh

# ==============================================================================
# This script loads declared SSH keys into the running ssh-agent, launching it
# if necessary. This should ideally be sourced in the user's shell profile.
# ==============================================================================

env=~/.ssh/agent.env

# --- Declare the path to the keys to add to the agent -------------------------
declare -a keys=(
"$HOME/.ssh/id_ed25519" # <-- Edit this line to load your own SSH key(s)
)

# --- Common methods and shortcuts ---------------------------------------------

agent_load_env() {
test -f "$env" && . "$env" >| /dev/null
}

agent_start() {
(umask 077; ssh-agent >| "$env")
. "$env" >| /dev/null 2>&1
}

agent_add_key() {
ssh-add $key >| /dev/null 2>&1
}

agent_add_keys() {
for i in "${keys[@]}"; do
ssh-add "$i" >| /dev/null 2>&1
done
}

# --- Load the agent -----------------------------------------------------------

agent_load_env

# agent_run_state:
# 0: agent running with key
# 1: agent running without key
# 2: agent not running
agent_run_state=$(ssh-add -l >| /dev/null 2>&1; echo $?)

# --- Load the keys to the agent -----------------------------------------------

if [ ! "$SSH_AUTH_SOCK" ] || [ $agent_run_state = 2 ]; then
agent_start
agent_add_keys
elif [ "$SSH_AUTH_SOCK" ] && [ $agent_run_state = 1 ]; then
agent_add_keys
fi

unset env

```
6 changes: 3 additions & 3 deletions docs/CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,11 @@ Start with your changes!
### Test your changes

Happy with your modifications to the odev codebase? Then it's time to test it and make sure everything still works as
expected! Run `coverage run -m pytest tests` in your terminal, if any of the tests fails you will need to correct your
code until it passes.
expected! Run `coverage run -m pytest tests && coverage report` in your terminal, if any of the tests fails you will need
to correct your code until it passes.

You implemented a brand new feature? Then it's probably good to implement new tests for it! Check what's inside the
[tests](./_tests/) directory for examples.
[tests](../tests/) directory for examples.

If you want to check the coverage of your code, you can now run `coverage html` and open the file `./htmlcov/index.html`
in your favorite browser.
Expand Down
3 changes: 2 additions & 1 deletion odev.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

for interpreter in ~/.config/odev/venv/bin/python3 /usr/bin/python3; do
if [ -x "$interpreter" ]; then
exec "$interpreter" $(readlink -m $(dirname "$0"/..)/../main.py) "$@"
SCRIPT_PATH=$(readlink -f "$0")
exec "$interpreter" "$(dirname "$SCRIPT_PATH")/main.py" "$@"
exit $?
fi
done
Expand Down
2 changes: 1 addition & 1 deletion odev/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def main():
odev = init_framework()
odev.start(start_time)
logger.debug(f"Framework started in {monotonic() - start_time:.3f} seconds")
odev.dispatch()
sys.exit(0 if odev.dispatch() else 1)

except OdevError as error:
logger.error(error)
Expand Down
2 changes: 1 addition & 1 deletion odev/_version.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@
# or merged change.
# ------------------------------------------------------------------------------

__version__ = "4.24.0"
__version__ = "4.29.3"

Check failure on line 25 in odev/_version.py

View workflow job for this annotation

GitHub Actions / version-bump

Version Not Updated

The odev version has not been updated. Please update incrementally the __version__ value on odev/_version.py

Check failure on line 25 in odev/_version.py

View workflow job for this annotation

GitHub Actions / version-bump

Version Update Not Incremental

The new version value does not follow the incremental pattern (e.g: 1.2.3 -> 1.2.4 or 1.3.0 or 2.0.0). Please update incrementally the __version__ value on odev/_version.py
2 changes: 1 addition & 1 deletion odev/commands/database/cloc.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def run(self):

process = self.odoobin.run(args=self.args.odoo_args, subcommand=self._name, stream=False)

if process is None:
if process is None or process.returncode:
raise self.error("Failed to fetch cloc result.")

headers = [
Expand Down
Loading
Loading