-
-
Notifications
You must be signed in to change notification settings - Fork 173
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
Allow user control of build number integer #119
Conversation
This allows folks who want to do particularly custom things with their versioning stamps to have a bit more data from the version.json file with which to work. Fixes #115
@onovotny can you confirm this will unblock you? |
I think so...? I need to play with it. I think what I need then is a custom targets to build the version from that, right? |
Yes. Do you mind playing with based on the package on AppVeyor's package feed (https://ci.appveyor.com/nuget/nerdbank-gitversioning) from this PR? |
Will try it out tomorrow or over the weekend and get back to you, thanks! |
Still looking at it, but one thing I noticed is that if I call |
I noticed that other than returning the value, everything else that uses it ignore it -- CloudBuildNumber, AssemblyInformationalVersion, etc. Possibly, one suggestion is that if
If I build on this PR to make those changes based on the value of |
I had briefly considered actually consuming the number when we first chatted about the idea. There are actually several projects that do specify a 3rd integer right now (of zero) in their version that is currently ignored so NB.GV changing its behavior based on its presence would be a breaking change. That might be tolerable, but I'll have to buy into the idea first and that takes more time. :) My first inclination is that if NB.GV was going to change its built-in logic to allow for this, I may perhaps let you describe it in the version.json with macros, for example: {
"version": "2.4.3-alpha.{height}"
} Which you could then put height anywhere. I need to think about that more though. In the meantime, yes I'm concerned about exposing this |
One possible approach is to control it by adding another property similar to how GitVersion does it -- an enum that has This could be in addition to any templating improvements. I could imagine that people could find an AssemblyInformationlVersion template useful too, potentially with different values than the regular version. |
One thing I'd need to figure out first is where would I put the git height if
Another concern I have with this whole thing is that one tenet of NB.GV is that every commit produces a unique versioned package. But in the releasing branch (e.g. master) where a pre-release tag is not acceptable to include, a |
I think that having the height as a I think they key here is that |
I'm mostly comfortable with users of NB.GV making that choice. I personally don't agree.
Semver demands that That's why I'm so opposed to it.
I just don't think it matters. I've never had a single user complain or express confusion at why a package jumped from 1.0.5 to 1.0.35. |
I don't mind the fourth number existing, but I personally wouldn't use it for NuGet versions. I don't know of many packages that do a four part version. I know I could override that NuGet version in a Targets though. In my primary workflow, I tend to rely on pushing to MyGet with a "preview" tag and then at some point, I'll push from MyGet to NuGet using MyGet's prerelease rewriting to remove the prerelease tag. I don't generally merge to Master and then do a build...no reason why I couldn't though and that might eventually be required if Package Signing ever becomes a thing making the rewriting impossible. That said, MyGet does allow for replacing existing package versions so if there was a case where a package had the same NuGet version (but different internal 4 part versions stamped), MyGet would happily accept that. Clearly package caching is still an issue. What do you think about AssemblyVersion? I know there's arguments on all sides due to binding redirects; some people advocate using only a major version for that, etc. Do you think it should be |
I personally avoid this feature for two reasons:
So instead, when I'm ready to release a package, I strip the
Myget is only a small part of the problem. When I'm developing packages I often consume them locally as I'm developing them. If I can't commit and build again and get a unique version, that local package cache issue immediately becomes very troublesome.
NB.GV already allows a lot of flexibility on this point. You can set AssemblyVersion to any major.minor version you want. Or you can set it to follow any of the 4 levels of precision in matching the AssemblyFileVersion. So you can do Major, Major.Minor, Major.Minor.Build, or Major.Minor.Build.Precision. Personally, consistent with semver semantics, I prefer to lock AssemblyVersion to major.minor. Patches should be in-place swappable so a binding redirect change is unacceptable. So the 3rd integer must not be in the assembly version. But I am in favor of incrementing the minor component of an AssemblyVersion consistent with AssemblyFileVersion, and I bump the minor component whenever I add a feature, including adding any public APIs. This is because I find diagnosing an exception that states "I was looking for version 1.2.0.0 but found 1.1.0.0" much easier to diagnose and correct than a MissingMethodException is to figure out what in heck went wrong. Binding redirects don't scare me. They are created automatically by the build anyway. So there's no big deal (modulo patch theory, as I've stated). |
One thing I just thought of where a three part version is mandatory is the |
Interesting scenario. NB.GV doesn't have anything specific to support Store apps at this point. Where does the version that is set in the appxmanifest come from? Does the user have to bump it every time (in which case NB.GV is irrelevant) or can it be calculated by the build like source.extension.vsixmanifest files allow? |
The version is prompted in the wizard when done from the VS UI, but there's nothing special that does it from a CI build ... people have to write up a regex or XML-based task to set the version. Not too hard with PowerShell but still something that needs to be done. The version should be bumped for each release to the store/user machine.... basically the same as NuGet. |
Well, I'm not a fan of changing source code during the build. But if I could copy that file, change the version, and then point the build at the copied and modified file, that would work. But I'd wait for a customer to ask for it. I have no need for it myself as I don't develop store apps. |
Agreed -- not suggesting that NB.GV do it -- I guess the ask would just be to ensure that the |
5f08205
to
68405a7
Compare
The preceding commits constitute at least a minor breaking change and a higher level of flexibility
@onovotny If you don't see your scenario covered in the tests I added, or don't like the results they assert, please let me know. Actually, can you let me know either way? As I'd very much like your validation on this before I complete the PR. |
Will try it out with a few projects -- what's the best feed for this (myget, AppVeyor CI?) and are there any specifics I should look for in the MSBuild tasks and/or config as I play around with it? |
Found it...couple of thoughts:
Here is the build output I get with a version of
Everything looks great, except for wanting the ability to not have the commit id in the prerelease tag for NuGet and/or SemVer1. It'd be nice if that was an option. In those case, it may be worth having an optional "padding" parameter where the height gets padded with 0's due to SemVer1/NuGet's sorting oddities. As it is so far, none of the numbers are directly useful by NuGet.org since it doesn't allow SemVer 2; I'd need something like With those, I think that should meet my needs. So far, it's looking really good though! |
Thanks for your review.
Per (at least my reading of) semver rule 9, an identifier is only sorted numerically if it is entirely numeric. For instance, two identifiers "beta-5" and "beta-42" would sort incorrectly with 5 as superior to 42 I believe. But "beta.5" and "beta.42" would sort with 42 as superior to 5.
That's an interesting one, if semver1 is actually interesting any more. But I'm curious whether it really is.
It is an option. The prerelease identifier with the git commit ID is always added (whether building prerelease or not) if and only if you are not building a "public release". You can build with I'll try to find some nuget.org docs on semver 2 support, unless you already know where they are. |
The format, For NuGet SemVer v2 support, I've been hearing about it for awhile...and it'd solve so many hacks once they do. Just yesterday, as I was publishing Rx.NET 4 preview 1, I had to go to annoying lengths since I couldn't publish 4.0.0-preview.1. |
I think I'll go with 4 digit padding, but make it configurable for folks who anticipate 5 digits. |
That sounds perfect, then the SemVer2 value can be used for the NuGet version at some point once nuget.org supports it (with much rejoicing). |
@onovotny Wanna take another look now?
The appveyor feed: https://ci.appveyor.com/nuget/nerdbank-gitversioning |
Looking really good, I think I can use this in it's current form! Here's with a non-public-release branch:
And here's the same as a public release
|
Actually, one catch --
I should think the I can modify the values in targets, but just wondering about your thoughts around defaults? |
That is the best way for now. Combining |
@emgarten any ETA on when NuGet.org will support SemVer2 packages? Would love to get rid of the hoop-jumping we're doing for v1 support. |
@onovotny not sure on the ETA but it is in progress. NuGet/NuGetGallery#3547 |
I agree. And NB.GV already supports and in facts defaults to something different than your output shows. For example, consider the output of the
Notice how the assembly version is only the major.minor of the assembly file version. This is the default behavior. For the output you're getting, I expect you're changing the default using a {
"version": "3.2.1-alpha.{height}",
"assemblyVersion": {
"precision": "revision"
}
} But if you drop the |
I've pushed a branch here: https://github.com/Reactive-Extensions/Rx.NET/tree/nbgv, the file is here: https://github.com/Reactive-Extensions/Rx.NET/blob/nbgv/Ix.NET/Source/version.json I do have "assemblyVersion": {
"precision": "revision"
} What should it be to get major/minor or major/minor/patch only? |
Answered my own question, looks like I need to use either minor or build here, https://github.com/AArnott/Nerdbank.GitVersioning/blob/4d80666c500dcab6ea6b6daaef2e47329dde9d90/src/NerdBank.GitVersioning/version.schema.json#L23
|
OK, good. So you're seeing exactly what I expected you to see. Why are you setting Just drop the field entirely if you want the default major.minor behavior. There is a JSON schema file, but you're not getting it because your schema line is wrong. If you remove it, some editors will automatically pick up the right one since I have "$schema": "https://raw.githubusercontent.com/AArnott/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json" Then Intellisense in your editor should help you discover that |
I think I had it set from when I was trying to get it to work before this PR was redone :) What do you generally think for assembly version, |
The one thing I'd suggest is to have a work item based on NuGet/NuGetGallery#3547 to flip the meaning of |
CoreFx folks prefer |
I'm stewing on the decision to bump this to version 2.0 and whether any more docs in the repo need to be updated to accommodate this change before merging. I hope to merge later tonight though. One regression I anticipate from this change is that the |
@AArnott one last Q, I think -- when it's time to do an actual release, what's the right way to do that? do I check in a new version.json without the prerelease tag or can I just tag a version and will it detect the tag and drop the pre-release label for that commit? |
Yes, but I personally usually don't wait for the actual release to do that. When the product is stable, I remove the unstable tag. I may not push a build to nuget.org for 20-30 more commits, but from the stable point on, my CI is building without the prerelease tag. And as I generally try to accompany any code changes with test additions, my code tends to always be stable (modulo a bug or two at times), so I usually use the prerelease tag for long-running feature development or leading up to v1 releases. I also update the version.json as soon as I know I'm working on v.next where the version would be bumped. For example, if I shipped 1.1 and know that 1.2 is coming up next, I'll go ahead and bump version.json as soon as 1.1 ships rather than building 1.1.x packages until I'm about to ship 1.2 and update it at the last minute.
No. Tags can be added to commits later, so the presence of any tag makes no difference to the build or else it violates build reproducibility, which is a firm tenet with NB.GV. The only effect tags or branches can have on versioning is automatically applying |
@AArnott if that's not already in the docs, that process would make a great addition :) |
The Overview section of the README covers the fact that branches and tags don't change the built version. But it doesn't go into the workflow of updating the version right after a release. Is that what you found interesting but not documented? I just want to double check what you thought should be documented before I take time to write it up. |
@AArnott Yep, I think the actual process of updating the version.txt/json around a release would be useful to spell out. |
Found one potential issue with the non public releases. Take the version Seems like we'd need to mark that branch as a release branch -- wonder if it's worth any sort of warning text, but you have no way of really knowing if they're using the version for NuGet or something else. |
@AArnott FYI dotnet/reactive#402. Will switch to a "public" build once it's on NuGet. |
This allows folks who want to do particularly custom things with their versioning stamps to have a bit more data from the version.json file with which to work.
Fixes #115