Gradle: Burning actual dependencies versions in release branch - java

In my team we develop several applications, all use the same in-house framework. This framework is separated to many sub modules, each with its own version, and each is published as a jar to artifactory (maven repository).
When we release an application we create a branch for it and we want to compile that branch against the latest release of each framework module (that's ok because in our nightly regressions we compile against the latest snapshot). We use gradle so this is done by setting the dependency version as "latest.release". This works great until we need to fix a bugs in production - then we release a patch for the released application by checking out the release branch, fixing the bug, compiling, validating and packaging the app.
Problem: latest.release now points to a different release version than the one we originally compiled against.
What I want: when releasing the app, burn all its resolved versions (the resolved latest.release) on the build.gradle (or in some other file) so when I compile it again in the future I will compile against the old releases.
I assume many developers face this issue, yet I haven't found any solution for this online. I never used maven but while searching for a solution I discovered there's a plugin in maven, release plugin, that does exactly what I need.
Would like to know if you have a solution for this problem.

Netflix has a plugin that handles locking dependency versions at releast time: https://github.com/nebula-plugins/gradle-dependency-lock-plugin
Alternatively, you can use this plugin: https://github.com/ben-manes/gradle-versions-plugin to identify dependencies that have newer versions, and replace them manually as needed.

Related

Problem with Eclipse when using Java 11 and Cassandra Spring Unit possibly along with lombok and gradle

So I ran into a problem with a project. Where Eclipse would say that java.util.* has an import error The package java.util is accessible from more than one module: <unnamed>, java.base
I dug around a lot it appears that for some reason no one else is really having this issue. Everyone in our office was. They have told me though that a RC version of Eclipse from 2018 I think Sept works, but that is the only one they can get it to work in. I'll try to post the real version later. So I searched a lot and then started playing with the gradle file for includes. And found that the problem only exists if I include the Cassandra-unit-spring testCompile requirement and because of that it only causes a problem on the test case side.
My assumption is that this is somehow a bug with eclipse as gradle itself has no problem with it. As well as intelij. Let me know what else I can provide here to narrow this down further.
Eclipse Build id: 20190917-1200
Eclipse with Lombok Lombok v1.18.10
Gradle 5.6.4
Oracle JDK 11.0.5
tried cassadnra-unit-spring versions 3.5.0.1 - 3.11.x
Also using spring boot 2.1.3.release
Thanks.
I have excluded all (transitive) dependencies of cassandra-unit and re-included them one by one. Eventually, I found out that the library com.boundary:high-scale-lib, i.e., a transitive dependency included by org.apache.cassandra:cassandra-all, is responsible for the import errors.
The library is not Java 9+ ready, since it uses a java.base package name, i.e., java.util. This is not allowed. Unfortunately, you cannot exclude this transtive dependency, since it is required.
I found out that the release version of Eclipse 4.10 does not indicate errors in projects using the library. This is probably a UI bug in newer Eclipse versions, since I can compile and build my application with Gradle without any errors.
You can try this Eclipse version.
Thank you very much for your hard work Sincostan
So with the information you provided, if you put into your build.gradle file the inclusion of the cassandra unit test like this
testImplementation ('org.cassandraunit:cassandra-unit-spring:3.11.2.0') {
exclude module: 'high-scale-lib'
}
This allowed it to work in my case. you would of course need to use your own version etc. This is with Gradle 6.3 at this time.

Which plugin of maven is better for manage release version?

For example:
maven-release-plugin prepare perform requires not having SNAPSHOT dependencies, this breaks the continuous integration in case of not being validated before the release, instead, flatten-maven-plugin only require -Drevision -Dchangelist scm:tag for tag the release version and not validate SNAPSHOT dependencies.
Having SNAPSHOT dependencies in a release version is always a bad idea. The build becomes non-reproducible.
The Maven Release Plugin offers you a thorough and thought-through release process. There are different opinions about some aspects of it, and if you don't like them, you can construct your own way, possibly in your build server (Jenkins) instead of Maven.

What about new versions of third party libraries?

I'm maintaining an open source java library which has itself some dependencies to third party libraries (e.g. commons-beanutils:commons-beanutils-1.8.3). During development I just added the most recent version of such libraries to my pom. Now I did some changes to my library and realized that those versions are no more recent.
I'm now wondering which strategy is best practice with such dependencies.
My feeling says run mvn versions:use-latest-releases test.
I would recommend using mvn versions:display-dependency-updates and updating relevant libraries by hand.
It is not necessary to always use the latest version of the library.
Usually, should update your dependencies if:
you need a feature of the new version (for major and minor releases)
the update resolves a known bug (that affects you)
the update fixes a security problem.
resolves an incompatibility with another dependency
Otherwise, consider staying on your current version.
You might, temporarily consider using version ranges commons-beanutils:commons-beanutils:[1.8.0,1.9.0) to always use the latest bugfix version. Note however, that this results in non-reproducable builds and must be changed before releasing your project.

Info needed on gradle release plugin as how maven provides release plugin

Can any one let me know if there is any release plugin provided by gradle to do similar tasks performed as Maven release plugin do? I know we can load the maven tasks in gradle but do not want to do it and keep things clean if there is any inbuilt plugin provided by gradle. If there is one please please post sample config or code. Thanks in advance.
In maven we have the following tasks performed by maven release plugin:
release:clean Clean up after a release preparation.
release:prepare Prepare for a release in SCM.
release:prepare-with-pom Prepare for a release in SCM, and generate release POMs that record the fully resolved projects used.
release:rollback Rollback a previous release.
release:perform Perform a release from SCM.
release:stage Perform a release from SCM into a staging folder/repository.
release:branch Create a branch of the current project with all versions updated.
release:update-versions Update the versions in the POM(s).
Thanks
Nithin
Right there are so many choices. I tested most of the release plugins and wrote couple of them for different clients on my own. I really recommend the nebula-release plugin (https://plugins.gradle.org/plugin/nebula.nebula-release). This is driven by the netflix guys, well documented, well maintained and supports all kind of use cases and customizations.
For what its worth, I have recently published a gradle-release-plugin of my own (https://github.com/anshulverma/gradle-release-plugin).
It works on convention rather than configuration. Which is why I built it in the first place. Most of the time we all want the same thing -- semantic versioning with ability to snapshot and tag commits along with publish ability to OSS and bintray repositories. This is what this plugin provides and takes care of most of the configuration.
It is in active development at the moment. Feel free to open issues if any advancements come to mind.
I have been using mentioned townsfolk's release plugin, but it is not actively developed anymore with a few open issues (update: It seems that Daniel Tschinder took over development of that plugin, so probably there will be newer versions).
Recently I have found Axion release plugin which doesn't use separate file to keep current version, but uses Git commits and tags to determine it. It simplifies releasing process and fits in Continuous Delivery trend. What is also very important the author is very responsible.
In addition to the README file nice description can be found on their blog.
Axion itself do only versioning tests from your list, but it can be used together with maven-publish, bintray or any other publishing plugin to push artifacts into remote artifacts repository.
As far as I can tell, there are 4 release plugins right now.
https://github.com/townsfolk/gradle-release
https://github.com/ari/gradle-release-plugin
https://github.com/stianh/gradle-release-plugin
https://github.com/anshulverma/gradle-release-plugin
The townsfolk plugin is the one that works the most like the maven plugin and it works quite well so far ... but is currently not maintained (see github). The other 2 plugins work much differently from the maven release plugin (and pretty similarly to each other). These other two plugins use version control (svn/git) to keep track of version numbers instead of burying (and updating) version numbers in the build.gradle file.
You can also find various approaches here: https://bitbucket.org/evgenyg/demo-releases-plugin/src/master/build.gradle
And some nice slides here: http://www.slideshare.net/evgenyg/release-it
Hope this helps!

Maven release plugin : Releasing with a SNAPSHOT version

I know, its not a good practice to release a project with SNAPSHOT dependencies.
But, I would like to know, Is there any way, we can make maven release plugin to release with SNAPSHOT dependencies?
Is there any parameters that I can pass to the maven release plugin to accept SNAPSHOT version of the dependencies while releasing?
Like
-Dallow.snapshots= true
You could consider using the allowTimestampedSnapshots option to release:prepare. This was apparently added to deal with use-cases where SNAPSHOT dependencies are unavoidable.
But you should only do this if it is unavoidable. Among other things, some Maven repositories can be configured to automatically delete old SNAPSHOT releases. If that happened, your released artifacts could end up with permanently broken dependencies.
Why would you want that? A released version is supposed to never change. Updating one of the snapshot dependencies risks breaking the system. I see two approaches:
Either you have control over the source code of your dependencies, in which case I recommend you to go through the, albeit tedious, process of releasing those projects.
If you don't control the source code you can still rename the binary and manually upload it to your release server. You might still take this approach even for projects under your control, although I strongly encourage you not to.

Categories

Resources