-
Notifications
You must be signed in to change notification settings - Fork 722
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
Define NUnit Versioning for post-3.0 Development #981
Comments
I'm posting the text of an email I sent to the developer list on the same subject. It contains my own thoughts on the various questions to be resolved. On Sun, Nov 1, 2015 at 4:54 PM, Charlie Poole charliepoole@gmail.com wrote:
|
I like what is implemented in #932, probably with some tweaks. I think that we should go with, Major - Is currently 3 and will not change unless there are breaking changes to the API. Hopefully not for a long time 😄 Minor - Increments for feature releases. Hopefully we will be creating these releases often once 3.0 is released. I am fine if we use the even/odd semantic version to indicate development releases, but I think that a suffix conveys that more clearly. Build - Increments constantly by AppVeyor. When released without a suffix and without incrementing Minor, is a bugfix only release (hotfix?). If we are doing regular feature releases, I would hope that these are rare and only to fix serious bugs. Suffix - If present, indicates a prerelease. This suffix can be anything,
If you mean the third digit being 1xx, 2xx, etc, then no. As we discussed privately, I would rather see the third digit incrementing with each CI build of AppVeyor.
To me, bugfix releases increment the third digit, so 3.0.{build}.
3.1.{build}-beta
To me, the fact that they are on the AppVeyor nuget feed indicates that they are nightlies. I don't think it needs to be clearly distinguished because people that go to the trouble of setting up NuGet to consume from that feed will know they are nightlies. Nightlies that we have tested and uploaded to NuGet.org are considered known goods. If they have a suffix, they are prerelease, if not, they are official releases.
I think that we should decide now and stick with it for the next feature release. |
@rprouse I think you mixed AssemblyVersion with package version in a few places. The incrementing number generated for Appveyor builds would be part of the package version, not the assembly version and I think most of what you write above the quote containing PACKAGE VERSION is actually about the package as well. But it's all good, because what I see is that the package version is what's mostly on your mind - and maybe what should be on all our minds. It's what the users see and what they download. So, henceforth, I'm giving the package version priority. We can come back to Assembly Version. WRT PACKAGE VERSION, there are few no-brainers - or at least things we seem to agree on. Stop me if I'm wrong!
WRT ASSEMBLY VERSION (by which I mean the value of the AssemblyVersionAttribute) we seem to agree on a few things, even if it's only implied agreement.
Do you all agree that the above are decided things? If so, the areas of further discussion can be limited a bit, which I think will be helpful. The rest of this too-long comment is about those areas that remain, as far as I have got them right anyway. ODD-EVEN MINOR VERSION SPLIT We actually have nominal agreement on this, but I'm not sure everyone agreed to the same thing! Here is what it means to me.
A few implementation details, which should not be our main focus at this instant, but which may illuminate some of the above...
ASSEMBLY VERSIONS Assuming we agree on the major and minor versions, what's left is the third and fourth component. I think that @oznetmaster and @rprouse have each made proposals that imply control by us of the third component of AssemblyVersion. Neil wants 200+ for RCs, for example, while Rob suggests a constantly incrementing number. I once did this for NUnit, many releases back. I set the third component to a calculated value based on the Julian date. I abandoned it because of some problems. I would be in favor of controlling this njumber if we could solve all the problems, but I'm not sure we can.
For all those reasons, I have so far left the third and fourth components floating. I'm willing to listen to reason, however. :-) Sorry this is so long and rambling... I suggest we try to discuss, in order, and possibly in separate comments:
|
The problem with the scheme you have proposed is that the AseemblyVersionAttribute only takes versions of the form The --version command has to provide information that will uniquely identify the current version of the framework, including things like betax and rc. If the version that is displayed is to continue to be obtained from the AssemblyVersionAttribute, then that version number is going to have to redefined to include all significant information. |
@oznetmaster We can't tell whose comment you are referring to in this issue, but I think "you" means @rprouse in this instant. :-) I agree. I think Rob was actually talking about the package version. The --version option could be impacted by what we decide, as you say. But I think it's secondary. We'll have to re-address it after we make changes to the version number. That said, I don't believe the version shown by the console runner can ever include a package suffix. I understand it's technically possible, if we add the package version to some other attribute besides AssemblyVersion, but it's not desirable in my view. Just as an object does not normally know what collections or arrays it is held in, an assembly can't really know what packages are including it. We may very well end up including the same assembly in multiple packages, without change. The version displayed by nunit-console, even back in 2.x, has always been an assembly version. We add (Debug) as appropriate. In the case of NUnitLite, we also add the runtime for which it was built. But we can't really say that it's a beta and I don't think we want to. However, if somebody needs to know that, they have always had the capability to look up which package release contained the nunit-console assembly at a particular version. I have filed an issue indicating we need a page that gives users that information for our 3.0 releases. |
Yes, I am talking about the package version. The main way to get NUnit these days is through NuGet, so I am mainly thinking about what we expose there. The internal version numbers are less important to me, but at least the third digit needs to increment with each release otherwise we will run into problems with the MSI install. |
You have my agreement on what we agreed upon 😄 You also pretty much have my agreement on everything down to the ASSEMBLY VERSIONS line. I agree with this if the third digit is constantly incrementing on one CI server like AppVeyor and it becomes the authority. I say that because it gives us a measure of flexibility with the suffix. If the third digit increments, then the suffixes can be in any alpha order. For local developer builds, what we do is set the third digit for the package and 3rd/4th for the assembly to 99999. Only official builds have non-99999 numbers. We could then use a build script like the one for the Cake project https://github.com/cake-build/cake/blob/develop/build.cake that knows when it is running on AppVeyor and patches the AssemblyInfo versions. |
@rprouse Well agreeing on what we agree on is definitely a step! :-) The third digit of the package version definitely needs to increment continuously. However, I can't see the Appveyor build number (for example) becoming "authoritative". We may end up using some other CI service instead or in addition. Or we may build it ourselves. I was considering separate suffixes as a way to distinguish the meaning of the third digit. So if it's CI, then it's an Appveyor build number and should only be compared with other packages having the CI suffix. Of course, I realize that is not how the NuGet client compares suffixes. People using the CI build would be forced to manually choose what release they want. That doesn't seem a terrible burden for the folks who would be using it. I already explained why I don't like the approach of using the desired package number to patch AssemblyInfo. I'll just add it's not because I'm unfamiliar with how it's done by Cake and other projects. It's been done that way by many projects I have worked on. I just think it's a bad idea unless you have a way to force the same number into all ways of building. Let me put it another way. What problems do you see with AssemblyVersion 3.0..? |
To be honest, I don't see problems, I am only proposing ways we can set those numbers and keep them in sync. I actually think we are in agreement on pretty much everything other than AppVeyor becoming the authorative build which I understand. To me, it is just a proposal. I am really just interested in how we maintain that third digit incrementing and make the AssemblyVersion match the package versions. So, I think we are pretty close to agreeing on everything except the process of creating the versions. Do you agree that we agree? 😄 That said, it doesn't mean others agree, so @nunit/contributors, please comment if you have opinions or ideas on how we should version NUnit going forward. |
I think we are a little bit farther apart than that, but not much. I don't think actually think it is necessary to try to make assembly versions match package versions. I even worry that this coupling could cause problems, once we start releasing updates of individual components. That does mean we can, depending on what other @nunit/contributors think, start implementing the package version side of this. |
If as you mention in other places, we maintain a list of at least the major components assembly versions along with the packages they are shipped in, then I am not wed to the idea of keeping in sync with the package version. For example, if the console does not change, we could ship an older version in the installer than that of the framework. I think the first two digits of the assembly version should probably reflect the package version, but even there, there could be some files that are older. The engine API for example, or even the engine if it doesn't change. |
I haven't time to go thru whole discussion yet, so appology if notes below are covered already. @rprouse Are you going distribute older version of binary in the package then? If not - with respect how some of the components are compiled (references to other files with conditional compilation) I believe that you would actually rebuild and ship a new binary which should have new version (it sounds odd to have different binaries with matching version) although it might be exactly same from the functional perspective. One more thing to consider - you package version can perhaps match assembly file version (not assembly version). So in Windows you can easily see the shipped version which can match the package version. And for assembly version which is used as a strong name component for reference you can use different scheme. Obviously - no idea if that will help on linux platforms... |
@voloda Let's divide our packages into two groups:
In case 1, I agree that it makes perfect sense for the assembly and package versions to be in sync. We can even use AssemblyFileVersion to include the suffixes. In case 2, I think it makes very little sense. Let's take a hypothetical case. Suppose we decide to do a master zip or msi that includes framework, engine, console, gui and project editor. Those are all existing components, except for the gui, which I'm working on privately. None of them have references to one another, although both runners reference the framework API, which is frozen at 3.0.0.0. Forcing them all to the same version number means rebuilding everything. That's much more complicated than simply pulling them into a common directory structure and creating the package. So basically, I'm saying that some packages are single-purpose and others are collections. They seem to need different rules. BTW, if I could get away with it, I'd completely do away with the aggregate packages. But Windows folks do like their msis. :-) |
In this post, I'm going to try to sum up all the discussions... Hope it works! DEFINITIONS / GIVENS
DECISIONS (with UNDECIDED items interspersed)
UNDECIDED: What about the AssemblyVersion? Should we use 3.2.0.* or 3.2..?
UNDECIDED: What about the AssembyVersion and AssemblyFileVersion? should we inject the build number into them? @rprouse @oznetmaster @OsirisTerje Does this match your understanding? What about the undecided items? |
For the DECIDED, I agree 😄 For the AssemblyVersion, I am now in the 3.2.0.* camp. I am not a fan of the odd minor being a dev version, but that is just a matter of taste and I don't really care, so I am happy to agree with everything in that section given the 3.2.0.* format. As for injecting the version, I am for whatever we can do to simplify developing and releasing. I like the way that the Cake team pulls the version out of the release notes and injects it. I don't think we should get too hung up on this though, it seems easy enough to change in the future if we don't like whatever we initially decide on. I would add one UNDECIDED item. I think you may have implied it, but should the AssemblyVersion match the AssemblyFileVersion? We currently allow the AssemblyVersion to drive the file version. For NuGet, it isn't important. we will have the package version which is set by CI or a release and the references will show 3.2.0.xxxx which indicate exactly which version of the framework you are using. To me, that is good enough. The downside is that during development, the revision will not increment, so people using the MSI will need to uninstall first. I think this is a common problem, so not something we need to worry about. We could also just not produce MSI's as build artifacts to prevent any possible confusion. Lastly, I think the engine.api needs to be a special case. In this one, AssemblyVersion should always be 3.0.0, but we need to start setting the AssemblyFileVersion to be the release version, for example, 3.2.0. We need to do this so that the api assembly gets updated by the MSI install. Ideally, we will eventually start injecting this version from wherever we get the AssemblyVersion for the rest of the assemblies. |
I'd like to go with the odd minor because I've seen it work well on some Linux projects. That said, I haven't tried it with a bunch of MS-oriented users, so we'll see. Here is why I like it:
Of course, like anything, we'll have to try it to see if it really does all that. |
Versioning odds and ends: I'm OK with 3.2.0.. In fact, that's what we did for NUnit 2.5 and 2.6. There's an implementation detail as to whether we use Microsoft's implementation of '' or inject the build ourselves. That's what we did in V2, using a coded value that represented the date of release. Regarding your comment about a downside: I don't see that. "During development" we're on 3.1, not 3.2 and the revision number is the Appveyor build number. There are no 3.2 releases (with fixed revison) during development, but only at the end of development. The odd/even convention permits us to have a different naming standard for the stable and unstable "branches." API Assembly: Yes, I was assuming it's a special case. |
This all seems good to me. I like the idea of using a coded release date for the build, if that does not complicate things too much. |
For reference, here's the logic used to generate the fourth component for the V2 version: |
We need to keep #1108 in mind when working this one. |
I'm re-summarizing the discussion here, hoping we have a resolution... DEFINITIONS / GIVENS
DECISIONS (with UNDECIDED items interspersed)
@rprouse @nunit/core-team Does this match your understandings now? |
@nunit/core-team This will require a relatively small change to the build script, which I will do once we are agreed on how it should work. |
This also sounds pretty straight forward. I understand the need for separation with the odd minor numbers only being development versions, because we are storing the major/minor in the repo and its updated manually this will assist in mitigating development versions leaking out, but i think long term this may confuse some people if for example version 3.3 was never released. I have few ideas about how to automate this but am still learning what you guys have setup, so will save the feedback for another issue. I'm just a little bit not clear on how when doing an official release the build number is incremented? do you guys have a separate build somewhere for generating the release that is run manually? I did notice a text file in the repo about creating a release that has some manual steps, is this how a full release is done now? or is this document old? Just on another topic, How about about pushing the CI build or a nightly build to nuget.org flagged as a pre-release package? So people can easily beta test the new versions. |
@dicko2 Best way to see how we build is to look at the build.cake script. The way we update our build is by modifying the script for releases. We don't use nuget.org for anything except "real" (i.e. stable) releases. Development packages are produced by our CI build on AppVeyor and nuget packages are available from our Appveyor nuget feed. They may be published on myget eventually. Right now, our production release is manual but that will change as we progress. |
@dicko2 The odd / even convention is pretty common in Open Source, particularly on Linux. It's true that it may confuse some users but I think that's not much of a problem because they would have to go out of their way to build or find a dev release. Also, the packages we have been producing are pretty clearly suffixed with -CI-nnnn. Anyone who goes to nuget.org can only get a stable release. |
This matches my understanding. I believe we have almost all of this already built into our build at this point except for the deterministic revision number for releases. @CharliePoole Is this the change you mention? Is there anything else outstanding? |
@rprouse That's the only change I'm aware of. If we're in agreement, I'll put in the code, translating from our V2 NAnt to C#/Cake. Are you ok with being limited to one version per day with the yyjjjj format? Essentially, an emergency update the same day would have to either increment the build number or use the exact same assembly version. |
@CharliePoole the one revision per day does worry me, but the MSI install does not overwrite on the revision, so even an emergency build would likely require a build number increment. |
Yet another reason to get rid of MSIs? :-) |
I actually don't mind getting rid of the MSI's. I think NuGet should be our primary source with binary ZIP files for people who need them. |
For 3.2? |
Let's keep them for 3.2. We should probably look at the number of downloads of the installer vs the nuget packages of the runners and make an informed decision. We should also give the community time to comment. |
OK, back to the generated revision number... Here's the problem... In NUnit V2, we generated a file called GeneratedAssemblyInfo.cs and used that in the build, leaving the original AssemblyInfo files untouched. We could do that because the NAnt tasks we used were basically command-line compiles and didn't use the VS project file at all. With 3.0, we build each project using MsBuild. The AssemblyInfo files are right in there as are our separate files that carry the AssemblyVersionAttribute. Any files we overwrite in the build script would stay changed on disk whenever the build script is run locally. We could work around that, but it will start to get complicated since we have multiple AssemblyInfo files, a CommonAssemblyInfo file and four XxxxxxVersion files. I'm wondering: is there a downside to just leaving the revision number at zero? |
I can't think of a problem with zero, it better reflects our intentions. Also, since we will immediately tick over to 3.3, there won't be many CI builds to cause confusion. If it bothers us, we can look at delay signing and injecting the version or something like that. |
Let's go with that for the release then. I'll check to see if there is anything to update before you branch, but i don't think there will be. |
Closed by PR #1314 |
We can't push any code for post-3.0 changes without first deciding on future assembly versioning, at least if we think we may want to change away from use of 3.x.. That makes this an immediate priority, since some of us are working on 3.0 stuff already!
Our package versioning is only slightly less critical. We can push but we can't create any CI, nightly or weekly packages until we decide about it. So I'm dealing with both types here
ASSEMBLY VERSIONS
We currently define assembly versions as 3.0.. for most assemblies. The sole exception is nunit.engine.api, which uses 3.0.0.0 for all releases. We can change this only for 3.1 and subsequent versions, because changing it for 3.0 would mess up the ordering of versions.
QUESTION: Do we want to start controlling the third digit of assembly version with 3.1 as has been suggested by @oznetmaster ?
PACKAGE VERSIONS:
We have so far put out packages numbered 3.0.0, with various suffixes. We will eventually put out our final release packages as "3.0.0"
QUESTION: What do we want to call bug fix releases of 3.0?
QUESTION: What will we call packages that we generate in CI? We know they will start with 3.1, but what comes after that?
QUESTION: Do we want any other development packages like nightly, weekly? What will we call them? It has to be consistent with the CI packages but also clearly distinguished, perhaps by a suffix.
QUESTION: What about the 3.2 release? We won't get to it for a few months but how do we want to version it. Is what we are doing for 3.0 OK or will it be something else? Obviously, this question is not critical immediately, but we may want to know where we are going in advance.
The text was updated successfully, but these errors were encountered: