Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Artifactory + Jenkins: Publishing to a maven repository from a freestyle build

I have a Jenkins freestyle build, based on a Scala project using SBT. I'm trying to use the Jenkins Artifactory plugin to publish the resulting artifacts to an Artifactory repository, specifically one hosted at artifactoryonline.com. However, I'm struggling to find a sane configuration. I'm inclined to suspect that there's something that I'm missing, but I'm at my wit's end, none of the documentation I've found seems to cover this use case in any detail, and I'm tired of going through the Artifactory plugin source code. Any help at all is appreciated.

The scenario is the following. I would like to:

  1. build a free-style Jenkins project using SBT, independent of version number such that the current project version (as encoded in the pom/ivy artifacts) is implicit and automatic.
  2. publish the artifacts and build info to an artifactory repository configured in Jenkins (not configured in the build.sbt in my SCM)

Below are the approaches that I've tried.

Approach 1: Free-style + Generic Artifactory Integration

First approach was to use a freestyle build, then use the Generic-Artifactory integration. For "Published Artifacts", I've set it to

target/scala-2.11/*=>com.mycompany/my-module_2.11

The build succeeds, the jar and sources-jar and javadoc-jar and ivy file and POM file are all generated in that directory. However, the publish fails, 209 Conflict. Artifactory log doesn't like the target path:

Sending HTTP error code 409: The target deployment path 'com/mycompany/my-module_2.11/my-module_2.11-1.0.6.pom' does not match the POM's expected path prefix 'com/mycompany/my-module_2.11/1.0.6'. Please verify your POM content for correctness and make sure the source path is a valid Maven repository root path.

I can make the 209 error go away, by not using the standard maven-2 pathing (which, among other things, requires disabling POM consistency checks for this repo), which suggests I'll have to update all downstream configuration to be able to work with this repo.

I can update the target path setting for the plugin to include the version number:

target/scala-2.11/*=>com.mycompany/my-module_2.11/1.0.6

but that means I have modify my Jenkins build for every release, which seems to defeat the purpose. I can't imagine that's the proper way to use these tools.

Approach 2: Free-style + Artifactory Maven

In this case, I stuck with the free-style SBT build. Under "Build Environment", I selected "Maven3-Artifactory Integration". I configured the plugin against my global artifactory repository, check "Deploy artifacts to Artifactory", and set the "Include Patterns" to

target/scala-2.11/*

I ran a build, which generated the artifacts (including POM and ivy.xml files in the target/scala-2.11 directory), but nothing seemed to happen with respect to the deployment of artifacts. There was nothing in the Artifactory log, no new builds, and nothing in the console output or Jenkins logs to indicate that it ever attempted to deploy any artifacts to my repository.

Approach 3: Free-style + Artifactory Ivy

In this case, I stuck with the free-style build, but under "Build Environment", I selection the "Ant/Ivy-Artifactory Integration." I selected my globally configured Artifactory repository, check "Publish artifacts to Artifactory" and "Use Maven Compatible Patterns". I configured my SBT project to "publishLocal" (per the plugin instructions), and I set the following paths screenshot of ivy configuration. The project built and the artifacts were deployed to ~/.ivy2/local, but apparently there was no interception by the plugin and nothing was pushed to my configured Artifactory repo (maybe this plugin isn't compatible with free-style?)

I modified the SBT build to do "publish" instead of "publishLocal", hoping that the plugin would kick in and intercept the Ivy publish, but because my built.sbt isn't configured with a publishTo repository target, I naturally got an error that "Repository for publishing is not specified".

Approach 4: Dummy Maven build

Next approach: skip generic, go full maven. I setup a new build in Jenkins, a Maven project. It has a Pre-build step which runs my SBT build, generating the pom artifact along with the binary and source jars. I then configure the Build step to use the POM generated by my SBT build. Unfortunately, the "Root POM" parameter of the jenkins/maven plugin doesn't accept a wildcard, so the only way I could get this to process was to specify the full (versioned) path:

target/scala-2.11/my-resource_2.11-1.0.6.pom

So, that's unfortunate and untenable, as far as I'm unwilling to update my Jenkins build everytime I increment version number. Still, I wanted to see if this approach would work, so I pushed on. I added a post-build step of "Deploy Artifacts to Artifactory", against my globally configured Artifactory. With the maven goals "help:help", nothing was pushed, therefore there was nothing for the maven interceptor to intercept and push to my artifactory (that's my understanding as to how it works, anyway). So I tried again, replacing the maven goals in the Build step with "deploy". This time, the interceptor pushed up most (all?) of my dependencies to my Artifactory server. However, after pushing all of the dependencies, it apparently failed trying to compile my "maven" project. I didn't look to much further into this, but I assume it is because the generated POM file doesn't specify any build instructions.

Conclusion

Once again, any help is appreciated. It seems that this should be a fairly mainstream use case, and the documentation for the Artifactory plugin explicitly states that free-style build + Maven deploy is supported, but I'm obviously missing something. Any help is greatly appreciated! Thank you.

like image 367
Chris Baker Avatar asked Oct 08 '15 02:10

Chris Baker


1 Answers

That's a great question!

Going with "Approach 1" is the way to go. If you don't want to include the version in the path, it makes the path non-maven compatible, which might be fine, but you need to configure the repo (as you know and did). And yes, the solution in the comment is a valid trick as well.

like image 166
JBaruch Avatar answered Nov 14 '22 17:11

JBaruch