Jenkins build parameterized with a choice of versions of a Nexus artifact (all GAVs)

7.1k views Asked by At

Is there a Jenkins plugin that can do a group-artifact-version (GAV) search of my Nexus repo and list the results? I would like the results to be available on a parameterized build as a choice (a dropdown).

3

There are 3 answers

0
bmcdonald On

I added a groovy script to a Dynamic Choice Parameter (See Jenkins Plugins)

Some hurdles were:

  1. Our Nexus server issues a basic authentication challenge so I couldn't simply use a groovy "http://blah".toURL().text
  2. I didn't want to load in missing groovy jars like httpbuilder so I simply used the Java URLConnection class and the encoded user:pass as a header.
  3. Used REST api to Nexus to get versions, but had to distinguish between release and snapshots. I added group based authentication so that only developers had access to the snapshots.
  4. GAV sort is not a straight forward. There is a better way to GAV sort (using org.apache.maven.artifact.versioning.ComparableVersion) but I have not implemented it yet so for now, I'm simply sorting so the smaller strings line up first.
import hudson.model.*
import jenkins.model.*

def versions=[ ]
def snapshots=[ ]

// The artifactName could be passed in from another parameter (eg. Extended Choice Parameter) linked to this 'dynamic choice' parameter.
def address = "https://xyzcompany.com/nexus/service/local/lucene/search?r=releases&g=com.xyzcompany&a=artifactName&c=features&p=xml"
def urlInfo = address.toURL()

// Consider using tokenstring technique instead of basic auth if pro version of Nexus.
def authString = "user:pass"; // replace 'user' with username, 'pass' with password.  
def authStr="Basic " + authString.bytes.encodeBase64().toString()

// Using URLConnection instead of HTTPBuilder et al.
def connection = urlInfo.openConnection()
connection.setRequestProperty( "Authorization" , authStr)

def xml="${connection.content.text}"
def root = new XmlParser().parseText( xml )
root.data.artifact.each {
 if (it.artifactHits.artifactHit.repositoryId.text() == "releases")
      versions.add("${it.version.text()}");
 else
    snapshots.add("${it.version.text()}");
}

// There is a better way to GAV sort (using org.apache.maven.artifact.versioning.ComparableVersion) but I have not implemented it yet so for now, I'm simply sorting so the smaller strings line up first.
versions.sort { -it.size() }
Collections.reverse(versions)

// Only certain users should be able to see the SNAPSHOT versions
def userid = User.current().id
def auths = Jenkins.instance.securityRealm.loadUserByUsername(userid).authorities.collect{a -> a.authority}
if (["OffShoreDevGroup", "DevGroup"].intersect(auths))
{
  snapshots.sort { -it.size() }
  Collections.reverse(snapshots)
  versions+=snapshots
}

versions.add(" "); // My build uses a blank version string to simply report what is already deployed to the container.
return versions;
0
Haber On

chose "Dynamic Choice Parameter" Plugin, and put the below code with your own host, groupId, artifactId.

we can use metadata API, you can use snapshots repo or release repo or public for both, just limit the last 5 versions.

def host="https://msnexus.xxx.com"
def groupId="com.xxx.cd".replaceAll("\\.", "/")
def artifactId="common-log"
def nexus_url="${host}/repository/public/${groupId}/${artifactId}/maven-metadata.xml"
def response=nexus_url.toURL().text
def metadata = new XmlParser().parseText(response)

metadata.versioning.versions.version.takeRight(5).collect({it.text()}).reverse()

same answer with a snapshot in https://stackoverflow.com/a/64831485/11411638

0
kubanczyk On

No need for custom Ruby scripts. There is now a dedicated plugin which does what you require: Maven Metadata Plugin for Jenkins CI server

Just mark "Parameterized Build" and "Add Parameter" of type "List Maven artifact versions":

  • Name MY_SNAPSHOT_JAR
  • Repository Base URL (this one is tricky) http://localhost/nexus/service/local/repositories/snapshots/content

Then add a shell command to wget/scp/etc, you can use the following variables resolved by plugin:

wget "$MY_SNAPSHOT_JAR_ARTIFACT_URL"
echo    "$MY_SNAPSHOT_JAR_VERSION" - the version you selected in the dropdown or that was selected as part of an automated build
echo    "$MY_SNAPSHOT_JAR_ARTIFACT_URL" - the full URL to the actual artifact selected. You can use something like "wget" to download that artifact and do something with it.
echo    "$MY_SNAPSHOT_JAR_GROUP_ID" - echoes back your configuration
echo    "$MY_SNAPSHOT_JAR_ARTIFACT_ID" - echoes back your configuration
echo    "$MY_SNAPSHOT_JAR_CLASSIFIER" - echoes back your configuration
echo    "$MY_SNAPSHOT_JAR_PACKAGING" - echoes back your configuration

Unfortunately you cannot ask about snapshot and release in the same dropdown list. A possible workaround is to add another parameter for MY_RELEASE_JAR (thus another dropdown list, somewhat confusing for a user). Another workaround is to have a separate job for release deployment.