Forums

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

How to update name components

Salim Hammar
Contributor
February 10, 2022

Hi everyoen

 

This script he dupplicate the components between differents projects : 

script_sync.png

But i have a problem when i modify a component in the "source_prj" in the "dest_prj" he create a component with the name changed and i would like when i change the name for component this name he updated for the project linked in the project for example in this script it's project key "TS" ??

You have a idea for resolve this issue ??

 

Thanks in advance

3 answers

0 votes
Salim Hammar
Contributor
February 21, 2022

Hi @PD Sheehan  

I need very help i don't can a update the lead or description or assignee , you can help me please ?

 

Thanks in advance

0 votes
Salim Hammar
Contributor
February 18, 2022

Hi @PD Sheehan 

I have 2 problems :

- When i change the lead for the component i goes on a loop 

and

- When i change the lead for the component after when i go to acces for the pages components , the page not working and for all project it's same (don't acces a page the component)

 

You have idea ?

0 votes
PD Sheehan
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.
February 10, 2022

Let me see if I understand ... you want to update the name in the source project and have the component matching the old name to be updated to the new name in all the destination projects?

Before I understood that, I reviewed your script and thought it could be made a little easier to read:

def destProjectKeys = ["TS"]
def source_prj = "TN"
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.project.AssigneeTypes
import com.atlassian.jira.project.Project
import com.atlassian.jira.bc.project.component.ProjectComponent

def projectManager = ComponentAccessor.projectManager
def projectComponentManager = ComponentAccessor.projectComponentManager
def projectSource = projectManager.getProjectObjByKey(source_prj)
def componentList = projectComponentManager.findAllForProject(projectSource.id) ?: [] as Collection<ProjectComponent>
destProjectKeys.each{deskProjectKey->
def project =projectManager.getProjectObjByKey(deskProjectKey)
componentList.each{ component->
def destComponent = projectComponentManager.findByComponentName(project.id, component.name)
if(!destComponent){
destComponent = projectComponentManager.create(component.name, component.description, component.lead, AssigneeTypes.COMPONENT_LEAD, project.id)
}
}
}

But if you want to propagate the changes to the component name, you will need an event listener script that listens for the ProjectComponentUpdatedEvent on the source project.

The listener would look something like this:

def destProjectKeys = ["TS"]

import com.atlassian.jira.bc.project.component.MutableProjectComponent
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.bc.project.component.ProjectComponentUpdatedEvent
import com.atlassian.jira.project.AssigneeTypes
import com.atlassian.jira.project.Project
import com.atlassian.jira.bc.project.component.ProjectComponent

event = event as ProjectComponentUpdatedEvent //this is here to help static type checking

def projectManager = ComponentAccessor.projectManager
def projectComponentManager = ComponentAccessor.projectComponentManager
def component = event.projectComponent
def oldComponentName = event.oldProjectComponent.name
destProjectKeys.each{deskProjectKey->
def project =projectManager.getProjectObjByKey(deskProjectKey)
def destComponent = projectComponentManager.findByComponentName(project.id, oldComponentName)
if(!destComponent){
projectComponentManager.create(component.name, component.description, component.componentLead.key, AssigneeTypes.COMPONENT_LEAD, project.id)
} else {
destComponent = MutableProjectComponent.copy(destComponent)
destComponent.with{
name = component.name
description = component.description
lead = component.lead
assigneeType = AssigneeTypes.COMPONENT_LEAD //or use component.assigneeType
}
projectComponentManager.update(destComponent)
}
}

This will sync all attributes of a component whenever the source project components are modified.

If you make this same script also listen for ProjectComponentCreatedEvent then it can serve both purposes. Create/update components in your destination project(s). Since this fires for each new component, you don't need to get all the components from the source project and iterate through them.

Salim Hammar
Contributor
February 10, 2022

Hi @PD Sheehan 

Yes you are understand me but i don't find the fight script for update the name component , you have idea ??

PD Sheehan
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.
February 10, 2022

Please review the second script I included in my response, it should suit your need.

Salim Hammar
Contributor
February 11, 2022

Hi @PD Sheehan 

 

I do this : 

SCRIPT8COMPO.png

 

But he don't working ?? you have idea ?

Thanks in advance

PD Sheehan
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.
February 11, 2022

This will only work without the even listener context. You need to have access to the "oldComponent" from the source project to be able to identify which component in the destination project needs to be renamed.

Salim Hammar
Contributor
February 11, 2022

Yes, but i  don't find for the function which allows me do this 

You have idea ??

Salim Hammar
Contributor
February 14, 2022

Hi @PD Sheehan 

 

I do for this but i have a problem you can help me ??

 

script_okay.png

 

Thanks in advance

PD Sheehan
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.
February 14, 2022

Try like this:

