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

Introduce PreRelaseTagNumber variable to encode complete PreReleaseTag in a number #1145

Closed
BCSharp opened this issue Jan 23, 2017 · 14 comments
Labels

Comments

@BCSharp
Copy link

BCSharp commented Jan 23, 2017

One of the values that the configuration option assembly-versioning-scheme can be set to is MajorMinorPatchTag. This is great except that that 'tag' does not really encode the full information form PreReleaseTag. Instead of it, it is replaced by PreReleaseNumber, which carries only a subset of information from PreReleaseTag: it ignores PreReleaseLabel. As a consequence, versions 1.2.3-unstable.1 and 1.2.3-beta.1 will produce identical assembly version 1.2.3.1, causing version collision.

It is often desirable to encode complete semantic version information in numbers. It is nice to have for assembly version, but essential for e.g Android apps, which have to have unique android:codeVersion values in their manifests. Therefore, for those of us who need it, I propose the following scheme of encoding pre-relase label into the number used in MajorMinorPatchTag versioning:

Each branch configuration can specify tag-offset value, being a number (0 by default). This number will be added to PreReleaseNumber to form PreReleaseTagNumber. This PreReleaseTagNumber will be used as the fourth number (revision) in AssemblyVersion when assembly-versioning-scheme is set to MajorMinorPatchTag.

By default, each tag offset is 0, which will maintain the currently implemented behaviour. However, the user can set it to different values together with custom tag labels and in this way differenciate between pre-release tags. For completeness, tag offset has to be applied (if specified) even on branches that do not have pre-release tags, e.g. master. For master, PreReleaseNumber is empty, revision number in assembly version defaults to 0, but adding a tag offset allows for proper ordering of revisions in assembly versions:

Example GitVersion.yml:

branches:
  develop:
    tag: alpha
    tag-offset: 0
  release:
    tag: beta
    tag-offset: 1000
  master:
    tag-offset: 2000

Then we get the following PreRelaseTagNumber:

  • 1.2.3-alpha.1 on develop is 1
  • 1.2.3-beta.1 on release/1.2 is 1001
  • 1.2.3 on master is 2000

This is just a proposal. I am interested in other ideas of handling the problem. Basically my requirement is to be able to uniquely encode the complete semantic version information in a sequence of numbers, in a flexible enough way such that the ordering is controllable.

@JakeGinnivan
Copy link
Contributor

I like the idea. I wonder if we could capture this as guidance rather than adding into GitVersion itself. The reason I say that is because this could be a confusing feature to explain unless you have a specific problem.

I feel you with the conversion to the AssemblyVersion. If we did build this in I would say it would be called something like numeric-only-tag-offset, and we introduce a new variable to expose the result. We could then use it in the AssemblyVersion and other variables which drop the label part of the pre-release.

@BCSharp
Copy link
Author

BCSharp commented Feb 26, 2017

it would be called something like numeric-only-tag-offset, and we introduce a new variable to expose the result

Sounds good. Having a numeric variable would already help a lot. How do you see it working with AssemblyVersion? Mabye by setting assembly-versioning-scheme to a new setting MajorMinorPatchNumericTag?

@JakeGinnivan
Copy link
Contributor

That sounds reasonable

@BCSharp
Copy link
Author

BCSharp commented Feb 28, 2017

OK, so just to check my understanding with examples:

Example GitVersion.yml:

assembly-versioning-scheme: MajorMinorPatchNumericTag
branches:
  develop:
    tag: alpha
    numeric-only-tag-offset: 0
  release:
    tag: beta
    numeric-only-tag-offset: 1000
  master:
    numeric-only-tag-offset: 2000

Then we get the following:

  • 1.2.3-alpha.1 on develop: "PreRelaseNumericTag": 1, "AssemblySemVer":"1.2.3.1"
  • 1.2.3-beta.1 on release/1.2: "PreRelaseNumericTag": 1001, "AssemblySemVer":"1.2.3.1001"
  • 1.2.3 on master: "PreRelaseNumericTag": 2000, "AssemblySemVer":"1.2.3.2000"

@asbjornu
Copy link
Member

How about we just use assembly-versioning-format instead and allow it to be 100% customizable?

@asbjornu
Copy link
Member

If what I describe in #1157 (comment) sounds like a fitting solution to this problem, I propose that we close this as a duplicate of #1157.

@BCSharp
Copy link
Author

BCSharp commented Mar 11, 2018

Unfortunately, the proposal in #1157 (comment) does not solve this problem, although it has a potential to address a part of it.

More specifically, it addresses the assembly-versioning-scheme extension. I like the proposal in #1157 because instead of proliferating predefined versioning schemes, it allows for full customization of it, so it is applicable to a wider range of cases and perhaps more extensible in the future.

But for this problem, this is the last part. Before that, we need a way of converting the tag (label) to a numeric format and making it available through a variable. Even if we forget (or solve) the assembly versioning scheme problems, this is still needed.

