How to change the Git URL in all Jenkins jobs - jenkins

Does anyone have an updated version of ceilfors answer that works for both AbstractProject and WorkflowJob?

This is the solution I came up with. It was tested on Jenkins 2.355
The test was run from the script console.
For testing purposes, I limited the test to one Freestyle (AbstractProject) and one Pipeline (WorkflowJob) job each. You would need to modify the code below.
I hope others find this useful
import org.jenkinsci.plugins.workflow.job.WorkflowJob;
import hudson.plugins.git.*
import jenkins.*
import jenkins.model.*
def modifyGitUrl(url) {
def updatedUrl = url.toString().replace("git#gitlab", "git#github")
// println "updatedUrl = ${updatedUrl}"
return updatedUrl
}
Jenkins.instance.getAllItems(Job.class).each {
project = it.getFullName()
if(project.toString().equals("PL_Quick_Testing") || project.toString().equals("A_Freestyle_Job")) {
try {
if (it instanceof AbstractProject){
def oldScm = it.scm
def newUserRemoteConfigs = oldScm.userRemoteConfigs.collect {
new UserRemoteConfig(modifyGitUrl(it.url), it.name, it.refspec, it.credentialsId)
}
def newScm = new GitSCM(newUserRemoteConfigs, oldScm.branches, oldScm.doGenerateSubmoduleConfigurations,
oldScm.submoduleCfg, oldScm.browser, oldScm.gitTool, oldScm.extensions)
it.scm = newScm
it.save()
println "Done"
} else if (it instanceof WorkflowJob) {
def oldScm = it.getTypicalSCM()
def definition = it.getDefinition()
String scriptPath = it.getDefinition().getScriptPath()
def newUserRemoteConfigs = oldScm.userRemoteConfigs.collect {
new UserRemoteConfig(modifyGitUrl(oldScm.userRemoteConfigs.url[0]), it.name, it.refspec, it.credentialsId)
}
def newScm = new GitSCM(newUserRemoteConfigs, oldScm.branches, oldScm.doGenerateSubmoduleConfigurations,
oldScm.submoduleCfg, oldScm.browser, oldScm.gitTool, oldScm.extensions)
def newDefinition = new org.jenkinsci.plugins.workflow.cps.CpsScmFlowDefinition(newScm, scriptPath)
it.definition = newDefinition
it.save()
println "Done"
} else {
println("${project} has no SCM")
}
} catch (Exception e) {
// e.printStackTrace()
}
}
}

Related

How to synchronize fields between epics and issues in Jira with Scriptrunner?

Let us assume a typical software project in Jira that uses Issues, Subtasks and Epics, with a custom field called "Customer" that can be set on any issue or the Epic. I want to have this field synchronized, so that its value for any tickets get automatically set to the highest parent of the hierarchy, up to the epics. How to achieve that with ScriptRunner for Jira?
This can be done with the following listener:
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.type.EventDispatchOption
import com.atlassian.jira.issue.Issue
import com.atlassian.jira.issue.MutableIssue
import com.atlassian.jira.issue.link.IssueLink
def issue = event.issue as MutableIssue
def customFieldManager = ComponentAccessor.customFieldManager
def issueManager = ComponentAccessor.issueManager
def issueLinkManager = ComponentAccessor.issueLinkManager
def customField = customFieldManager.getCustomFieldObjectsByName('Customer').first()
def epicLink = customFieldManager.getCustomFieldObjectsByName('Epic Link').first()
def EPIC_STORY_LINK = "Epic-Story Link"
def issuesToUpdate = [] as ArrayList<Issue>
def valueFromTop = null
if (issue.issueType.name == 'Epic') {
// The issue is an epic. Propagate the custom field value down
valueFromTop = issue.getCustomFieldValue(customField)
issueLinkManager.getOutwardLinks(issue.id).find {
it.issueLinkType.name == EPIC_STORY_LINK
}.each { IssueLink it1 ->
issuesToUpdate.addAll(it1.destinationObject)
it1.destinationObject.subTaskObjects.findAll { it2 ->
issuesToUpdate.addAll(it2)
}
}
}
else {
// Normal issue. Look up to find the reference issue to get the value from.
def issueIterator = issue
while ( true ) {
def value = issueIterator.getCustomFieldValue(customField)
if ( value ) {
valueFromTop = value
}
issuesToUpdate.addAll(issueIterator)
if ( issueIterator.parentObject ) {
issueIterator = issueIterator.parentObject
}
else {
break
}
}
// Check if the parent issue is an Epic.
issueLinkManager.getInwardLinks(issueIterator.id).find {
it.issueLinkType.name == EPIC_STORY_LINK
}.each { IssueLink epicIssueLink ->
// Get the value from the Epic
valueFromTop = epicIssueLink.sourceObject.getCustomFieldValue(customField)
}
// Add child issues to list
issue.subTaskObjects.findAll {
issuesToUpdate.addAll(it)
}
}
def loggedInUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser
issuesToUpdate.each {
def mutableTicket = it as MutableIssue
mutableTicket.setCustomFieldValue(customField, valueFromTop)
ComponentAccessor.issueManager.updateIssue(loggedInUser, mutableTicket, EventDispatchOption.DO_NOT_DISPATCH, false)
}

