ajoberstar / reckon

Infer a project's version from your Git repository.
Apache License 2.0
185 stars 28 forks source link

When using -Preckon.stage=final on a clean tagged commit, the reckoned version becomes the next available version. #133

Closed bowenwp closed 2 years ago

bowenwp commented 4 years ago

We're attempting to run gradle assemble -Preckon.stage=final on tagged commits to build the version that was tagged.

reckon {
  scopeFromProp()
  snapshotFromProp()
}

When not using the final flag, the reckoned version matches the tag on the current commit.

✔ ~/PROJECT [v0.5.2|✔]
$ ./gradlew app:assemble

> Configure project :app
Reckoned version: 0.5.2

However, with the final flag, Reckon increments the version number instead.

✔ ~/Project [v0.5.2|✔]
$ ./gradlew app:assemble -Preckon.stage=final

> Configure project :app
Reckoned version: 0.5.3

The final behavior seems odd in this later case, we'd expect final build on a clean tagged commit to produce the same versioned release build as tagged.

We can resort to using the default command to build a release build matching the tag, but there's a slight caveat here. If the repo is dirty in anyway (CI script dropping a few temp files in the source repo), then the default command will bump the version to v0.5.3-SNAPSHOT where as -Preckon.stage=final could've caught this and not allow a dynamic version change during automated builds.

ajoberstar commented 4 years ago

That's intended behavior. The idea was that if you were providing scope or stage input, you wanted something to change.

The use case you seem to have is a "rebuild" where you essentially want to assert that it will be a "rebuild" and have it fail if not. Does that seem accurate?

bowenwp commented 4 years ago

Thanks for the quick response.

Yes, I think that's the correct interpretation.

To provide more context, our specific use case is building the release builds from CI hosts and to trigger the release builds off version tags. Therefore, when the builds were executed, the tag specifying the version is checked out and we want to make sure the build off that tag is always the same version. Therefore, we do want to assert it is a rebuild of the tag and not a version bump.

Is keeping the source directory clean sufficient condition to ensure the default command build the version of the tag? We would love to have final's behavior of failing on a dirty repo as well.

damnhandy commented 4 years ago

@bowenwp sounds like you're looking for a task that would return the current version of the project. Something similar to the Axion release plugin's currentVersion task? I'd also be looking for something that as well.

x80486 commented 3 years ago

Hello! I would really like to be able to achieve such thing. I have exactly the same use case. It would be nice to have such behaviour: just return the current version on a final stage (while failing if the repo is dirty).

Thanks for the good work and for making Reckon open source! :tropical_drink:

x80486 commented 3 years ago

I think a Gradle property here is more viable because Reckon sets the version automatically for the artifact. So providing something like -Preckon.use-current-version=true (or something around those lines) makes a lot of sense, but probably that property should overwrite the behavior for the current behavior.

@ajoberstar, have you had a chance to give it some thought and consider this one?

ajoberstar commented 2 years ago

As of 0.15.0, you should be able to do something like this:

tasks.register("assertReckonedFinal") {
  doLast {
    assert reckon.getVersion().get().isFinal()
  }
}

You could do something similar to enforce isSignificant() if you preferred.

And you'd probably want to run it before other tasks:

./gradlew assertReckonedFinal publish

This one feels fairly workflow dependent, so I'm not too fond of adding more flags into the tool to support this. However, let me know what you think of the above approach.

ajoberstar commented 2 years ago

It appears I didn't mention this explicitly, so to ensure people are aware... To build an existing tag without incrementing the version again, provide no input. Omit both the stage and scope and it will pick up the version already tagged. This is the exact approach used by reckon's own release process (see the .GitHub/workflows/release.yaml) and note that I don't provide either property to the build.

If you want added assurance that it's a rebuild, use a task like the assert one noted above.

bowenwp commented 2 years ago

We've been using shell script and git command to compare tagged version number against the reckoned version. The update you showed is definitely cleaner and should work better in our case.

Thank you @ajoberstar for the update and detailed explanations.