Files
odoo-elabore-ci/README.md
2026-09-23 11:23:15 +02:00

10 KiB

odoo-elabore-ci

Centralized CI/CD configuration for Elabore's Odoo repositories.

Purpose

This repository manages linting and CI configuration centrally for all Odoo repositories (*-addons and *-tools) in the Elabore organization on Gitea.

Benefits:

  • Single, consistent configuration across all repos
  • Automatic updates via deployment workflow
  • Multi-version Odoo support (16.0, 18.0, etc.)
  • Based on OCA (Odoo Community Association) standards

Architecture

odoo-elabore-ci/
├── .gitea/workflows/
│   └── deploy-config.yml        # Manual deployment workflow (with dry-run)
└── config/
    ├── common/                   # Shared files (all versions)
    │   ├── .editorconfig
    │   └── .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
    │   └── .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
        └── .gitea/workflows/
            └── test.yml         # Odoo tests workflow (deployed to 18.0 repos)

How It Works

Deployment Workflow (deploy-config.yml)

The deployment is manually triggered via Gitea Actions interface, giving you full control over what gets deployed and where.

Features:

  • Version filter: Deploy to all versions or a specific one (16.0, 18.0)
  • Repo filter: Deploy to all repos or specific ones (comma-separated)
  • Dry-run mode: Preview changes without pushing anything
  • Direct push: Commits are pushed directly to target branches (no PR)

Process:

  1. Detects available versions (folders in config/ other than common/)
  2. For each target repository:
    • For each selected Odoo version:
      • Attempts to clone the corresponding branch
      • Copies config/common/ then config/{version}/
      • In dry-run: shows what would change
      • In live mode: commits and pushes directly to the branch

CI Workflow (pre-commit.yml)

Deployed to each target repository, this workflow runs on every Pull Request:

  1. Sets up Python 3.11 environment
  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) for details.

Linting Tools

Tool Purpose Target Files
Ruff Python linter + formatter .py
Pylint-Odoo Odoo-specific rules .py, __manifest__.py, XML
ESLint JavaScript linter .js
Prettier Multi-language formatter JS, CSS, XML, JSON, YAML, MD
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 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

Deployment is done via the Gitea Actions interface:

  1. Go to Gitea → odoo-elabore-ci → Actions
  2. Select "Deploy CI Config" workflow
  3. Click "Run workflow"
  4. Fill in the parameters:
Parameter Description Examples
Version Odoo version to deploy all, 16.0, 18.0
Repos Target repos (empty = all) crm-addons, hr-addons
Dry-run Preview without pushing true (recommended first)

Deployment Examples

I want to... Version Repos Dry-run
Preview all changes all (empty) ✅
Deploy 16.0 to one repo 16.0 crm-addons ❌
Deploy 18.0 to multiple repos 18.0 crm-addons, hr-addons ❌
Deploy all versions everywhere all (empty) ❌
1. Make changes in config/
2. git commit && git push origin main
   → Nothing happens (no auto-deploy)

3. Run workflow with DRY-RUN enabled
   → Review the logs to see what would change

4. If satisfied, run again WITHOUT dry-run
   → Changes are pushed directly to target branches

Modifying CI Configuration

  1. Edit files in config/:

    • config/common/: changes applied to all versions
    • config/{version}/: version-specific changes
  2. Commit and push to main:

    git add .
    git commit -m "[IMP] description of change"
    git push origin main
    
  3. Trigger deployment manually (see above)

Adding a New Odoo Version

  1. Create the configuration directory:

    mkdir config/{new_version}
    
  2. Copy and adapt files from the closest version or from an OCA repo:

    # Example for Odoo 19.0 based on 18.0
    cp config/18.0/* config/19.0/
    
  3. Adapt the copied files:

    File Required Changes
    .pylintrc valid-odoo-versions=19.0
    .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:

    git add config/19.0/
    git commit -m "[ADD] support for Odoo 19.0 configuration"
    git push origin main
    
  5. Deploy via Gitea Actions:

    • The new version will appear in the "Version" dropdown
    • Use dry-run first to verify which repos have a 19.0 branch

Secrets Configuration

The workflow requires a Gitea token with the following permissions:

  • Read access to all organization repos
  • Write access (to create PRs)

Configure the ELABORE_BOT_TOKEN secret in the repository settings.

Version Differences

16.0 vs 18.0

Aspect 16.0 18.0
ESLint config .eslintrc.yml eslint.config.cjs (flat config)
Prettier config .prettierrc.yml prettier.config.cjs
Node.js 16.17.0 22.9.0
Prettier 2.7.1 3.3.3
ESLint 8.x 9.x
Additional hooks - whool-init, oca-gen-external-dependencies

Configuration Files

.pylintrc vs .pylintrc-mandatory

  • .pylintrc: All rules (optional + mandatory), non-blocking mode (--exit-zero). Useful for IDEs.
  • .pylintrc-mandatory: Critical rules only, blocking mode. Used by CI.

Elabore-Specific Rules

Files are customized for Elabore:

  • manifest-required-authors=Elabore
  • URLs pointing to https://git.elabore.coop/elabore/

Contributing

  1. Test changes locally with pre-commit run --all-files
  2. Follow commit conventions (tags [IMP], [FIX], [ADD], etc.)
  3. Auto-generated PRs should be reviewed before merging

Resources

License

AGPL-3.0