Please check the build logs for more information.
See Builds for ideas on how to fix a failed build, or Metadata for how to configure docs.rs builds.
If you believe this is docs.rs' fault, open an issue.
Odoo Developer eXtension: a Rust CLI for managing Odoo projects from a
single [tool.odx] table in pyproject.toml. The command is odx; the
package is odx-cli.
odx aggregates unmerged pull requests on top of upstream Odoo and OCA
repositories, pins the result in a lockfile, vaults the pinned commits on a
private mirror so they cannot disappear, refuses to follow PR heads whose CI
is red, prepares a local development workspace, promotes exactly tested pins
between environments, and analyzes the project (migration scripts, dependency
drift, upstream merge status, portable fixes on other series, upgrade
readiness). The same engine is available as a drop-in replacement for
git-aggregator's gitaggregate: odx git-aggregate, or the standalone
git-aggregate-rs package.
Status: pre-alpha. The workspace skeleton (roadmap phase 0) is in place: the full command line exists, and every command not yet implemented names the roadmap phase in which it lands.
Features
- Aggregate: parallel fetch of PRs, commits and branches into a shared object cache; sequential merges per repository with clean abort on conflict; optional syntax-aware merging through mergiraf.
- Lock and vault:
odx.lockpins every merged commit with its SHA, tree id and patch-id; commits are pushed to content-addressed refs on a private mirror (Forgejo, Gitea, GitLab) so a force-pushed PR cannot break a rebuild. - Force-push guard rail: when a tracked PR head changes, odx checks the new head's CI; red heads are not adopted, the vaulted pin is kept and flagged, and dropping a PR is always a human decision.
- Packages: addons consumed through
uvVCS sources are vaulted the same way and written to[tool.uv.sources](replaces uvault), with a one-command switch to a local editable clone. - Dev workspace: generates the Odoo
addons_path(and rewritesodoo.conf) and runs PEP 660 editable installs throughuv. - Verify: one command for CI and pre-commit that proves a checkout matches
odx.lockanduv.lock. - Sniff: lists database migration scripts introduced by aggregated PRs before they reach production.
- Check-deps: compares
__manifest__.pydependencies withpyproject.toml; reports missing addons, the same addon from two sources, and license conflicts. - Status / track: aggregated PRs that were merged upstream, PRs with new commits, orphaned pins, red upstream heads, local modifications on vendored modules.
- Suggest: a dashboard of PRs and commits on other Odoo series that touch the modules you use, with mutes (reason and expiry) committed to the repo.
- Upgrade: module availability on the index and the forge for the next Odoo series, plus code readiness from odoo-lint.
- Port: ports a PR or an addon's missing commits onto another series from the local cache, with a maintainer sweep over a whole repository, patch-id deduplication, oca-port-compatible blacklists, authorship preserved, odoo-lint's upgrade fixes applied, and PRs opened on GitHub, GitLab, Gitea or Forgejo; addons that moved repositories between series are followed through a cross-series addon index.
- Platform profiles:
generic-wheels,vendored-source,odoo-shandcustomdefine how artefacts are delivered and verified; odx prepares and verifies, the platform deploys. Provided-package sets per platform and series keep requirements that the platform already ships out of the generated requirements file. - Build: builds aggregated, unmerged and private addons as wheels with
content-derived versions (
+odx.<shortsha>) and publishes them to the private index, so wheel-capable platforms install hashes instead of copying source. - Vendor: materializes the locked packages of each dependency group into deployable addon directories for source-based platforms, with the manifest version-bump rule, a content-hash manifest and the platform requirements file.
- Verdicts: a declined forward-port ("not needed on 19.0") is recorded once, keyed by patch-id, addon and target series, shared privately across every environment and every project of the organisation, and re-checked when the target code changes; project-level mutes stay with the project.
- Promote: copies the exact pins of modules, a feature set or a
functional description (
--search "invoicing") along a configurable promotion graph between environments (presets for common branch layouts and Odoo.sh), always plan first, detects divergence, optionally carries the project's own commits, and supports rollback;odx env diffshows what differs. Scripts and AI coding agents drive it through--jsonand--yes. - Dashboard: one view of everything beyond Dependabot: pinned PRs and droppable overrides, new upstream PRs touching deployed modules, forward-port suggestions (fixes merged on a lower series and missing on yours), translation-only bumps and promotion drift, in the terminal, as a TUI, as JSON or as Markdown, each entry with actions: include in the project, open a forward-port PR upstream (human-triggered only), or mute with a reason.
- Bot: a nightly job posts the same dashboard as one rolling issue per series with checkboxes, and opens grouped PRs for merged overrides, green re-pins, translation-only bumps and promotions, on GitHub Actions and Forgejo Actions, inside the private project repository only.
- Background sync: an opt-in user-level scheduled job prefetches
repositories, PR refs, index metadata and wheels into the shared cache
within the API budget, mirror first, so
aggregate,status,dashboardandportanswer from the cache immediately, show data staleness, refresh only what is stale, and keep working offline. - Lint: odoo-lint embedded with project context.
- Stats: lines of code per language via
tokei. - Import: converts git-aggregator
repos.yamland doodbaaddons.yamlto[tool.odx]. - Auto-update: translation-only wheel bumps are re-locked automatically under a configurable policy with a wheel content check.
- Polite to APIs: tokens from the environment,
ghor the keyring; batched GraphQL, ETag caching, per-host rate limiting,--offline.
Example configuration
[]
= "17.0"
= "auto"
= "follow-if-green"
[]
= "ssh://git@forgejo.internal/odoo/vault.git" # private
[[]]
= "https://github.com/OCA/pos.git"
= "vendor/pos"
= ["pos_discount", "pos_loyalty*"]
= [
{ = 123, = true },
{ = "a1b2c3d4e5f67890123456789012345678901234" },
]
[]
= { = "OCA/pos", = 45, = "pos_vouchers" }
[]
= ["pos_loyalty", "pos_loyalty_reports"]
Everything else in pyproject.toml ([project], [build-system], other
[tool.*] tables) is left alone.
Planned CLI
odx aggregate [--locked | --update] [--config repos.yaml]
odx lock [--check] [--auto-update] [--no-push]
odx vendor [--requirements]
odx build --publish --index private
odx verify [--vendored | --installed .venv | --requirements]
odx dev [<package> --branch <name>] [--restore]
odx add <url> --pr <n> | odx drop <repo>#<pr>
odx import repos.yaml [addons.yaml] [--write] | odx export repos.yaml
odx dashboard [--tui | --json | --markdown] | odx dashboard act <id> --include
odx status [--fail-on-merged]
odx suggest [--env uat] [mute <ref> --reason "..."]
odx verdict add OCA/contract#1480 --addon contract --target 19.0 --kind not-applicable --reason "..."
odx check-deps [--licenses] [--fix]
odx sniff | odx stats | odx upgrade --target 18.0
odx port pr OCA/sale-workflow#1234 --to 17.0 [--open-pr]
odx port sweep --to 19.0 --from 16.0,17.0,18.0 [--open-pr]
odx promote <module>... | --feature pos-loyalty | --search "invoicing" --to prod [--open-pr] [--yes --json]
odx env diff test prod
odx bot run --apply
odx sync [--all] | odx daemon install --interval 30m | odx cache gc
odx lint [--only-changed] [--format github]
odx doctor | odx auth login <host> | odx completions <shell>
odx git-aggregate -c repos.yaml -j 4 # gitaggregate drop-in
git-aggregate-rs -c repos.yaml -j 4 # same, standalone package
Every command supports --json.
Installation (planned)
Static binaries will also be published on GitHub Releases.
Quality
The codebase is held to a fixed set of gates enforced in CI behind one
required all-checks status on main: rustfmt, clippy with pedantic
and selected restriction lints as errors, unsafe_code = "forbid",
missing_docs = "deny", 100% line coverage with cargo llvm-cov, doc tests,
cargo doc and the Sphinx documentation with warnings denied, cargo deny,
cargo machete, an MSRV check, typos and Conventional Commits.
Rust edition 2024, MSRV 1.97, MIT license.
Documentation
User documentation is published on Read the Docs.
Contributing
Contributions are welcome. Read CONTRIBUTING.md for the development setup, the quality gates and the Contributor License Agreement. This project follows the Contributor Covenant.
License
MIT. See LICENSE.
Maintained by Strategic Efficiency B.V. under the getfluvo organization.
Built with Rust & AI-accelerated engineering