1. First create something that works (to provide business value).

  2. Then something that’s beautiful (to lower maintenance costs).

  3. Finally works on performance (to avoid wasting time on premature optimizations).

Stability policy

This project more or less follows Semantic Versioning.

Which boils down to the following rules of thumb regarding stability:

  • Patch releases: 0.x.n0.x.(n+1) upgrades

    Are bug-fix only. These releases must not break anything and keep backward-compatibility with 0.x.* and 0.(x-1).* series.

  • Minor releases: 0.n.*0.(n+1).0 upgrades

    Includes any non-bugfix changes. These releases must be backward-compatible with any 0.n.* version but are allowed to drop compatibility with the 0.(n-1).* series and below.

  • Major releases: n.*.*(n+1).0.0 upgrades

    Make no promises about backwards-compatibility. Any API change requires a new major release.

Build status

main branch: Unittests status Coverage status

Setup environment

This step is required for all the other sections from this page.

Check out latest development branch:

$ git clone
$ cd ./mail-deduplicate
$ git checkout main

Install package in editable mode with all development dependencies:

$ python3 -m pip install poetry
$ poetry install

Now you’re ready to hack and abuse git!

Test mdedup development version

After the steps above, you are free to play with the bleeding edge version of mdedup:

$ poetry run mdedup --version
mdedup, version 7.0.0-dev


Run unit-tests with:

$ poetry run pytest

Coding style

Code linting is handled by a workflow.


The documentation you’re currently reading can be built locally with Sphinx:

$ poetry run sphinx-build -b html ./docs ./docs/html

The generation of API documentation is covered by a dedicated workflow.


Project screenshots found in the documentation and the file needs to be refreshed by hand once in a while.

To produce clean and fancy terminals screenshots, use either:


Before a release, the maintainers will review and rewrite the changelog to make it clean and readable. Inspiration can be drawn from the keep a changelog manifesto.

Changes can be inspected by using the comparison URL between the last tagged version and the main branch. This link is available at the top of the ChangeLog.

Release process

All steps of the release process and version management are automated in the changelog.yaml and release.yaml and workflows.

All there’s left to do is to:

  • check the open draft prepare-release PR and its changes,

  • click the Ready for review button,

  • click the Rebase and merge button,

  • let the workflows tag the release and set back the main branch into a development state.

Version bump

Versions are bumped to their next patch revision during the release process above by the release.yaml workflow.

At any point during development, you can bump the version by merging either the minor-version-increment or major-version-increment branch, each available in their own PR.