How to check if a variable is defined in a Jenkins folder?

I created a Jenkins folder which has multiple jobs in it. I've also defined some variables in the folder itself. How can I check if the folder has a variable defined? I tied
import jenkins.model.*
private def getBuildJob(final String folder) {
def jobFolder = null
for (f in Jenkins.instance.getAllItems(AbstractItem.class)) {
if (f.fullName == folder) {
jobFolder = f
break
}
}
return jobFolder
}
node("linux-ubuntu") {
stage("test") {
def folder = getBuildJob("MyFolderName")
println folder.hasVariable("MY_VARIABLE")
}
}
But I get
hudson.remoting.ProxyException: groovy.lang.MissingMethodException: No signature of method: com.cloudbees.hudson.plugins.folder.Folder.hasVariable() is applicable for argument types: (java.lang.String) values: [MY_VARIABLE]
at org.jenkinsci.plugins.scriptsecurity.sandbox.groovy.SandboxInterceptor.onMethodCall(SandboxInterceptor.java:153)
at org.kohsuke.groovy.sandbox.impl.Checker$1.call(Checker.java:161)
If you are using the folder-properties plugin you can use the following script.
#NonCPS
def checkVar() {
def folderName = "Folderycr"
def propToCheck = "YCRPROP"
def folderItem = Jenkins.instance.getAllItems(com.cloudbees.hudson.plugins.folder.AbstractFolder.class).find{ (it.name == folderName) }
println folderItem.getProperties().each { prop ->
if(prop instanceof com.mig82.folders.properties.FolderProperties){
prop.getProperties().each{
if(it.key == propToCheck) {
println "Prop is available. Vale is : " + it.value
}
}
}
}
}
node("linux-node") {
stage("Run test") {
checkVar()
}
}

Jenkins only executes first line of groovy closure

I have the following two Classes which work just fine locally in groovy, but once I use them with Jenkins Shared Libraries I run into some issues.
./Template.groovy
class Template {
String arch
String type
def body = {}
Template(type, arch, body) {
this.arch = arch
this.type = type
this.body = body
}
}
./TemplateBook.groovy
import Template
class TemplateBook {
def templates = []
TemplateBook() {
def template = new Template("test", "lnx", { args -> sh('echo "Hello World!"'); sh("echo Test"); sh("echo $args")})
templates.push(template)
}
def getTemplate(type, arch) {
def template
for (def i = 0; i < templates.size(); i++) {
if (templates[i].arch == arch && templates[i].type == type) {
template = templates[i].getBody()
i = templates.size()
}
}
return template
}
}
Using the Template.body directly works just fine (locally and on Jenkins), but using the TemplateBook.getTemplate() only executes the first line of the closure (body).
def templateBook = new TemplateBook()
def body = templateBook.getTemplate("test", "lnx")
body.resolveStrategy = Closure.DELEGATE_FIRST
body.delegate = this
body("test")
Output:
Hello World!
def template = new Template("type", "arch", { args -> sh('echo "Hello World!"'); sh("echo Test"); sh("echo $args")})
def body2 = template.body
body2.resolveStrategy = Closure.DELEGATE_FIRST
body2.delegate = this
body2("test")
Output:
Hello World!
Test
test

Prioritize Jenkins Build via Groovy Postbuild

