DEV Community

Cover image for FckVer: A Practical Versioning Strategy for Odoo
Michael Elian Kevin
Michael Elian Kevin

Posted on

FckVer: A Practical Versioning Strategy for Odoo

FckVer: A Practical Versioning Strategy for Odoo

Disclaimer

This article contains profanity. The naming is intentional. The idea started from a long debugging session with Odoo's module versioning. If you don't appreciate the name, feel free to rename it internally.

The Problem

Odoo has a single version field inside __manifest__.py.

{
    "version": "18.0.1.0.0",
}
Enter fullscreen mode Exit fullscreen mode

Simple?

Not really.

That single version is expected to represent several completely different concepts:

  • application version
  • module version
  • migration version
  • deployment ordering
  • upgrade detection

In reality, these are different things.

Coming from ecosystems like Django, Rails, Alembic, Flyway or Liquibase, this felt strange because those ecosystems separate:

  • application release
  • database migration

For example:

Application
v2.0.0

Database
Migration 001
Migration 002
Migration 003
Enter fullscreen mode Exit fullscreen mode

Nobody tries to squeeze both into one version number.

Unfortunately, Odoo only gives us one.


Our Development Workflow

Our company does not have disposable development databases.

Instead, we have:

Developer
      │
      ▼
Shared Development Server
(real company users)
      │
      ▼
QA
      │
      ▼
Production
Enter fullscreen mode Exit fullscreen mode

The shared development server contains real data.

Sales use it.

QA uses it.

Project members use it.

Because of that, every deployment to this server becomes part of the database history.

That immediately breaks many traditional versioning assumptions.


The Problem with Semantic Versioning

Semantic Versioning asks questions like:

  • Is this a major change?
  • Is this a minor feature?
  • Is this a patch?

Our team had a different question:

"We deployed a new build to the shared development server. Which number do we bump?"

Semantic Versioning doesn't answer that.

Odoo documentation doesn't answer that.

Different Odoo teams even interpret the five-part version differently.

Eventually we realized something.

We weren't trying to version software.

We were trying to version our deployment lifecycle.


Introducing FckVer

FckVer (Fuckantic Versioning)

Because sometimes software engineering deserves an appropriately named versioning system.

The format is:

18.0.RELEASE.HOTFIX.DEV
Enter fullscreen mode Exit fullscreen mode

where

Component Meaning
18.0 Odoo version
RELEASE Production release generation
HOTFIX Production hotfix generation
DEV Shared development deployment generation

Unlike Semantic Versioning, none of these numbers describe API compatibility.

They describe our deployment lifecycle.


The Rules

Rule 1

Every deployment to the shared development server increments DEV.

It doesn't matter whether the change is:

  • migration
  • new feature
  • bug fix
  • refactoring
  • view changes
  • security rules
  • XML data

If users receive a new build on the shared development server...

...DEV increments.

We call this a fump.

Definition

fump = fucking bump


Rule 2

Production releases increment RELEASE.

Suppose production currently runs

18.0.4.0.0
Enter fullscreen mode Exit fullscreen mode

Development continues:

18.0.4.0.1
18.0.4.0.2
18.0.4.0.3
...
18.0.4.0.696
Enter fullscreen mode Exit fullscreen mode

Eventually QA signs off.

Now comes an important step.

Before deploying to production, we perform a release fump on the shared development server.

18.0.5.0.0
Enter fullscreen mode Exit fullscreen mode

No code changes.

No migration changes.

Nothing.

Only the version changes.

Then we perform one final smoke test.

If everything passes...

Deploy that exact build to production.

Shared Dev
18.0.5.0.0

↓

Production
18.0.5.0.0
Enter fullscreen mode Exit fullscreen mode

Production always receives the exact version that was tested.


Rule 3

Hotfixes increment HOTFIX.

Suppose production is

18.0.5.0.0
Enter fullscreen mode Exit fullscreen mode

An emergency fix is required.

The hotfix becomes

18.0.5.1.0
Enter fullscreen mode Exit fullscreen mode

That version is tested.

Then deployed.

Development continues from there.

18.0.5.1.1
18.0.5.1.2
18.0.5.1.3
Enter fullscreen mode Exit fullscreen mode

Typical Lifecycle

18.0.4.0.0   Production Release 4

18.0.4.0.1   Dev deployment
18.0.4.0.2
18.0.4.0.3
...
18.0.4.0.696

18.0.5.0.0   Release fump
              Final smoke test

18.0.5.0.0   Production Release 5

18.0.5.0.1   New development
18.0.5.0.2

18.0.5.1.0   Production hotfix

18.0.5.1.1   Continue development
18.0.5.1.2
Enter fullscreen mode Exit fullscreen mode

Why This Works

This approach gives us several nice properties.

Monotonic versions

Odoo's version parser is always happy.

Every version is greater than the previous one.


No version rewrites

Once a version has been deployed anywhere shared, it is permanent.

No rewriting history.

No pretending intermediate versions never existed.


Production always runs a tested version

There is never a last-minute version change immediately before production deployment.

The production artifact is the same artifact that passed QA.


No Semantic Versioning debates

Nobody asks

"Is this a patch?"

Nobody asks

"Is this a minor feature?"

Nobody asks

"Should this be 2.1 or 2.2?"

The only question becomes

"Did we deploy a new build to the shared development environment?"

If yes...

Fump.


Is FckVer Better Than SemVer?

No.

It solves a different problem.

Semantic Versioning describes compatibility.

FckVer describes deployment history.

For our Odoo workflow, deployment history is far more important than compatibility semantics.


Final Thoughts

I don't claim this should become an industry standard.

I don't even claim it's the best possible solution.

But after trying to force Semantic Versioning into Odoo's module versioning, our team realized we were solving the wrong problem.

Once we started treating the manifest version as a deployment lifecycle instead of a semantic version...

Everything became much simpler.

Sometimes the best engineering solution isn't the most elegant one.

It's the one your team can understand at a glance.


P.S.

Yes, the official name is Fuckantic Versioning.

You might want to abbreviate it to FckVer because writing "fuck" into deployment scripts somehow felt unprofessional.

Top comments (0)