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.
01
Tech stack
Nothing exotic — install these once and you're set for local development on any Leonix Odoo repo.
Runs the Odoo app container and PostgreSQL locally, matching the CI/production images.
Match the version pinned in the project's Dockerfile / requirements.txt.
VS Code, PyCharm, (neo)vim — whatever you're fastest in. No house preference.
Claude Code, Cursor, etc. Follow each repo's AGENTS.md for commit and contribution rules the agent should respect.
All source lives on GitHub under the leonixvn org. Ask your lead for org access on day one.
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.
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
Only reached by fast-forwarding a verified staging. Never push or commit here directly.
The integration branch. Every PR targets this branch — pushing/merging here is what triggers the Woodpecker pipeline and the Coolify staging deploy.
fix/*
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.
(pylint-odoo)→ test-addons→ build-image→ deploy-staging
(Coolify webhook)
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.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:
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.
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.
| Phase | Owner | Verified by |
|---|---|---|
| 1. Code completion | Software Engineer (you) | Module written, local tests pass, follows AGENTS.md |
| 2. Automated CI validation | Woodpecker CI | pylint-odoo passes, unit tests run, image builds |
| 3. Staging deployment | Coolify | Image pulled, module upgraded, HTTP health check 200 OK |
| 4. Functional validation | Functional Consultant / QA | Business 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.
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 -dand 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
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.mdconventions - Push, open a PR into
staging, and get it through the pipeline to a green deploy
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.)
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
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