I want to schedule a job to be at the top of the build queue in Jenkins via a Groovy Postbuild.
For example, for Build X
If previously the build queue looks like this:
Generic Build 1
Generic Build 2
Generic build 3
Now it should look like:
Build X
Generic Build 1
Generic Build 2
Generic Build 3
So far I've been able to schedule the job using
def waitingItem = Jenkins.get().getQueue().schedule(job, 0)
if (waitingItem == null) {
manager.listener.logger.println "Error scheduling ${job}!"
} else {
manager.listener.logger.println "${job.name} was scheduled!"
}
but now I also want waitingItem to be at the top of the queue.
Any help is much appreciated.
Ok so after countless hours of browsing the web I've been able to come up with a Groovy Postbuild script that does the following: once it finishes the build, it triggers another build (let's call it buildToBeTriggered) and buildToBeTriggered automatically gets pushed at the front of the queue.
The code is below:
import hudson.model.AbstractProject
import hudson.model.Queue
import hudson.model.queue.QueueSorter
import jenkins.model.Jenkins
def job = (AbstractProject)Jenkins.get().getItem('gcimpoies-toTrigger')
def isSuccess = manager.getResult() == 'SUCCESS'
def isRelease = manager.getEnvVariable('RELEASE') == 'true'
def secondsToWait = 20
if (isSuccess) {
def waitingItem = Jenkins.get().getQueue().schedule(job, 0)
if (waitingItem == null) {
manager.listener.logger.println "Error scheduling ${job}!"
} else {
manager.listener.logger.println "${job.name} was scheduled!"
}
Thread.sleep(secondsToWait * 1000)
//replace the original queue sorter with one that will place our project build first in the queue
QueueSorter originalQueueSorter = Jenkins.get().getQueue().getSorter()
AcceleratedBuildNowSorter acceleratedBuildNowSorter = new AcceleratedBuildNowSorter(job, originalQueueSorter)
Jenkins.get().getQueue().setSorter(acceleratedBuildNowSorter);
// we sort the queue so that our project is next to be built on the list
Jenkins.get().getQueue().getSorter().sortBuildableItems(Jenkins.getInstance().getQueue().getBuildableItems())
}
class AcceleratedBuildNowSorter extends QueueSorter {
private final AbstractProject project
private final QueueSorter originalQueueSorter
private final AcceleratedBuildNowComparator comparator
AcceleratedBuildNowSorter(AbstractProject project, QueueSorter originalQueueSorter) {
this.project = project
this.originalQueueSorter = originalQueueSorter
comparator = new AcceleratedBuildNowComparator(this.project)
}
#Override
void sortBuildableItems(List<Queue.BuildableItem> buildables) {
if (this.originalQueueSorter != null) {
this.originalQueueSorter.sortBuildableItems(buildables)
}
Collections.sort(buildables, comparator)
}
}
class AcceleratedBuildNowComparator implements Comparator<Queue.BuildableItem> {
private final AbstractProject mostPriorityProject;
AcceleratedBuildNowComparator(AbstractProject mostPriorityProject) {
this.mostPriorityProject = mostPriorityProject;
}
int compare(Queue.BuildableItem buildableItem0, Queue.BuildableItem buildableItem1) {
AbstractProject<?, ?> project0 = (AbstractProject<?, ?>) buildableItem0.task
AbstractProject<?, ?> project1 = (AbstractProject<?, ?>) buildableItem1.task
if (project0.equals(mostPriorityProject)) {
return -1
}
if (project1.equals(mostPriorityProject)) {
return 1
}
return 0
}
}

jenkins cli with checkout Subversion using groovy script

