It's not the same without you

Join the community to find out what other Atlassian users are discussing, debating and creating.

Atlassian Community Hero Image Collage

ScriptRunner Component sync

I want to be able to Sync Components from my Main "DevOps" project to all other projects in JIRA,

Because we want a unified place for components.

I started with this:



import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.project.Project
import com.atlassian.jira.project.version.Version

def projectManager = ComponentAccessor.getProjectManager()
def projectSource = projectManager.getProjectObjByKey("DEVOPS") // change project name here
def projectDestinationList = projectManager.getProjectObjects()
//def projectDestination = projectManager.getProjectObjByKey("DESTINATION_PROJECT_KEY")

def ProjectComponentManager = ComponentAccessor.getProjectComponentManager()
Collection<ProjectComponent> componentList = ProjectComponentManager.findAll(projectSource.getid())
def componentTemp
if (componentList != null)
{
    for (project in projectDestinationList) {
    if (project.getKey() != "DEVOPS") {
    for (component in componentList) {
        componentTemp = ProjectComponentManager.findComponent(project.getid(), component)
        if  (componentTemp == null) {
            log.debug("Now adding component " + component + " to " + project.getName())
            def component = ProjectComponentManager.create(component, "description", "admin", 1,  "admin user ID")
            //ProjectComponentManager.createComponent()
        }
    }
    }
    }
}

Now I need assistance on completing this because I dont know how to get it to work

 

3 answers

OK,

 

I finally have the solution:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.project.Project
import com.atlassian.jira.project.version.Version
import com.atlassian.jira.bc.project.component.ProjectComponent

def projectManager = ComponentAccessor.getProjectManager()
def projectSource = projectManager.getProjectObjByKeyIgnoreCase("DEVOPS").getId() // change project name here
def projectDestinationList = projectManager.getProjectObjects()
def projectComponentManager = ComponentAccessor.getProjectComponentManager()

Collection<ProjectComponent> componentList = projectComponentManager.findAllForProject(projectSource) as Collection<ProjectComponent>

if (componentList != null) {
   for (project in projectDestinationList) {
      if (project.getKey() != "SOFTENG") {
         for (component in componentList) {
            def componentTemp = projectComponentManager.findByComponentName(project.getId(), component.getName())
            if  (componentTemp == null) {
                log.debug("Now adding component " + component.getName() + " to " + project.getName())
                def componentTempResult = projectComponentManager.create(component.getName(), component.getDescription(), component.getLead(), 1,project.getId())
                // 1= COMPONENT_LEAD, 2= PROJECT_DEFAULT, 3 =PROJECT_LEAD , 4= UNASSIGNED
            }
         }        
      }
   }
}


So, with a little help from my friend and some additional research,

1. I added "as Collecion" after defining my componentlistcollection

2. I used component.getName() instead of component

3. I added a remark of the ENUM values of the AssigneeType for a component.

Thank you Atlassian Community and Adaptavist documentation.

Great script ! You used it as a script listener on all Component events, right ?

Anyhow, you should probably suggest adaptavist to add it to their library.adaptavist.com ;-)

Like ofirgu@bezeqint.co.il likes this

ofirgu@bezeqint.co.il just to tidy it up, you can remove this line:

import com.atlassian.jira.project.version.Version
Like ofirgu@bezeqint.co.il likes this

 

I'd like to adapt this to sync Components from a source project to a list of specific projects only instead of to ALL projects.

Would it just be a matter of changing this line

def projectDestinationList = projectManager.getProjectObjects() 

to this??  (please help me with the syntax)

def projectManager.getProjectObjByKeyIgnoreCase("PROJECT1", "PROJECT2", "PROJECT3").getId()

