I'm a long time user of the maven-release-plugin
which will not release (aka deploy jars to maven repo) if there are unit test failures.
For various reasons I want to use only the maven deploy plugin but apparently will still deploy even if there are test failures in the maven-surefire-plugin
.
Consequently instead of just
mvn clean deploy
I must setup my CI to do a two step analagous to (shell):
mvn clean test && mvn deploy -DskipTests=true
I have made sure surefire is not set to ignore failures. Ideally I would not like to run two separate processes.
Certainly deployment on test failures can't be the default? Am I missing something?
EDIT it appears to be a Jenkins issue.. Can't reproduce
I'm not sure why or how Jenkins forces the maven build to continue on test failure (I assume this is for reporting) but it doesn't show any of the options being passed to for it to continue. It appears to only happen when Jenkins says "Modules changed, recalculating dependency graph".
clean : removes files generated at build-time in a project's directory ( target by default) install : installs the package into the local repository, for use as a dependency in other projects locally.
The deploy plugin is primarily used during the deploy phase, to add your artifact(s) to a remote repository for sharing with other developers and projects. This is usually done in an integration or release environment.
When you call mvn deploy , mvn will also execute every lifecycle phase before deploy , in order: validate , compile , test , package , verify , install . Same for verify : validate , compile , test , package .
mvn install: Deploys the packaged JAR/ WAR file to the local repository. mvn deploy: Copies the packaged JAR/ WAR file to the remote repository after compiling, running tests and building the project.
You are encountering a known issue (or feature, depending on tastes) of Jenkins, which in Maven builds (hence created from the Maven Jenkins job template) would always pass by default -Dmaven.test.failure.ignore=true
to the concerned Maven build, mainly because it would set the status of the build to UNSTABLE
and not FAILED
in case of test failures.
This behavior has already been tacked in different Stack Overflow threads, here and here for some references, and it is also an open ticket (providing detailed description) on the Jenkins JIRA platform, although since already a while and would probably not be fixed (or at least clarified in the job configuration UI).
However, the behavior is not provided when creating a Maven build from a freestyle Jenkins job template, that is, using a template which is not already pre-configured for Maven and hence no maven.test.failure
property would be passed by default.
The guideline indeed is to not deploy artifacts in case of test failures (which is the default behavior of the maven-surefire-plugin
btw), which you can tackle in different ways:
-Dmaven.test.failure.ignore=false
option as part of the initial mvn clean deploy
commandmvn clean install
, leaving then a next step to deploy either via Maven (see next) or a Jenkins plugin (there are Artifactory/Nexus Jenkins plugin which handle this task nicely, with the direct advantage of easier credentials and repositories management for snapshot/releases and hence more governance/security on CI side, removing noise from the pom.xml
file or from every developer's maven settings).Concerning the additional Maven step which would only deploy, some considerations to also address some points in the comments above:
There is a relevant difference between mvn deploy
and mvn deploy:deploy
, where the former is invoking a Maven phase and hence in cascade each phase from validate
till deploy
(hence, compile
, test
, package
, e.g.) and each and every potential plugin execution configured in the pom file for a certain phase; the latter instead is only invoking a goal, the deploy
goal of the maven-deploy-plugin
, with the obvious direct advantage of performances (it's only performing one quick action and not the whole build again) and concerns (it's only performing what we actually really want at this stage).
Yes, you can skip tests and the maven-jar-plugin
would not re-package the application once again, e.g., and further default optimization provided by Maven, but still the former would be much slower and less correct.
However, deploy:deploy
would not work because of missing information in the Maven build context, looking simply at the target
folder would not be enough to identify what to deploy, Maven needs to know which artifact is attached to the current build to be deployed. The additional jar:jar
comes to the rescue in this case, not re-packaging anything but simply detecting what it was supposed to be packaged, attaching it as an artifact to the build context and making the maven-deploy-plugin
happy. This mechanism is also explained in this Stack Overflow answer, as previously pointed out in the comments.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With