mvn release:prepare failure cleanup - maven

I was building a release using mvn and have seem to hosed things up. This is what I did:
mvn release:prepare -Darguments="-DskipTests=true" -DautoversionSubmodules=true -Dpassword=... -Dusername=...
and it failed due to a incorrect password.
Mistakenly I did a
mvn release:clean
which then blew away my backups preventing me from now doing the correct thing, a
mvn release:rollback.
This fails with an error saying it cannot restore from a backup.
Is there a way to tell mvn to just start fresh building this release?

When you (mistakenly) invoked mvn release:clean, all of the intermediate back-up files of your project were removed, so Maven can't roll back to the initial state (simply because it doesn't know what the initial state is anymore).
You don't have much options left: you need to restore the initial state yourself. This means:
Restoring the project version. This can be done by hand or with the help of the versions-maven-plugin:set plugin goal.
Restoring the <scm> element of your POM.
Restoring any SNAPSHOT dependencies that you might have had (between modules of a multi-module Maven project for example). This also means updating the <parent> element in case of a multi-module project.
Since you say the release failed because of an incorrect password, I assume it failed during SCM authentication. In that case, you don't need to remove the tag that the release should have created.
Since there is no back-ups, on your next invocation of the maven-release-plugin, it will start a new release from scratch.
And remember for the future: Think before you type!

Related

should I use release:prepare before release:perform?

My regular CI build takes 1 hr and a release build takes 2 hrs. Can I skip the release:prepare and directly do a release:perform to save time? What will I miss?
Any other way to decrease the release build time if I cant skip this?
Thanks
Nube to mvn
The short answer is no you can't skip the release:prepare goal. If you want more then read on.
From the maven release plugin documentation:
Prepare for a release in SCM. Steps through several phases to ensure the POM is ready to be released and then prepares SCM to eventually contain a tagged version of the release and a record in the local copy of the parameters used.
What this actually does is the following:
Modify all your x-SNAPSHOT versions to simply x. So 1.0-snapshot will turn into 1.0
Build everything to make sure this still compiles and tests after the version change
Commit the changes (And tag them in your SCM)
Upgrade all the versions to the next SNAPSHOT version, in our case 1.1-SNAPSHOT
Commit this new change
An intended by-product of this process are files with the poms to be built for the release:perform goal, so that's why you can't skip the release:prepare.
If you're still interested in shortening your build time, and do not care for all the commits to SCM you can implement your own release mechanism (which I do not recommend) using maven-versions-plugin and maven-deploy-plugin. See this for details.

Why does release:prepare change versions back to SNAPSHOT?

I'm using the maven-release-plugin and I'm noticing that it appears to change the released version BACK to -SNAPSHOT at the end.
Here's the command line args that I'm passing to maven:
--batch-mode release:prepare -DupdateWorkingCopyVersions=false -Darguments="-DskipTests -Djava.awt.headless=true -Dmaven.javadoc.failOnError=false"
Everything appears to go well - and I notice a commit and a push from the plugin where all of the proper version numbers are indeed updated to NOT have the -SNAPSHOT.
[WARNING] Ignoring unrecognized line: ?? myProject/pom.xml.releaseBackup
I see a few of these warnings ^ in the log file (not sure if this is relevant, but appears to be related to the release plugin)
Finally I see that the plugin modifies the POMs again:
[INFO] Transforming 'myProject POM'...
[INFO] Updating my-project to 6.2-SNAPSHOT
Following this the plugin makes and pushes a commit with the following:
[maven-release-plugin] rollback changes from release preparation of myProject-6.2
Why is this last bit happening?
I don't understand the lifecycle of release:prepare or release:perform. Why does all of my code appear to be built twice?
Any help appreciated. Thanks
As I understand it, release:prepare
Updates the POM files to the version that was specified
performs the build, which runs the tests
performs other validations (ie, no dependencies to SNAPSHOT artifacts)
Commits the changes (which should be restricted to the POM files and their versions)
Tags the source that was just committed
Updates the pom files back to the nominated SNAPSHOT version
Commits those changes
Note: I'm not sure if that's the specific order. The above list is not an exhaustive list, it's just my recollection.
At this point, the release doesn't exist. That's what release:perform does. Release:perform checks out the code against the TAG and builds the artifacts against the tagged source.
This is why release:prepare moves it back to the snapshot version. It's simply preparing the source to have a release built against it. Developers working on that branch, once the tag is cut, can continue to commit changes without affecting release:perform. It also allows a release to be re-cut at a later date, as it is built against the tag.
Of course, there are variations to this plugin which is documented. But, as I understand it, this is a common workflow for this.

Maven does not take newly built snapshot, uses global repository

I am trying to build a patch branch, into which I build both a parent(a snapshot) and a child(a snapshot as well) as modules listed in an aggregation pom.
Maven finds out everyone depends on the parent, and builds it first, BUT it does not use the newly built parent when I build into clean repository.
When built immediately afterwards, against the same repository, that the built Parent 2.2.5- Snapshot is installed in already, everything works correctly and the patched parent is used in its children.
The problem is that the CI build is always built on a clean repo, and hence, the parent that we use is the one from the global repository, not the local one.
Is this wrong pom.xml, maven settings or possible a bug in maven algorithm?
I tried
mvn clean install -nsu
but in vain.
If you use the option -nsu which means:
-nsu,--no-snapshot-updates Suppress SNAPSHOT updates
It will never use the most up-to-date snapshots. To force maven to do so you should use:
mvn -U clean install
instead.
It turned out the major problem was that we were building the parent pom together with the rest.
Maven downloads all parents first and then resolves dependencies.
So, it was not correct that the parent is listed together with the rest, as a module, when this is a clean build and this version of the parent was not yet deployed(children saw an old snapshot of it instead).
Solution 1: use relativePath to point to the branched parent. This is the better solution in case you do not have very complex hierarchy of modules.
Solution 2: build and deploy the parent of the patch first, so that it is seen by all children, and hence they use correct versions of each other.

