Configure settings.xml in jenkins slave created on the fly in AWS - maven

I am creating Jenkins Slave on the fly configuring it on AWS with Spot Instances.
In the global tool configuration, I have set to use my own "settings.xml" for the master is working perfectly.
But when the server start slaves (without maven installed) it auto install maven (set in the Jenkins file to install this tool) but without putting any settings.xml
*I know I can copy the setting.xml directly from the server but for me looks like it is not the appropriate way to do it.
* I already did mvn -X in order to see find the folder for the settings but this is not used.
Added one small slice of the jenkinsfile
pipeline {
tools{
maven 'maven default'
}
agent any
stages {
stage('Maven build') {
steps {
sh 'mvn clean install'
}
}
}
}

You have to use withMaven() in the Pipeline code..which has to look like this:
withMaven(jdk: jdkName, maven: MavenInGlobalToolsName, mavenSettingsConfig: 'IdInConfigFileProvided', mavenLocalRepo:".repository") {
sh "mvn clean verify"
}
The IdInConfigFileProvided is the important part which makes the reference to the config file provider plugin...
The other solution could be to use the config file provider directly in Jenkins file:
configFileProvider(
[configFile(fileId: 'maven-settings', variable: 'MAVEN_SETTINGS')]) {
sh 'mvn -s $MAVEN_SETTINGS clean package'
}
But this solution will not handle the support global tools support for Maven itself. So I would suggest to prefer the withMaven() solution.

Related

How to use specific maven and jdk on Jenkins

