Remove Timestamp from an artifact name while keeping the Build number - maven

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.

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

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;
}

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

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