Friday, July 28, 2017

Combining multiple Maven goals into one transaction (e.g. deploy and site-deploy, what if site-deploy fails?)

Leave a Comment

I configured the build server to do

clean javadoc:jar deploy site-deploy

Now if site-deploy fails (because the site did not build, or somebody used the wrong parent pom), the build server shows a failed build, but the deploy was already applied.

Is there a way to "combine" deploy and site-deploy in a transactional way?

Or should I use a different chain of goals/phases (e.g. install before site-deploy)?

3 Answers

Answers 1

Here I am proposing a close solution with the help bash && operator

mvn clean javadoc:jar install site-deploy && mvn deploy:deploy-file {PARAM} 

This will let you

  • fails the build if any of the goal fails during install phase
  • if site-deploy fails, then your artifact will not be pushed/deployed to your remote repository
  • no need to write any custom rollback mechanism if site-deploy fails

The only case this will fail is when your deploy goal fails, there will be no rollback site-deploy. I think failure of deploy phase will be very much rare.

Answers 2

The only way I could find using Maven core features is through the Release Plugin's rollback goal. This however implies that you'd better change the original build command to use the Release Plugin as well, since this page in the documentation mentions the following:

To rollback a release, the following requirement must be met:

  • You haven't run release:clean on the project. This means that the backup files and the release descriptor from the previous release command still exists.

However, it seems it is easy to do this, as the Release Plugin's perform goal already executes deploy site-deploy by default which is exactly what you are doing. As for the javadoc:jar goal, it can be attached to the release profile as mentioned in this FAQ.

If for some reason, the Release Plugin could not be used, then I think the only way to get around this is through the build environment itself. You could split the build into two stages:

  1. The first stage runs the deploy goal.
  2. The second stage run site-deploy.

In case the second stage fails, you manually rollback by executing the first stage but against the previous revision in your SCM (the one that was last deployed successfully).

Answers 3

deploy and site-deploy are usually done over HTTP and potentially deploy to different places, so achieving transactional semantics is probably impossible and you need to approach this as an eventual consistency problem.

In a CI context (that you mentioned you are using), if site-deploy fails, you'd need to either:

  • rollback the deploy;
  • retry the site-deploy goal.

I'm not familiar with quickbuild but with other common CI tools you are able to split the tasks into separate jobs to make it easy to apply either solution.

Since the goal (pun intended) seems to be to catch errors while building the site, an option might be to create a chain of jobs:

  1. mvn install site to run regular tests and build the site;
  2. two jobs that run in parallel and can be retried if failed:
    • mvn deploy;
    • mvn site-deploy.

This could more or less complex depending on how the workspace is shared between jobs.

If You Enjoyed This, Take 5 Seconds To Share It

0 comments:

Post a Comment