[ADD] Odoo tests workflow for 16.0 and 18.0

This commit is contained in:
Stéphan Sainléger
2026-09-23 11:23:15 +02:00
parent f86c403ab2
commit e1c1a86ee7
4 changed files with 215 additions and 4 deletions

View File

@@ -21,22 +21,29 @@ odoo-elabore-ci/
└── config/
├── common/ # Shared files (all versions)
│ ├── .editorconfig
│ └── .gitea/workflows/
│ └── pre-commit.yml # CI workflow deployed to each repo
│ └── .gitea/
│ ├── workflows/
│ │ └── pre-commit.yml # Lint workflow deployed to each repo
│ └── scripts/
│ └── odoo-tests.sh # Odoo test runner used by test.yml
├── 16.0/ # Odoo 16.0 configuration
│ ├── .eslintrc.yml
│ ├── .prettierrc.yml
│ ├── .pre-commit-config.yaml
│ ├── .pylintrc
│ ├── .pylintrc-mandatory
│ └── .ruff.toml
│ ├── .ruff.toml
│ └── .gitea/workflows/
│ └── test.yml # Odoo tests workflow (deployed to 16.0 repos)
└── 18.0/ # Odoo 18.0 configuration
├── eslint.config.cjs
├── prettier.config.cjs
├── .pre-commit-config.yaml
├── .pylintrc
├── .pylintrc-mandatory
└── .ruff.toml
├── .ruff.toml
└── .gitea/workflows/
└── test.yml # Odoo tests workflow (deployed to 18.0 repos)
```
## How It Works
@@ -68,6 +75,19 @@ Deployed to each target repository, this workflow runs on every Pull Request:
2. Installs and runs `pre-commit` with all configured hooks
3. Verifies no untracked files were generated
### Test Workflow (`test.yml`)
Deployed to each target repository (per Odoo version), this workflow runs
the Python tests of the modules changed in a Pull Request, on the
self-hosted runner hosted at `ci.elabore.coop`:
1. Runs inside the Elabore doodba image for the repo's Odoo version
2. Starts a PostgreSQL 17.2 service container
3. Detects the installable modules touched by the PR
4. Installs them and runs their tests (`odoo --test-enable`)
See [Odoo Tests (CI)](#odoo-tests-ci) for details.
## Linting Tools
| Tool | Purpose | Target Files |
@@ -79,6 +99,66 @@ Deployed to each target repository, this workflow runs on every Pull Request:
| **pre-commit-hooks** | Generic checks | Trailing whitespace, merge conflicts, etc. |
| **OCA hooks** | Odoo community standards | Manifests, README, translations |
## Odoo Tests (CI)
Each target repository gets a `tests` workflow (`.gitea/workflows/test.yml`)
that runs the Python tests of the modules changed in a Pull Request.
### How it works
| Aspect | Value |
|--------|-------|
| Runner | self-hosted Gitea runner on `ci.elabore.coop`, label `odoo-ci` |
| Job image | `docker.0k.io/mirror/odoo:rc_<version>-ELABORE-LIGHT` (doodba) |
| Database | `docker.0k.io/postgres:17.2.0-myc` service container |
| Test runner | `.gitea/scripts/odoo-tests.sh` |
The workflow:
1. Checks out the PR head with full history.
2. Computes the changed installable modules with
`git diff origin/<base>...HEAD` (first-level directories containing
`__manifest__.py`).
3. Runs `odoo-tests.sh <modules>` inside the doodba image. The script
generates `odoo.conf` from the environment (via the doodba
entrypoint), then runs:
```
odoo --test-enable --stop-after-init -i <modules> \
--addons-path="$PWD,/opt/odoo/auto/addons" --test-tags "/<modules>"
```
The checked-out repository is prepended to the addons path, so the
PR's code takes precedence over the modules already baked in the
image.
If no installable module is touched (e.g. docs-only PR), the test step
is skipped.
### Runner (`gitea-runner`)
The runner is provided by the `gitea-runner` charm of the
[`0k-charms`](https://git.myceliandre.fr/0k/0k-charms) collection. It
registers against the Gitea instance with an organization-level token
and exposes the `odoo-ci` label; the job image is chosen by each
workflow through its `container:` key.
Required secrets (Gitea → organization **Elabore** → Settings → Actions
→ Runners): a **registration token**, configured in the runner's
deployment file on `ci.elabore.coop`. It is never stored in this
repository.
### Adding a new Odoo version
1. Add `config/<version>/.gitea/workflows/test.yml` (copy the closest
version, adjust the branch filter and the `container.image` tag).
2. Deploy as usual.
### Limitations
- Modules are tested against the dependencies **already present in the
Elabore image**. A dependency introduced in another Elabore repo and
not yet baked in requires rebuilding that image.
- One job runs at a time (`capacity: 1` on the runner).
## Usage Guide
### Deploying Configuration
@@ -155,6 +235,7 @@ Deployment is done via the Gitea Actions interface:
| `.pylintrc-mandatory` | `valid-odoo-versions=19.0` |
| `.ruff.toml` | `target-version` if Python version changes |
| `.pre-commit-config.yaml` | Hook versions if needed |
| `.gitea/workflows/test.yml` | Branch filter and `container.image` tag |
4. **Commit and push**:
```bash

