I have the following groovy script that does the following
- checks all the builds for a specific job to see if it has the same build parameter as the current build
- stops the build with the same parameter as the current build
import hudson.tasks.Ant
def myBuildNumber = build.getEnvVars()['BUILD_NUMBER'].toInteger();
def myFractureNO = build.getEnvVars()['FRACTURE_NO'].toInteger();
def projectXml = new XmlSlurper().parseText("curl http://test.corp.test.com:8080/job/FractureAUT/api/xml".execute().text);
projectXml.build.each {
if(it.number.toInteger() < myBuildNumber)
{
def jobXml = new XmlSlurper().parseText(("curl http://test.corp.test.com:8080/job/FractureAUT/" + it.number + "/api/xml").execute().text);
def myparams = jobXml.getAction(hudson.model.ParametersAction.class);
for( p in myparams ) {
printlin p.name.toString();
if (p.name.toString == "FRACTURE_NO") {
if (p.value.toString() == myFractureNO.toString()) {
"curl http://test.corp.adobe.com:8080/job/FractureAUT/" + it.number + "/stop".execute().waitFor();
break;
}
}
}
}
}
the script outputs a bunch of urls to the screen because of the line:
def projectXml = new XmlSlurper().parseText("curl http://test.corp.test.com:8080/job/FractureAUT/api/xml".execute().text);
and it doesn't do what it suppose to do. How can I make it so that the line
def projectXml = new XmlSlurper().parseText("curl http://test.corp.test.com:8080/job/FractureAUT/api/xml".execute().text);
doesn't output the urls to the screen?
I get the following output
189http://test.corp.test.com:8080/job/FractureAUT/189/188http://test.corp.test.com:8080/job/FractureAUT/188/187http://test.corp.test.com:8080/job/FractureAUT/187/186http://test.corp.test.com:8080/job/FractureAUT/186/185http://test.corp.test.com:8080/job/FractureAUT/185/184http://test.corp.test.com:8080/job/FractureAUT/184/183http://test.corp.test.com:8080/job/FractureAUT/183/182http://test.corp.test.com:8080/job/FractureAUT/182/181http://test.corp.test.com:8080/job/FractureAUT/181/179http://test.corp.test.com:8080/job/FractureAUT/179/178http://test.corp.test.com:8080/job/FractureAUT/178/177http://test.corp.test.com:8080/job/FractureAUT/177/176http://test.corp.test.com:8080/job/FractureAUT/176/174http://test.corp.test.com:8080/job/FractureAUT/174/173http://test.corp.test.com:8080/job/FractureAUT/173/172http://test.corp.test.com:8080/job/FractureAUT/172/171http://test.corp.test.com:8080/job/FractureAUT/171/170http://test.corp.test.com:8080/job/FractureAUT/170/169http://test.corp.test.com:8080/job/FractureAUT/169/168http://test.corp.test.com:8080/job/FractureAUT/168/167http://test.corp.test.com:8080/job/FractureAUT/167/166http://test.corp.test.com:8080/job/FractureAUT/166/165http://test.corp.test.com:8080/job/FractureAUT/165/164http://test.corp.test.com:8080/job/FractureAUT/164/163http://test.corp.test.com:8080/job/FractureAUT/163/162http://test.corp.test.com:8080/job/FractureAUT/162/161http://test.corp.test.com:8080/job/FractureAUT/161/160http://test.corp.test.com:8080/job/FractureAUT/160/159http://test.corp.test.com:8080/job/FractureAUT/159/158http://test.corp.test.com:8080/job/FractureAUT/158/157http://test.corp.test.com:8080/job/FractureAUT/157/156http://test.corp.test.com:8080/job/FractureAUT/156/155http://test.corp.test.com:8080/job/FractureAUT/155/154http://test.corp.test.com:8080/job/FractureAUT/154/153http://test.corp.test.com:8080/job/FractureAUT/153/152http://test.corp.test.com:8080/job/FractureAUT/152/151http://test.corp.test.com:8080/job/FractureAUT/151/150http://test.corp.test.com:8080/job/FractureAUT/150/148http://test.corp.test.com:8080/job/FractureAUT/148/146http://test.corp.test.com:8080/job/FractureAUT/146/144http://test.corp.test.com:8080/job/FractureAUT/144/143http://test.corp.test.com:8080/job/FractureAUT/143/142http://test.corp.test.com:8080/job/FractureAUT/142/141http://test.corp.test.com:8080/job/FractureAUT/141/140http://test.corp.test.com:8080/job/FractureAUT/140/139http://test.corp.test.com:8080/job/FractureAUT/139/138http://test.corp.test.com:8080/job/FractureAUT/138/137http://test.corp.test.com:8080/job/FractureAUT/137/136http://test.corp.test.com:8080/job/FractureAUT/136/135http://test.corp.test.com:8080/job/FractureAUT/135/134http://test.corp.test.com:8080/job/FractureAUT/134/133http://test.corp.test.com:8080/job/FractureAUT/133/132http://test.corp.test.com:8080/job/FractureAUT/132/131http://test.corp.test.com:8080/job/FractureAUT/131/130http://test.corp.test.com:8080/job/FractureAUT/130/129http://test.corp.test.com:8080/job/FractureAUT/129/128http://test.corp.test.com:8080/job/FractureAUT/128/127http://test.corp.test.com:8080/job/FractureAUT/127/126http://test.corp.test.com:8080/job/FractureAUT/126/125http://test.corp.test.com:8080/job/FractureAUT/125/124http://test.corp.test.com:8080/job/FractureAUT/124/123http://test.corp.test.com:8080/job/FractureAUT/123/122http://test.corp.test.com:8080/job/FractureAUT/122/121http://test.corp.test.com:8080/job/FractureAUT/121/120http://test.corp.test.com:8080/job/FractureAUT/120/119http://test.corp.test.com:8080/job/FractureAUT/119/118http://test.corp.test.com:8080/job/FractureAUT/118/117http://test.corp.test.com:8080/job/FractureAUT/117/116http://test.corp.test.com:8080/job/FractureAUT/116/115http://test.corp.test.com:8080/job/FractureAUT/115/114http://test.corp.test.com:8080/job/FractureAUT/114/113http://test.corp.test.com:8080/job/FractureAUT/113/112http://test.corp.test.com:8080/job/FractureAUT/112/111http://test.corp.test.com:8080/job/FractureAUT/111/110http://test.corp.test.com:8080/job/FractureAUT/110/109http://test.corp.test.com:8080/job/FractureAUT/109/108http://test.corp.test.com:8080/job/FractureAUT/108/107http://test.corp.test.com:8080/job/FractureAUT/107/106http://test.corp.test.com:8080/job/FractureAUT/106/105http://test.corp.test.com:8080/job/FractureAUT/105/104http://test.corp.test.com:8080/job/FractureAUT/104/103http://test.corp.test.com:8080/job/FractureAUT/103/102http://test.corp.test.com:8080/job/FractureAUT/102/101http://test.corp.test.com:8080/job/FractureAUT/101/100http://test.corp.test.com:8080/job/FractureAUT/100/99http://test.corp.test.com:8080/job/FractureAUT/99/98http://test.corp.test.com:8080/job/FractureAUT/98/97http://test.corp.test.com:8080/job/FractureAUT/97/96http://test.corp.test.com:8080/job/FractureAUT/96/95http://test.corp.test.com:8080/job/FractureAUT/95/94http://test.corp.test.com:8080/job/FractureAUT/94/93http://test.corp.test.com:8080/job/FractureAUT/93/92http://test.corp.test.com:8080/job/FractureAUT/92/91http://test.corp.test.com:8080/job/FractureAUT/91/90http://test.corp.test.com:8080/job/FractureAUT/90/89http://test.corp.test.com:8080/job/FractureAUT/89/88http://test.corp.test.com:8080/job/FractureAUT/88/87http://test.corp.test.com:8080/job/FractureAUT/87/86http://test.corp.test.com:8080/job/FractureAUT/86/85http://test.corp.test.com:8080/job/FractureAUT/85/
Why do I get the output above?
Why are you invoking curl at all? Just retrieve the contents of the URL from groovy:
def xmlString = new URL("http://test.corp.test.com:8080/job/FractureAUT/api/xml").getText()
def projectXML = new XMLSlurper().parseText(xmlString)
XmlSlurper can parse the URL directly:
def projectXml = new XmlSlurper().parse('http://test.corp.test.com:8080/job/FractureAUT/api/xml')
I think the output on screen is because of curl. So can try to silence it with -s or --silent option:
def projectXml = new XmlSlurper().parseText("curl -s 'http://test.corp.test.com:8080/job/FractureAUT/api/xml'".execute().text);
Related
I'm trying to add a Snyk installation to Jenkins using groovy. The plugin is installed and I can see the installation option in Global Tool Configuration:
The problem is the Descriptor is not available until I manually add the installer and click Save. If I don't do this task manually, which I want to prevent, it causes my code to fail with the following error message "Cannot invoke method setInstallations() on null object"
My code:
import hudson.model.*
import jenkins.model.*
import hudson.tools.*
import hudson.tasks.*
import io.snyk.jenkins.tools.SnykInstaller
import io.snyk.jenkins.tools.SnykInstallation
def snyk_name = "Snyk"
def snyk_home = ""
def snyk_installer = new SnykInstaller("", "latest", 24)
def snyk_properties = new InstallSourceProperty([snyk_installer])
def instance = Jenkins.getInstance()
println("[init.groovy.d] START Configuring Snyk Installation...")
// Get the GlobalConfiguration descriptor of Snyk plugin.
def snyk_conf = instance.getDescriptor("io.snyk.jenkins.SnykStepBuilder.SnykStepBuilderDescriptor")
def snyk_inst = new SnykInstallation(
snyk_name,
snyk_home,
[snyk_properties]
)
// Only add the new Snyk setting if it does not exist - do not overwrite existing config
def snyk_installations = snyk_conf.getInstallations()
def snyk_inst_exists = false
snyk_installations.each {
installation = (SnykInstallation) it
if (snyk_inst.getName() == installation.getName()) {
snyk_inst_exists = true
println("Found existing installation: " + installation.getName())
}
}
if (!snyk_inst_exists) {
snyk_installations += snyk_inst
snyk_conf.setInstallations((SnykInstallation[]) snyk_installations)
snyk_conf.save()
}
// Save the state
instance.save()
println("[init.groovy.d] END")
Is there any way to do what I want programmatically?
After testing your groovy on my local Jenkins (v 2.263.1) I came up with the below which then worked for me:
import hudson.model.*
import jenkins.model.*
import hudson.tools.*
import hudson.tasks.*
import io.snyk.jenkins.tools.*
def instance = Jenkins.getInstance()
def snyk_name = "SnykLatest"
def snyk_home = ""
def snyk_installer = new SnykInstaller("", "latest", 24L, null)
def snyk_properties = new InstallSourceProperty([snyk_installer])
println("[init.groovy.d] START Configuring Snyk Installation...")
// Get the GlobalConfiguration descriptor of Snyk plugin.
def snyk_conf = instance.getDescriptor("io.snyk.jenkins.tools.SnykInstallation")
def snyk_inst = new SnykInstallation(
snyk_name,
snyk_home,
[snyk_properties]
)
// Only add the new Snyk setting if it does not exist - do not overwrite existing config
def snyk_installations = snyk_conf.getInstallations()
def snyk_inst_exists = false
snyk_installations.each {
installation = (SnykInstallation) it
if (snyk_inst.getName() == installation.getName()) {
snyk_inst_exists = true
println("Found existing installation: " + installation.getName())
}
}
if (!snyk_inst_exists) {
snyk_installations += snyk_inst
snyk_conf.setInstallations((SnykInstallation[]) snyk_installations)
snyk_conf.save()
}
// Save the state
instance.save()
println("[init.groovy.d] END")
In basic Terms the SnykInstaller was expecting 4 values not 3. Groovy also took the 3rd value as an Integer when it was expecting a Long Value.
References:
https://javadoc.jenkins.io/plugin/snyk-security-scanner/io/snyk/jenkins/tools/SnykInstaller.html
https://github.com/jenkinsci/snyk-security-scanner-plugin/blob/master/src/main/java/io/snyk/jenkins/tools/SnykInstaller.java
https://github.com/jenkinsci/snyk-security-scanner-plugin/blob/master/src/main/java/io/snyk/jenkins/tools/PlatformItem.java
I'm trying to add new functionality, without refactoring the entire code. Actually the code calls msg.typeOfMsg('msg'), but I want to add validation when it comes true change all the typeOfMsg to a specific type:
def specialRule = true
def message = changeMessageType()
def changeMessageType() {
def toInform = { def message -> thePath.toChange.inform(message) }
return specialRule ? [reprove : toInform, approve : toInform] : thePath.toChange
}
println(message.reprove('Standart reprove message')
This is the solution I found, it works, but I have a lot of message types and custom message types, there's some way to dynamically change all calls to inform, without refactoring all the code to calls something like message(typeOfMessage, message)?
-----Edit-----
Here's a runnable version
def message = changeMessageType()
def changeMessageType() {
def originalPath = new OriginalPath()
def specialRule = true
def toInform = { def message -> originalPath.inform(message) }
return specialRule ? [reprove : toInform, approve : toInform] : originalPath
}
message.approve('Standart reprove message')
class OriginalPath {
def reprove(message) {
println "Reprove: ${message}"
}
def approve(message) {
println "Approve: ${message}"
}
def inform(message) {
println "Inform: ${message}"
}
}
I'm changing my jenkins job's SCM url from, lets say gitlab to github by using Groovy script. Is there any way to minimize the complexity of this code ?
I have used Jenkins.instance.items.each {} which traverses through all the jobs in my jenkins
import hudson.plugins.git.*
import jenkins.*
import jenkins.model.*
def modifyGitUrl(url) {
def newurl = url.replace("source", "destination")
return newurl
}
def modifyGitID(credentialsId) {
def newID = ("Jenkins User ID")
return newID
}
Jenkins.instance.items.each {
if(it.name == "expected name"){
if (it.scm instanceof GitSCM) {
def oldScm = it.scm
def newUserRemoteConfigs = oldScm.userRemoteConfigs.collect {
new UserRemoteConfig(modifyGitUrl(it.url), it.name, it.refspec, modifyGitID(it.credentialsId))
}
def newScm = new GitSCM(newUserRemoteConfigs, oldScm.branches, oldScm.doGenerateSubmoduleConfigurations,
oldScm.submoduleCfg, oldScm.browser, oldScm.gitTool, oldScm.extensions)
it.scm = newScm
it.save()
}
}
}
I am working on Jenkins version 2.32.1 pipeline. I want to extract the parameters that were chosen in the previous build of my job.
In our previous Jenkins instance ( 1.627 ) we were using jenkins.model.Jenkins.instance.getItem(job).lastBuild.getBuildVariables().get(param);
For some reason this is not working in this version (I also tried disabling the sandbox).
Any pointers on how to accomplish it?
Simplified version of the previous script:
def build = Jenkins.get().getItems(org.jenkinsci.plugins.workflow.job.WorkflowJob).find {it.displayName == 'YOUR_JOB_NAME_HERE'}?.getLastBuild()
build.actions.find{ it instanceof ParametersAction }?.parameters.each {echo "${it.name}=${it.value}"}
Actually a little bit shorter version for those who want to get the params for the current build from the previous run and is working on new 2+ Jenkins versions.
To get 1 particular parameter:
def cls = currentBuild.getPreviousBuild().getRawBuild().actions.find{ it instanceof ParametersAction }?.parameters.find{it.name == 'cls'}?.value
Get all params respectfully:
def cls = currentBuild.getPreviousBuild().getRawBuild().actions.find{ it instanceof ParametersAction }?.parameters
Something like this might work, based on https://stackoverflow.com/a/19564602/3920342:
def h = hudson.model.Hudson.instance
def r = null
h.getItems(org.jenkinsci.plugins.workflow.job.WorkflowJob).each {project ->
if (project.displayName.equals('YOUR_JOB_NAME')) {
r = project
}
}
r.getBuilds().findAll { b -> // here we loop over all past builds, apply some filter if necessary
def p = b?.actions.find{ it instanceof ParametersAction }?.parameters
p.each {
echo "parameter ${it.name}: ${it.value}"
}
}
For those who are not able to access getActions() due to admin permissions i.e. facing the following error:
Scripts not permitted to use method hudson.model.Actionable getActions
They can copy the parameter variables to the env and get them using build.previousBuild.buildVariables
stage('Prepare environment') {
steps {
script {
env.MY_PARAM_COPY = "${MY_PARAM}"
}
}
}
println("MY_PARAM in previous build: ${currentBuild.previousBuild.buildVariables["MY_PARAM_COPY"]}")
That's how I made it works, answer from #dan.goriaynov and #jherb caused some CPS closure issues for me.
(the gist of the code is to allow only greater TAG number than the previous one to be deployed)
stage('Validate build number') {
def previous_build = currentBuild.getPreviousBuild().getRawBuild();
def PREVIOUS_TAG = '';
for (int i = 0; i < previous_build.allActions.size(); i++) {
if (previous_build.allActions[i] in hudson.model.ParametersAction) {
PREVIOUS_TAG = previous_build.allActions[i].getParameter("TAG").value
}
}
if (PREVIOUS_TAG.toInteger() > TAG.toInteger()) {
echo PREVIOUS_TAG
error('TAG number needs to be greater than the previous one')
}
}
Hi I have am trying to implement a file upload in my application where the file uploaded is parsed and an entry is created in the database using that information.
def save = {
def file = request.getFile("file");
def filename = file.getOriginalFilename();
def type = filename.split('\\.');
if(!file.isEmpty()){
if(type[1] == "properties"){
redirect(action:"parsePropertyFile", params:params);
}
}
}
def parsePropertyFile = {
println "\n"
println params.file;
println "\n";
def f = params.file;
println f;
def filename = f.getOriginalFilename();
println filename;
}
when I print out f this is output:
org.springframework.web.multipart.commons.CommonsMultipartFile#29d32df9
but when I try to call getOriginalFilename() on f I get the following error:
groovy.lang.MissingMethodException: No signature of method:
java.lang.String.getOriginalFilename() is applicable for argument types: () values: []
I also printed out file from the save function and the output of that is also:
org.springframework.web.multipart.commons.CommonsMultipartFile#29d32df9
so why am I getting the error?
Instead of redirecting, can you just call your another function? Redirect will issue an http redirect with the file as param with no need.
if(type[1] == "properties") {
parsePropertyFile(file)
}
And then:
private def parsePropertyFile(def file) {
String filename = file.getOriginalFilename();
...
}
In your parsePropertyFile action you aren't getting a File object, you're getting the String from params. Just like in your save action, you need to do
def f = request.getFile('file')
println f.getOriginalFilename()