maven release perform failed

Today while doing the release of our project, the release:perform command failed in between as our nexus was having intermittent issues. The release command only able to upload one pom file to nexus.
Now, the nexus issue is resolved and I am trying to do the release, it fails as the pom file already exists and its not the snapshot version and we don't have access to nexus so that I can delete that file and start over again.
Is there any way I can pass an argument so that release:perform should continue if the file is already there and ignore this but continue with uploading the rest.
I have looked for options of such type but didn't find anything.
My last resource would be to start the release again, which will bump the version number, but would like to understand if there is any other approach where in I don't need to bump the version.
I am using maven 2.2.1
Here's how I have handled this in the past. The release:perform command does a checkout of the tag from your SCM provider (e.g. SVN). This is done in the target/checkout directory of that project - whatever is there should be an exact copy of the released tag, so it will have the right version number in the pom files etc.
If you move to that directory (target/checkout in the directory where you started the release), you can simply do a mvn deploy there and it should compile and package that version, and then upload it to your Nexus instance.
If you don't have the target/checkout directory, you can check out the Tag created as part of the release:prepare phase from your SCM system to a fresh directory and run mvn deploy there.
Since the tag in your SCM has already been created, the only thing that's left is really compiling, packaging and deploying the release, which is exactly what mvn deploy should do.
If you have provided additional parameters (e.g. for activating profiles) for the build during the call to mvn release:perform, you will have to provide these as well when you run mvn deploy.
Using this approach, your version number will not have to change, it can stay the same, since you're just uploading what has already been tagged as part of mvn release:prepare.
My advice would be for you to request from the admins that the old artifact be removed. You can either re-deploy the code from the tag by checking it out and simply doing
mvn deploy
Or rolling back your release:
mvn release:rollback
And re-doing it as usual.
It is essential to remove the old artifact from the remote repository, if the sizes do not match. Release repositories do not allow the redeployment of artifacts, unless this has been explicitly switched on on the server side.
Furthermore, #nwinkler's answer is also quite good.

Maven release plugin - SNAPSHOT project needed

I am using the M2 release plugin from within Jenkins which calls the maven-release-plugin 2.3.2 internally and while building throws this error : You don't have a SNAPSHOT project in the reactor projects list. Problem is , my projects poms do have their version as 1.0.0-SNAPSHOT. What am I missing ?
com.abc.def is the company parent POM , and I am just doing for mvn release for utils
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.abc</groupId>
<artifactId>def</artifactId>
<version>1.0.0</version>
</parent>
<groupId>com.abc.def</groupId>
<artifactId>utils</artifactId>
<version>1.0.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>utils</name>
And yes, I have done my basic Google + SO trawl and everywhere it points that my POMs should be having SNAPSHOT as the version , which is already there. Except that my company parent POM is not snapshot. Could that be the reason ?
I had the same problem but these solutions didn't work. This blog post by Tomek Kaczanowski hit the nail on the head.
The cause often is that the Jenkins SVN strategy is set to "use svn update as much as possible" which does not clean up the build workspace between builds.
When you try to cut a release, Jenkins will update your pom and create some temporary files. If the release fails, these pom updates and temp files are not cleaned up. So then, when you fix the pom and try to rebuild, you get the You don't have a SNAPSHOT project in the reactor projects list error due to these funky workspace artifacts confusing Jenkins.
The solution is to change your Jenkins SVN strategy. Any of the following should work:
always check out a fresh copy
emulate clean checkout by first deleting unversioned/ignored files, then 'svn update'
use svn update as much as possible, with 'svn revert' before update
I'd also recommend you clear out your Jenkins workspace just to make sure you're starting fresh.
Master pom doesn't need to be SNAPSHOT as well (at my company we have the same setup and it works OK). This part of utils pom is OK as far as I can tell, so maybe you're missing something else, like
<scm>
<developerConnection>scm:${release-scm}</developerConnection>
</scm>
and of course the maven release plugin section in build definition in your POM ?
(a long shot I know)
i sometimes found spelling problems with the term: "SNAPSHOT", which basically will also lead to the same error. like:
1. SNAPSOT
2. SNASHOT
3. SHNAPSOT
;-) so it is worth to check this out upfront.
cool for fixing is to use on the parent pom:
versions:set
Actually the Jenkis's workspace contain old non SNAPSHOT versions of some modules. Try to wipout the workspace (=to clean and clear it), then do a release again, he will get the correction versions with the suffix -SNAPSHOT
I found the reason: The latest company Parent POM was not being picked up
I had clean and -U both in the mvn argument list. Did not work
Then I cleaned the ~/.m2 repository. Did not work
What worked is, in Jenkins
Goto the Job config page
Go to Build , click Advanced
Check the box Use private Maven repository
Select Local to the workspace. Save
I know this is one of those weird things Maven has a habit of doing for some reason. And as usual the errors are not informative/intuitive enough.

Resources