Maven stop build if svn is out of date - maven

After reading through a lot of SO questions as well as other sites I still haven't been able to exactly address this problem.
We have a long build cycle (10-20 mins) because there are a lot of dependencies. It sometimes happens that you start a build with everything up do date, but while it's being done, someone pushes new changes to the remote svn.
I would like Maven to check on the validate and verify phases if svn is still up to date basically, on all dependent projects.
I've tried using the Enforcer plugin, and the Build number plugin with no success yet. The enforcer seems like it could do the trick, but I haven't figured out which rules to set.
The build number plugin on the other hand checks if there are no local modifications, but I don't think it checks the remote changes.
I don't think the POM is very relevant to the question, but if anyone needs it, or some parts please let me know and I'll update with it.

I would try a combination of the maven-scm-plugin's diff goal and Enforcer.
scm:diff may be configured to write output to a file. Run that when there are no changes and see how big the file is, or, if it generates the file at all if there are no changes. Then, use the Enforcer plugin's requireFilesDontExist and/or requireFileSize rules to make sure the scm:diff output file is the "no changes" size you determined. If it's larger than that, changes were committed during this build.

After a lot of testing I found another solution. This solution is for people that work with SVN and only want to commit changes once the build succeeds, and need to use the latest revision for a build.
What this will do is retrieve the latest revision number from SVN and update the working copy. At the end of the build process it will check the revision number again, to ensure that no one has pushed any changes.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>buildnumber-maven-plugin</artifactId>
<version>1.2</version>
<executions>
<execution>
<id>get-svn-local-revision-before</id>
<phase>validate</phase>
<goals>
<goal>create</goal>
</goals>
<configuration>
<doCheck>false</doCheck>
<doUpdate>true</doUpdate>
<buildNumberPropertyName>buildNumberLocal</buildNumberPropertyName>
<useLastCommittedRevision>true</useLastCommittedRevision>
</configuration>
</execution>
<execution>
<id>get-svn-remote-revision-before</id>
<phase>validate</phase>
<goals>
<goal>create</goal>
</goals>
<configuration>
<doCheck>false</doCheck>
<doUpdate>false</doUpdate>
<buildNumberPropertyName>buildNumberRemote</buildNumberPropertyName>
<useLastCommittedRevision>false</useLastCommittedRevision>
</configuration>
</execution>
<!-- Repeat after everything is done -->
<execution>
<id>get-svn-remote-revision-after</id>
<phase>verify</phase>
<goals>
<goal>create</goal>
</goals>
<configuration>
<doCheck>false</doCheck>
<doUpdate>false</doUpdate>
<buildNumberPropertyName>buildNumberRemote</buildNumberPropertyName>
<useLastCommittedRevision>false</useLastCommittedRevision>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>1.3.1</version>
<executions>
<execution>
<id>check-svn-revisions-before</id>
<phase>process-test-resources</phase>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<evaluateBeanshell>
<condition>${buildNumberLocal} == ${buildNumberRemote}</condition>
<message>[ERROR] Local build (${buildNumberLocal}) doesn't match remote build (${buildNumberRemote})</message>
</evaluateBeanshell>
</rules>
<fail>true</fail>
</configuration>
</execution>
<!-- Repeat after everything is done -->
<execution>
<id>check-svn-revisions-after</id>
<phase>verify</phase>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<evaluateBeanshell>
<condition>${buildNumberLocal} == ${buildNumberRemote}</condition>
<message>[ERROR] Local build (${buildNumberLocal}) doesn't match remote build (${buildNumberRemote})</message>
</evaluateBeanshell>
</rules>
<fail>true</fail>
</configuration>
</execution>
</executions>
</plugin>

Related

Why does maven-release-plugin uploads build information? And can it be removed?

