Skip to content
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

Support always building -SNAPSHOT versions when not building with a special flag #90

Open
magneticflux- opened this issue Sep 10, 2021 · 7 comments

Comments

@magneticflux-
Copy link

My workflow is as follows:

  1. Start with branches release/xyz and develop.
  2. Branch off of develop to feature/xyz.
  3. Complete development of the feature, merge feature/xyz into develop.
  4. Possibly repeat 2-3 multiple times.
  5. When it's time for a release (large enough changes, finished with changes for now), merge develop into release/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)

@mockitoguy
Copy link
Contributor

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!

@magneticflux-
Copy link
Author

magneticflux- commented Sep 11, 2021

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.

@mockitoguy
Copy link
Contributor

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 new incrementStrategy configuration 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?

@magneticflux-
Copy link
Author

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:

  1. main just built and tagged v1.0.0
  2. feature/abc branches off and adds 3 new commits, it builds v1.0.3
  3. feature/abc merges (via PR or otherwise) into main
  4. main builds and tags v1.0.1.
  5. Problem! v1.0.1 can be built after checking out main OR after checking out the first commit of feature/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.

@mockitoguy
Copy link
Contributor

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)

@magneticflux-
Copy link
Author

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 (allegro/axion-release-plugin#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.

@mockitoguy
Copy link
Contributor

@magneticflux-, it's been long, I'll close the ticket. Reopen if needed!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants