Jenkins: Accessing other plugins from Active Choices Parameter groovy script - jenkins

I'm quite new to Jenkins, Groovy and all that, so forgive me if this sounds dumb.
I'm using the Active Choices plugin, and from one of the AC Parameters inside the Groovy script I want to use a different plugin - Artifactory, to fetch a file and display each line inside it as an option.
try {
def server = Artifactory.newServer url: 'http://localhost:8081/artifactory/', username: 'user', password: 'pass'
def downloadSpec = """{
"files": [
{
"pattern": "example-repo-local/file.txt",
"target": "example/"
}
]
}"""
server.download(downloadSpec)
String text = readFile("example/file.txt")
return text.tokenize("\n")
} catch (Exception e) {
return [e]
}
However, the Active Choices Parameter doesn't seem to recognize other plugins, and it can't find the Artifactory property:
groovy.lang.MissingPropertyException: No such property: Artifactory for class: Script1
My question is - do I need to import the plugin somehow? If so, how do I determine what to import?
There is an option to also specify an "Additional classpath" near an Active Choice Parameter, but the plugin contains 75 jar files in its WEB-INF/lib directory. (just specifying the artifactory.jar one doesn't seem to change anything)
Just a note - the Pipeline recognizes the Artifactory plugin and it works fine - I can successfully connect and retreive a file and read it.

I can't fine any possibility to run Artifactory plugin in reasonable way. So i thing better option is use curl, and Artifactory API. For example my Active Choices Parameter based on Json file from Artifactory;
import groovy.json.JsonSlurper
def choices = []
def response = ["curl", "-k", "https://artifactory/app/file.json"].execute().text
def list = new JsonSlurper().parseText( response )
list.each { choices.push(it.name) }
return choices

Related

Jenkins Pipeline dynamically set parameter based on Artifactory trigger URL

I have a pipeline job that triggers when finding changes in Artifactory at a specific path. I want to pass the Artifactory url value to a parameter (my goal for this job is to allow users to manually build this job and enter a path as well as have this job automatically trigger when changes are found in a specific path in Artifactory and pass that value to the parameter).
node {
def server
def rtTriggerUrl = currentBuild.getBuildCauses('org.jfrog.hudson.trigger.ArtifactoryCause')[0]?.url
stage ('Artifactory configuration') {
server = Artifactory.server 'artifactory-1'
}
stage('Trigger build') {
server.setBuildTrigger spec: "H/2 * * * *", paths: "maven-examplerepo-local/path/to/jar"
}
}
pipeline {
parameters {
string(
name: 'JAR_LOCATION',
defaultValue: rtTriggerUrl,
trim: true,
description: 'Artifactory URL of jar'
I have tried setting it a couple different ways:
defaultValue: rtTriggerUrl
defaultValue: "${currentBuild.getBuildCauses('org.jfrog.hudson.trigger.ArtifactoryCause')[0]?.url}"
However these gave blank or null values (I also tried setting the rtTriggerUrl function before node to see if that'd make it available to the parameter but that didn't work either).
Has anyone figured out how to do this? As a workaround I created an upstream job that triggers when changes are in Artifactory, then it triggers the downstream job and passes the url value to the downstream job's parameter. I wanted to see if I could combine that logic into one job.

Jenkins Remote Access API: Retrieve up-to-date parameter choices

I'm currently building my choices depending on available agents and its labels in a pipeline:
def loadConfigurations() {
def configurations = [];
def jenkins = Jenkins.instance;
def onlineComputers = jenkins.computers.findAll { it.online };
def availableLabels = onlineComputers.collect {
it.assignedLabels.collect { LabelAtom.escape(it.expression) } }
.flatten().unique(false);
def lineage16Configurations = ['samsung:klte:lineage:16.0'];
if (availableLabels.containsAll(['lineage', '16.0'])) {
configurations.addAll(lineage16Configurations);
}
return configurations;
}
def configurations = loadConfigurations();
pipeline {
agent { label 'master' }
parameters {
choice name: 'CONFIG', choices: configurations, description: 'Configuration containing vendor, device, OS and its version. Each separated by a colon.'
}
//...
Now, lets say all agents are offline, when requesting the remote access API I don't get up-to-date choices cause they're only updated when starting a build. Is there any existing way to retrieve them somehow through remote access API or do I need to write my own plugin which adds a new endpoint for the remote access API?
I've already tried the Active Choices Parameter and the Extended Choice Parameter without success. Both don't display any choices in the API.
I was playing around with the Extensible Choice Parameter and created a Pull Request which exposes the choiceList to the Remote Access API. The API was then returning changed choices without building the job.

Can I access current stage id in Jenkins pipeline?

I'm using shared library to build CI/CD pipelines in Jenkins. And in my case, some of the stages need to send the execute info through web apis. In this case, we need to add stage id for current stage to api calls.
How can I access the stage id similar with ${STAGE_NAME}?
I use Pipeline REST API Plugin as well as HTTP Request Plugin
Your methods in Jenkinsfile can look like:
#NonCPS
def getJsonObjects(String data){
return new groovy.json.JsonSlurperClassic().parseText(data)
}
def getStageFlowLogUrl(){
def buildDescriptionResponse = httpRequest httpMode: 'GET', url: "${env.BUILD_URL}wfapi/describe", authentication: 'mtuktarov-creds'
def buildDescriptionJson = getJsonObjects(buildDescriptionResponse.content)
def stageDescriptionId = false
buildDescriptionJson.stages.each{ it ->
if (it.name == env.STAGE_NAME){
stageDescriptionId = stageDescription.id
}
}
return stageDescriptionId
}
Questiion is old but i found the solution: use some code from pipeline-stage-view-plugin( looks like it is already installed in jenkins by default)
we can take current job ( workflowrun ) and pass it as an argument to
com.cloudbees.workflow.rest.external.RunExt.create , and whoala: we have object that contains info about steps and time spent on it's execution.
Full code will looks like this:
import com.cloudbees.workflow.rest.external.RunExt
import com.cloudbees.workflow.rest.external.StageNodeExt
def getCurrentBuildStagesDuration(){
LinkedHashMap stagesInfo = [:]
def buildObject = com.cloudbees.workflow.rest.external.RunExt.create(currentBuild.getRawBuild())
for (StageNodeExt stage : buildObject.getStages()) {
stagesInfo.put(stage.getName(), stage.getDurationMillis())
}
return stagesInfo
}
Function will return
{SomeStage1=7, SomeStage2=1243, SomeStage3=5}
Tested with jenkins shared library and Jenkins 2.303.1
Hope it helps someone )

How to have HTML/JS on a Jenkins build configuration page?

I am trying to run some AJAX on the frontend of a Jenkins build configuration page. To be exact to have a dropdown selection of available databases on a remote server. How do I accomplish this?
In case you need a dynamic list you can use Active Choice Parameter and add a groovy script to generate dynamic list from a remote api call.
below is an example i use to generate list of vpc's from aws :
#!groovy
def sout = new StringBuffer(), serr = new StringBuffer()
def process = [ "aws", "ec2", "describe-vpcs", "--query", "Vpcs[*].[Tags[?Key==`Name`].Value]"].execute()
process.consumeProcessOutput(sout, serr)
process.waitFor();
def s3_vpcs = sout.tokenize('\n')
def vpcs = []
for ( vpc in s3_vpcs) {
vpcs.add(vpc)
}
return vpcs

How to get the last build number from a Trigger/call builds on other projects if a multibranch pipeline Build is called?

I use the Parameterized Trigger Plugin for Jenkins to trigger a Multibranch Pipeline project (RED Outlook Addin). After the build has finished I want to copy the artifacts via Copy Artifact Plugin.
I Add a build step "copy artifacts from another project" with project name "RED Outlook Addin/${CIOS_BRANCH_NAME}" because I get the branch name as a parameter. This works if I specify the build number like "12". But if I set the build number to $TRIGGERED_BUILD_NUMBER_RED_Outlook_Addin_${CIOS_BRANCH_NAME} I get this error: Unable to find project for artifact copy.
How can I call the $TRIGGERED_BUILD_NUMBER_ Parameter with the specified branch?
Thx for help
Chris
You could query the json api of your jenkins server, for example using httpRequest plugin:
#NonCPS
def parseJson(String text) {
def sup = new JsonSlurper()
def json = sup.parseText(text)
sup = null
return json
}
def getLastStableBuildNumber(String project, String branchName = 'master') {
def response = httpRequest url: "http://jenkins/job/${project}/job/${branchName}/lastStableBuild/api/json", validResponseCodes: '200'
def json = parseJson(response.content)
return json.number
}

Resources