How to deploy builds to different Artifactory in Jenkinsfile? - jenkins-pipeline

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

Related

How to setup a CICD build with 2 Artifactory instances

I have 2 Artifactory URLs, one for production and another for non-production. I want to configure CICD pipeline that publishes non-production artifacts to 1 Artifactory server and final prod artifacts to the other Artifactory URL.
Can we have 2 Artifactory repo entries in the same pom.xml file? How can the above scenario be achieved in a single CI job?

Artifactory Maven layout version

I would like to know what dictates when an artifact is deployed to snapshot vs release repo.
Artifactory has two repos:
libs-snapshot
libs-release
Layout for both:
[orgPath]/[module]/[baseRev](-[folderItegRev])/[module]-[baseRev](-[fileItegRev])(-[classifier]).[ext]
When I run the Jenkins Pipeline the artifacts are always uploaded to libs-release. Note that I do not explicitly put a SNAPSHOT modifier in my pom files. Snapshots have version with build number (e.g. 1.0.0-010) while release only has version (e.g. 1.0.0)
rtMaven.deployer releaseRepo: 'libs-release', snapshotRepo: 'libs-snapshot', server: rtServer
How does the Artifactory plugin decide if it should go to release vs snapshot repo here? Is it the fileItegRev? or folderItegRev?
A snapshot is a version that ends with -SNAPSHOT. It has to be in the path of the artifact to deploy, as gathered by build info extractor.
Relevant code is:
public String getTargetRepository(String deployPath) {
return StringUtils.isNotBlank(snapshotRepo) && deployPath.contains("-SNAPSHOT") ? snapshotRepo : releaseRepo;
}

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.

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'

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