Part of the difficulty here is inconsistent terminology already implemented, which needs to stay to prevent breaking changes. Following the documentation, if we have a semantic version 1.2.3-beta.4, then 1 is Major, 2 is Minor, 3 is Patch, beta is PreRelaseLabel, 4 is PreReaseNumber, and the whole beta.4 is PreReaseTag. However the code sometimes uses name Tag for the label (e.g. tag: beta in the .yml) and sometimes tag for the tag number only (like in MajorMinorPatchTag). I suppose this is for the sake of brevity of the assembly versioning scheme names. Having assembly versioning format string, with explicit definition, does away with the confusion.

The latest proposal by @JakeGinnivan is to introduce a new variable, say, PreReleaseNumericTag, and have numeric-only-tag-offset to assign a number to a label. I find the latter name somewhat confusing and difficult to explain to the user (I'd prefer something simpler, like tag-label-number) but I will take anything that works.

So, the bottom line is that both issues can be implemented in parallel and fairly independently form each other as they address different goals.

@asbjornu
Copy link
Member

@BCSharp, I see. If you were able to set the PreReleaseNumber somehow, would that help?

The confusion with tag vs. label has been brought up in #1054. Please add to the discussion there if you want.

@jbaehr
Copy link
Contributor

jbaehr commented Mar 20, 2018

What do you think about the term "weight", so tag-weight (or label-weight, according to #1054)? This could make it easier to explain the matter: "beta.1" weights heavier then "alpha.1" and thus the numerical representation of "beta.1" must be larger then "alpha.1". To achieve this, the the pre-release weight is added to the pre-release number.
If you already have PreReleaseNumber, maybe PreReleaseWeight (pre-release-weight in yaml) would be a good name. And WeightedPreReleaseNumber is the place holder to use in format strings.

This approach would also solve our issue with Windows Installer, see #1366.

@BCSharp
Copy link
Author

BCSharp commented Mar 20, 2018

Setting PreReleaseNumber misses the point. This number needs to stay being managed by GitVersion.

The term “weight” and related names as proposed by @jbaehr would work.

@jbaehr
Copy link
Contributor

jbaehr commented Apr 12, 2018

@BCSharp GitVersion already provides the PreReleaseNumber

Now that the PR #1385 is merged, you can use an env var in the format string to provide a WeightedPreReleaseNumber. The following snipped of Jenkins Pipeline Groovy does what you want:

// Note the /nocache switch! it is required in order to bypass the cache;
// else the GitVersionTask via MsBuild won't evaluate the format string again and only see the fallback value from this call here
// Also not that it *must* be "/output buildserver /nocache"; the other way round "/nocache /output buildserver" won't write the properties file!
bat '\\path\\to\\GitVersion\\4.0.0-beta0013custom1\\GitVersion.exe /output buildserver /nocache'
def props = readProperties file: 'gitversion.properties'
def preReleaseWeight = [alpha:0, beta:30000, '':60000] // no prerelease-label means final release
def currentWeight = preReleaseWeight.get(props.GitVersion_PreReleaseLabel, 0) // default: 0 for everything else not in the mapping
def toIntOrZero = { try { Integer.parseInt(it) } catch (NumberFormatException) { 0 }} // GitVersion_PreReleaseNumber may be an empty string
def weightedPreReleaseNumber = toIntOrZero(props.GitVersion_PreReleaseNumber) + currentWeight
withEnv(["WeightedPreReleaseNumber=${weightedPreReleaseNumber}"]) {
    // calling msbuild....
}

So basically call gitversion, use GitVersion_PreReleaseLabel to get the corresponding offset from a dictionaly and add this offset to GitVersion_PreReleaseNumber. Export the result in an environmental variable you reference from a format string in your gitversion.yml: assembly-versioning-format: '{MajorMinorPatch}.{env:WeightedPreReleaseNumber ?? 0}'.

The downside is that gitversion is executed twice and the gotcha with the order of the CLI parameters and the requirement for /nocache. So in terms of usability it would still be nice if GitVersion would support the WeightedPreReleaseNumnber natively, but generally using env-vars in format strings is flexible enough to address your particular issue, too.

@BCSharp
Copy link
Author

BCSharp commented Apr 13, 2018

Yes, there are workarounds possible. I have mine too, all done in MSBuild scripts, using GitVersionTask; I do not use Jenkins. Not that the workarounds are nice. Having #1385 helps, though.

@ruhullahshah
Copy link
Contributor

ruhullahshah commented Jul 2, 2018

#1433 Waiting for this PR to get merged

@stale
Copy link

stale bot commented Jun 29, 2019

This issue has been automatically marked as stale because it has not had recent activity. After 30 days from now, it will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Jun 29, 2019
@stale stale bot closed this as completed Jul 29, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

6 participants