When using the maven-release-plugin to release an artifact onto a repository, the entire pom is copied. This includes sections build and reporting.
I can understand that deployement information is propagated since dependencies of a project by the same creators are likely to be deployed on the same servers, but, for non-pom artifact, I don't understand the point of having the build information.
Is it possible to create a release stripped of this information?
Use the flatten-maven-plugin
https://www.mojohaus.org/flatten-maven-plugin/
I copied the relevant plugin configuration from the website above.
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>flatten-maven-plugin</artifactId>
<!--<version>1.1.0</version>-->
<configuration>
</configuration>
<executions>
<!-- enable flattening -->
<execution>
<id>flatten</id>
<phase>process-resources</phase>
<goals>
<goal>flatten</goal>
</goals>
</execution>
<!-- ensure proper cleanup -->
<execution>
<id>flatten.clean</id>
<phase>clean</phase>
<goals>
<goal>clean</goal>
</goals>
</execution>
</executions>
</plugin>
I strips the POM from all unnecessary information.

Maven execute a goal on build fail / FindBugs

I have integrated FindBugs plugin to fail the build in case of bugs.
Then using that brilliant answer I configured FindBugs to generate html reports (xml version is barely readable).
The problem is that I have failOnError property set to true, which means that the build would fail in case of bug.
.....
<configuration>
.....
<failOnError>true</failOnError>
</configuration>
And then no html report would be generated.
I read about Maven build lifecycle and there is no such thing as "Execute on fail" (like finally block in Java). So, are there any possible workarounds?
And shouldn't it be out-of the box Maven feature?
Special thanks to #SpaceTrucker for workaround suggestion.
Here is the configuration I ended up with:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>findbugs-maven-plugin</artifactId>
<version>3.0.4</version>
<configuration>
<effort>Max</effort>
<threshold>Low</threshold>
<findbugsXmlOutputDirectory>${project.build.directory}/findbugs</findbugsXmlOutputDirectory>
</configuration>
<executions>
<execution>
<id>noFailOnError</id>
<phase>verify</phase>
<goals>
<goal>check</goal>
</goals>
<configuration>
<failOnError>false</failOnError>
</configuration>
</execution>
<execution>
<id>failOnError</id>
<phase>install</phase>
<goals>
<goal>check</goal>
</goals>
<configuration>
<failOnError>true</failOnError>
</configuration>
</execution>
</executions>
</plugin>
The solution is to use different configurations in verify and install phases.
Note, that according to that answer transformation (to html) is executed in verifyphase.
Issue was submitted for html report generation.
Results are also can be seen by simply run mvn findbugs:gui

Maven dependency plugin - How can I ensure that an artifact is present when using dependency-unpack