def dest_prj = ["TS"]
def source_prj = 'TH'
import com.atlassian.jira.bc.project.component.MutableProjectComponent
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.bc.project.component.ProjectComponentCreatedEvent
import com.atlassian.jira.event.bc.project.component.ProjectComponentUpdatedEvent
import com.atlassian.jira.project.AssigneeTypes
import com.atlassian.jira.project.Project
import com.atlassian.jira.bc.project.component.ProjectComponent

def projectManager = ComponentAccessor.projectManager
def projectComponentManager = ComponentAccessor.projectComponentManager
def sourceProject = projectManager.getProjectByCurrentKey(source_prj)
def sourceComponents = projectComponentManager.findAllForProject(sourceProject.id)

if(event instanceof ProjectComponentCreatedEvent){
dest_prj.each{
def project = projectManager.getProjectObjByKey(it)
sourceComponents.each{component->
def checkComponent = projectComponentManager.findByComponentName(project.id, component.name)
if(!component){
def newComponent = projectComponentManager.create(component.name, component.description, component.lead, 1, project.id)
} else {
log.error "Can't create a copy of $component.name in $it project. A component with that name alreay exist."
}
}
}
}
if(event instanceof ProjectComponentUpdatedEvent) {
def component = event.projectComponent
def oldComponentName = event.oldProjectComponent.name
destProjectKeys.each { deskProjectKey ->
def project = projectManager.getProjectObjByKey(deskProjectKey)

def destComponent = projectComponentManager.findByComponentName(project.id, oldComponentName)
if (destComponent) {
destComponent = MutableProjectComponent.copy(destComponent)
destComponent.with {
name = component.name
description = component.description
lead = component.lead
assigneeType = AssigneeTypes.COMPONENT_LEAD //or use component.assigneeType
}
projectComponentManager.update(destComponent)
} else {
log.warn "No component found in $deskProjectKey with name $oldComponentName. Can't update it."
}
}
}
Salim Hammar
Contributor
February 14, 2022

Hi  @PD Sheehan 

 

Thanks for your answer but i paste  but i have the errors : 

problem.png

 

Thanks in advance

PD Sheehan
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.
February 14, 2022

Not all static type-checking errors are necessarily bad. When event can be many different type, the editor doesn't know what type to consider.

You can cast "event" accordingly:

def component = (event as ProjectComponentUpdatedEvent).projectComponent
def oldComponentName = (event as ProjectComponentUpdatedEvent).oldProjectComponent.name

 2022-02-14 13_13_28-Listeners.png

Salim Hammar
Contributor
February 14, 2022

Hi @PD Sheehan 

Thanks , but i have 2 errors when i add the "event": 

pro.png

Thanks in advance

PD Sheehan
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.
February 14, 2022

Remove those 2 lines, they are duplicates of line 32 and 33.

Salim Hammar
Contributor
February 14, 2022

Okay thanks @PD Sheehan 

 

i did it differently and it works and i find for do delete component you have a idea ?

 

Thanks in advance

Salim Hammar
Contributor
February 15, 2022

Hi @PD Sheehan 

 

I don't understand for this example : https://www.tabnine.com/code/java/methods/com.atlassian.jira.bc.project.component.DefaultProjectComponentService/delete

for do a function delete ??

 

You can help me ?

Thnaks in advance 

PD Sheehan
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.
February 15, 2022

I've never user ProjectComponentService. 

But it looks like it can only be used to remove a component from issues.

Are you trying to delete a project component from a project?

Salim Hammar
Contributor
February 15, 2022

Yes i try a delete component in the project A but in the project B the component no has deleted

 

@PD Sheehan 

PD Sheehan
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.
February 15, 2022

Sorry, never tried deleting components programmatically before.

You can try to add this to your listener

if (event instanceof ProjectComponentDeletedEvent) {
event = event as ProjectComponentDeletedEvent
dest_prj.each { String deskProjectKey ->
def project = projectManager.getProjectObjByKey(deskProjectKey)
def destComponent = projectComponentManager.findByComponentName(project.id, event.projectComponent.name)
if (destComponent) {
projectComponentManager.delete(destComponent.id)
} else {
log.warn "No component found in $deskProjectKey with name $event.projectComponent.name. Can't delete it."
}
}
}
Salim Hammar
Contributor
February 15, 2022

Okay, thanks @PD Sheehan   i go to try the script 

But i have a question in my script 

i have a variable "dest_prj" in this variable i insert the project key 

for this :  "def dest_prj = ["TS"]" but in this varibale i would like insert many projects key and i try for "def dest_prj = ["TS","TD"]" bur it's not working 

you have idea ??

 

Thanks in advance

PD Sheehan
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.
February 15, 2022

That should work, that was the whole point to changing

def dest_proj = "TS"

to

def dest_proj = ["TS"]

This question about updating a component name sure turned into something ...

Here is a completely rewritten script that will allow you to sync components from a project (identified in the script listener configuration) with multiple destination projects.