and then comment out this line and remove its closing "}"??

 if (project.getKey() != "SOFTENG") { 

 

Leaving us with something like this?

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.project.Project
import com.atlassian.jira.bc.project.component.ProjectComponent

def projectManager = ComponentAccessor.getProjectManager()
def projectSource = projectManager.getProjectObjByKeyIgnoreCase("SOURCEPROJECTKEYHERE").getId() // change project key here
def projectDestinationList = projectManager.getProjectObjByKeyIgnoreCase("KEY1", "KEY2", "KEY3").getId()
def projectComponentManager = ComponentAccessor.getProjectComponentManager()

Collection<ProjectComponent> componentList = projectComponentManager.findAllForProject(projectSource) as Collection<ProjectComponent>

if (componentList != null) {
   for (project in projectDestinationList) {
   //   if (project.getKey() != "EXCLUDEDPROJECTKEYHERE") {
         for (component in componentList) {
            def componentTemp = projectComponentManager.findByComponentName(project.getId(), component.getName())
            if  (componentTemp == null) {
                log.debug("Now adding component " + component.getName() + " to " + project.getName())
                def componentTempResult = projectComponentManager.create(component.getName(), component.getDescription(), component.getLead(), 1,project.getId())
                // 1= COMPONENT_LEAD, 2= PROJECT_DEFAULT, 3 =PROJECT_LEAD , 4= UNASSIGNED
            
         }        
      }
   }
}

 

Or perhaps leave everything as is and just change this line:

if (project.getKey() != "EXCLUDEDPROJECTKEYHERE") {

to this instead? (again, please forgive/correct my syntax)

if (project.getKey() == "KEY1" || "KEY2" || "KEY3") {

I'm really out of my depth here... any help/ideas would be greatly appreciated.  I think that a 1:some use case would be more common for most people so I'm sure others would also benefit.

Hi @Andy Ukasick,

 

I would use this:

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.project.Project
import com.atlassian.jira.bc.project.component.ProjectComponent

def projectManager = ComponentAccessor.getProjectManager()
def projectSource = projectManager.getProjectObjByKeyIgnoreCase("SOURCEPROJECTKEYHERE").getId() // change project key here
def projectDestinationList = projectManager.getProjectObjByKeyIgnoreCase("KEY1", "KEY2", "KEY3").getId()
def projectComponentManager = ComponentAccessor.getProjectComponentManager()

Collection<ProjectComponent> componentList = projectComponentManager.findAllForProject(projectSource) as Collection<ProjectComponent>

if (componentList != null) {
   for (project in projectDestinationList) {
         for (component in componentList) {
            def componentTemp = projectComponentManager.findByComponentName(project.getId(), component.getName())
            if  (componentTemp == null) {
                log.debug("Now adding component " + component.getName() + " to " + project.getName())
// HERE I would add a function to verify that a user called getLead() actually exists in the setination project. we added all Enterprise users as viewers to all projects.
                def componentTempResult = projectComponentManager.create(component.getName(), component.getDescription(), component.getLead(), 1,project.getId())
                // 1= COMPONENT_LEAD, 2= PROJECT_DEFAULT, 3 =PROJECT_LEAD , 4= UNASSIGNED
            
         }        
   }
}

Hi ofirgu@bezeqint.co.il, can you elaborate on what your problem is? Do you get an error when running the script?

Also, please keep in mind that synchronising components involves a bit more magic, as Jira will throw an error if the component already exists. Do you want your script to update existing components upon changes? Have you also thought about when this script should run? Contrary to version changes Jira does not offer events for component changes so you will need some sort of schedule task.

If you need help with any of these questions, feel free to DM me! I have some experience with this problem as I've created a specific app for it (Version & Component Sync) :D

Cheers,

Remie

1. My Script fails

2. I did check for the component existence in the target project, and leave it as is if it already exists.

3. your plugin is nice, But I have to manage links or create links in order for it to work, while on my script, I go to the script runner panel, trigger it, and it does a sync on all projects. no link creation required.

 

I am really close on getting it to work

I think the problem lies with the following line:

componentTemp = ProjectComponentManager.findComponent(project.getid(), component)

If you look at the ProjectComponentManager documentation, it does not include a findComponent() method which allows you to specify the projectId and ProjectComponent object.

In this case it is probably best to use findByComponentName:

componentTemp = ProjectComponentManager.findByComponentName(project.getid(), component.getName())

here is the log error:
2019-01-16 18:38:31,873 ERROR [runner.AbstractScriptListener]: *************************************************************************************
2019-01-16 18:38:31,873 ERROR [runner.AbstractScriptListener]: Script function failed on event: com.atlassian.jira.event.bc.project.component.ProjectComponentCreatedEvent, file: <inline script>
org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
Script173.groovy: 14: unable to resolve class ProjectComponent
@ line 14, column 12.
Collection<ProjectComponent> componentList = ProjectComponentManager.findAll(projectList.getid())
^
1 error

Suggest an answer

Log in or Sign up to answer
Community showcase
Posted in Jira

Demo Den Ep. 7: New Jira Cloud Reports

Learn how to use two new reports for next-gen projects in Jira Cloud:  Cumulative flow diagram and Sprint burndown chart. Ivan Teong, Product Manager, Jira Software, demos the Cumulative ...

334 views 1 3
Join discussion

Community Events

Connect with like-minded Atlassian users at free events near you!

Find an event

Connect with like-minded Atlassian users at free events near you!

Unfortunately there are no Community Events near you at the moment.

Host an event

You're one step closer to meeting fellow Atlassian users at your local event. Learn more about Community Events

Events near you