Maven + Jenkins + Artifactory - maven

This is very similar to Jenkins + Gradle + Artifactory: Couldn't read generated build info but apparently i violate a SO rule if i write this comment there so spawning a new question...
Using v2.8.2 of the artifactory plugin for jenkins, i am getting the following error:
ERROR: Couldn't read generated build info at : /tmp/generated.build.info9054669860133637092.json
[Pipeline] }
[Pipeline] // node
[Pipeline] End of Pipeline
hudson.model.Run$RunnerAbortedException
at org.jfrog.hudson.pipeline.Utils.getGeneratedBuildInfo(Utils.java:188)
at org.jfrog.hudson.pipeline.steps.ArtifactoryMavenBuild$Execution.run(ArtifactoryMavenBuild.java:109)
at org.jfrog.hudson.pipeline.steps.ArtifactoryMavenBuild$Execution.run(ArtifactoryMavenBuild.java:75)
at org.jenkinsci.plugins.workflow.steps.AbstractSynchronousStepExecution.start(AbstractSynchronousStepExecution.java:40)
at org.jenkinsci.plugins.workflow.cps.DSL.invokeStep(DSL.java:184)
My Jenkinsfile looks like this:
def buildNo = "${env.BUILD_NUMBER}"
def jarVersion = "1.0.${buildNo}" //default major version of zip artifact
node {
// checkout from source
stage 'Checkout'
checkout scm
// release using the Jenkins Artifactory plugin. Jenkins buildNo is used as release version
stage 'Create Release & Deploy to Artifactory'
// get artifactory server from global config
def server = Artifactory.server('artifactory')
// maven build - plugin auto deploys the build artifact to the specifid repo
def rtMaven = Artifactory.newMavenBuild()
rtMaven.tool = 'M3'
rtMaven.deployer server: server, releaseRepo: 'libs-release-local', snapshotRepo: 'libs-snapshot-local'
def buildInfo = rtMaven.run pom: 'pom.xml', goals: 'clean install -DreleaseVersion=' + jarVersion
//finally publish build info
server.publishBuildInfo buildInfo
}
The problem seems to happen at the rtMaven.run stage of the pipeline. Has anyone seen this when using the artifactory plugin with maven?
The strange thing is the issue doesn't happen all the time, it's intermittent. I am running Jenkins inside Openshift (Kubernetes) as well so the jenkins slave is running as a docker container and not persisting any build state across build versions.

Related

How to deploy builds to different Artifactory in Jenkinsfile?

I have a Jenkinsfile and I want to be able to deploy maven build to different artifactory based on the build. For instance if the Jenkinsfile is triggered when I push my code to development branch I want to deploy the build from development branch to "maven-dev" artifactory. I have 4 Git branches (dev, preprod, stage, prod) and subsequently 4 different Artifactory locations (maven-dev, maven-preprod, maven-stage, maven-prod).
I have the following script in my Jenkinsfile for build deployment however, I need to know what changes I need to make to the following script in order to be able to deploy each build (mentioned above) to the corresponding Artifactory location?
script {
def server = Artifactory.server('artifacts')
def rtMaven = Artifactory.newMavenBuild()
rtMaven.deployer server: server, releaseRepo: 'maven-prod', snapshotRepo: 'maven-dev'
def buildInfo = rtMaven.run pom: 'pom.xml', goals: 'clean install -DskipTests=true -q -Dartifactory.publish.buildInfo=true'
buildInfo = Artifactory.newBuildInfo()
server.publishBuildInfo buildInfo
}
You should put all of the Artifactory server configurations in a "rtServer" block. This defines a new Artifactoruy server for this build, and you can configure different Artifactory instances in different builds by configuring different names in the "def server = Artifactory.server('NAME')" line, and give it the proper configuration (repository names, paths, etc). You can see this link for more information - https://www.jfrog.com/confluence/display/RTF/Declarative+Pipeline+Syntax#DeclarativePipelineSyntax-CreatinganArtifactoryServerInstance

Integrate Artifactory into Jenkins Pipeline

I am trying to integrate Artifactory into my Jenkins pipeline in order to push Maven artifacts to Artifactory.
My current understanding is, that I should deploy the built Maven artifacts with using the Jenkins pipeline rather than through a Maven plugin during the deploy lifecycle of Maven.
Based on the documentation that I have read so far I think I need code similar to this in my pipeline:
stage('Build') {
steps {
/** Start a docker container with maven and run mvn clean install */
}
}
stage ('Deploy to Artifactory') {
steps {
script {
def server = Artifactory.server 'my-server-id'
def rtMaven = Artifactory.newMavenBuild()
rtMaven.deployer.addProperty("status", "in-qa")
buildInfo = rtMaven.run pom: 'pom.xml', goals: 'clean install'
server.publishBuildInfo buildInfo
}
}
}
However, I fail to completely understand what this is doing and I am unable to find more detailed documentation, execept for this JFrog blog entry and this JFrog Confluence page.
In particular it seems that if I specify goals to the run directive it will run the Maven Pipeline again, which would not make much since the pipeline already ran in the first stage (e.g. 'Build').
In addition I should note, that I am running the maven build inside a docker container, so it seems that using the above setup is not quite enough for me.
Is there a best practice to approach this?
What I am looking for is a way to collect the artifacts that I built with maven in my docker container and upload them to Artifactory without running maven again.

