-
Notifications
You must be signed in to change notification settings - Fork 94
Support concurrent development in auto versioning #115
Comments
First thing I'll mention is that I'm partway through a more general implementation of the version inference portion of gradle-git in semver-vcs, though I intend it to have more defined semantics (which should still line up with your use case). The goal is to support more than just Git and more than just Gradle. I don't know if I'm far enough along to address how it would work in the new library, but I plan to keep compatibility with the current version for a while at least. So we can move forward either way (targeting the new or the old). Back to your specific question... I'm kind of surprised that the current plugin wouldn't support your use case. The only requirement would be that you merge the commit tagged as 1.0.0 back into the develop branch. I haven't used GitFlow personally, but that was my assumption of how it would work. Can you provide some insight into the gap between the plugins abilities and your goals? Regarding the max concept... Assuming I'm interpreting it correctly, the "max" would be the tagged version with the highest semantic versioning precedence, regardless of whether it's an ancestor of the current HEAD or not. That seems like it wouldn't allow you to do maintenance (as soon as 2.0.0 is released, you can't infer a 1.1.0). Maybe I'm interpreting this wrong though. If you already have some code prepared, a pull request would be helpful to continue the conversation. |
Thanks for the reply -- I can work to getting a pull request ready for you. But in the short term, to explain: In gitflow, work for the next release is done on the "develop" branch. When we are declared ready, we'll cut a release branch -- say "release/1.0.0". From the release branch we will build release candidates. So using gradle-git on the release branch, we want the normal version to be derived from the branch name - in this case 1.0.0 Each build off the release branch will increment the release candidate number. While the release branch is being stablized, some team members can continue to do work on the develop branch for the next release -- that is why as soon as the release branch is cut and a build produced, we want builds off the "develop" branch to be interpreted as "1.1.0" (incrementing minor scope) In my experience using gradle-git plugin, this doesn't work -- primarily because tags that were produced from the release branch are not ancestors of the develop branch anymore. That being said, its quite possible I was doing something wrong. There's a lot to absorb walking through the code. |
That makes a lot more sense now. Thanks for the explanation. I'm still thinking a max could be problematic in some situations. That said, there does need to be some global context that's understood about what other versions are in development in order to meet this type of use case. Could be based on just all tagged versions or maybe based on the branches tied to a version (or set of versions). I'll spend some more time thinking this through, but let me know if have more thoughts or questions. |
So I've thought through this some more and some form of the max version you described is probably the best way to support this in the current code. One question. Is the max version determined from tagged versions or from branch names? Seems like branch names would be ideal, but tags would probably be easier to fit in to the code. I think there may need to be a couple constraints to ensure maintenance use cases are still possible. Let me know if you think these would work out (or if they're overkill):
I think this would at least guarantee some "nearness" for the MaxVersion, while still leaving it open enough for your use case. If it's just based on tags, there wouldn't need to be any configurability besides maybe a flag that enables searching for nearby maxes. This could then just be implemented as part of NearestVersionLocator such that a nearby max would override the nearest any. The remainder of the code (Strategies, etc) wouldn't even need to know anything about the concept of the max. |
Sorry for the delayed response and appreciate noodling on this more. I don't seem to be getting email notifications on this thread and have been focused on other things. My initial feedback is in alignment with you. I think deriving max version from branch names would be ideal (in addition to tags), but yes, that seems to be harder to do in code as it exists today. As an example of that scenario, consider cutting a branch release/1.0.0 off of develop branch We might have two CI builds jobs that in parallel building these projects off these branches but perhaps still only producing -SNAPSHOT artifacts not not creating tags (until someone chooses to do a build with -Prelease.stage=rc Without tags produced from the the release/1.0.0 branch, -SNAPSHOT versions off these branches would produce the same version # if version wasn't derived from branch name. I was going down the path of trying to create a "gitflow" plugin similar to you "opinion" plugin which would make use of maxVersion, but punted on trying to support deriving from branch names. There was so much to consider -- how to register the branch names/patterns one would use. As far as the constraints you propose, I think I have to noodle on them a bit more before I can comment. My brain is fried at the end of this week and I can't think of any counter-arguments that might negate their need. I agree on your solution if it just tag based -- I hadn't thought about a flag to alert the behavior of NearestVersionLocator. That seems easier than my solution of creating a parallel MaxVersionLocator. It is still my intent to share what I've done in a pull request, but work has been busy and its been hard to get back to this pet project. Thanks again for your willingness and interest to accept this use case and Happy Memorial Day weekend. Doug |
Happy Memorial Day to you too! Feel free to take your time. My goal is to address the branch and tag use case in semver-vcs (not sure how yet), but I'd still like to support something in the current API. Just let me know when you have something ready or something else to discuss. |
I'll continue this discussion on your PR (#117). |
In order to support #115, sort versions by ancestry instead of distance, with version precedence being the tie breaker. A flag is now available on the locate() method to include tags from parallel histories. These tags will always be treated as normal versions, indicating that they are developing towards that version and that the current branch should not use it.
Sorry to never get a chance to followup on this issue. It was something I really wanted to personally get implemented, but never a priority for my team (Primarily a maven shop....) and I just could not find the cycles to concentrate on this before moving off that project a year ago and eventually leaving the company. This past month I started working at a new company and there is one gradle project for which we are working to revise the continuous delivery processes, including the possibility to automate versioning artifacts through git meta-data. That project currently has a similar branching model to git flow and would run into the same issues described above, though one of the possibilities might be to change the branching model moving forward if causes more challenges than it solves. We have a spike in our upcoming sprint to flesh out, document, and model our developer/ci/cd workflows. We can then evaluate whether this plugin would meet our needs our of the box or if customization related to the above might be needed and make a decision based on how much work would be involved. My new company is not a java-shop -- This is primarily for our android mobile app and its variants. If customizing the plugin becomes necessary but more that half-a-week to get implemented in a fork, then auto-versioning might be de-scoped as there are (as always...) a boat-load of other higher-priorities in the queue. Will update this conversation with our path when I know more. Thanks again. |
No problem, I'd like to see this one solved too, but also have had other priorities. Most of the time this one will require is just thinking through how the branching model would relate to the versioning. I don't high hopes for it being a very quick fix, but who knows. Thanks for the continued interest! |
Hi @ajoberstar. I really like your plugin since it is easy to configure and quite flexible. So I only had a quick look at the semver-vcs, but think that it would be easier and cleaner to achieve my goals with this plugin. Because I am using this plugin, I can get rid of the release branches. As Vincent stated, there are two major reasons for a release branch:
So for me a simple custom startSearchAt (see draft proposal) is sufficient. For the described simplification of the Vincent Driessen's approach, the following customization is sufficient:
I know that this is only a starting point, but I think in the end, there will always be different needs of customization. So the git-flow approach should be a default configuration set than a hard implemented design as provided in #118. I think, if the customization is furthermore enhanced by providing the TagStrategy with a member to grgit from ReleasePluginExtension, the user can already configure nearly everything he wants in terms of git-flow in combination with a custom VersionStrategy:
Let me know whether my story sounds reasonable to you or whether I missed vital points. Maybe we can agree on a way forward, which in the end can lead to a git-flow support, but also covers simplified scenarios like I described. |
Hi @fvgh. Glad that others are interested in improving this, though I don't plan to accept any more changes to the When you looked at semver-vcs/reckon, did you review the latest code? The documentation is very out of date, so if that's what you started with it may have misled you on the current features. I'd be interested to know if the new algorithm would meet your needs. |
I am afraid reckon has the same problem. I can fully understand that you don't want to maintain both versions. Maybe you could state that in the ReadMe of this project? The solution for reckon I can think of is based on the same principals as for gradle-git:
I think the major question, is whether you agree to my story line provided in my previous comment. |
I think I understand the change you propose making, but I don't think I understand what problem it solves. Could you describe your use case in more detail? |
In my opinion your current implementation does not support custom branching models at all, or have I missed something? I personally need the following custom behavior:
So all this can be achieved by allowing custom starting point for starting the search/walk by But then I still have no possibility to check miss-usage. What if the branch name used does not fit into the conventions described above? What do I do if a hotfix branch is not branching off from master? How do I check and tell the user? So there the grgit access and an agreement how custom functions can report exceptions is inevitable. |
TL;DR Supporting this level of configuration is out of scope for both gradle-git and reckon. I plan to provide better guidance in the README on whether reckon is right for a particular project/person/team. gradle-git was very customizable, far more than it should have been IMO. This has been a little bit of a maintenance problem for me and also just distracts from the core value: an opinionated and hands-off approach to versioning. In reckon, I'm starting from an immutable and opinionated core and leaving the configuration to the edges (mostly for the user input type stuff, e.g. scope/stage). The downside is that while reckon can support a number of branching models, it intentionally does not support them all. From my understanding, the majority of git flow should comply with reckon's assumptions. Your described (and I think the pure) implementation of the master branch is where the conflict comes in. One of reckon's core assumptions is that HEAD is the relevant starting point, and that its history has tags that inform what the next version should be. If master holds all of the tags, but those tags are on merge commits not visible outside of master, this is violated. I do see that you could make it work with the configurability of the search start point, but this opens up too many possibilities for extension points within the core of reckon that I don't really want to pursue. I certainly don't want to push someone away from a branching model that they like, but if you do want to use reckon/gradle-git, you would want to reconsider your approach to master. As long as you can keep the version tag being in the history of whatever development HEAD you are on, you should be fine. |
OK, thanks for the clarification. When I saw this issue, I thought there is some common interest. |
Closing this as the plan is to address it in reckon. |
I've been spending some time on-and-off when I can find it walking through your plugin and looking to see if I can extend and contribute back adding support for version strategies that are derived from the maximum version -- either from a tag or from a branch.
Taking git flow as an example, if I am on the develop branch and my derived version is 1.0.0-SNAPSHOT, if I were to create a release/1.0.0 branch, then when I return to the develop branch, I want the derived version to be 1.1.0-SNAPSHOT (based on a policy that assumes MINOR updates.
I took a stab at starting to implement something like this in a fork of the codebase and have some of this working. It involves modifying SemVerStrategyState class to include in addition to having a NearestVersion, having a MaxVersion as well.
In order to get some feedback with the goal of hopefully getting this into the codebase, is it better to just provide you a link in this issue to a fork of the repo, or should I submit a pull request, even though the current solution might not be mature enough. Do you have a preference?
Once I have the field in place in the Strategy state, I can then build some PartialStateStrategies similar to what's in Strategies class. There is then the question of whether they should be added to Strategies, or possibly create a new plugin similar to the release-opinion -- possibly called release-gitflow, and have perhaps a GitFlowStrategies file.
Any insights into how you might solve and decompose this problem would be greatly appreciated.
Cheers.
Doug
The text was updated successfully, but these errors were encountered: