Combined site/deploy goal for Maven - maven-2

When running a Maven build on the CI server, I generate the site to publish the documentation and reports, and also deploy the artifact to the snapshot repository for use by other projects. To do this I run the following goals:
mvn clean site deploy
This means the unit tests are run twice, once for the site lifecycle and once for the deploy lifecycle. If I configure the site goal to be bound to the standard lifecycle the tests are still run twice, running the site goal always causes the tests to be run because of the #requiresDependencyResolution test annotation. This is fine if you're only creating the site, but in the context of a deploy it greatly increases the build time for no benefit.
I have a workaround that involves copying the SiteMojo (and the required parents) to a new plugin and removing the #requiresDependencyResolution test annotation from the copy.
This modified mojo will generate the reports without forcing the tests to be run again but I'd prefer a solution that doesn't involve any hacking of the site plugin. Is there a way to suppress the requiresDependencyResolution annotation?

I'm surprised this works - the #requiresDependencyResolution test tag doesn't actually trigger the tests being built - that should be one of the reports that you've included. Normally, I recommend running the site and the build in separate Maven executions in CI so you can get fast feedback on your build and publish the latest site only when that succeeds.
Another alternative is to run it as mvn clean deploy site, and choose the report-only mojo for surefire-report-maven-plugin (this is usually the report that is running the tests again). This will use the previous test results. Of course, another alternative is disabling that report altogether, since you likely get those results from another source such as your CI server anyway.