Remove Timestamp from an artifact name while keeping the Build number

I am using Maven artifactory build to store war files on the artifactory.
def server = Artifactory.newServer url: 'ARTIFACTORY_URL', username: 'USERNAME', password: 'PASSWORD'
def rtMaven = Artifactory.newMavenBuild()
rtMaven.deployer server: server, releaseRepo: 'libs-release-local', snapshotRepo: 'libs-snapshot-local'
rtMaven.tool = 'MAVEN_JENKINS_TOOL'
rtMaven.opts = '-Djavax.net.ssl.trustStore=/PATH_OF_TRUSTSTORE'
def buildInfo = rtMaven.run pom: 'pom.xml', goals: 'clean install -DskipTests -Dv=${BUILD_NUMBER} '
server.publishBuildInfo buildInfo
The artifactory is storing the war files with a timestamp and build number appended to the file name.
I am using unique version in Maven Snapshot Version Behavior under ARTIFACTORY_URL/admin/repository/local/libs-snapshot-local. I tried non-unique version but that removes timestamp as well as build number from the artifact name.
I want the artifact to have build number, which should be in sync with Jenkins build number, and no timestamp to be included in the artifact name.
I also tried by changing version to 1.0-SNAPSHOT-$(v) and using command -Dv={BUILD_NUMBER} in the script while having Maven Snapshot Version Behavior as Deployer.

How to use Artifactory Maven Build in Jenkins Pipeline

i am trying to publish my build artifacts via artifactory maven to my artifactory server.
stage("${buildType} publish to Artifactory") {
def server = Artifactory.server 'artifactory'
def rtMaven = Artifactory.newMavenBuild()
rtMaven.resolver server: server, releaseRepo: 'libs-release', snapshotRepo: 'libs-snapshot'
rtMaven.deployer server: server, releaseRepo: 'libs-release-local', snapshotRepo: 'libs-release-local-SNAPSHOT'
rtMaven.tool = 'maven tool name'
def buildInfo = rtMaven.run pom: 'pom.xml', goals: 'clean package -Dskip.unit.tests=true -Dskip.integration.tests=true'
server.publishBuildInfo buildInfo
}
But the Job fails with
ERROR: Couldn't find Maven executable.
i tried to match the "maven tool name" with the name of maven in my jenkins tools, but it still doesn't work
Any help appriciated
It seems that you "copy paste" the example without changing the variables.
In order for it to work you will need to verify the following:
You will need to check what is the name of the Artifactory instance in the Jenkins system configuration page. The name is something that you gave it once configured Artifactory in Jenkins.
This will be the value under 'Server ID'. This value should be placed instead the 'Artifactory' in:
def server = Artifactory.server 'artifactory'
The rtMaven.tool = 'maven tool name' should also be replaced with the name you entered on the "Global Tool Configuration" for the Maven version you installed.
Once doing the above this should work.
It seems that you are using the correct maven tool name but not the correct Server ID of your artifactory.
If you are not sure about the artifactory serverID, you may alternatively specify the artifactory using artifactory server address.
def server = Artifactory.newServer url: 'YOUR_ARTIFACTORY_URL', username: 'ARTIFACTORY_USERNAME', password: 'ARTIFACTORY_PASSWORD'

Jenkins Pipeline Maven Artifactory Plugin Cannot Resolve Artifact From Central Maven Repository

