// leonix odoo engineering

Onboarding for new Odoo software engineers

This is the map of how we build, test, and ship custom Odoo modules at Leonix — across testing-odoo, ION, KHL, and Netta. Read it top to bottom once, then keep it open as a reference for your first few pull requests.

git clone feature branch PR to staging Woodpecker CI Coolify deploy FC/QA sign-off

01

Tech stack

Nothing exotic — install these once and you're set for local development on any Leonix Odoo repo.

Docker + Docker Compose

Runs the Odoo app container and PostgreSQL locally, matching the CI/production images.

Python 3

Match the version pinned in the project's Dockerfile / requirements.txt.

A text editor

VS Code, PyCharm, (neo)vim — whatever you're fastest in. No house preference.

An AI coding agent

Claude Code, Cursor, etc. Follow each repo's AGENTS.md for commit and contribution rules the agent should respect.

Git + GitHub CLI

All source lives on GitHub under the leonixvn org. Ask your lead for org access on day one.

Woodpecker CLI (optional)

Lets you run the same lint/test pipeline steps locally before pushing, so failures surface before CI does.

02

Repository structure

Every Leonix Odoo repo follows the same layout. Once you know one, you know them all.

. ├── addons/ # every custom module lives here, one folder each │ ├── leo_demo_data/ │ ├── leo_mapping_cv_recruitment/ │ └── leo_project_github/ ├── AGENTS.md # commit conventions + rules for AI coding agents ├── scripts/ │ ├── test_addons.py # local/CI test runner │ └── update_addons.py # local/CI module update runner ├── config/ │ └── odoo.conf # server runtime parameters ├── docker-compose.yml # local container orchestration ├── Dockerfile # app image build definition ├── .dockerignore ├── .gitignore ├── .gitmodules # submodule config, if any ├── .pylintrc # pylint-odoo rule set ├── README.md ├── requirements.txt # Python dependencies └── .woodpecker/ └── staging.yml # CI pipeline definition

Two files are worth reading before you write a single line of code: AGENTS.md (commit message format, module conventions) and .woodpecker/staging.yml (exactly what checks your push will trigger).

03

Branching model

main
Production

Only reached by fast-forwarding a verified staging. Never push or commit here directly.

staging
Staging

The integration branch. Every PR targets this branch — pushing/merging here is what triggers the Woodpecker pipeline and the Coolify staging deploy.