I made some adjustments to remove duplicate code. Now instead of iterating through projects in each event block, it put the project iterator on the outside.

I also added several logging messages so you can see perhaps where it might go wrong.

 

def dest_prj = ['TS', 'TD']
import com.atlassian.jira.bc.project.component.MutableProjectComponent
import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.event.bc.project.component.ProjectComponentCreatedEvent
import com.atlassian.jira.event.bc.project.component.ProjectComponentDeletedEvent
import com.atlassian.jira.event.bc.project.component.ProjectComponentUpdatedEvent
import com.atlassian.jira.project.AssigneeTypes
import com.atlassian.jira.project.Project
import com.atlassian.jira.bc.project.component.ProjectComponent

def projectManager = ComponentAccessor.projectManager
def projectComponentManager = ComponentAccessor.projectComponentManager

ProjectComponent component = event.projectComponent
log.info "Deletected ${event.getClass()} for $component.name ($component.id)"
dest_prj.each { String destProjectKey ->
log.info "Getting project object from dest_prj: $destProjectKey"
def project = projectManager.getProjectObjByKey(destProjectKey)
log.info "Project object found: $project"
def destComponent = projectComponentManager.findByComponentName(project.id, component.name)
log.info "Attempted to identify matching destination component in $project using name=$component.name : $destComponent"
if (event instanceof ProjectComponentCreatedEvent) {
if (!destComponent) {
log.info "Attempting to create $component.name into $project"
projectComponentManager.create(component.name, component.description, component.lead, 1, project.id)
} else {
log.error "Can't create a copy of $component.name in $destProjectKey project. A component with that name alreay exist."
}
}
if (event instanceof ProjectComponentUpdatedEvent) {
def oldComponent = (event as ProjectComponentUpdatedEvent).oldProjectComponent as ProjectComponent
if (event instanceof ProjectComponentUpdatedEvent) {
destComponent = projectComponentManager.findByComponentName(project.id, oldComponent.name as String)
log.info "Attempted to identify matching destination component in $project using name=$oldComponent.name : $destComponent"
}
if (destComponent) {
log.info "Attempting to update $destComponent.name ($destComponent.id) from $project project using data from $component.name ($component.id)"
destComponent = MutableProjectComponent.copy(destComponent)
destComponent.with {
name = component.name
description = component.description
lead = component.lead
assigneeType = AssigneeTypes.COMPONENT_LEAD //or use component.assigneeType
}
projectComponentManager.update(destComponent)
} else {
log.warn "No component found in $destProjectKey with name $oldComponent.name. Can't perform an update."
}
}
if (event instanceof ProjectComponentDeletedEvent) {
log.info "Detected Component Deletion event for $component.name"
if (destComponent) {
log.info "Attempting to detelete $destComponent.name ($destComponent.id) from $project project"
projectComponentManager.delete(destComponent.id)
} else {
log.warn "No component found in $destProjectKey with name $component.name. Can't delete it."
}
}
}
Salim Hammar
Contributor
February 15, 2022

Hi @PD Sheehan 

I'm insert the script but i have a error

Capture d’écran 2022-02-15 232409.png

PD Sheehan
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.
February 15, 2022

You will have no errors if you select the correct events in the listener

2022-02-15 14_34_37-Listeners.png

Salim Hammar
Contributor
February 15, 2022

Okay thanks you , but i have another error when i paste the script for Deleted Event 

deleted.png

PD Sheehan
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.
February 15, 2022

That error is not critical. The script will still work.

If you insist on getting rid of the error, you can add

ProjectComponent component = event.projectComponent

Then in the findByComponentName, use component.name instead.

Salim Hammar
Contributor
February 15, 2022

Excuse me @PD Sheehan  but is not working i don't can add this script

hghggh.png

 

Thanks in advance

Salim Hammar
Contributor
February 15, 2022

Hi @PD Sheehan 

 

Thank you very match

now the script work Perfectly

 

And i would like know and learn for programming in grooy  have you a video youtube to advise me or free training for to learn and understand this language please ?

PD Sheehan
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.
February 15, 2022

There isn't really a one-stop-shop place to learn everything if you have no prior coding knowledge.

I learned with trial and error and much googling.

Salim Hammar
Contributor
February 15, 2022

Thank you very match for your help.

Salim Hammar
Contributor
February 17, 2022

Hi @PD Sheehan 

 

I come back for you because i have a problem 

 

when i create a component in the project source 

1.png

 

in the projet destination in the column default assignee is not updated

2.png

 

You have idea ?

Thanks in advance

Salim Hammar
Contributor
February 17, 2022

and it's possible the create component only the projet source no since for project destination  ? @PD Sheehan 

Salim Hammar
Contributor
February 17, 2022

Because i don't have find the example ?? @PD Sheehan 

Suggest an answer

Log in or Sign up to answer