When using a Jenkins Freestyle Project I am able to successfully run a build with Maven using the "Maven3-Artifactory Integration."
When trying to use this feature in pipeline I run into issues with resolving artifacts from the central maven repository. I am under the impression that when Jenkins cannot find an artifact in artifactory it should fall back to the central maven repository,https://repo.maven.apache.org/maven2, to look for the artifact. Is this not the case?
def server = Artifactory.server SERVER_ID
def rtMaven = Artifactory.newMavenBuild()
rtMaven.resolver server: server, releaseRepo: 'my-release-local', snapshotRepo: 'my-snapshot-local'
rtMaven.deployer server: server, releaseRepo: 'my-release-local', snapshotRepo: 'my-snapshot-local'
rtMaven.deployer.artifactDeploymentPatterns.addInclude("").addExclude("")
rtMaven.deployer.deployArtifacts = false
rtMaven.tool = MAVEN_TOOL
def buildInfo = rtMaven.run pom: POM_FILE, goals: GOALS
server.publishBuildInfo buildInfo
From the console output it seems like Jenkins is forcing the build to only resolve artifacts from Artifactory and nowhere else, even though it sees the central repo.
[main] DEBUG org.jfrog.build.extractor.maven.resolver.ArtifactoryEclipseRepositoryListener - [buildinfo] Resolved artifact: org.apache.maven.plugins:maven-clean-plugin:pom:2.5:build from: central (https://repo.maven.apache.org/maven2, releases) Context is: plugin
[main] DEBUG org.jfrog.build.extractor.maven.resolver.ResolutionHelper - [buildinfo] Properties file '/tmp/buildInfo6034012728922541318.properties' retrieved from 'System.getProperty(buildInfoConfig.propertiesFile)'
[main] DEBUG org.jfrog.build.extractor.maven.resolver.ArtifactoryEclipseResolversHelper - [buildinfo] Enforcing snapshot repository for resolution: mysnapshotartifactoryURL
[main] DEBUG org.jfrog.build.extractor.maven.resolver.ArtifactoryEclipseResolversHelper - [buildinfo] Enforcing repository authentication: username=myusername, password=*** for snapshot resolution repository
[main] DEBUG org.jfrog.build.extractor.maven.resolver.ArtifactoryEclipseResolversHelper - [buildinfo] Enforcing release repository for resolution: myreleaseartifactoryURL
[main] DEBUG org.jfrog.build.extractor.maven.resolver.ArtifactoryEclipseResolversHelper - [buildinfo] Enforcing repository authentication: username=myusername, password=*** for release resolution repository
[main] DEBUG org.jfrog.build.extractor.maven.resolver.ArtifactoryEclipseArtifactResolver - Verifying availability of /home/myusername/.m2/repository/org/apache/maven/plugins/maven-plugins/22/maven-plugins-22.pom from [artifactory-release (myreleaseartifactoryURL, releases), artifactory-snapshot (mysnapshotartifactoryURL, snapshots)]
[main] DEBUG org.jfrog.build.extractor.maven.resolver.ArtifactoryEclipseRepositoryListener - [buildinfo] Could not resolve artifact: org.apache.maven.plugins:maven-plugins:pom:22:build
[main] ERROR org.apache.maven.cli.MavenCli - Plugin org.apache.maven.plugins:maven-clean-plugin:2.5 or one of its dependencies could not be resolved: Failed to read artifact descriptor for org.apache.maven.plugins:maven-clean-plugin:jar:2.5: Could not find artifact org.apache.maven.plugins:maven-plugins:pom:22 in artifactory-release (myreleaseartifactoryURL)-> [Help 1]
org.apache.maven.plugin.PluginResolutionException: Plugin org.apache.maven.plugins:maven-clean-plugin:2.5 or one of its dependencies could not be resolved: Failed to read artifact descriptor for org.apache.maven.plugins:maven-clean-plugin:jar:2.5
I had the same problem some time ago. I don't know if it applies for you. The flow is what I remember from artifactory:
check on libs-release-local, which we were using for local builds. this has Virtual Repository Associations with libs-release
libs-release is a virtual repo. And Included Repositories under libs-release are libs-release-local AND maven-central-custom
Resolution and upload of artifacts is done to/from libs-release-local. Incase the requred artifact is not available, maven is following libs-release-local --> libs-release --> maven-central-custom
And the following is how we use it inside our jenkinsfile:
// Obtain an Artifactory server instance, defined in Jenkins --> Manage:
def server = Artifactory.server 'localArtifactory'
def rtMaven
def buildInfo
// Artifactory Maven Build instance
rtMaven = Artifactory.newMavenBuild()
rtMaven.tool = 'localMaven'
//where the Maven build should download its dependencies from
rtMaven.resolver server: server, releaseRepo: 'libs-release' , snapshotRepo: 'libs-snapshot'
//define where our build artifacts should be deployed to. we define the Artifactory server and repositories on the 'rtMaven' instance
rtMaven.deployer server: server, releaseRepo: 'libs-release-local', snapshotRepo: 'libs-snapshot-local'
//disable pushing to artifactory, true if requered
rtMaven.deployer.deployArtifacts = false
//By default, all the build artifacts are deployed to Artifactory. So, let's make filter and deployArtifacts=true
rtMaven.deployer.artifactDeploymentPatterns.addInclude("*-common-*")
rtMaven.run pom: 'pom.xml', goals: 'clean package'
rtMaven.deployer.deployArtifacts buildInfo

Resources