feature/*
fix/*
Feature & fix branches

Everything you personally work on: new modules, bug fixes, refactors. Branch off staging, open a PR back into staging when ready.

04

Coding guidelines

We don't maintain a separate style guide — we follow Odoo's own. Read these two pages before your first PR; the linter in CI enforces most of this automatically, but it's much faster to know the rules than to discover them one pylint-odoo error at a time.

05

Local development & deploy

You develop and smoke-test locally with Docker before anything touches CI.

# 1. clone and branch off staging
git clone git@github.com:leonixvn/<project-repo>.git
cd <project-repo>
git checkout staging
git pull origin staging
git checkout -b feature/my-change

# 2. bring up the local stack
docker compose up -d

# 3. develop inside addons/<your_module>, then test locally
python scripts/test_addons.py

# 4. commit following AGENTS.md conventions
git add addons/my_module/
git commit -m "[ADD] my_module: short description"
git push origin feature/my-change

Once your branch is pushed, open a pull request into staging on GitHub. That PR (or a direct push to staging) is what triggers the Woodpecker pipeline — nothing is built or deployed from your local machine or feature branch directly.

06

CI/CD pipeline

Woodpecker builds and validates; Coolify only ever runs pre-tested, immutable images. Nothing is built or compiled on staging or production servers directly.

clone lint-addons
(pylint-odoo)
test-addons build-image deploy-staging
(Coolify webhook)
Woodpecker CI

woodpecker.greeni.leonix.cc — sign in with GitHub, org membership in leonixvn required. Runs linting, automated tests, and builds the Docker image, then pushes it to the private registry with an immutable tag (e.g. customer:a8f31c2).

Coolify

coolify.greeni.leonix.cc — receives an authenticated webhook once the pipeline is green, pulls the new image, and restarts the Odoo staging/production service. Handles SSL, reverse proxy, and restarts only — it never builds anything itself.

A failed lint-addons or test-addons stage halts the pipeline immediately — build-image and deploy-staging never run, so a broken staging deploy from bad code isn't possible in this flow.

07

Common pipeline failures & fixes

The two you'll hit most often as a new contributor:

C8116 · manifest-superfluous-key

Your __manifest__.py explicitly sets 'installable': True or 'application': False — these are already the defaults.

Fix: delete the redundant key(s) rather than setting them to the default value.

C8113 · no-wizard-in-models

A transient model (models.TransientModel) is defined inside models/ instead of wizards/.

Fix: move the file to a wizards/ folder in the module.

Re-commit, push, and the pipeline re-runs automatically. Repeat until every stage shows Exit Code 0.

08

Definition of done

A passing pipeline means your code is technically correct — it doesn't mean the task is finished. Functional sign-off is a separate, required step.

PhaseOwnerVerified by
1. Code completionSoftware Engineer (you)Module written, local tests pass, follows AGENTS.md
2. Automated CI validationWoodpecker CIpylint-odoo passes, unit tests run, image builds
3. Staging deploymentCoolifyImage pulled, module upgraded, HTTP health check 200 OK
4. Functional validationFunctional Consultant / QABusiness workflow tested end-to-end in staging UI, marked PASS

09

Week-one plan (5 working days)

Day by day, from reading the pipeline docs to shipping a real (small) piece of work independently.

Day 1
Read & run the pipeline once

Get environment access and understand the CI/CD flow by watching it work, not just reading about it.

  • Get GitHub org access, sign in to Woodpecker, clone a project repo
  • Read the CI/CD architecture doc and that repo's AGENTS.md
  • docker compose up -d and confirm Odoo loads locally
  • Push one trivial change (e.g. a comment or a demo-data tweak) to a feature branch and watch it run through lint → test → build → deploy on a real pipeline
  • Bonus: deliberately break the manifest or misplace a wizard, so the C8116/C8113 failures from section 07 are already familiar
Day 2
Rebuild a module from an old spec

Practice reading requirements and translating them into Odoo, without the pressure of a live client ticket.

  • Pick 1–2 completed modules from a past project and hand over their original functional requirements only (not the finished code)
  • Have them build the module(s) from scratch on a feature branch, following AGENTS.md conventions
  • Push, open a PR into staging, and get it through the pipeline to a green deploy
Day 3
Review, unblock, mentor

A dedicated check-in day — this is where you calibrate how they think, not just what they shipped.

  • Review the Day 2 module(s) with them line by line: what would change in a real review
  • Ask what blocked them and for how long — that's more diagnostic than what they finished
  • Share one or two war stories: a pipeline failure you hit, a modeling decision you got wrong early on
  • Point them at any gaps you noticed (git hygiene, module structure, security files, etc.)
Day 4
First real ticket, run solo

Everything so far has been practice or closely supervised. Day 4 is the first time they run the whole loop themselves on work that matters.

  • Assign one small, well-scoped ticket from the actual backlog — a real bug fix or a small feature, not a toy
  • They work it fully independently: branch → code → local test → PR into staging → fix whatever CI flags → get it deployed to staging
  • You stay reachable for blockers but don't pre-empt them — resist fixing it for them based on yesterday's review notes
  • If time allows, have them review one teammate's open PR and leave real comments — reading someone else's code is as instructive as writing your own
  • Hand the deployed change to the Functional Consultant / QA for sign-off, so they see the full Definition of Done (section 08) close, not just the CI part
Day 5
Review the week

Close the loop: what they've internalized, what's still shaky, and what week two should focus on.

  • Walk back through Days 1–4 together — what came easily, what didn't
  • Confirm they can explain the pipeline and branching model in their own words, not just execute the commands
  • Agree on 2–3 concrete focus areas for week two (e.g. a specific Odoo app area, testing practices, code review habits)
  • Give direct feedback now, while the week is fresh — don't save it for a formal review cycle