View File

@@ -0,0 +1,44 @@
name: tests
on:
pull_request:
branches:
- "16.0*"
workflow_dispatch:
jobs:
test:
runs-on: odoo-ci
container:
image: docker.0k.io/mirror/odoo:rc_16.0-ELABORE-LIGHT
services:
postgres:
image: docker.0k.io/postgres:17.2.0-myc
env:
POSTGRES_USER: odoo
POSTGRES_PASSWORD: odoopassword
POSTGRES_DB: postgres
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Detect changed modules
id: changed
run: |
base="${{ gitea.base_ref }}"
base="${base:-${{ gitea.event.pull_request.base.ref }}}"
git fetch origin "$base"
modules="$(
git diff --name-only "origin/$base...HEAD" |
awk -F/ '{print $1}' | sort -u |
while read -r dir; do
[ -f "$dir/__manifest__.py" ] && echo "$dir"
done | paste -sd, -
)"
echo "modules=$modules" >> "$GITHUB_OUTPUT"
echo "Changed installable modules: ${modules:-<none>}"
- name: Run Odoo tests
if: steps.changed.outputs.modules != ''
run: bash .gitea/scripts/odoo-tests.sh "${{ steps.changed.outputs.modules }}"

View File

@@ -0,0 +1,44 @@
name: tests
on:
pull_request:
branches:
- "18.0*"
workflow_dispatch:
jobs:
test:
runs-on: odoo-ci
container:
image: docker.0k.io/mirror/odoo:rc_18.0-ELABORE-LIGHT
services:
postgres:
image: docker.0k.io/postgres:17.2.0-myc
env:
POSTGRES_USER: odoo
POSTGRES_PASSWORD: odoopassword
POSTGRES_DB: postgres
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Detect changed modules
id: changed
run: |
base="${{ gitea.base_ref }}"
base="${base:-${{ gitea.event.pull_request.base.ref }}}"
git fetch origin "$base"
modules="$(
git diff --name-only "origin/$base...HEAD" |
awk -F/ '{print $1}' | sort -u |
while read -r dir; do
[ -f "$dir/__manifest__.py" ] && echo "$dir"
done | paste -sd, -
)"
echo "modules=$modules" >> "$GITHUB_OUTPUT"
echo "Changed installable modules: ${modules:-<none>}"
- name: Run Odoo tests
if: steps.changed.outputs.modules != ''
run: bash .gitea/scripts/odoo-tests.sh "${{ steps.changed.outputs.modules }}"

View File

@@ -0,0 +1,42 @@
#!/bin/bash
#
# Run the Python tests of the given Odoo modules.
#
# This script is meant to be executed *inside* an Elabore doodba image
# (docker.0k.io/mirror/odoo:rc_<version>-ELABORE-LIGHT), with a
# PostgreSQL service reachable at $PGHOST. The modules under test are
# read from the current working directory (the checked-out repository),
# which is prepended to the addons path so that the PR's code takes
# precedence over the modules already baked in the image.
#
# Usage: odoo-tests.sh <module1,module2,...>
set -euo pipefail
modules="${1:?usage: odoo-tests.sh <module1,module2,...>}"
export PGHOST=postgres
export PGUSER=odoo
export PGPASSWORD=odoopassword
export PGDATABASE="test_$(basename "$PWD" | tr '.-' '__')"
export WITHOUT_DEMO=all
export DB_FILTER='.*'
# Generate /opt/odoo/auto/odoo.conf from the environment and wait for
# the database to accept connections.
/opt/odoo/common/entrypoint
# Odoo test-tags format: "/module1,/module2" (one leading slash).
tags="/$(echo "$modules" | tr ',' ',/')"
exec odoo \
--config=/opt/odoo/auto/odoo.conf \
--max-cron-threads=0 \
--limit-time-real=10000 \
--workers=0 \
--test-enable \
--stop-after-init \
--addons-path="$PWD,/opt/odoo/auto/addons" \
-d "$PGDATABASE" \
-i "$modules" \
--test-tags "$tags"