Forums

Articles
Create
cancel
Showing results for 
Search instead for 
Did you mean: 

ScriptRunner Component sync

ofirgu@bezeqint.co.il January 15, 2019

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

 

4 answers

1 vote
ofirgu@bezeqint.co.il January 16, 2019

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.

Corentin Méhat
Rising Star
Rising Star
Rising Stars are recognized for providing high-quality answers to other users. Rising Stars receive a certificate of achievement and are on the path to becoming Community Leaders.
January 16, 2019

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
Remie Bolte
Contributor
January 16, 2019

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
ofirgu@bezeqint.co.il January 17, 2019

10x

Andy Ukasick
Contributor
August 23, 2019

 

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.

ofir gutmacher October 2, 2019

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
            
         }        
   }
}
Like Andy Ukasick likes this
0 votes
Raul Pelaez _TecnoFor - Marketplace Partner_
Atlassian Partner
April 21, 2021

Our proposal Script:

 

def dest_prj = ["PRJ1","PRJ2"]

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.getProjectObjByKey("COMPMASTER").getId()
def projectComponentManager = ComponentAccessor.getProjectComponentManager()
Collection<ProjectComponent> componentList = projectComponentManager.findAllForProject(projectSource) as Collection<ProjectComponent>

def i = 0
while ( i < dest_prj.size() ) {
def projectDestinationList = projectManager.getProjectObjByKey(dest_prj[i])
def project = projectDestinationList

if (componentList != null) {
for (component in componentList) {
//log.debug("Component " + component.getName() )
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
}
}
}
i++
}

0 votes
ofirgu@bezeqint.co.il January 16, 2019

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

0 votes
Remie Bolte
Contributor
January 15, 2019

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

ofirgu@bezeqint.co.il January 16, 2019

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

Remie Bolte
Contributor
January 16, 2019

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())
Salim Hammar
Contributor
February 9, 2022

Hi @Raul Pelaez _TecnoFor - Marketplace Partner_  and @Remie Bolte 

I have a error when i create the component 

 

Error : 

 

2022-02-09 16:25:44,064 ERROR [runner.AbstractScriptListener]: *************************************************************************************
2022-02-09 16:25:44,064 ERROR [runner.AbstractScriptListener]: Script function failed on event: com.atlassian.jira.event.bc.project.component.ProjectComponentCreatedEvent, file: null
java.lang.NullPointerException: Cannot invoke method getId() on null object
at Script29.run(Script29.groovy:24)

 

You can help me ?

Raul Pelaez _TecnoFor - Marketplace Partner_
Atlassian Partner
February 9, 2022

Hello @Salim Hammar ,

Probably the error is the initial parameters because the destination project is an array of keys of projects.

The source project initial param is a String with the key of the project (is different than the other)

Best regards!

Salim Hammar
Contributor
February 9, 2022

Hi @Raul Pelaez _TecnoFor - Marketplace Partner_ 

look the script : 

script_sync.png

 

and tell where is the error please ?

Raul Pelaez _TecnoFor - Marketplace Partner_
Atlassian Partner
February 9, 2022

change the first line by this:

def dest_prj = ["TS"]

That's all!

Salim Hammar
Contributor
February 9, 2022

Yes good

Thank you very match 

Salim Hammar
Contributor
February 10, 2022

Hi @Raul Pelaez _TecnoFor - Marketplace Partner_ 

But i see than i create a issue in the project "dest_prj" the "source_prj" in the column issues is not updated ,because i'm create a issue in the project "dest_prj" for the components who are in the project "source_prj" it's possible the synchronise the numer issue created in the differents project bound in the script 

It's possible ?

Raul Pelaez _TecnoFor - Marketplace Partner_
Atlassian Partner
February 10, 2022

Hello Salim, I cannot understand the question sorry, but seems another topic different of the main of this ticket. Please raise another Community question and I will try to answer it if you mention me :)

Best regards

Salim Hammar
Contributor
February 10, 2022

Hi @Raul Pelaez _TecnoFor - Marketplace Partner_ 

Actually the scirpt he syncronise the components ok

And i would like when i create issue in the project "dest_prj" in the project with component "compo1" and in  "source_prj" in the components "compo1" the number issues does not update.

 

compo.png

it's possible to syncronise the number the issue created in the project "dest_prj" and he updated in the project "source_prj" ?

Salim Hammar
Contributor
February 10, 2022

Hi @Raul Pelaez _TecnoFor - Marketplace Partner_ 

And i note when i modify a name for component , he create a component and a component are modify he stays 

you have solution for this issue ?

Raul Pelaez _TecnoFor - Marketplace Partner_
Atlassian Partner
February 10, 2022

Hello @Salim Hammar 

The script you see is only a little part of a sync of Components, as you see it needs more code if you do modifications in names of components or if you delete a component, etc...

Regards

Salim Hammar
Contributor
February 10, 2022

Hi @Raul Pelaez _TecnoFor - Marketplace Partner_ 

Okay im understand and you know the code added in this script because im find but i don't find a fuction or script for add in the script ?? you have idea ??

Regards

Thanks in advance

Salim Hammar
Contributor
February 11, 2022

Hi @Raul Pelaez _TecnoFor - Marketplace Partner_ 

 

I try do modfify the script for add a function for update the name components

Look this script , have you idea for error ??

 

SCRIPT8COMPO.png

Thanks in advance 

Raul Pelaez _TecnoFor - Marketplace Partner_
Atlassian Partner
February 11, 2022

Hello Salim,
Here you can see an example to obtain the type of event:
https://community.atlassian.com/t5/Marketplace-Apps-Integrations/Jira-Custom-Listener-with-event-ProjectComponent/qaq-p/1047574

Because you must listen events of different types: ProjectComponentUpdatedEvent and ProjectComponentCreatedEvent in your case
Hope this info helps
Best regards :)

Salim Hammar
Contributor
February 11, 2022

Hi @Raul Pelaez _TecnoFor - Marketplace Partner_ , thank you for your answer

I try but , my script he don't work 

Capture d’écran 2022-02-11 224716.png

 

You can help me ?

 

Thanks in advance

Salim Hammar
Contributor
February 15, 2022

Hi @Raul Pelaez _TecnoFor - Marketplace Partner_  

I have a problem , because 

for the variable  "def dest_prj = ["TS","TK"] " i would like insert many project key but for this way is not working ?

You have idea ??

Thanks in advance

Suggest an answer

Log in or Sign up to answer