commitizen icon indicating copy to clipboard operation
commitizen copied to clipboard

Mono Versioning Schema

Open YazdanRa opened this issue 1 month ago • 9 comments

Description

Add a new single number (monotonic) versioning schema.

For example:

v1, v2, v3, ...

Possible Solution

Adding a new schema. It won't affect the rest of the code.

I have already implemented this feature for our own use. Wanted to share if it will be useful for others.

Additional context

Some services are using monotonic versioning (e.g. AWS SageMaker Models) for their artifacts, this will enable the users to keep the code and registry in sync.

Related issues

No response

YazdanRa avatar Dec 10 '25 02:12 YazdanRa

Hi @YazdanRa , thanks for your contribution!

I wonder how monotonic versioning works. It would be great if you could provide some references.

The only reference I could find using the keyword "monotonic versioning" is monotonic-versioning-manifesto, but it does not work as you mentioned in the issue description.

bearomorphism avatar Dec 10 '25 13:12 bearomorphism

Hi @bearomorphism, Thanks for prompt response!

I can see the confusion. I picked the name "monotonic" purely based on what it means and honestly didn't really dig into the specifications.

For what I meant this to be, version only has 1 section, a single number that only can increases. In my PR I treated it as the major section of the version to don't change a lot from the code.

class MonotonicVersion(BaseVersion):
    """
    Monotonic versioning scheme

    Any increment bump simply increases the single numeric component.
    """

    parser: ClassVar[re.Pattern] = re.compile(
        r"v?(?P<version>([0-9]+)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z.]+)?(\w+)?)"
    )

    def increment_base(self, increment: Increment | None = None) -> str:
        return f"{self.major + 1}"

    def _get_increment_base(
        self, increment: Increment | None, exact_increment: bool
    ) -> str:
        return self.increment_base(increment)

I probably should change the naming so it's not confusing. Any suggestions on what it should be called instead?

YazdanRa avatar Dec 10 '25 16:12 YazdanRa

Maybe "Sequential Version", "Integer Version", "Number Version", "Single Number Version".

YazdanRa avatar Dec 10 '25 16:12 YazdanRa

I would ask AI to provide naming suggestions. Naming is hard.

"Monotonic" has nothing to do with "single". Probably "Single number version" or "Monic version"? (I haven't checked if the names are already used.)

Despite the naming, making your custom version scheme as a third-party plugin is a preferred way to extend our tool, as we want to keep our core code light. You may refer to our third-party-plugin documentation for more details. If you still have questions, feel free to discuss here!

bearomorphism avatar Dec 11 '25 01:12 bearomorphism

I took a look at plugins and tried to implement one, however, I will need a small change in the tags.py to get the plugin working. Would it be ok to send that change along with the documentation?

Currently we have:

https://github.com/commitizen-tools/commitizen/blob/1e5869ec87c3886e1e2d313fd9d3d273db974b33/commitizen/tags.py#L231

I would like to change it to:

major, minor, patch = (list(version.release) + [0, 0, 0])[:3]

This is the minimum change required to get is work for versions that are less than 3 components.

YazdanRa avatar Dec 12 '25 04:12 YazdanRa

I believe the type of version.release should be Tuple[int, int, int], although it's Tuple[int, ...] on master now.

Is there any reason you think the change should be at core code?

bearomorphism avatar Dec 12 '25 04:12 bearomorphism

When the version is just a single number, it can't get unpacked to major, minor, patch. The easiest way to handle this, is to consider it as a major version. e.g. v1 -> v1.0.0.

However, since the version of the projects are actually single numbers, they will get ValueError: not enough values to unpack (expected 3, got 1) error on that line. The change I suggest will only consider tham as a major version instead.

To test this out, you can try run any of the commands on an empty project with version 1 on their pyproject.toml file.

YazdanRa avatar Dec 12 '25 04:12 YazdanRa

If I understand correctly, the basic assumption for commitizen version providers is that the release version number always consists of three numbers. @woile @Lee-W wdyt

bearomorphism avatar Dec 12 '25 07:12 bearomorphism

I think we can allow the change as long as all the tests are passing 👍🏻

We try to give as much flexibility as possible for version providers, as long as the core keeps working

woile avatar Dec 12 '25 08:12 woile

I did updated the PR and removed the extra stuff, just kept the version unpacking change and added some specific test for that.

PR is now ready for review ツ

I created the plugin but haven't published nor included in this PR as it will require the new version of commitizen as its dependency.

Will send a separate PR later to add it to the documentation once its published.

Thanks!

YazdanRa avatar Dec 12 '25 19:12 YazdanRa