Support always building `-SNAPSHOT` versions when not building with a special flag
My workflow is as follows:
- Start with branches
release/xyzanddevelop. - Branch off of
developtofeature/xyz. - Complete development of the feature, merge
feature/xyzintodevelop. - Possibly repeat 2-3 multiple times.
- When it's time for a release (large enough changes, finished with changes for now), merge
developintorelease/xyz.
I already publish builds from release/xyz branches to various maven repos and Github Releases using the Shipkit plugins.
I would like to expose snapshot builds from develop and feature/xyz branches somewhere (Maven, Github Actions build artifacts, etc.). Additionally, local builds (potentially having non-committed changes) should by default be marked as snapshots to distinguish them from reproducible builds on CI. I personally like having Git tree status included in the version like is done here: https://github.com/CaffeineMC/sodium-fabric/blob/68ca12bcbd57eddfaf47aa66492464540c2c7581/build.gradle#L75-L97
This would be extremely useful for simply linking development builds to users in order to get feedback on issue fixes quickly. Examples of this workflow can be found in one of my repos here: https://github.com/magneticflux-/fabric-tree-chopper
#37 and #77 are similar to this, but #37 requires an override for snapshot builds rather than the reverse and #77 requires -SNAPSHOT in the version property to be set (if I'm reading the PR's code correctly: https://github.com/shipkit/shipkit-auto-version/pull/78/files#diff-b565cb97994bdd103d4038e053277da3b27f44237fcc958388e286ec930caa1aR112-R114)
Interesting. Can you describe the the requested feature in the form of current vs requested behavior? I want to make sure I understand it. Thanks for reporting!
Sorry about the ramble, I wrote all that just before going to bed 😄.
What currently happens:
Local builds on feature/xyz and develop branches get versioned n patch versions ahead of the last version where n is the number of commits since last tagged release.
What I would like to happen:
Whenever a build is run anywhere, it should be suffixed with -SNAPSHOT and be one patch version ahead of the last tagged release UNLESS a special flag (for CI runs on release/xyz branches) is set somewhere.
Hey @magneticflux-
Interesting use case. I think the -SNAPSHOT part is fairly easy to solve and I don't think it requires changing the plugin. You could just if () { version += "-SNAPSHOT" }
The incrementing bit is a little tricky. Some options:
- do nothing, be happy with patch version incremented by
n - do nothing, the customer can hack the version in the build file, previous version is available at
ext.'shipkit-auto-version.previous-version'- expose
ext.'shipkit-auto-version.previous-version.patch'. It's a variant of above, just making "hacking" a little easier. - expose
ext.'shipkit-auto-version.previous-semver'. Another variant, we would expose jsemver object that has cool methods like incrementPatchVersion(). This would make it really easy for customers to increment the version in any way they want. The downside is leaking 3rd party API.
- expose
- expose new
incrementStrategyconfiguration setting with values: incrementStrategy=default or incrementStrategy=simple. In your case, you'd just pick "simple". This adds complexity (Axiom plugin has tons of configuration settings). - expose an API where the customer can register a callback/Groovy closure to "hook up" to version selection logic in the core plugin. Feels like adding more complexity.
Thoughts? Other options?
I think incrementStrategy is the way to go, but I also think there's an underlying issue in the selection of next version that my workflow exposes:
When building a version on a feature branch, the patch number is incremented for each commit. However, as soon as that feature branch is merged, the patch number goes back to +1 for the merge commit. An example:
-
mainjust built and taggedv1.0.0 -
feature/abcbranches off and adds 3 new commits, it buildsv1.0.3 -
feature/abcmerges (via PR or otherwise) intomain -
mainbuilds and tagsv1.0.1. - Problem!
v1.0.1can be built after checking outmainOR after checking out the first commit offeature/abc; these two artifacts are different but have the same version.
If I'm understanding the plugin behavior correctly, this leads to situations where a feature branch from the past could have built a version that a different branch now builds, and there's no way to tell which branch a given version was built from. I think this could be a big problem down the road if someone were to just discover a jar file somewhere and not know where it was built from.
To resolve this, I think the plugin needs some understanding of if it's on a feature branch or on the main branch. A regex match on a branch name could indicate being on a "main" branch (for me release/.+, for a simple branching model main or master). Being on a non-main branch would just build a snapshot version of what would be released if it were merged: the last tag +1 patch version.
If I'm understanding the plugin behavior correctly
The reason we count the commits is to allow "concurrent PR merges" that trigger releases. If you close 3 PRs at the same time, you'll get 1.0.1, 1.0.2, 1.0.3 (assuming that previous was 1.0.0).
there's no way to tell which branch a given version was built from
I think that's normal ;-) Version number does not contain this information. (you could add it will little effort version = version + 'branch'). Have you seen Axion plugin? (it has features that you might like)
The reason we count the commits is to allow "concurrent PR merges" that trigger releases. If you close 3 PRs at the same time, you'll get 1.0.1, 1.0.2, 1.0.3 (assuming that previous was 1.0.0).
I totally agree, this works great for counting merge commits! I just don't think it makes sense to count non-merge commits on non-release branches the same way. I'm also skeptical if people actually use the generated version numbers on non-release branches (this project at least doesn't do anything with them since releases are only pushed on master)
My idea still doesn't solve the problem of two concurrent feature branches building the same snapshot versions, but it would prevent feature branches with dozens of commits from (IMO confusingly) "blowing up" the patch version +N before the merge takes it down to just +1 again.
I've looked at Axion, but it seems to have pretty poor support for Kotlin DSL which is a personal must for my new projects (https://github.com/allegro/axion-release-plugin/issues/285). I also feel it's a little further from the "sensible defaults, batteries included" approach that I like with this plugin (of course, I'm biased by my own opinions of "sensible" 😉).
there's no way to tell which branch a given version was built from
I think that's normal ;-)
I also agree with this to some extent: it's definitely not expected to be able to pinpoint what branch, commit, and VCS history went into an artifact. However, in this instance I think it's really useful to be able to immediately see -SNAPSHOT and know it was built on a non-release branch and based on a certain previously released version.
@magneticflux-, it's been long, I'll close the ticket. Reopen if needed!