[ADD] Odoo tests workflow for 16.0 and 18.0
This commit is contained in:
89
README.md
89
README.md
@@ -21,22 +21,29 @@ odoo-elabore-ci/
|
|||||||
└── config/
|
└── config/
|
||||||
├── common/ # Shared files (all versions)
|
├── common/ # Shared files (all versions)
|
||||||
│ ├── .editorconfig
|
│ ├── .editorconfig
|
||||||
│ └── .gitea/workflows/
|
│ └── .gitea/
|
||||||
│ └── pre-commit.yml # CI workflow deployed to each repo
|
│ ├── 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
|
├── 16.0/ # Odoo 16.0 configuration
|
||||||
│ ├── .eslintrc.yml
|
│ ├── .eslintrc.yml
|
||||||
│ ├── .prettierrc.yml
|
│ ├── .prettierrc.yml
|
||||||
│ ├── .pre-commit-config.yaml
|
│ ├── .pre-commit-config.yaml
|
||||||
│ ├── .pylintrc
|
│ ├── .pylintrc
|
||||||
│ ├── .pylintrc-mandatory
|
│ ├── .pylintrc-mandatory
|
||||||
│ └── .ruff.toml
|
│ ├── .ruff.toml
|
||||||
|
│ └── .gitea/workflows/
|
||||||
|
│ └── test.yml # Odoo tests workflow (deployed to 16.0 repos)
|
||||||
└── 18.0/ # Odoo 18.0 configuration
|
└── 18.0/ # Odoo 18.0 configuration
|
||||||
├── eslint.config.cjs
|
├── eslint.config.cjs
|
||||||
├── prettier.config.cjs
|
├── prettier.config.cjs
|
||||||
├── .pre-commit-config.yaml
|
├── .pre-commit-config.yaml
|
||||||
├── .pylintrc
|
├── .pylintrc
|
||||||
├── .pylintrc-mandatory
|
├── .pylintrc-mandatory
|
||||||
└── .ruff.toml
|
├── .ruff.toml
|
||||||
|
└── .gitea/workflows/
|
||||||
|
└── test.yml # Odoo tests workflow (deployed to 18.0 repos)
|
||||||
```
|
```
|
||||||
|
|
||||||
## How It Works
|
## 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
|
2. Installs and runs `pre-commit` with all configured hooks
|
||||||
3. Verifies no untracked files were generated
|
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
|
## Linting Tools
|
||||||
|
|
||||||
| Tool | Purpose | Target Files |
|
| 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. |
|
| **pre-commit-hooks** | Generic checks | Trailing whitespace, merge conflicts, etc. |
|
||||||
| **OCA hooks** | Odoo community standards | Manifests, README, translations |
|
| **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
|
## Usage Guide
|
||||||
|
|
||||||
### Deploying Configuration
|
### Deploying Configuration
|
||||||
@@ -155,6 +235,7 @@ Deployment is done via the Gitea Actions interface:
|
|||||||
| `.pylintrc-mandatory` | `valid-odoo-versions=19.0` |
|
| `.pylintrc-mandatory` | `valid-odoo-versions=19.0` |
|
||||||
| `.ruff.toml` | `target-version` if Python version changes |
|
| `.ruff.toml` | `target-version` if Python version changes |
|
||||||
| `.pre-commit-config.yaml` | Hook versions if needed |
|
| `.pre-commit-config.yaml` | Hook versions if needed |
|
||||||
|
| `.gitea/workflows/test.yml` | Branch filter and `container.image` tag |
|
||||||
|
|
||||||
4. **Commit and push**:
|
4. **Commit and push**:
|
||||||
```bash
|
```bash
|
||||||
|
|||||||
44
config/16.0/.gitea/workflows/test.yml
Normal file
44
config/16.0/.gitea/workflows/test.yml
Normal 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 }}"
|
||||||
44
config/18.0/.gitea/workflows/test.yml
Normal file
44
config/18.0/.gitea/workflows/test.yml
Normal 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 }}"
|
||||||
42
config/common/.gitea/scripts/odoo-tests.sh
Executable file
42
config/common/.gitea/scripts/odoo-tests.sh
Executable 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"
|
||||||
Reference in New Issue
Block a user