nunit / NUnit.System.Linq

Partial implementation of System.Linq for use with NUnit's .NET 2.0 builds
MIT License
1 stars 4 forks source link

Standardize version number generation #8

Open CharliePoole opened 8 years ago

CharliePoole commented 8 years ago

The versions now being generated by GitVersion for NUnit.System.Linq follow GitVersion's internal standards, which are not the same as our own.

The latest master build would have been something like 0.6.1-CI-23 by our current standards. However, the GitVersion generated numbering is 0.6.1+23.build.62 and the package published to MyGet is version 0.6.1. I'm assuming the internal AssemblyVersion is also 0.6.1 as we can't actually tell any longer without examining the assembly.

All of this is OK and expected at this point. NUnit.System.Linq was chosen for us to work with GitVersion because it is only used by us. However, we should conclude our experiments quickly and remove any extraneous packages form MyGet.

This issue will be used to decide on our versioning going forward and will also apply to other packages.

@asbjornu I'll get this started by creating a branch and giving you access to it.

CharliePoole commented 8 years ago

I created the issue-8 branch and added @asbjornu as a collaborator for this repo. it seems to me that the first step is to generate the configuration so we can see it. Right?

CharliePoole commented 8 years ago

Oh... I see you're in Oslo and probably asleep now. :-) When you're available, would you generate the configuration and push to the branch? Then we can figure out together with other developers on the team how we may want to modify it.

I'm currently working on the NUnit 3 TestAdapter 3.4 release. Once that's out, I want to start following in your footsteps to get this implemented in that project.

asbjornu commented 8 years ago

@CharliePoole Just to get this right, what you'd like to replicate with GitVersion are these lines that were removed from build.cake?

var tag = AppVeyor.Environment.Repository.Tag;      

if (tag.IsTag)      
{       
    packageVersion = tag.Name;      
}       
else        
{       
    var buildNumber = AppVeyor.Environment.Build.Number;        
    packageVersion = version + "-CI-" + buildNumber + dbgSuffix;        
    if (AppVeyor.Environment.PullRequest.IsPullRequest)     
        packageVersion += "-PR-" + AppVeyor.Environment.PullRequest.Number;     
    else if (AppVeyor.Environment.Repository.Branch.StartsWith("release", StringComparison.OrdinalIgnoreCase))      
        packageVersion += "-PRE-" + buildNumber;        
    else        
        packageVersion += "-" + AppVeyor.Environment.Repository.Branch;     
}
CharliePoole commented 8 years ago

No...but that code represents our existing branch naming policy. The new policy in this repo is "whatever invisible thing GitVersion is doing" :-)

Whatever we do in this repo will be ported to all of our NUnit projects. Those projects have public feeds - as opposed to this one, which is publicly accessible but not advertised or used by anyone except us. Since we almost never expect to change this repo, it's a good one for experiments, but if we had done the same thing in the nunit project, for example, all of our feeds would now be broken.

So we need to

  1. Make the configuration visible
  2. Decide what we want the new standard to be
  3. Implement it in this repo
  4. Port it to all our other repos

In an earlier comment, you said that you could create a config file that we would then change to set standards for versioning, including per-branch standards. Creating it would be step 1, which is what I was asking you to do. Right now, looking at the generated versions we don't even know what they mean. Some of them contain two int numbers, for example. How does the programmer know where they came from? How does the user know what they are if we publish them? Which ones do we want to deploy? So it seems to me that visibility is the first step to getting anywhere with this.

If you could easily add comments or even change it to replicate the existing standard, that would be great, but you shouldn't spend a lot of effort on that because it's pretty certain that some parts of the existing standard will be changed in step 2 anyway because GitVersion gives us better capabilities.

This Issue is going to be more about discussion with the team than coding. :-)

asbjornu commented 8 years ago

@CharliePoole I see. I've committed and pushed a GitVersion.yml file with the defaults, so we can now go on and adjust them. I'm just not entirely sure what I'm supposed to adjust. :smile:

CharliePoole commented 8 years ago

That's why we're pairing on this issue. Anyway, I'm not sure either, but I expect we'll get sure as we proceed. I'll take a look and post any questions for you, then I'll start to invite other people to the party.

asbjornu commented 8 years ago

@CharliePoole Excellent! :+1:

CharliePoole commented 8 years ago

OK... First question... it seems like the way we work is more like ContinuousDeployment than ContinuousDelivery. Can you tell me (or point me to info about) how GitVersion acts differently using the two modes?

CharliePoole commented 8 years ago

Never mind... I got the terms switched in my brain... I'm used to "deployment" meaning not yet in production but ready for it but the modern usage is that deployment == to production. If you work long enough, the terms don't just change they even reverse meanings!

CharliePoole commented 8 years ago

I found the reference doc, which is helping a bit.

asbjornu commented 8 years ago

@CharliePoole Yea, the documentation is quite extensive. Glad you figured it out, although I agree that the terms "deployment" and "delivery" are ambiguous, which makes them hard to distinguish.

CharliePoole commented 8 years ago