My current approach is to create a new plugin with copies of the relevant types from the maven-site-plugin. These types are identical to the standard versions except for changing the type name, the goal name and the removal of the #requiresDependencyResolution test annotation.
The copied types are:
org.apache.maven.plugins.site.AbstractSiteMojo
org.apache.maven.plugins.site.AbstractSiteRenderingMojo
The parent mojos are required so Maven can process the javadoc-based annotations (this shouldn't be required for Maven 2.2.0+).
org.apache.maven.plugins.site.SiteMojo
org.apache.maven.plugins.site.SiteJarMojo
These two are copied as SiteOnlyMojo and SiteJarOnlyMojo respectively, SiteJarOnlyMojo is changed to inherit from SiteOnlyMojo . Otherwise the only changes are to change the goal namess and remove the annotation.
So SiteOnlyMojo has:
* #goal site
* #requiresDependencyResolution test
changed to:
* #goal site-only
and SiteJarOnlyMojo has:
* #goal jar
* #phase package
changed to:
* #goal jar-only
* #phase package
These types are declared in a maven-plugin project with artifactId maven-site-only-plugin with a dependency declared on the proper site plugin.
To use this I define a profile (I don't want the reports running on every execution, only when -Psite is declared on the command line) and bind it to the prepare-package phase (prior to 2.1.0, you'd have to bind it to the package phase instead).
<profile>
<id>site</id>
<build>
<plugins>
<plugin>
<artifactId>maven-site-only-plugin</artifactId>
<version>1.0.0</version>
<executions>
<execution>
<phase>prepare-package</phase>
<goals>
<goal>jar-only</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>

<build>
<pluginManagement>
<plugins>
...
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-site-plugin</artifactId>
<version>3.2</version>
<executions>
<execution>
<goals>
<goal>site</goal>
<goal>deploy</goal>
</goals>
<phase>deploy</phase>
</execution>
</executions>
</plugin>
...
</plugins>
</pluginManagement>
</build>
This will automatically execute the site action when issuing a 'mvn deploy' command, as well as ensuring the testing suite is only executed once.

Related

skip the execution of maven-war-plugin

How do I skip the execution of the maven-war-plugin during a mvn command?
Based on the documentation, it seems like I should be able to do so by running something like the following, using -Dmaven.war.skip=true:
mvn verify -P integration-test -Dmaven.war.skip=true
But when I do that the maven-war-plugin still gets executed.
Also strange is that when I remove the maven-war-plugin from my pom altogether, it still gets executed. That leaves me wondering why maven-war-plugin is getting executed at all, as I don't have it mentioned anywhere in my pom.xml.
So maybe a better question is: what brings the maven-war-plugin into the project if I don't have it listed as a plugin?
As it turns out, removing the packaging of my pom to war (<!--<packaging>war</packaging>-->) keeps the maven-war-plugin from executing. The maven-jar-plugin gets executed instead. That's not really what I want (I just want to run integration tests via mvn verify without taking too long). But it runs quicker at least.
You must override the default war execution.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.3.2</version>
<configuration>
<skip>true</skip>
</configuration>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>war</goal>
</goals>
</execution>
</executions>
</plugin>
Explanation
By default, the war goal binds to the package lifecylcle phase as stated in the documentation.
So we override the package execution in the pom with the skip configuration.
You need to override executions configuration of maven war plugin:
<plugin>
<artifactId>maven-war-plugin</artifactId>
<configuration>
<webappDirectory>target/stampli-output/</webappDirectory>
</configuration>
<executions combine.children="override">
</executions>
</plugin>
It should do.
Why those instructions?
There is something like super-pom for every pom that has some standard defaults.
These defaults will be merged with your configuration if you don't override them.
Therefore also executions will be merged, which bind plugin goals with phase in mvn.
Links to read:
https://maven.apache.org/ref/3.0.4/maven-model-builder/super-pom.html
https://maven.apache.org/plugins/maven-help-plugin/effective-pom-mojo.html
https://maven.apache.org/pom.html#build - it has info on combine.children
https://maven.apache.org/guides/mini/guide-configuring-plugins.html

Run static analysis tools in compile or package step in Maven2?

I'm researching using Maven for my team, and one of my goals for the build is to have static analysis tools run for every build, and perhaps fail the build for certain severe errors. However, in maven it seems that these are treated as reports and run on the site lifecycle. This presents a couple of problems as we don't intend to use the site for most projects, and it requires an extra step (or at least additional phase) to get the static analysis.
Is there a way to run static analysis tools in maven-2 in the compile or package phase (or equivalent)?
This can be done by configuring the plugin (findbugs for example) in the <build> section and configuring the <phase> in the <executions>:
<executions>
<execution>
<id>findbugs-run</id>
<phase>process-classes</phase>
<goals>
<goal>check</goal>
</goals>
</execution>
</executions>

howto disable compile of modules when tests are skipepd

In our "big build" (40+ modules), we have several modules that contain only tests.
When I give -DskiptTests to mvn, the tests are not executed.
But they are compiled, which costs up to a minute of build time.
How can I selectively turn off such modules when the option skipTests is set?
You'd have to organize your root pom such that the test modules are activated via a profile, and instead of using -Dmaven.test.skip to turn use -P!testProfile to deactivate them and hence skipping them.
Another thought is that you could just do:
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<skip>${maven.test.skip}</skip>
</configuration>
</plugin>
</plugins>
I haven't actually tried that... it should in theory work. I seem to remember that the <skip> configuration is on all plugins.
Just to clarify the Gareth David point:
When you run mvn ... -DskipTests, only the execution of tests is skipped. This is the same behavior if you run mvn ... -Dtest=notest
When you run mvn ... -Dmaven.skip.test=true, then both test execution and compilation are skipped.
So the second command is enough, without any modification of your pom.xml file.
(source)

maven-assembly-plugin causing tests to run twice

I have a maven project where I am using the assembly plugin.
I typically create my artifacts by running:
mvn clean verify assembly:assembly
(I have integration tests which I want run separately to unit tests).
When this runs, the assembly plugin is running the unit tests itself.
This causes them to be run twice.
Is there a way I can tell the assembly plugin not to run the tests?
I am tempted to run this in two steps:
1. mvn clean verify
2. if previous command successful, run mvn assembly:assembly -DskipTests=true
However, this is a little clumsy and would rather the single command.
Thanks,
Steven
When this runs, the assembly plugin is running the unit tests itself. This causes them to be run twice.
The assembly:assembly goal Invokes the execution of the lifecycle phase package prior to executing itself and running it on the command line will thus invoke any phase prior to package. And this includes the test phase.
Is there a way I can tell the assembly plugin not to run the tests?
No. My suggestion would be to create the assembly as part of the build lifecycle instead of invoking the plugin on the command line i.e. to bind it on a particular phase. For example:
<project>
...
<build>
<plugins>
<plugin>
<artifactId>maven-assembly-plugin</artifactId>
<version>2.2-beta-5</version>
<executions>
<execution>
<id>create-my-assembly</id>
<phase>package</phase><!-- change this if not appropriate -->
<goals>
<goal>single</goal>
</goals>
<configuration>
...
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
And if you don't want the assembly to be created if your integration tests fail, then bind it on a later phase (e.g. post-integration-test or verify).
And if you don't want the assembly to be systematically created, put the above configuration in a profile.

How to display dependency conflicts in 'mvn site'

I can easily see if there are conflicts between (transitive) dependency versions using:
mvn dependency:tree -Dverbose=true
... this will show the full resolution tree, including which elements were omitted (for duplicate or conflict or whatever). What I would like to do is to add the full tree to the 'mvn site' report.
Currently, the site report includes the dependency tree but only as resolved, i.e., without any conflicts. I see in the project-info-reports plugin that there is not currently any way to do what I want using the standard report.
I tried adding a section to the pom to include the maven-dependency-plugin 'tree' goal with the outputFile specified, but it wasn't included when I ran 'mvn site'. It was something like this:
<reporting>
....
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<reportSets>
<reportSet>
<id>deptree</id>
<reports>
<report>tree</report>
</reports>
<configuration>
<verbose>true</verbose>
<outputFile>${project.reporting.outputDirectory}/deptree.txt</outputFile>
</configuration>
Of course, the 'tree' goal is explicitly identified as not a report, but I was hoping to at least be able to produce a file that I could link to from the generated site. No dice.
Is there any way to force an arbitrary plugin's goal to execute during site generation? Am I totally out of luck here? Obviously I could write my own reporting plugin to do this, and/or submit a patch for the project-info-reports plugin, but I want to make sure I've exhausted all the built-in maven options.
(I'm using maven 2.1.0, but I didn't see anything about a change to this functionality in the release notes for later versions.)
Is there any way to force an arbitrary plugin's goal to execute during site generation? Am I totally out of luck here?
Just to answer your question, you can bind a mojo to the pre-site phase of the Site Lifecycle:
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>tree</id>
<phase>pre-site</phase>
<goals>
<goal>tree</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
<reporting>
...
</reporting>
If you then run mvn site, dependency:tree will run.