Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

an option to disable rc/alpha/beta version processing #594

Open
estekhin opened this issue Nov 17, 2023 · 12 comments
Open

an option to disable rc/alpha/beta version processing #594

estekhin opened this issue Nov 17, 2023 · 12 comments

Comments

@estekhin
Copy link

The rc/alpha/beta version processing is too aggressive due to overly generic pattern in https://github.com/tcurdt/jdeb/blob/master/src/main/java/org/vafer/jdeb/utils/Utils.java#L44 that matches single a, b and m letters surrounded by numbers.

We are using git hash as part of the final artifact name, and would like to use (almost) the same string as the deb version, but the current processing messes with some git hashes that happen to have a or b surrounded by numbers, for example
1.0-a0ff00 becomes 1.0~a0ff00
1.0-ff00a0 becomes 1.0+ff00~a0

I am not sure if it is even possible to "fix" the regex because while the a0ff00 is a git hash for me it is quite possible that it is alpha version named 0ff00 for somebody else.

I propose to add a new mojo parameter betaExpand (similar to the existing snapshotExpand) that will control whether the rc/alpha/beta processing should be used.

The default value should be true to match the current behavior.

When set to false, the examples above would be
1.0-a0ff00 becomes 1.0+a0ff00
1.0-ff00a0 becomes 1.0+ff00a0

and the user is responsible for any issues related to the version ordering.

Related issues #172 and #210.

@tcurdt
Copy link
Owner

tcurdt commented Nov 18, 2023

While I am not against adding (yet) another switch I am not sure the reason is totally sound.

AFAIR using a git hash like that is against the debian rules and might cause problems anyway.

https://www.debian.org/doc/debian-policy/ch-controlfields.html#version

I've used number of commits (since the last release) over the sha in the past for something like this.

@estekhin
Copy link
Author

I am not sure that using git hash is exactly against debian rules, but it does mess up the versions sorting of all other parts are the same.

Another example of the current behaviour - 1.0~ff00a0 becomes 1.0~ff00~a0.
So maybe the regex should not match of the version already contains ~?

And after a bit of though - my actual problem is that the generated deb version is directly linked to the maven artefact version.

The templates in the deb file can either use the "raw" project.version from https://github.com/tcurdt/jdeb/blob/master/src/main/java/org/vafer/jdeb/maven/DebMojo.java#L414 or the processed version from https://github.com/tcurdt/jdeb/blob/master/src/main/java/org/vafer/jdeb/maven/DebMojo.java#L409.

And the version suitable for the maven artefacts (for example JARs published to the repo) is not guaranteed to be suitable for deb package published to the apt repo.

So problem reframing - provide an option to specify the final deb version which can be different from the project.version?

Still an additional mojo parameter.
If not specified (default), then the final deb version is convertToDebianVersion(project.version), like now.
If specified, then the value is used as is, and the user is responsible for any problems.

@estekhin
Copy link
Author

I am not sure the reason is totally sound.

I am required to use git hash in all our internal artefacts (JARs, deb packages and docker images) for, your know, security reasons. 😜

@tcurdt
Copy link
Owner

tcurdt commented Nov 18, 2023

I am not sure that using git hash is exactly against debian rules, but it does mess up the versions sorting of all other parts are the same.

Well, it's no longer sortable - and AFAIK that is a requirement.

So what I would do is to have number of commits and maybe append the hash for kicks.
That still retains order.

So maybe the regex should not match of the version already contains ~?

That certainly is an idea. But it also feels for a very limited audience.

So problem reframing - provide an option to specify the final deb version which can be different from the project.version?

I am not totally against that. But I don't quite see when you wouldn't want to the two versions to match.

@estekhin
Copy link
Author

So what I would do is to have number of commits and maybe append the hash for kicks. That still retains order.
I am not totally against that. But I don't quite see when you wouldn't want to the two versions to match.

We are actually using the number of commits and the hash as part of our versioning scheme for JARs right now, so i do need a way to prevent the accidental mangling of a and b inside the hash to use the same (or similar) version string both for JARs and for the deb package.

The betaExpand parameter would allow me to achieve that.

To better conform to deb version rules, i would prefer to place the whole hash in the deb version after the ~ character to use its special sorting rules, but at the same time, i would prefer to use - in the JAR version.

This is where explicit debVersion parameter would help and it seems that it also covers what betaExpand would do.

One more thing about hypothetical debVersion parameter - sooner or later somebody will need to add the epoch to their deb version, and using : in the maven project.version is a no go.

The epoch will need a bit of the special handling too - as far as i understand, it should be present in the control/control file in the Version: [[version]] section, but the deb file name should not contain that 1: epoch anywhere in its name.

So, my current thought - the new version parameter

  • if not specified (the default) then the current behaviour with convertToDebianVersion(project.version) is used
  • if specified, then it is used as is (except for the file part where the epoch is dropped)

@tcurdt
Copy link
Owner

tcurdt commented Nov 18, 2023

I'll be honest. I am happy to accept modifications but the current suggestion feels like a bit of a work around.
Maybe we should take step back.

99% of the user should not have tinker with the debVersion as long as the source version makes sense.
And the code should be made robust enough to deal with this. I guess the basic format is:

epoch:package-name-version+revision_arch

With ~ allowing for a lower match on version.

This is what the debian docs say:

The version number of a package. The format is: [epoch:]upstream_version[-debian_revision].

The three components here are:

epoch
This is a single (generally small) unsigned integer. It may be omitted, in which case zero is assumed.

Epochs can help when the upstream version numbering scheme changes, but they must be used with care. You should not change the epoch, even in experimental, without getting consensus on debian-devel first.

