On 15 December 2014 at 01:29, Jason van Zyl <ja...@takari.io> wrote: > > Hi, > > The discussion keeps resurfacing about how we deal with failed releases so > I'll summarize how I think it should ultimately be done as a starting point. > > I'll go over the cases we've encountered thus far: > > 1) The user case prefers non-disjunct sets of releases, or from our PoV > re-used versions. I believe people are confused by missing versions and > will always result in questions like "What happened to version X?", where X > is a non-viable build. Not many people read release notes, will not > self-serve and it will just be a lot of questions and confusion. The > typical user doesn't care about the question of whether a particular build > is viable or not. I think they naturally expect contiguous, increasing > versions when they update to new versions of a product. >
I have not seen anyone asking what happened to 3.2.0 Similarly I have not seen anyone asking what happened to 3.1.2, 3.1.3, 3.1.4, 3.1.5, 3.1.6, 3.1.7, 3.1.8 or 3.1.9 And also nobody was visible to me about what exactly happened to 3.0.6-3.0.9 inclusive or the vast range of continuous numbers we skipped before 3.0.0 I seem to recall a few questions about what da f*ck exactly was 2.0.10 and was it newer than 2.0.4 but, you know what, our users are by and large reasonably smart people, they can read an answer if we provide one, and the user community itself can probably sort out explaining where any missing versions went, especially if we put the explanation on a page on our website... So this use case is, to my mind, not really relevant. I think we can divide our users into two large groups: a. Those users who have a mandated version of maven that they must use b. Those users who are happy to use the latest version of maven whatever that is There are other groups out there, but I believe that the above two groups covers at least 80% of our users A final point on the user community... if we treat our users like idiots, then that's the kind of users we will get. I don't know how the rest of you feel about our users, but I know that our users are by and large a reasonably smart group of people. I just plain do not buy this argument about users expecting contiguous increasing versions. I think users expect us to actually cut releases on a reasonably frequent basis and to fix things and generally not make things worse... and that we will have a page somewhere that is easy to find (probably called release history) that will let them track down when the thing they care about right now changed so that they can either fix or roll-back to Get Things Done™ > 2) The tester case prefers new versions but has tolerated re-used > versions. Testers for core only really have to deal with the binary > distribution and if it gets thrown away there's not much chance of local > repository inconsistency because the typical tester, who is not an > integrator, isn't going to depend on the new core release for anything. > Running 3.2.4 doesn't put anything related to 3.2.4 in your local > repository. > This applies to core... but not so for testing plugins. We are not just a project about core. If we decide on a policy it should be a policy that works for both core and plugins. One thing we always complain about is the lack of testing in areas where our automated tests are weak. To combat that we need to grow our pool of testers to include people from the user community right now. Those users may not be as comfortable ensuring that they have cleared out their local repo of any side artifacts pulled in when testing a staged release... If they know that the artifact version number will never be re-used it gives them a bit more confidence. And this is not just about testing on your local machine, you might push the changes to your CI server via a pull request and a pull request builder to get even better test coverage. Then you have to worry that the CI server will have some build slaves with old pre-release versions. If we want to grow testing then I see re-use of versions a complete no-no. > > 3) The integrator case prefers new versions. Different content with the > same version is a violation of our immutability philosophy and can cause > issues. Even though this is very much contained at the moment let's be > optimistic and believe we will have many integrators that will test > pre-released versions. Igor is right in that it's not fun to keep track of > this and why should the burden be placed on the integrator. The answer is > it shouldn't. > Again, from this use case I see re-use of versions as a complete no-no also. > > 4) The release manager case prefers new versions. When something is found wrong in 3.2.4 during voting, a user will create an issue in JIRA... found in 3.2.4... so we go and fix it... in 3.2.4... that just feels messy to me. I much rather say that an issue found in 3.2.4 is fixed in a later version... And before anyone asks, if the regression/issue was found in 3.2.4-SNAPSHOT and we don't want to have -SNAPSHOT versions in JIRA then the regression/issue gets fixed before the actual 3.2.4 gets released and the JIRA issue needs to be reclassified... * if it was a regression and we fix that before the regression gets released, that's not a bug, and the issue should be marked as such and should not show up on the release notes * it it was something else then we should be documenting the new feature via a JIRA A final issue. When you are running a release build, release:perform does not produce idempotent artifacts. Just take a look at virtually any random artifact produced by Maven: $ unzip -c ~/Downloads/maven-dependency-tree-2.2.jar > META-INF/maven/org.apache.maven.shared/maven-dependency-tree/pom.properties > Archive: /Users/stephenc/Downloads/maven-dependency-tree-2.2.jar > inflating: > META-INF/maven/org.apache.maven.shared/maven-dependency-tree/pom.properties > > #Generated by Maven > #Sun Sep 14 20:07:30 CEST 2014 > version=2.2 > groupId=org.apache.maven.shared > artifactId=maven-dependency-tree Now that is just one file where the content is dependent on the date of creation. We also have timestamps of different files that are in there and make each .jar file different... And that is before we even get as far as which JDK was used to compile, etc. A long long time ago I remember a project I was working on where we would touch all the compiled binaries to have the last modified time of the newest source that contributed to them (and the Makefile was one of those sources too BTW) the result of this was that you could check out the code on any machine (which would apply the source file timestamps) and rebuild the artifact using the same toolchain and end up with the *exact same* (bit for bit) binary. The JDK does not give us the tools to have that luxury, so I am not saying that we should try and reverse engineer a similar effect... rather When I am releasing stuff and the release:perform goes wrong, as a release manager, I really just want to burn that version number and use a new one. Yes the staging repo is helpful, but I need to worry about my own local repo having mixed builds... and this same worry crops up for those broken builds that need `clean install` as preparationGoals... in fact its worse for them because if they need `clean install` then likely they are pulling things out of order from the local repo and thus within my release artifacts I may indeed have *equivalent* artifacts claiming to be the same release but not having a checksum match to the actual released artifacts. I don't think a release manager only "prefers" new versions... I think a much stronger word is needed ;-) I have typically reused versions because I believe 1) is true. It's a PITA > to erase tags, shuffle issues around in JIRA, and reset the POMs. I would > prefer to just move forward, but I have done it because the user confusion > is not worth the small effort it takes me to clean up a few resources. One > hour for me versus thousands of hours of confusion for all users. It's an > easy calculation. > Well I can agree with that calculation on the assumption that 1) is true. I, however, believe 1) is actually false... and thus the trade-off to my way of thinking is completely useless. > > Taking all these cases into consideration so that all participants are > satisfied I think we ultimately want increasing and contiguous versions for > users, testers and integrators while the release manager does not have to > shuffle a bunch of resources around in the event of a non-viable build. > What we want is a form of continuous delivery where a version like 3.2.4 is > the version that we call it to the outside world (some refer to it as the > marketing version) and the qualifier changes from build to build so we have: > > 3.2.4-qualifier > > And for simplicity's sake let's just say the qualifier is a build number > so we end up with: > > 3.2.4-01 > 3.2.4-02 > ... > 3.2.4-NN > WHY WHY WHY why don't we just use buildnumber? (other than users getting confused about is 3.2.6-12 before or after 3.2.6-7) we have it in our version spec anyway (i.e. if no leading 0 then it's a build number, if leading 0 then its a qualifier)... oh and any users that are confused by the missing 3.2.4 will be just as confused by 3.2.6-03 with a missing 3.2.6-01 and 3.2.6-02 > Every build is a complete build that can be released, and in the stream of > builds that are produced we decide that one is good enough for public > consumption. Nothing in the issue tracking or documentation needs to change > as it's still referred to as 3.2.4. People who download the distribution > aren't going to care what the exact versions say on the JARs but some > education might be required to tell people that something like 3.2.4 is > actually 3.2.4-05 if they want to refer to an artifact from 3.2.4. I don't > think making aliases to the marketing versions are a good idea and wouldn't > want to duplicate artifacts so that they can be referred to by the > marketing version. Ahh, perhaps here is the argument for being able to skip version 3.2.4 only now being applied to excuse skipping 3.2.6-01 and 3.2.6-02 > People will just become accustom to knowing a qualifier is necessary to > find the actual version. > Or similarly people could just become accustomed to knowing that we skip versions if we think they are no good... and we stick with our 3 part version numbers > > This is more how things work at Eclipse where if you look at something > from Jetty: > > > http://search.maven.org/#search%7Cgav%7C1%7Cg%3A%22org.eclipse.jetty%22%20AND%20a%3A%22jetty-servlet%22 > > You'll see that something like jetty-servlet 9.2.3 is actually referred to > as 9.2.3.v20140905. Jetty seems somewhat inconsistent with respect to > milestones but you get the idea. I think this works for all parties but > especially users where say we all happen to write blog entries about 3.2.4 > and it fails twice and we actually release 3.2.6. This is just so confusing > as anything that referred to 3.2.4 now really means 3.2.6 which is totally > inconsistent. Seriously? Anyone who reads that something is available from 3.2.4 will expect that to be present in 3.2.6... and who's going to pick up 3.2.4 when 3.2.6 is available (and should have more bug fixes, and the feature should be bedded down more, etc) "People will just become accustomed to knowing" that if we say it's going to be in 3.2.4 and then we release 3.2.6 then it's in 3.2.6 > I think skipping failed versions from the users perspective like we are > currently doing is just a recipe for a massive amount of confusion and > wasted time. Or maybe "People will just become accustomed" > Moving toward a stream based approach with a marketing version and > qualifiers for actual versions is really the only way it can work for > everyone. > > Thanks, > > Jason > > ---------------------------------------------------------- > Jason van Zyl > Founder, Apache Maven > http://twitter.com/jvanzyl > http://twitter.com/takari_io > --------------------------------------------------------- > > To think is easy. To act is hard. But the hardest thing in the world is to > act in accordance with your thinking. > > -- Johann von Goethe > > > > > > > > > >