OK, another couple of questions...

What if the branch doesn't match any of the patterns?

What if you aren't on a branch at all - i.e. you just took an export of the code from git?

CharliePoole commented 8 years ago

@nunit/core-team @nunit/vs-extensions-team @nunit/contributors

I'm using this issue, as a vehicle to figure out how we should be doing versioning across all our projects. Please read the comments and tune in to what is discussed here as it will impact a lot of stuff.

Questions to be sorted out, eventually...

Should every build use a unique version? file virsion? informational version?

Which builds should be on feeds? How many feeds? How versioned?

Finally - what exact naming pattern will we use for each kind of package we build.

All of this in the context of what GitVersion is capable of.

asbjornu commented 8 years ago

@CharliePoole:

What if the branch doesn't match any of the patterns?

The default naming strategy is to include the name of the branch. This is expressed through the tag configuration property, which has useBranchName as the default for all branches except known git flow branches such as:

These known branches have default as can be seen in the GitVersion.yml file.

What if you aren't on a branch at all - i.e. you just took an export of the code from git?

Then we have a problem. It can be addressed by Cake, for instance, but without the .git folder, GitVersion is clueless.

CharliePoole commented 8 years ago

Is there an alternative where we keep version info for use in such builds in AssemblyInfo.cs but write and use a modified copy for the builds where GitVersion comes into play? Alternatively, is there a way to tell GitVersion "If running outside of a repository, use this version as the default?"

CharliePoole commented 8 years ago

To be clear, I'm just gathering info here. I'm not sure this is really that great a problem any longer, now that we use Git. In the far past, with CVS, there was a much greater need to use exported source.

@nunit/core-team What do you think? Is it OK that our AssemblyInfo.cs contains no version info but that it gets filled in by GitVersion when it's being built? Come to think of it, should we be packaging source at all these days, when people can just clone our repository? As always in this issue, I'm talking about all our projects, not just NUnit.System.Linq.

rprouse commented 8 years ago

I've been questioning the need to package source lately, especially since GitHub creates a ZIP download whenever we tag a release. I am also fine with the version getting filled in at compile time, it is actually closer to where I wanted to get. It would be nice if there was only one authoritative version for each repository.

I've never tried it, but do you get a default version if not is specified and GitVersion hasn't injected one? In other words, is AssemblyVersion or FileVersion required to compile? Does GitVersion only inject the version, or can it overwrite one if present? If so, we could put something like 9.9.9.9 into the various AssemblyInfos to indicate it is an unofficial build.

OsirisTerje commented 8 years ago

I'm fine with gitversion handling this. The assemblyinfo files should then stay with 1.0.0.0, and prod would almost always be higher (!). @rprouse : having it at 9.9.9.9 means higher than most of what we have, I would like to see it lower, so that prod versions always takes precedence.
Source is on github, so fully agree it is not needed in release packages. A link is more than enough.

About feeds: one production feed (nuget.org), and a prerelease feed on myget would be nice. Many have nightly feeds, but I think a prerelease feed is more important. Anyone can build from sources if they want the latest.

Build numbers would be updated on each build, the latest being the the incrementally updated number. Versions should be identical, except for the last part, but pre-releaseinfo should be kept.

And just throwing in: We talked earlier of an odd- even practice on build numbers, to separate out release versions from pre-release and things-in-process. nuget would not need that, since it has the letters (1.2.3-beta1) to indicate pre-releases, but anything else would need something else. I am not sure how gitversion handles this..... Packages should follow closely to the build numbers, if the build is a pre-release, the package should be marked as such.

CharliePoole commented 8 years ago

Easy decisions first: let's stop packaging source then! I'll make the change right away in this one and in the NUnit 3 Test Adapter, which has an outstanding PR. We can drop source in others as it's convenient.

AssemblyVersion: As currently implemented by @asbjornu we don't have any version in the AssemblyInfo for this repo. To implement that, he used the GitVersion msbuild task, which will execute whenever anybody builds this project, following the rules we establish for versioning. The assemblyinfo in GitHub is replaced by a generated one that adds assembly and file versions.

I was dubious but became convinced that it's a good approach. There will be no version info in any of our files, therefore we will have nothing to update. Builds on local systems will do the same thing as builds on AppVeyor or Travis. Still, I admit that not having it in the file makes me nervous. I'm hoping that getting more familiar with GitVersion will make me more comfortable. Right now, I don't understand enough to know what version it is that I'm about to build!

I have asked @asbjornu if there is an alternate way that this can work where we continue to have a fixed version in the AssemblyInfo. Waiting to hear back.

@rprouse I don't know what happens if you happen to build without specifying a version anywhere. I'll have to do an experiment on that. Still... in principle this would only happen if somebody did an export and made a non-git directory, so it's very much an edge case.

@OsirisTerje Yes, two feeds is what I think as well. The way I have implemented it here, only merged builds of master go to the MyGet feed. Rob and I have also talked about using the account feed on AppVeyor instead of the Project feed as we now do. It seems we are probably misusing the project feed and it suffers from the fact that we can't remove anything!

@OsirisTerje Could you clarify what you mean by incrementing the build number? The term is used in a few different ways: part of the standard assembly version, the AppVeyor build number, the build number that GitVersion tacks on as metdadata!

One issue we will need to deal with... vsix packages can't use a prerelease suffix internally. We'll cross that bridge when I try to apply GitVersion to the NUnit 3 Adapter.

The odd/even convention is handly when long-term development is going on because people can choose whether to get the latest stable version or the development version. However, what I didn't think of originally is that implementing it really requires separate feeds as well. People would need a place to go to get the development version. The downside of this is more work for us. The upside is that you can do less frequent production releases, since folks who need the latest have a place to get it. Of course, they can also get that from a separate pre-release feed on MyGet. We should talk about that and make any changes rather quickly if we are going to make them. It could be we want to do different things with different projects as well.

I think we'll have to set up GitVersion in our case so that it never increments the major or minor component automatically. If we are following semver - or something close to it - then only we know if a particular change is a new feature or a breaking change. We could do minor increments automatically, but that would mean being quite disciplined in how we distinguish bug fix branches from feature branches. I'm not sure if we can do that. :-)

asbjornu commented 8 years ago

@CharliePoole:

Is there an alternative where we keep version info for use in such builds in AssemblyInfo.cs but write and use a modified copy for the builds where GitVersion comes into play?

Not with GitVersionTask. Then we would need to use GitVersion.exe, which doesn't (really) work compile-time, but on the upside supports patching of existing AssemblyInfo.cs files.

Alternatively, is there a way to tell GitVersion "If running outside of a repository, use this version as the default?"

We can hard-code next-version in GitVersion.yml, although I'm not sure GitVersion will actually execute at all with the .git directory missing. If that's a desired use-case, I'll have to test it to make sure it actually works.

I don't know what happens if you happen to build without specifying a version anywhere.

I'm pretty sure that without any Assembly*Version attributes, the version number defaults to 0.0.0.0.

@OsirisTerje:

We talked earlier of an odd- even practice on build numbers, to separate out release versions from pre-release and things-in-process. nuget would not need that, since it has the letters (1.2.3-beta1) to indicate pre-releases, but anything else would need something else. I am not sure how gitversion handles this.....

I would strongly advice against doing odd/even versioning, both because users find it hard to understand and because it's incompatible with semver (which is what most people seem to have the best intuitive understanding of these days, with penetration and understanding increasing every day). People seem to be moving away from odd/even versioning, so I find it peculiar that NUnit would start employing that scheme now.

More importantly, I don't see that odd/even versioning is at all necessary, given the availability of a pre-release MyGet feed. For long-term support of a certain unstable branch of 2.0, just maintain that in a support/2.x-unstable and have packages from it published to an unstable feed. I don't really see the use-case of having long-term support for unstable packages, though.

@CharliePoole:

The odd/even convention is handly when long-term development is going on because people can choose whether to get the latest stable version or the development version.

They can do that with semver too. With MyGet, you can even maintain a different feed per branch, to make consumption easy. I don't really see why you would want long-term support for an outdated unstable branch, though.

If you have ongoing unstable work for both version 2 and 3 of NUnit, they will have a different major version number, which will separate them in the feed. If people configure their dependencies correctly with version intervals, they won't accidentally upgrade from version 2 to 3, but instead follow version 2's unstable/stable ticks and tocks for as long as that branch is being maintained.

I think we'll have to set up GitVersion in our case so that it never increments the major or minor component automatically.

That can be configured. The default is to increment patch for most branches, but for develop it's minor because you usually want the latest release from develop to be of a higher version number than any previous releases from any other branch originating from the same tag. This is important when sorting packages in NuGet. If you screw this up, you'll end up with a pre-release package that suddenly is considered "latest" that shouldn't and you will have to remove it from the feed to fix it.

If we are following semver - or something close to it - then only we know if a particular change is a new feature or a breaking change.