I'm wondering if there is a way to enforce the existence of a dependency to unpack when using the dependency-unpack goal of the maven dependency plugin. I'm using the configuration below and the problem is that if there is no dependency specified for "${properties.artifactId}" in the dependencies section of the pom the build goes ahead even though nothing has been unpacked. It invariably fails later at the test stage but it would be so much easier if the build could fail when no dependency is present. So does anyone know of a way that this can be enforced?
Thanks
Piers
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-dependency-plugin</artifactId>
<executions>
<execution>
<id>unpack-properties</id>
<phase>generate-resources</phase>
<goals>
<goal>unpack-dependencies</goal>
</goals>
<configuration>
<includeArtifactIds>${properties.artifactId}</includeArtifactIds>
<outputDirectory>${project.build.directory}</outputDirectory>
<includes>${properties.file.name}</includes>
</configuration>
</execution>
</executions>
</plugin>
A couple of executions of the maven-enforcer-plugin should do it. You need one to run before the dependency plugin, to make sure ${properties.artifactId} has a value, then another that runs after the dependency plugin to make sure there are files in the target location. Here's the idea, modify for your requirements.
You may write your own rules too if those available don't quite fit.
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-enforcer-plugin</artifactId>
<version>fillInTheVersion</version>
<executions>
<execution>
<id>enforce-config-properties</id>
<phase>validate</phase>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireProperty>
<property>properties.artifactId</property>
<message><![CDATA[### Missing property 'properties.artifactId': the artifact that ....]]></message>
</requireProperty>
</rules>
</configuration>
</execution>
<execution>
<id>enforce-files-exist</id>
<phase>process-resources</phase>
<goals>
<goal>enforce</goal>
</goals>
<configuration>
<rules>
<requireFilesExist>
<files>
<file>${project.build.directory}/${properties.artifactId}</file>
</files>
<message><![CDATA[### Did not find unpacked artifact ...]]></message>
</requireFilesExist>
</rules>
</configuration>
</execution>
</executions>
</plugin>

maven :: install multiple third-party artifacts to local repository at once from filesystem

We're using non-public artifacts from third-party companies in our project. We don't have maven proxy installed (and there're no plants to do so, because we found it complicates things rather than solves problems. especially if no internet connection or VPN is available).
So I created set of 'maven install file' plugin executions, like this:
<plugin>
<artifactId>maven-install-plugin</artifactId>
<version>2.3.1</version>
<inherited>false</inherited>
<executions>
<execution>
<id>install-artifacts.1</id>
<goals>
<goal>install-file</goal>
</goals>
<phase>initialize</phase>
<configuration>
<pomFile>thirdparty/gwt-0.99.1.pom</pomFile>
<file>thirdparty/gwt-0.99.1.jar</file>
</configuration>
</execution>
<execution>
<id>install-artifacts.2</id>
<goals>
<goal>install-file</goal>
</goals>
<phase>initialize</phase>
<configuration>
<pomFile>thirdparty/morphia-0.99.1.pom</pomFile>
<file>thirdparty/morphia-0.99.1.jar</file>
</configuration>
</execution>
<execution>
<id>install-artifacts.3</id>
<goals>
<goal>install-file</goal>
</goals>
<phase>initialize</phase>
<configuration>
<pomFile>thirdparty/gwt-oauth2-0.2-alpha.pom</pomFile>
<file>thirdparty/gwt-oauth2-0.2-alpha.jar</file>
</configuration>
</execution>
</executions>
</plugin>
it works great and does exactly what we need. However if new artifact is added - new big XML section has to be added.
Is there any way to avoid this, like use 'yet another plugin' which will search for folder and install everything from it?
Best solution for such kind of thing is to install a repository manager.
You've written you won't installing a proxy but that's the wrong way. The only solution to solve such kind of problems is to install a repository manager.

Maven Tycho: How to Exclude eclipsec.exe in a product build?

I switched the build of our Eclipse RCP product from PDE-build to Maven Tycho. In addition to the main (branded) launcher executable, the product now includes the "eclipsec.exe" file. We would like to omit this console-based launcher from our product as it might confuse our customers. Is there a way to do that with Tycho?
I got this answer on the tycho-users list:
In your eclipse-repository project, assuming that you have a .product file, you can place another file in the same directory called .p2.inf
For the contents of your p2.inf file you can put a p2 touchpoint to remove the file:
instructions.configure=org.eclipse.equinox.p2.touchpoint.natives.remove(path:${installFolder}/eclipsec.exe);
I don't know how to solve with tycho directly, but you can achieve this with the maven-antrun-plugin. There's a little trick to get the deletion of the eclipsec.exe on the timely position.
You have to put the delete step between materialize and the archive goal of the p2-director-plugin. I put the delete step on the phase pre-integration-test and moved the archive step to the phase integration-test.
<plugin>
<artifactId>maven-antrun-plugin</artifactId>
<executions>
<execution>
<id>delete-eclipsec.exe</id>
<phase>pre-integration-test</phase>
<configuration>
<target>
<delete file="${project.build.directory}/products/<<your.product.id>>/win32/win32/x86/eclipsec.exe"/>
</target>
</configuration>
<goals>
<goal>run</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.eclipse.tycho</groupId>
<artifactId>tycho-p2-director-plugin</artifactId>
<version>${tycho-version}</version>
<executions>
<execution>
<id>materialize-products</id>
<goals>
<goal>materialize-products</goal>
</goals>
</execution>
<execution>
<id>archive-products</id>
<phase>integration-test</phase>
<goals>
<goal>archive-products</goal>
</goals>
</execution>
</executions>
</plugin>
The result: No eclipsec.exe in the product.zip.
Hope that helps.

Resources