upstream_version
This is the main part of the version number. It is usually the version number of the original (“upstream”) package from which the .deb file has been made, if this is applicable. Usually this will be in the same format as that specified by the upstream author(s); however, it may need to be reformatted to fit into the package management system’s format and comparison scheme.

The comparison behavior of the package management system with respect to the upstream_version is described below. The > upstream_version portion of the version number is mandatory.

The upstream_version must contain only alphanumerics 6 and the characters . + - ~ (full stop, plus, hyphen, tilde) and should start with a digit. If there is no debian_revision then hyphens are not allowed.

debian_revision
This part of the version number specifies the version of the Debian package based on the upstream version. It must contain only alphanumerics and the characters + . ~ (plus, full stop, tilde) and is compared in the same way as the upstream_version is.

It is conventional to restart the debian_revision at 1 each time the upstream_version is increased.

The package management system will break the version number apart at the last hyphen in the string (if there is one) to determine the upstream_version and debian_revision. The absence of a debian_revision is equivalent to a debian_revision of 0.

Presence of the debian_revision part indicates this package is a non-native package (see Source packages). Absence indicates the package is a native package.

When comparing two version numbers, first the epoch of each are compared, then the upstream_version if epoch is equal, and then > debian_revision if upstream_version is also equal. epoch is compared numerically. The upstream_version and debian_revision parts are > compared by the package management system using the following algorithm:

The strings are compared from left to right.

First the initial part of each string consisting entirely of non-digit characters is determined. These two parts (one of which may be empty) are compared lexically. If a difference is found it is returned. The lexical comparison is a comparison of ASCII values modified so that all the letters sort earlier than all the non-letters and so that a tilde sorts before anything, even the end of a part. For example, the following parts are in sorted order from earliest to latest: ~~, ~~a, ~, the empty part, a. 7

Then the initial part of the remainder of each string which consists entirely of digit characters is determined. The numerical > values of these two parts are compared, and any difference found is returned as the result of the comparison. For these purposes an empty string (which can only occur at the end of one or both version strings being compared) counts as zero.

These two steps (comparing and removing initial non-digit strings and initial digit strings) are repeated until a difference is > found or both strings are exhausted.

from https://www.debian.org/doc/debian-policy/ch-controlfields.html#s-f-version

Which is why 1.0-<hash> isn't really acceptable for a deb package name.

I guess what could work is:

example-package-1.2.3+git.YYYYMMDD.commitSHA
example-package-1.2.3~git.commitCount.commitSHA

Maybe work out a scheme and then start by adding that to the testcase.

What is your marker for a pre-release?

@tcurdt
Copy link
Owner

tcurdt commented Nov 21, 2023

Let me know how you want to move forward here.

@estekhin
Copy link
Author

estekhin commented Nov 22, 2023

"For historical reasons" our current versioning scheme for maven project version is commitCount-commitHash and for the deb package version is commitCount+commitHash, but we are using somewhat adhoc deb package builder.

Also, right now we are using versions-maven-plugin to versions:set the project version before building the package, but moving to ${revision} from https://maven.apache.org/maven-ci-friendly.html.
Either way the final project version is constructed from individual commitCount and commitHash values outside of the maven.

At the very least, i would like to use jdeb to build the deb package, and for that i need a way to leave the commitHash part intact. I can change the deb versioning scheme to commitCount~commitHash, but i still need the commit hash to remain unchanged when it contains something like 0a0.

This can be solved either by just detecting the ~ in the string, or by fixing regex, or by betaExpand=false, or by explicit debVersion=....

Also, that commitCount as the first part of the version was a bad decision, but it was made quite a long time ago. To fix it and move to something like 2.0~git.commit.hash i will need the epoch support.

The epoch support can't be really implemented over something based on the plain project.version because project version should not contain :, so it is either a debVersion parameter with a special epoch handling or one more debEpoch parameter in addition to the project.version or debVersion.

My current take to solve all of these in the backward-compatible way: introduce a new debVersion parameter with the default value of ${project.version} with the following processing:

debEpoch = 0

if debVersion contains ':'
  debEpoch = the part before ':'
  debVersion = the part after ':'

if debVersion == project.version
  debVersion = existing_processing_for_snapshot_and_rc_alpha_beta(debVersion)
    may be simply detect the presence of the ~ in the string and do not apply rc/alpha/beta processing

debVersion = replace_bad_characters_with_plus(debVersion)

if debEpoch != 0
  need a way to filter the control file so that it contains debEpoch:debVersion

use debVersion as part of the output deb package file name

The idea is that by default everything works like now, but the user can explicitly set the debVersion (either in the pom or as a property from the build command line) to a value different from the project.version.

If it is completely different then the user is completely responsible for it.

@tcurdt
Copy link
Owner

tcurdt commented Mar 2, 2024

Sorry for the late reply.
What have you ended up doing in the meantime?

I am open to a new version property and deprecate the old way.

The versions processing still feels like a lot of magic though.
And I think it would be good to start this off with a testcase covering all the cases.

@inglepriyanka148867
Copy link

You can disable processing of rc/alpha/beta versions in Maven by setting <maven.buildNumber.incrementer.skip>true</maven.buildNumber.incrementer.skip> in your pom.xml.

@tcurdt
Copy link
Owner

tcurdt commented Apr 16, 2024

@inglepriyanka148867 this isn't about maven build number increments but the target version of the debian package.

@inglepriyanka148867
Copy link

inglepriyanka148867 commented Apr 16, 2024 via email

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants