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.
Related
Is it best practise to store snapshot versions in Artifactory in maven applications?
As snapshot versions should be used only for development purposes.
It's not true that SNAPSHOT versions should be used only for development. When SNAPSHOT version is uploaded it's not uploaded as is - it gets transformed into a unique version, something like this: 1-20150904.140213-59. When referencing such dependency you can:
either use SNAPSHOT word like 1-SNAPSHOT, then you don't really know which exact version is used
or use a resolved version: 1-20150904.140213-59
Using the 1st option is discouraged for any purpose - be it a deployment, or a <dependency> in pom.xml (even for development purposes), because it leads to non-repeatable actions. You run build once - you get a dependency with version 1-20150904.140213-59 downloaded, you run it for the 2nd time you may get another version like 1-20150904.140214-60.
But there's nothing wrong with referencing the full (resolved) version. So you can leverage snapshots the same way you do with release versions. Note though that remote repositories (e.g. Nexus) can be configured to delete old snapshot versions - so you need to take this into consideration.
By the way, snapshots are very convenient for releases.
A SNAPSHOT version is meant to be used for development. You can store it in Artifactory, but for using an artifact productively, you should build a release version.
#Stanislav is right that timestamped SNAPSHOTs could technically be used like release versions, and I believe him that this works, but I wouldn't do it because it is not how SNAPSHOTs and releases were meant to be.
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.
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!
I have a Maven project that needs to be versioned. I have chosen to use the versions-maven-plugin as my versioning plugin but am unsure if that's the best option.
I have read the documentation that such plugin actually modifies the POM and I don't really like that approach. I have worked on projects where they had separate build.properties file that got modified manually.
What I want to achieve is to have my CI generating the artifact for me ready to be deployed and update the version number automatically.
So, any suggestions? How have you done before?
Thank you
I'd get the version number from the one source that matters: that's the source code management system (Subverson, Mercurial, or Git), not Maven.
I'd say that Maven might be out of synch unless your Maven plug-in is getting it from SCM.
Use the Release Plugin. You want to perform automatic deployment and batch release. The Versions Plugin is designed for something else.
We have found MAVEN-RELEASE-PLUGIN super useful and can not imagine releasing and managing version with it.
Is there any way to force Maven to use remote artifacts and not those installed on your machine? since I worry about runtime errors and not compilation errors build server is not valid option.
P.S. I know I could delete or rename the .m2 folder, but I bet there is some more clever way of doing this. Maybe some plugin or special command param?
Having no local repository would mean your classpath consisting almost entirely of URLs on remote servers. I can't see why this would be supported as execution would be awful, and any dropped connection would result in classloader issues. Having a local repository ensures the jars are available before compilation/execution begins.
Also consider that WAR and EAR projects (and many using the dependency plugin) rely on downloading the jars to complete their packaging. There would be a huge overhead if these had to be retrieved from a remote repository on every build. I'm pretty sure the managers of central would not be keen on dealing with that load.
Some alternatives for you to consider:
If you want to force a clean local repository on each build, you can use the purge goal of the dependency plugin.
If you want to keep builds isolated, you can use separate Maven settings by passing -Dorg.apache.maven.global-settings=/path/to/global/settings.xml
Alternatively you can override the local repository on a per build basis by passing -Dmaven.repo.local=/some/repo/path
If you want to avoid hitting remote repositories on each build, add <updatePolicy>never</updatePolicy> to your remote repository configurations. This means Maven will only check for updates if you force it to with a "-U" switch on the command line
If you want to take the latest version of a dependency, you can use the LATEST keyword in the version declaration (instead of the version number), though this can be risky if the dependency is incompatible.
If you want to take the current release version of a dependency, you can use the RELEASE keyword in the version declaration (instead of the version number). This is like LATEST, but tends to be the newest stable build, rather than the newest.
If you want to take the latest version of a dependency within a range, use Maven's version range notation, for example [1.0.0,2.0.0) means any version from 1.0.0 inclusive to 2.0.0 exclusive
For more details on LATEST and RELEASE, see section 9.3.1.3 of the Maven book.
If you use an internal repository manager (obligatory Nexus and Artifactory references here), the overhead of purging the local repository is greatly reduced - you'll just have an increased local network traffic load.
I don't think there's really a way to do what you are asking for. You could look into depending on SNAPSHOT releases (but that means changing your version string of the upstream projects to be SNAPSHOT versions).
Incidentally, this was discussed at length in a recent Java Posse episode (#268). I don't think they ended up with a solution, but you may get some good ideas there.
I also like some of Rich Seller's ideas, which I'll be looking into myself.