Is there a way to check out any Subversion project using Jenkins-Cli by executing a groovy script on the master? I can get to the point of creating SVN client manager[org.tmatesoft.svn.core.wc.SVNClientManager], but can't really understand how to employ that in checking out an SVN project from the URL.
After a lot of hit and trials I have come up with this, might be useful for someone else:
import jenkins.*;
import jenkins.model.*;
import hudson.*;
import hudson.model.*;
import hudson.slaves.SlaveComputer;
import hudson.scm.SubversionSCM;
import hudson.remoting.Channel;
import hudson.FilePath;
import org.tmatesoft.svn.core.SVNURL;
import org.tmatesoft.svn.core.io.SVNRepository;
import org.tmatesoft.svn.core.io.SVNRepositoryFactory;
import org.tmatesoft.svn.core.SVNException;
import org.tmatesoft.svn.core.wc.SVNClientManager;
import org.tmatesoft.svn.core.auth.ISVNAuthenticationProvider;
import org.tmatesoft.svn.core.wc.SVNLogClient;
import org.tmatesoft.svn.core.SVNDirEntry;
import org.tmatesoft.svn.core.wc.SVNRevision;
import org.tmatesoft.svn.core.SVNDepth;
import org.tmatesoft.svn.core.SVNDirEntry;
import org.tmatesoft.svn.core.ISVNDirEntryHandler;
import org.tmatesoft.svn.core.wc.SVNUpdateClient;
import java.lang.*;
import java.util.ArrayList;
import java.util.List;
private boolean checkNodeExist(String node_Name){
if (Jenkins.getInstance().slaves.find({it.name == node_Name}) == null)
return false;
else
return true;
}
private ISVNAuthenticationProvider createAuthenticationProvider(AbstractProject context) {
return Jenkins.getInstance().getDescriptorByType(SubversionSCM.DescriptorImpl.class)
.createAuthenticationProvider(context);
}
public class SimpleSVNDirEntryHandler implements ISVNDirEntryHandler {
private final List<SVNDirEntry> dirs = new ArrayList<SVNDirEntry>();
public List<String> getDirs() {
List<String> sortedDirs = new ArrayList<String>();
for (SVNDirEntry dirEntry : dirs) {
sortedDirs.add(dirEntry.getName());
}
return sortedDirs;
}
public void handleDirEntry(SVNDirEntry dirEntry) throws SVNException {
dirs.add(dirEntry);
}
}
public void PerfromSVNListOperationOnMaster(SVNURL svnUrl){
try{
SVNRepository repo = SVNRepositoryFactory.create(svnUrl);
SVNClientManager clientManager = SubversionSCM.createSvnClientManager(createAuthenticationProvider())
SVNLogClient logClient = clientManager.getLogClient();
SimpleSVNDirEntryHandler dirEntryHandler = new SimpleSVNDirEntryHandler();
List<String> dirs = new ArrayList<String>();
logClient.doList(repo.getLocation(),SVNRevision.HEAD, SVNRevision.HEAD,false,SVNDepth.INFINITY,SVNDirEntry.DIRENT_KIND,dirEntryHandler)
dirs = dirEntryHandler.getDirs();
println (dirs)
}
catch(SVNException svnEx){
println "#Error: " + svnEx;
throw svnEx
}
}
public void PerfromSVNCheckOutOperation(SVNURL svnUrl,boolean isMaster,String appender,SlaveComputer computer = null){
try{
SVNRepository repo = SVNRepositoryFactory.create(svnUrl);
SVNClientManager clientManager = SubversionSCM.createSvnClientManager(createAuthenticationProvider());
SVNUpdateClient updateClient = clientManager.getUpdateClient();
updateClient.setIgnoreExternals(false);
String destDir = svnUrl.getPath().substring(svnUrl.getPath().lastIndexOf('/')+1);
if (isMaster == true){
updateClient.doCheckout(repo.getLocation(),new java.io.File(System.getProperty("java.io.tmpdir"),destDir + '_' + appender),SVNRevision.HEAD,SVNRevision.HEAD,SVNDepth.INFINITY,false);
}else{
if (computer == null){
throw new IllegalArgumentException("#Error: Argument:computer can't be null when we need to checkout in slave");
}else{
updateClient.doCheckout(repo.getLocation(),new java.io.File(System.getProperty("java.io.tmpdir"),destDir + '_' + appender),SVNRevision.HEAD,SVNRevision.HEAD,SVNDepth.INFINITY,false);
Channel slaveChannel = computer.getChannel();
FilePath fpSrc = new hudson.FilePath(new java.io.File(System.getProperty("java.io.tmpdir"),destDir + '_' + appender));
//println new java.io.File((slave.getWorkspaceRoot().toString()),destDir).toString().replace('\\','/')
FilePath fpDestination = new hudson.FilePath(slaveChannel,new java.io.File((slave.getWorkspaceRoot().toString()),destDir + '_' + appender).toString().replace('\\','/'));
println "Copying files recursively from Temp directory in master to slave";
int files_copied = fpSrc.copyRecursiveTo(fpDestination);
println files_copied
fpSrc.deleteRecursive();
}
}
}
catch (Exception ex){
throw new Exception("#Error:",ex);
}
}
if (args.length == 4){
String url = new String(args[0]);
SVNURL svn_url = null;
try{
svn_url = SVNURL.parseURIDecoded(url);
}
catch(SVNException svnEX){
println "#Error: Check SVN repository Location.";
throw svnEX;
}
String nodeName = new String(args[1]);
String operation = new String(args[2]);
String checkoutAppendString = new String(args[3]);
println args
if (nodeName.equalsIgnoreCase("master")){
println "Executing script on master"
if (operation.equalsIgnoreCase("list")){
PerfromSVNListOperationOnMaster(svn_url);
}else{
PerfromSVNCheckOutOperation(svn_url,true,checkoutAppendString);
}
}else{
if (checkNodeExist(nodeName)){
slave = Jenkins.getInstance().slaves.find({it.name == nodeName});
SlaveComputer computer = slave.getComputer();
if (computer.isOffline()){
println "#Error: $slave is offline."
return
}else{
if (operation.equalsIgnoreCase("list")){
PerfromSVNListOperationOnMaster(svn_url)
}else{
PerfromSVNCheckOutOperation(svn_url,false,checkoutAppendString,computer);
}
}
}else{
println "#Error: $nodeName not found."
return
}
}
}else{
println "Invalid Usage, expecting 3 arguments : 1.RepositoryURL 2.NodeName 3.OperationType"
return
}

Resources