Questions about pom.xml in Jenkins to run sonarQube through maven project - maven

I'm trying to run sonarQube through Jenkins but I have some difficulties right now. When I build a new job, I use Maven Project and inside the configuration I have to give à pom.xml path but what does it correspond to ?
Thank you in advance

You should find in any jenkins job a post action for sonarqube analyse.
The pom.xml you mention is the pom.xml for your maven project, because sometimes you can put your parent pom.xml in a subdirectory and this is the way for helping jenkins to find it.

Instead of adding Sonar Task to each project why not just configure Sonar at Global Level configuring the settings.xml for your maven configuration, just go to $HOME/someUser/.m2/settings.xml (if you don't have it created yet) with this content:
<settings>
<pluginGroups>
<pluginGroup>org.sonarsource.scanner.maven</pluginGroup>
</pluginGroups>
<profiles>
<profile>
<id>sonar</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<!-- Optional URL to server. Default value is http://localhost:9000 -->
<sonar.host.url>
http://myserver:9000
</sonar.host.url>
</properties>
</profile>
</profiles>
</settings>
After you you have done that you will be able to run sonar in all the projects this way:
mvn clean verify sonar:sonar
 
# In some situation you may want to run sonar:sonar goal as a dedicated step. Be sure to use install as first step for multi-module projects
mvn clean install
mvn sonar:sonar
 
# Specify the version of sonar-maven-plugin instead of using the latest. See also 'How to Fix Version of Maven Plugin' below.
mvn org.sonarsource.scanner.maven:sonar-maven-plugin:3.2:sonar
You may find more information in sonar official documentation:
https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner+for+Maven

Related

Upload artifacts to multiple nexus instances without running build twice using maven

We have some legacy reasons to upload our software artifacts to two instances of nexus (one internal and the other with the cloud solution we are hosted with)
Currently, we accomplish the same running the build twice with different settings files
mvn clean deploy -s=internal_nexus_settings.xml
mvn clean deploy -DskipTests=true -s=external_nexus_settings.xml
Is there a possibility of uploading artifacts to both without running the build twice
Currently, settings file contain
external_nexus_settings.xml
<id>external_cloudprovider</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<nexus.release.url>https://cloudvendor/nexus/content/repositories/releases/</nexus.release.url>
<nexus.snapshot.url>https://cloudvendor/nexus/content/repositories/snapshots/</nexus.snapshot.url>
<nexus.site.url>dav:https://cloudvendor/nexus/content/repositories/sites/${project.groupId}/${project.artifactId}/${project.version}/</nexus.site.url>
<nexus.username>admin</nexus.username>
<nexus.password>mycreds</nexus.password>
</properties>
internal_nexus_settings.xml
<profile>
<id>internal_nexus</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<nexus.release.url>https://internal/nexus/content/repositories/releases/</nexus.release.url>
<nexus.snapshot.url>https://internal/nexus/content/repositories/snapshots/</nexus.snapshot.url>
<nexus.site.url>dav:https://internal/nexus/content/repositories/sites/${project.groupId}/${project.artifactId}/${project.version}/</nexus.site.url>
<nexus.username>admin</nexus.username>
<nexus.password>mycreds</nexus.password>
</properties>
Tried adding multiple profiles (activating the profile via default and command line params) but maven picks the settings of the latest profile only
mvn clean deploy -DskipTests=true -s=external_nexus_settings.xml -P internal,external

How to activate a profile in a maven submodule using a property?

I am using Maven 3.6.0 and OpenJDK8 on Ubuntu 18.04 (also tested with Alpine Linux).
I have a pom.xml in the root of my project that includes my submodules :
...
<modules>
<module>mysubmodule</module>
</modules>
...
In the mysubmodule folder, the pom.xml has a profile that I want to activate based on a property passed to the mvn executable:
...
<profile>
<id>my-profile</id>
<activation>
<property>
<name>activateMyProfile</name>
</property>
</activation>
...
</profile>
...
I then execute mvn to start the build, but the profile is never activated:
If I run mvn -DactivateMyProfile release:prepare from the root of my project, the profile is never activated and never runs
If I run mvn release:prepare from the root of my project, the profile is never run.
I also tried the inverse:
...
<profile>
<id>my-profile</id>
<activation>
<property>
<name>!doNotActivateMyProfile</name>
</property>
</activation>
...
</profile>
...
If I run mvn -DdoNotActivateMyProfile release:prepare from the root of my project, the profile is still executed
If I run mvn release:prepare from the root of my project, the profile is also executed
It looks like mvn is not able to see the properties being passed through the command line. What is the correct way to activate a profile in a submodule using a property?
As I am using the maven release plugin, parameters must be passed using the -Darguments argument.
For example, instead of using mvn -DactivateMyProfile release:prepare, the correct invocation is: mvn -Darguments=-DactivateMyProfile release:prepare
If there are multiple arguments, use mvn -Darguments="-DactivateMyProfile -DsomeOtherArg -DanotherArg=something" release:prepare

Override URL to nexus repository specified in pom.xml

I have web project which I am going to deploy to nexus repository after successful build on jenkins. Currently in project in pom.xml I have following configuration as below where host and port to nexus repository is hardcoded:
<profiles>
<profile>
<id>deploy-snapshot</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<distributionManagement>
<snapshotRepository>
<id>snapshots</id>
<name>Repository for snapshots</name>
<url>http://ip1:port1/nexus/content/repositories/snapshots</url>
</snapshotRepository>
</distributionManagement>
</profile>
</profiles>
My goal is override nexus url from jenkins without any changes in pom.xml, because currently that configuration in pom.xml is used on another environment which cannot be reconfigured.
It would be good to know in which way it can be done on jenkins taking into account that in future I am going to make similar for other job which will be in charge of deploying npm packages.
I've looked into following jenkins plugin https://wiki.jenkins.io/display/JENKINS/Nexus+Artifact+Uploader, but not sure that this one is actual one, also not sure that plugin will be good for zip archives for npm build.
That was requested in 2008(!) with Make the issue 295: "distributionManagement.site.url configurable from the command line"
In your case, check if passing the property altDeploymentRepository would help:
-DaltDeploymentRepository=...
More precisely, as in "Maven deploy:deploy using -DaltDeploymentRepository"
-DaltDeploymentRepository=releaseRepository::default::http://your.repo.url
"defaut" is the maven2 layout ("legacy" is for maven 1)
In order to overwrite it, you can set it in settings.xml file
In the version of Jenkins I'm using, which is ver. 1.602, if you configure your project as a Maven project, you can specify a "Deploy artifacts to Maven repostitory" post build action for which you can indicate the destination repository.

Maven deploy snapshot or release based off of profile

Is there a way to append the -SNAPSHOT suffix to the version of a project based on profile? I'd like the prod profile to be the only one able to deploy RELEASES to nexus.
We can use user-defined properties to accomplish this:
<profile>
<id>local</id>
<properties>
<env>local</env>
<snapshot>-SNAPSHOT</snapshot>
</properties>
<profile>
<id>prod</id>
<properties>
<env>prod</env>
<snapshot></snapshot>
</properties>
</profile>
Then update the version to refer to our new property:
<version>0.1.0${snapshot}</version>
by configuring different profile do SNAPSHOT build or a RELEASE build is not a good idea, here you are going to make both of them to have same source, (i.e. the source in development would be in release and vice versa)
you should keep only one version at a time, RELEASE it once and increment to the next SNAPSHOT by using mvn release plugin
They better way to acomplish this is using the maven-release-plugin this will versioning your project and modules and prepare it to the release version saving you from the tedious work.

How to tell Maven to ignore a dependency if failed to resolve it?

I have a dependency which I have installed in Maven local repository and is being used locally but is not available on deployment server. I use that dependency using Class.forName(...) so there will be no problem if it's missed from classpath on deployment server.
Is there any way to tell Maven to ignore a dependency if it failed to resolve it?
I doesn't seem that <scope> or <optional> can solve this problem, but it may be possible to do it with <profiles> if there is any way to activate/deactivate a profile based on dependencies availability.
Short answer: no.
Long answer: Once dependency is declared - either in common part or in an active profile - it must be resolvable when Maven attempts it; otherwise the build fails.
If maven allowed the requested behavior, the reproducibility of build would suffer a lot.
If obscurity and irreproducibility is not an issue for you, here is a hint how to do it:
call external ant from your pom.xml, using either exec-maven-plugin or maven-antrun-plugin
in the ant code, use artifact:dependencies from Maven Ant Tasks
wrap it in ant-contrib's trycatch block
In any case, I strongly discourage including such things into maven build. Having it as separate functionality, invoked via ant from commandline, might often be enough.
assuming the missing dependency is only important in the local environment you can use a combination of profile and activation via your .m2/settings.xml
You remove the dependency from your general dependencies and move it as a referenced dependency into a profile of your pom.xml (Project level profile) and activate the profile through your m2/settings.xml.
You may also remove the dependency completly from your pom.xml and move the dependency into a profile which resides in your .m2/settings.xml (User level profile)
see the introduction to profiles section
another way which fits your needs maybe better
The activation of the above mentioned profile based on the presence of the file in .m2/repository/local/dependency/1.0.0-Snapshot/local.jar
<profiles>
<profile>
<activation>
<file>
<exists>/home/user/.m2/repository/local/dependency/1.0.0-Snapshot/local.jar</exists>
</file>
</activation>
...
</profile>
</profiles>
Bizarrely, I had a problem with maven where it would say "cannot resolve dependency" (of some weird transitive dependency that didn't exist anymore), but it only failed with that error message if my ~/.m2/settings.xml had a
got my jars from a local repository
<profiles>
<profile>
<id>nexus</id>
<repositories>
<repository>
<id>a name</id>
<url>http://somewhere/local/a</url>
</repository>
If I changed it to mirror, it would not fail.
<mirrors>
<mirror>
<id>a name</id>
<name>an awesome description</name>
<url>http://some/where/local</url>
<mirrorOf>external:*</mirrorOf>
(same repo). Go figure.
Please try to exclude the dependencies from the POM
<executions>
<execution>
<id>***failed dependency Id***</id>
</execution>
</executions>

Resources