I have corporate Jenkins where I don't have access to Manage Jenkins option. I want to make a build of my java app using maven.
When I try to run mvn clean install:
dir("test/test2/project") {
sh "mvn clean install -Dmaven.test.skip=true"
}
I get the following error:
[ERROR] The goal you specified requires a project to execute but there is no POM in this directory (/var/jenkins/workspace/test/test2/project). Please verify you invoked Maven from the correct directory.
I was trying to add mvn -f /var/jenkins/workspace/test/test2/project/pom.xml (I have pom file in the folder) but it did not work.
I also tried
withEnv(["PATH+MAVEN=${tool 'maven-3.5.0'}/bin:${env.JAVA_HOME}/bin"]) {
sh "mvn --batch-mode -V -U -e clean install -Dmaven.test.skip=true"
which also did not work.
I would like to point to maven and java which are installed on the agent but can't seem to sucseed.
Any idea?
Can you try something like below?
dir("test/test2/project") {
sh "mvn clean install"
}

Is there a way to programmatically specify pom.xml path in jenkinsfile

In a declarative pipeline, I manually specify pom.xml path in Jenkinsfile and Jenkins is able to locate it as expected at build time.
pipeline {
agent any
options {
timestamps()
}
stages {
stage('Compile') {
steps {
withMaven(maven: 'MAVEN_HOME') {
sh 'mvn -f /Users/jo/.jenkins/workspace/DeclarativePipelineDemo/Demo/pom.xml clean install' //filepath
}
}
}
}
Now, is there a more elegant way to tell Jenkins to dynamically capture the workspace/pom.xml classpath directly from my project so I don't need to manually specify it?
If your Jenkinsfile in same repo of pom.xml, you can use relative path.
When Jenkins run you pipeline, it will automatically clone the repo that holds the Jenkinsfile to Jenkins slave.
If pom.xml in base dir of project, you can try
sh mvn -f pom.xml ...

Jenkins use docker to build maven image cannot access to nexus

I am using a Jenkins pipeline to download my code and building it inside the official maven container
pipeline {
agent none
stages {
stage('Back-end build') {
agent {
docker {
image 'maven'
label 'master'
}
}
steps {
sh 'mvn -f de.vitasystems.qrcode.generator/pom.xml -s /usr/share/maven/ref/settings.xml clean package'
stash includes: 'target/*.war', name: 'app'
}
}
}
}
After doing that I realized that I need the settings.xml for the nexus repository configuration and the settings-security.xml in order to allow to download it.
Then I did this:
I had created another Dockerfile that use the maven one (FROM maven)
and it copy the necessary files setting.xml and for been used in the
previous pipeline.
It is referring to the correct repository but it is not authorized to download files
Add the security-settings.xml is needed in order to be able to download the data from my nexus (maven nexus password) but I can not reference it or use it.
How can I use the security-settings.xml in this container?? Maven documentation says that I put the file in the $HOME/.m2 folder but it is not working.
Regards.
try to use the config file provider plugin , he will copy the settings.xml from the master into your workspace
stage('Build')
{
steps {
configFileProvider(
[configFile(fileId: 'your-id-xxx', variable: 'MAVEN_SETTINGS')]) {
sh 'mvn -s $MAVEN_SETTINGS clean install -P integration-tests'
}
I have already found the solution, the setting-security are not used until you are with the root user.
I make a Dockerfile to create a new docker images that wrap-up:
FROM maven
COPY settings.xml /root/.m2/settings.xml
COPY settings-security.xml root/.m2/settings-security.xml
ENTRYPOINT ["/usr/local/bin/mvn-entrypoint.sh"]
CMD ["mvn"]
This image will wrap-up the security configuration but for be able to be use in the jenkinsfile you need to run the container using root user.
Example
agent {
docker {
image 'maven'
label 'master'
args '-u root'
}

Deploying maven artifacts without rebuilding

We are using declarative pipeline, latest Jenkins. Builds are executed in a docker slave container, which has maven and other tools. Our current Jenkinsfile resembles this:
stage('build') { steps { sh 'mvn clean install'} }
stage('test') { /* functional tests using a different tool */ }
stage('publish') {
steps {
// mvn clean deploy -DskipTests -DaltDeploymentRepository... (rebuilds, which we want to avoid, as its a multimodule project)
// withMaven(options:[artifactsPublisher()] { } ... (from maven-pipeline-plugin)
}
}
Jenkins classic mode has a Maven Integration plugin which provides a section "Deploy artifacts to Maven repository" which uses Maven RedeployPublisher to only publish artifacts. I am looking for a pipeline equivalent of this, I thought the maven-pipeline-plugin does this, but cant find an example. Any pointers appreciated!
I stumbled upon your question looking for the same thing, and what worked for me was this:
stage('Deploy') {
sh "'${mvnHome}/bin/mvn' war:war deploy:deploy"
}
Of course, you need to change war:war to the type of the artifact that you want to deploy (so jar:jar or ear:ear). I found this basing on this answer, but it seems to be relevant to maven-war-plugin, as well as to maven-jar-plugin, although there is no forceCreation option in the war goal.

How do you provide a managed file to a Jenkins build using docker.image?

I am trying to use Jenkins Pipelines to build a Maven Java project and deploy its artifacts into Nexus. The Nexus credentials are managed by Jenkins, so I need Jenkins to provide the Maven settings.xml file. My pipeline uses docker to run the build. My Jenkinsfile looks like:
node('docker') {
git 'git#bitbucket.org:myorg/myproject.git'
stage 'Build and Test'
// This throws: java.lang.UnsupportedOperationException: Refusing to marshal org.codehaus.groovy.runtime.InvokerInvocationException for security reasons
//configFileProvider([configFile(fileId: '7d6efcd2-ff3d-43dc-be40-898dab2bff64', variable: 'MYSETTINGS')]) {
// sh 'cp ${MYSETTINGS} mysettings.xml'
// }
docker.image('maven:3.3.9').inside {
// sh 'mvn -s mysettings.xml -U -e clean deploy'
// This fails trying to access AWS ECR (???)
withMaven(mavenSettingsConfig: '7d6efcd2-ff3d-43dc-be40-898dab2bff64') {
sh 'mvn -U -e clean deploy'
}
}
So far I am unable to provide the correct maven settings. There are some 'Knows limitation' on the withMaven (Maven Pipeline Plugin, https://wiki.jenkins-ci.org/display/JENKINS/Pipeline+Maven+Plugin)
Is there a workaround ? I tried to use the configFileProvider, but it throws UnsupportedOperationException because of security reasons.

Resources