Yes, absolutely. Any merge against develop or master is worthy of an explicit version number increment. How you do the increment, however, is up to you. You can do it with tagging (my preference, since it's more explicit and easier to figure out after the fact) or by adding +semver: minor to your commit messages, for instance.

We could do minor increments automatically, but that would mean being quite disciplined in how we distinguish bug fix branches from feature branches.

Packages produced from bugfix and feature branches will have a different pre-release tag in their version number, so they will be easily distinguishable. They will, however, be considered "the same" by NuGet, so it might suggest upgrades from a bugfix to a feature branch package if the latter has a higher semver, though. Problems like this can be avoided by using different feeds, but that of course adds administrative overhead.

I wish NuGet had a "branch" concept, so newer versions of a package from another branch than the one currently installed weren't suggested as upgrades unless explicitly asking NuGet to suggest them.

CharliePoole commented 8 years ago

@asbjornu Thanks for the answers. I think I'll experiment with the Cake tool, which is essentially a wrapper around GitVersion executable. I'll do that for the NUnit3 Test Adapter, which is the next thing I want to apply GitVersion to - issue nunit/nunit3-vs-adapter#199. Then we can compare the two approaches and see what we like best.

CharliePoole commented 8 years ago

@asbjornu Regarding the odd/even convention, understand that it's not a proposal - it's what we have been doing since 3.0. That's why 3.2 and 3.4 were the next releases after 3.0 for both NUnit and the NUnit3 Test Adapter. So, if we decide to drop it we will next have to decide how to drop it, i.e. if we need to phase it out. Possibly, if we made that decision right away there wouldn't need to be any phasing. I just wanted you to be up to speed on that before getting to the meat of the issue.

I'm the big advocate for odd / even and I provided the push for implementing it with 3.0. My main reason is that we go a long time between feature releases and some people want to get those features early. The odd / even convention is a long-time Linux convention and I agree that it's a bit confusing to Windows people. (Even though .NET is primarily for Windows, the development of this framework, and the whole testing/TDD movement were long dominated by non-Windows, or at least non-MS people.) That's history, however.

Yes, I am seeing that the ability to have different feeds would essentially eliminate most of the problem that odd / even was intended to resolve. I was imagining a single feed, with people who did not want to "upgrade" from stable to unstable having to use nuget version bracketing to prevent the next odd version from being installed. They would also have to explicitly upgrade to the next even version, which is an inconvenience. I also thought that we would have incompatible pre-release suffixes for the odd and the even versions. That is, odd would use our CI suffixes, while even would use Alpha, Beta, RC.

I can see that having different feeds - say NUnit stable and unstable - on MyGet would provide the same functionality and possibly be simpler. What do the rest of you think?

CharliePoole commented 8 years ago

@All Does this discussion open up the possible need to change our branching model? Currently we have master, issue branches and (pre)release branches.

We don't distinguish bugs from features in naming the branches. We could do that, but as I said earlier, it would take a bit of discipline. For our own work, we generally label issues as bugs, features or enhancements, so it's possible we could just start creating branches with different names in order to give GitVersion something to base its decisions on. I'm not sure how we would handle PRs from contributors though.

We earlier talked about GitFlow and decided not to go with it. One advantage it would have is that the dev branch could have a different set of versioning rules from master. I'm not advocating for this, just throwing out the possibility.

It seems like we are at a point, just after a release, where we could make changes easily so lets consider the options. One thing - even though it's not absolutely necessary, I'd like to see us adopt one set of standards across all the projects.

rprouse commented 8 years ago

I would strongly advice against doing odd/even versioning, both because users find it hard to understand and because it's incompatible with semver (which is what most people seem to have the best intuitive understanding of these days, with penetration and understanding increasing every day). People seem to be moving away from odd/even versioning, so I find it peculiar that NUnit would start employing that scheme now.

More importantly, I don't see that odd/even versioning is at all necessary, given the availability of a pre-release MyGet feed. For long-term support of a certain unstable branch of 2.0, just maintain that in a support/2.x-unstable and have packages from it published to an unstable feed. I don't really see the use-case of having long-term support for unstable packages, though.

I also dislike the odd/even versioning for the same reasons. We never release odd numbered builds in any format other than NuGet feeds, so I don't think the convention adds anything for us that the pre-release nuget suffixes also add in a way that is more familiar with the majority of our users.

rprouse commented 8 years ago

We don't distinguish bugs from features in naming the branches. We could do that, but as I said earlier, it would take a bit of discipline. For our own work, we generally label issues as bugs, features or enhancements, so it's possible we could just start creating branches with different names in order to give GitVersion something to base its decisions on. I'm not sure how we would handle PRs from contributors though.

We earlier talked about GitFlow and decided not to go with it. One advantage it would have is that the dev branch could have a different set of versioning rules from master. I'm not advocating for this, just throwing out the possibility.

Other than the fact that we made the mistake of branching off master instead of the release branch for the 3.4.1 hotfix, we have a branching model that is working fairly well and fits in with GitHub well, so I would prefer not to change it unless we have strong reasons to do so.

As for branch naming, I'd be fine with switching to a new naming convention, as long as it isn't too complicated. I want to keep it as simple as possible for new developers to on-board without reading reams of documentation on our development processes :smile:

asbjornu commented 8 years ago

@CharliePoole:

Regarding the odd/even convention, understand that it's not a proposal - it's what we have been doing since 3.0.

Oh, I wasn't aware of that. I've been happily upgrading to every new version as if it followed semver. Although I understand the history behind this, I disagree with the conclusion. NuGet is the prevalent distribution model and package manager for .NET, NUnit is written for a .NET audience and NuGet uses semver. Anything breaking the rules of semver practically breaks NuGet and consumers of the package.

@rprouse:

As for branch naming, I'd be fine with switching to a new naming convention, as long as it isn't too complicated.

Why not just use git-flow directly and its rather standardized naming scheme:

That has the added benefit of being a known scheme to GitVersion, which then won't need any special configuration to figure out everything and do its thing. It's also a scheme well known and implemented in most visual Git tools, such as SmartGit and Tower, all of which makes it the most known naming scheme for Git branches in existence, I assume.

rprouse commented 8 years ago

Why not just use git-flow directly and its rather standardized naming scheme

Mainly because we decided to use GitHub flow and don't feel a strong need for a develop branch :smile:

We do use some of the GitFlow branches like release/* and I wouldn't mind switching to feature/* instead of issue-xx. I just like that developers can pull master, build and test the latest fixes. Then again, we could always just switch our default branch on GitHub to develop and treat it like we do master. I've just never really seen the point of the master branch in GitFlow since it is just tags of release points. I just tag the release branches. GitFlow is probably a bit cleaner.

You also say it is supported by most tools which is true, but it isn't supported by GitHub for Windows or GitHub for Visual Studio AFAIK which GitHub does a pretty good job of pushing on users. I don't use them and would actually find Git Flow easier in many ways, but I do worry about junior developers.

Don't take my comments too negatively. I actually like GitFlow, I just want to keep things as simple as possible for NUnit and only add complexity if it is needed. I also feel that more developers are comfortable with the GitHub Flow model. If people really want to change though, it won't take much to convince me :wink:

OsirisTerje commented 8 years ago

There is also a gitflow extension for Visual Studio which works well, https://visualstudiogallery.msdn.microsoft.com/f5ae0a1d-005f-4a09-a19c-3f46ff30400a

The only thing I miss is the Issue branch "folder", it is not features and it is not hotfixes, and a lot of what is done is bug fixes, so......

I agree with @rprouse about keeping things simple, and in our case I dont really see the need for the develop branch, but heck, it is just a pointer, we dont really need to bother too much.

CharliePoole commented 8 years ago

I had already come to see that the odd / even versioning scheme wasn't getting me what I had hoped to achieve with it. So we either need to make it work or do something different. Let me try to list what it was that I was trying to accomplish...

  1. We should be free to add features and try them out without burdening users.
  2. Users who don't want to change until we do a formal release should be able to do so readily.
  3. Users who only want to get bug fixes should be able to do that easily.
  4. Users who want to follow us closely as new features get added should be able to do that. They should have the choice of doing it by getting binary drops or forking/cloning our repo.
  5. When users report a problem, they should be able to tell us exactly what they are using.

Doing all that requires a clear separation between stable and unstable releases and stable and unstable source. It's clear that just using odd and even releases has not done that. It seems that they worked well in the past when the releases were encapsulated in branches - in SVN for example.

So, I'd be ready to drop the odd/even thing but would still want to reach those goals listed.

Users need to get packages from us. We need to have a stable and an unstable feed. The stable feed would contain packages like 3.4.0, 3.4.1, etc. I think that's what nuget.org is for nuget packages. The unstable would be packages like 3.5.0-xxx, 3.5.0-yyy, etc. where the suffix values have yet to be determined. Our myget feed does that for nuget packages and we can create multiple myget feeds if we need to. Does this make sense? If so, how should it tie back to branches?

CharliePoole commented 8 years ago

Just for the record, I'm unswayed by the existence of gui tools that support a particular flow. I'm a command-line guy and I would hope that anyone contributing to NUnit would be reasonably comfortable on the command-line. So anything we use needs to have a straightforward implementation in commands and/or aliases as well.

asbjornu commented 8 years ago

@rprouse:

Mainly because we decided to use GitHub flow and don't feel a strong need for a develop branch :smile:

Well, when you say:

We do use some of the GitFlow branches like release/* and I wouldn't mind switching to feature/* instead of issue-xx.

…then you're not really using GitHub Flow, but GitFlow.

I just like that developers can pull master, build and test the latest fixes. Then again, we could always just switch our default branch on GitHub to develop and treat it like we do master.

Yes, that's the way to do it. If you want unstable releases without an odd/even versioning scheme, why would you not want a develop branch? I have great experience with setting develop as the default branch on GitHub; it makes it easier on everyone, including outside contributors.

I've just never really seen the point of the master branch in GitFlow since it is just tags of release points. I just tag the release branches. GitFlow is probably a bit cleaner.

I think GitFlow is cleaner, yes. With it, you won't have any commits on master that isn't a tagged merge-commit. Very easy to follow. If you want to see details, just poke into whatever was merged from develop, which again is mostly merges from feature branches or pull requests.

You also say it is supported by most tools which is true, but it isn't supported by GitHub for Windows or GitHub for Visual Studio AFAIK which GitHub does a pretty good job of pushing on users. I don't use them and would actually find Git Flow easier in many ways, but I do worry about junior developers.

True, but the fact that we use GitFlow isn't something outside contributors really need to be aware of. How we organize our branches is internal and up to us. Outside contributors can't affect that and we can't affect what they do in their repository, but when they submit a pull request, we can decide what to do with it.

Don't take my comments too negatively. I actually like GitFlow, I just want to keep things as simple as possible for NUnit and only add complexity if it is needed.

Sure, no problem. I just utterly fail to see the complexity of GitFlow, that's all. :smile:

I also feel that more developers are comfortable with the GitHub Flow model. If people really want to change though, it won't take much to convince me :wink:

I don't see why anyone outside of the NUnit team would even notice what flow we're using. Okay, we have a develop branch, but I doubt most contributors would care as that's just a (new) default, just the same way master is today.

@OsirisTerje:

I agree with @rprouse about keeping things simple, and in our case I dont really see the need for the develop branch, but heck, it is just a pointer, we dont really need to bother too much.

If we abandon the odd/even versioning scheme, from which branch are we going to do unstable releases if we don't have a develop branch?

@CharliePoole:

  1. We should be free to add features and try them out without burdening users.
  2. Users who don't want to change until we do a formal release should be able to do so readily.
  3. Users who only want to get bug fixes should be able to do that easily.
  4. Users who want to follow us closely as new features get added should be able to do that. They should have the choice of doing it by getting binary drops or forking/cloning our repo.
  5. When users report a problem, they should be able to tell us exactly what they are using.

Yep:

  1. feature/* published to a separate MyGet feed.
  2. Consume the stable releases on NuGet and follow the master branch on GitHub.
  3. Use semver. If you have versions 3.0.2 and 3.2.0 with the same bug in it and don't want 3.0.x people to upgrade to 3.2.x, just put up a new 3.0.3 and 3.2.1 package. This sounds theoretical to me, since minor increments shouldn't break anything so people should therefore not be afraid of upgrading from a minor to the next, but it's the same principle if it is indeed a breaking change and a new major increment.
  4. Consume pre-releases on MyGet (or NuGet, for that matter) and follow the develop branch on GitHub.
  5. Have them report the AssemblyInformationalVersion of the assembly they're consuming. It will contain everything we need to know, including the hash of the commit that was built. If we're using GitVersion, that is.

Doing all that requires a clear separation between stable and unstable releases and stable and unstable source.

I believe GitFlow and semver gives you this. I don't even thing we need to use MyGet to accomplish the release bit; we can do pre-releases to NuGet too. It only makes it difficult or probably impossible to publish pre-releases from different branches, because NuGet doesn't separate them.

So, I'd be ready to drop the odd/even thing but would still want to reach those goals listed.

I believe we can reach those with GitFlow and semver.

Users need to get packages from us. We need to have a stable and an unstable feed. The stable feed would contain packages like 3.4.0, 3.4.1, etc. I think that's what nuget.org is for nuget packages. The unstable would be packages like 3.5.0-xxx, 3.5.0-yyy, etc. where the suffix values have yet to be determined. Our myget feed does that for nuget packages and we can create multiple myget feeds if we need to. Does this make sense?

Yes, this sounds like what I have in mind.

If so, how should it tie back to branches?

That depends. :smile: The branch/publish matrix might look something like this:

Branch Feed Example version number
master NuGet stable 3.4.1
develop NuGet or MyGet pre-release 3.5.0-alpha.1
feature/* MyGet feature feed 3.4.2-feature-x.4
release/* MyGet release feed 3.4.1-beta.8
hotfix/* MyGet hotfix feed 3.4.1-beta.10
support/* NuGet stable 2.6.1
OsirisTerje commented 8 years ago

@asbjornu : Good points! Agree. And yes, without odd/even, develop branch makes even more sense, also your other points on that makes sense.

CharliePoole commented 8 years ago

Agree, all good points.

As I wrote earlier, let's get back to basics of what we want to accomplish and how to do it. Discussion of "name brands" of flows is no more helpful than discussion of whether somebody is truly doing XP, Scrum, etc. in the Agile world.

What we are doing isn't GitFlow and it isn't GitHubFlow. What we will do needs to be decided bit by bit, not by picking a "brand", which only fuels debate rather than problem solving.

So... here is one piece...

Do we need an unstable feed? I say yes, separate from nuget.org. Our nuget feed only has room for one sequence of pre-releases: like alpha, beta and RC. Additionally, it follows semver. An unstable feed can't really follow semver, at least in spirit since by definition it may add and drop features at any time. If you follow an unstable feed, you follow the ups and downs of our efforts as we add things, try them out and then either keep them or drop them. Such a feed could either have a new release for each merge or just a daily release. I doubt we need both.

You could create such a feed without a dev branch, but it's a lot easier with one and that gives folks building from source a place to get the unstable bits. So I would like to have the branch. My preferred name BTW is dev but I can live with the longer one.

A few years back I had talked about doing this in conjunction with the odd/even split. Master would have been even, dev odd. After discussion we agreed it was too complicated. We dropped dev and kept the split. I think now we should have kept the branch.

Let's find out if we agree on any of the above before moving on to release branches, etc.

asbjornu commented 8 years ago

@CharliePoole:

What we are doing isn't GitFlow and it isn't GitHubFlow. What we will do needs to be decided bit by bit, not by picking a "brand", which only fuels debate rather than problem solving.

True, and I agree. However, if you switch from odd/even to semver, you have a need for develop, which aligns the NUnit development process pretty straight with GitFlow.

Do we need an unstable feed?

I agree. From reading your points I even think we need more than one. At least two; one for develop and release/* (producing "alpha", "beta" etc.) and one for feature/* and pull requests (which might be the same thing, depending on how we merge them). The former can (imho, should) be on NuGet, the latter can (imho, should) be on MyGet.

My preferred name BTW is dev but I can live with the longer one.

My preferred name and what I introduced in my org. before knowing about GitFlow was development. We've standardized on develop now, though, since that's what "everyone" else is using.

Let's find out if we agree on any of the above before moving on to release branches, etc.

:+1:

CharliePoole commented 8 years ago

Back when I first encountered SCM systems, we used main, test and dev. Every letter had to be typed, of course. :-)

On Thu, Jul 7, 2016 at 5:11 AM, Asbjørn Ulsberg notifications@github.com wrote:

@CharliePoole https://github.com/CharliePoole:

What we are doing isn't GitFlow and it isn't GitHubFlow. What we will do needs to be decided bit by bit, not by picking a "brand", which only fuels debate rather than problem solving.

True, and I agree. However, if you switch from odd/even to semver, you have a need for develop, which aligns the NUnit development process pretty straight with GitFlow.

Do we need an unstable feed?

I agree. From reading your points I even think we need more than one. At least two; one for develop and release/* (producing "alpha", "beta" etc.) and one for feature/* and pull requests (which might be the same thing, depending on how we merge them). The former can (imho, should) be on NuGet, the latter can (imho, should) be on MyGet.

My preferred name BTW is dev but I can live with the longer one.

My preferred name and what I introduced in my org. before knowing about GitFlow was development. We've standardized on develop now, though, since that's what "everyone" else is using.

Let's find out if we agree on any of the above before moving on to release branches, etc.

👍

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/nunit/NUnit.System.Linq/issues/8#issuecomment-231060035, or mute the thread https://github.com/notifications/unsubscribe/ACjfhSv_ygvq0W23S7VDIMhz1rAR6QLbks5qTOz5gaJpZM4JDbve .

CharliePoole commented 8 years ago

Once we have agreement on having a dev/develop branch and dropping the odd/even split, I'll update the milestones that we set up for nunit and the adapter... 3.6, 3.8, 3.10 will become 3.5, 3.6, 3.7. I don't want to do that till I'm sure we are in agreement.

oznetmaster commented 8 years ago

I did not really like odd/even when we last had this discussion, so I am all for the proposed approach.

rprouse commented 8 years ago

@asbjornu strong arguments, you are winning me over :+1:

I am fine with a develop branch. If we are changing, I think we should stick with default GitFlow naming as outlined by @asbjornu above. All tools that I have seen use that as the default for the tool users among us.

image

OsirisTerje commented 8 years ago

One small thing more: We are doing a bunch of bugfixes, intermixed with new feature development. We have used the "Issue" prefix for that, but since the git flow has a standard name for that too, "bugfix", we should also use that. See it is not in @asbjornu list above, but it has been added to git flow.

CharliePoole commented 8 years ago

I'm OK with adopting GitFlow terminology for whatever we do but I still see value in looking at things one at a time. We don't want to complicate our work by adding a branch type we don't need just because it's in GitFlow.

Note... this is not in response to @OsirisTerje 's bugfix comment... just to the general idea that we might "adopt GitFlow" en masse.

Given what we have decided so far, I just changed our future milestones to increment by 1 rather than 2. NUnit project has 3.5, 3.6, 3.7 scheduled. NUnit 3 Test adapter has 3.5. AFAIK no other projects have established advance milestones.

asbjornu commented 8 years ago

@CharliePoole, @OsirisTerje Why isn't the word hotfix fitting for your definition of "issue" or "bugfix"? hotfix/* is a GitFlow term.

CharliePoole commented 8 years ago

@asbjornu Well... I only commented to say I wasn't commenting on it. :-)

However, my understanding is that some GitFlow users make a distinction. A bugfix may wait for a release, while a hotfix actually causes an immediate direct release on master and also gets merged to develop. I'm not sure I buy the need for two different naming conventions, but I'm willing to listen. @OsirisTerje ?

I think that there is a big prior decision about how we want to do releases that has to be made before worrying about this detail. How do we handle bugs? That is, if we are on 3.4.0 and we fix a bug, when will that be released to the user. Will it be in 3.4.1 or 3.5.0? Do we do the same thing with all bugs or are critical bugs treated differently. I think the answer depends on how much overhead there is in doing a release. Currently, because of the overhead, we save up fixes until we are ready to release. If we do that for everything we will only have minor releases because there will always be some kinds of features mixed with bugs.

asbjornu commented 8 years ago

@CharliePoole Yea, I can see the difference. But as you mention, it depends more on how and when you're able to release than the philosophical semantics of "issue" versus "hotfix" versus "bugfix".

What matters in GitFlow, though, is that it thinks of a hotfix branch as something that is created from master and then merged back into master as well as develop to get the fix out there as soon as possible. I'm not sure that's a use-case NUnit needs, but that's how it deals with it. If bugfixes can wait a bit, you can basically just treat bugfixes the same way as feature branches.

That is, if we are on 3.4.0 and we fix a bug, when will that be released to the user. Will it be in 3.4.1 or 3.5.0?

SemVer says it should be 3.4.1, unless it's a breaking change, which would make it 4.0.

Do we do the same thing with all bugs or are critical bugs treated differently.

Good question. I don't know the history of the NUnit repositories well enough to have a say in that decision. 😃

I think the answer depends on how much overhead there is in doing a release. Currently, because of the overhead, we save up fixes until we are ready to release. If we do that for everything we will only have minor releases because there will always be some kinds of features mixed with bugs.

I didn't know there was such an overhead doing releases of NUnit, but I'm happy to let you know that if you adopt GitFlow or a variation of it, you can start using tools like GitReleaseNotes to automate the creation of release notes and GitReleaseManager to help automate the release process.

OsirisTerje commented 8 years ago

Bugfix as a term has been added to gitflow, I think it was lately, just because it makes things a bit more clear I assume.
image

I have just noted that when we work with NUnit we do a bunch of bugfixes, which mostly wait for the next release, and to keep easy track of them I think having them in a bugfix "folder" would be very useful. Of course it is possible to have them in a "feature" folder, but I can't see any harm separating them out. When we document releases we often also separate between what is new features and what is bugfixes.

The use of tools like you mention to help out with release notes and the process sounds great, the more than can be automated the better. (Both your links point to GitReleaseNotes, the second should have been https://github.com/GitTools/GitReleaseManager I assume).

asbjornu commented 8 years ago

@OsirisTerje Ah, look at that. From what branch is hotfix normally created from, then? Is it functionally like a feature branch, only with a different name? If so, that sounds like a perfect match for NUnit's workflow.

(Both your links point to GitReleaseNotes, the second should have been https://github.com/GitTools/GitReleaseManager I assume).

Yes, fixed. 😃

OsirisTerje commented 8 years ago

@asbjornu Yes, agree, I think of bugfix branches just the same as feature branches, the naming just to make it easier to do the bookkeeping, so off develop it goes :-)

CharliePoole commented 8 years ago

@asbjornu

SemVer says it should be 3.4.1, unless it's a breaking change, which would make it 4.0.

Actually, not quite. Semver says it should be 3.4.1 if we release it by itself. If we release it mixed with new, non-breaking features, it should be 3.5.0. How we decide to do a release and what we group in it drives the decision.

In the past, the policy has been that a critical bug got fixed and forced a release, while other bugs got queued. However, we are generally flexible about this, so we are doing a forced release due to a critical bug, we have usually released all the other finished work along with it.

Right now, of course, we are throwing everything up in the air to see where it lands. :-)

Right now, with the NUnit project, we have enough overhead that releasing every three months seems like a reasonable goal. With the work on Cake and intro of GitVersion I think we can push that down to a month. That won't change how we do things much though. However, if releasing gets extrememly easy, we might release more even more rapidly, even to the point of one feature at a time, one critical bug at a time and something like weekly for non-critical bugs. That's my fantasy, anyway. :-)

CharliePoole commented 8 years ago

Both GitReleaseNotes and GitReleaseManager are available through Cake integration. We could look at them after we get a satisfactory GitVersion implementation up and running.

asbjornu commented 8 years ago

Actually, not quite. Semver says it should be 3.4.1 if we release it by itself. If we release it mixed with new, non-breaking features, it should be 3.5.0. How we decide to do a release and what we group in it drives the decision.

Indeed. And as you say, the frequency of the releases will be a dominant factor for what version number the next release is going to be. Give it enough time and you're bound to have at least one new noteworthy feature in there, requiring you to do a minor increment. I'd like to point out that you can do large refactorings and such in feature branches that won't add a new feature to the end product and thus only requiring you to do a patch increment.

But, yeah, I think this is going to work itself out. Figuring out the version number for a release is always going to be a manual process, so that's not going to become much different regardless of the overall process and tools involved.

CharliePoole commented 8 years ago

So let's say we name branches as @asbjornu listed, with the addition of bugfix. His description of standard version numbers works for me except for some of the suffixes.

For example, why would you call the development branch alpha? Alpha has a traditional implication of a short trial period, leading to a beta period and then a final release. The develop branch, otoh, seems like a new thing in itself. FWIW, I would hope we can get away from alphas and betas in the future and either do an rc or just release.

On feature branches, are you considering just the word feature plus a number? That is, no designation of what the feature is about? How about nnn-Description, where nnn is the issue or pr number?

Release branches make more sense to me as rc versions rather than beta. In a beta, you will add more features while an rc is intended to use as is unless something goes wrong.

Feature branches as beta don't make sense either, especially if they are then merged into an alpha prefixed develop branch. Like develop, I think they are something new.

Support branches will probably go unused.

One question... is it important that all the suffixes we use be in a proper alphabetic order or only the suffixes that are used on the same branch?