How to use Artifactory Maven Build in Jenkins Pipeline - maven

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'

Related

Artifact upload with NexusArtifactUploader failing with error for Maven project using Jenkins declarative pipeline

I am currently using Jenkins version 2.222.4, Nexus repository 3.X and NexusArtifactUploader jenkins plugin. This all is on organisation's production.
I have a maven project which I am able to build using jenkins pipeline. However, for uploading artifact I am having issue with NexusUploadArtifact plugin.
At the NexusUpload stage the pipeline is failing with below error.
Error: Uploading file filename.jar failed
I do not see any other error message which could have helped me to debug the issue.
I tried with two ways with NexusArtifactUploader plugin but ended with same error.
First way:
stage('Upload Nexus Artifact') {
steps {
script {
def pom = readMavenPom file: 'pom.xml'
nexusArtifactUploader artifacts: [[artifactId: "${pom.artifactId}", classifier: '', file: "target/${pom.artifactId}-${pom.version}.${pom.packaging}", type: "${pom.packaging}"]], credentialsId: 'Here_Is_The_Creds', groupId: "${pom.groupId}", nexusUrl: 'nexus.something.com', nexusVersion: 'nexus3', protocol: 'http', repository: 'maven-snapshots', version: "${pom.version}"
}
}
}
Second way
stage('Upload Nexus Artifact') {
steps {
script {
def pom = readMavenPom file: 'pom.xml'
nexusArtifactUploader(
nexusVersion: 'nexus3',
protocol: 'http',
nexusUrl: 'nexus.something.com',
groupId: "${pom.groupId}",
**version: "${pom.version}",**
repository: 'maven-snapshots',
credentialsId: 'Here_Is_The_Creds',
artifacts: [
[artifactId: "${pom.artifactId}",
file: "target/${pom.artifactId}-${pom.version}.${pom.packaging}",
type: "${pom.packaging}"]
]
)
}
}
When I read documentation of NexusUploadArtifact jenkins plugin, I learned that this plugin is not for artifacts generated by Maven project. Added snap and url for reference.
Many of the blogs outside stackoverflow and answers on stackoverflow suggested to use Sonatype Nexus Platform Plugin for Jenkins but in my case as I am on Jenkins 2.222.4, this plugin is not supported.
I tried to replicate this on my local machine but with latest version of Jenkins along with NexusArtifactUploader plugin and it did worked.
So, I am stuck on how can this be resolved. Can anyone help me on this as Jenkins version upgrade and Sonatype Nexus Platform Plugin are not the correct fit for me at this moment.
Thanks!
Update.
As mentioned and suggested by #khmarbaise, I was able to deploy artifacts to nexus with Maven without any plugin. Also, when I tried with maven, first I got complete error in Jenkins console about authentication then post correcting credentials I was able to upload artifact using Maven and using NexusArtifactUpload jenkins plugin. One issue / bug I found in NexusArtifactUpload jenkins plugin that, it intermittently do not show status of artifact upload on jenkins's console output log and that is the reason I decided to go with Maven.

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

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.

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

Maven + Jenkins + Artifactory

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.

Resources