How to create projects in post-function with API from Scriptrunner built-in function "copy project"?

Johannes Heger (CD) June 27, 2019

Currently the Jira admin (me) creates new projects from a template project with Scriptrunner built-in function "copy project".

I like to give collegues the ability to create projects as well, but in a post-function. These collegues don't have Jira admin privelliges.

The project name and the project key will be in custom fields. The template project key should be configured in the post-function. The post-function has to run with Jira admin privileges.

Is there any grovvy script out there to accomplish this?

Best regards, Johannes

1 answer

0 votes
Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
July 2, 2019

You can call the built-in script from a post function custom script. But you should validate it first in a validator custom script in case any of the input fail.

So something like this in validator:

import com.onresolve.scriptrunner.canned.jira.admin.CopyProject
import com.opensymphony.workflow.InvalidInputException

def sourceKey = ''
def targetKey = ''
def targetName = ''

def
copyProject = new CopyProject()
def inputs = [
(CopyProject.FIELD_SOURCE_PROJECT) : sourceKey,
(CopyProject.FIELD_TARGET_PROJECT) : targetKey,
(CopyProject.FIELD_TARGET_PROJECT_NAME) : targetName,
(CopyProject.FIELD_COPY_VERSIONS) : false,
(CopyProject.FIELD_COPY_COMPONENTS) : false,
(CopyProject.FIELD_COPY_ISSUES) : false,
(CopyProject.FIELD_COPY_DASH_AND_FILTERS): false
]

def errorCollection = copyProject.doValidate(inputs, false)
if (errorCollection.hasAnyErrors()) {
log.warn("CopyProject input invalid: $errorCollection")
throw new InvalidInputException(errorCollection)
}

And this in the post function

import com.onresolve.scriptrunner.canned.jira.admin.CopyProject
import com.onresolve.scriptrunner.runner.util.UserMessageUtil
import com.atlassian.jira.component.ComponentAccessor

def adminUser = 'admin'
def sourceKey = ''
def targetKey = ''
def targetName = ''

def
copyProject = new CopyProject()
def inputs = [
(CopyProject.FIELD_SOURCE_PROJECT) : sourceKey,
(CopyProject.FIELD_TARGET_PROJECT) : targetKey,
(CopyProject.FIELD_TARGET_PROJECT_NAME) : targetName,
(CopyProject.FIELD_COPY_VERSIONS) : false,
(CopyProject.FIELD_COPY_COMPONENTS) : false,
(CopyProject.FIELD_COPY_ISSUES) : false,
(CopyProject.FIELD_COPY_DASH_AND_FILTERS): false
]


ComponentAccessor.getJiraAuthenticationContext().setLoggedInUser(ComponentAccessor.userManager.getUserByName(adminUser))
def cpOutput = copyProject.doScript(inputs)
def newProject = ComponentAccessor.projectManager.getProjectObjByKeyIgnoreCase(targetKey)
if (!newProject) {
UserMessageUtil.error("There was an error creating your project. Contact your Jira Admin")
} else {
UserMessageUtil.success("$targetKey project created successfully")
}

 You'll have to either hard code or fetch from custom fields the values for sourceKey, targetKey  and targetName. Also, you may want to set other copy options for version, components etc.

Fidelidade JIRA Admin August 3, 2022

Hi Peter-Dave,

As I have several types of projects in my instance, I created several templates.
So I created a project in Jira, with a Kanban board and a three-state workflow (Backlog, Rifinement, Done).

From this project, in the transition from the "Rifinement" to "Done" state, I intend to run the script to clone one of the templates.
I'm trying to use the script you posted here, but I see errors and as I'm not very good at code, I'm having trouble correcting them.
What am I doing wrong?
Can you help me?
It is very important to me because I create a lot of projects manually.
Thank you so much
Emanuel Lima

Post Functions.JPGValidator.JPG

Fidelidade JIRA Admin August 3, 2022

Hi Peter-Dave,
Here, maybe you can better understand what is happening.

Thank you so much
Emanuel Lima

 

Capturar_02.JPGCapturar_01.JPG

Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
August 3, 2022

This is probably partially caused by new version of scriptrunner.

Try the following:

import com.onresolve.scriptrunner.canned.jira.admin.CopyProject
import com.opensymphony.workflow.InvalidInputException
import com.onresolve.scriptrunner.runner.ScriptRunnerImpl

def sourceKey = ''
def targetKey = ''
def targetName = ''

def copyProject = ScriptRunnerImpl.scriptRunner.createBean(CopyProject)
def inputs = [
(CopyProject.FIELD_SOURCE_PROJECT) : sourceKey,
(CopyProject.FIELD_TARGET_PROJECT) : targetKey,
(CopyProject.FIELD_TARGET_PROJECT_NAME) : targetName,
(CopyProject.FIELD_COPY_VERSIONS) : false,
(CopyProject.FIELD_COPY_COMPONENTS) : false,
(CopyProject.FIELD_COPY_ISSUES) : false,
(CopyProject.FIELD_COPY_DASH_AND_FILTERS): false
]

def errorCollection = copyProject.doValidate(inputs as Map<String, String>, false)
if (errorCollection.hasAnyErrors()) {
log.warn("CopyProject input invalid: $errorCollection")
throw new InvalidInputException(errorCollection)
}

And

import com.onresolve.scriptrunner.canned.jira.admin.CopyProject
import com.onresolve.scriptrunner.runner.ScriptRunnerImpl
import com.onresolve.scriptrunner.runner.util.UserMessageUtil
import com.atlassian.jira.component.ComponentAccessor

def adminUser = 'admin'
def sourceKey = ''
def targetKey = ''
def targetName = ''

def copyProject = ScriptRunnerImpl.scriptRunner.createBean(CopyProject)
def inputs = [
(CopyProject.FIELD_SOURCE_PROJECT) : sourceKey,
(CopyProject.FIELD_TARGET_PROJECT) : targetKey,
(CopyProject.FIELD_TARGET_PROJECT_NAME) : targetName,
(CopyProject.FIELD_COPY_VERSIONS) : false,
(CopyProject.FIELD_COPY_COMPONENTS) : false,
(CopyProject.FIELD_COPY_ISSUES) : false,
(CopyProject.FIELD_COPY_DASH_AND_FILTERS): false
]


ComponentAccessor.getJiraAuthenticationContext().setLoggedInUser(ComponentAccessor.userManager.getUserByName(adminUser))
def cpOutput = copyProject.doScript(inputs)
def newProject = ComponentAccessor.projectManager.getProjectObjByKeyIgnoreCase(targetKey)
if (!newProject) {
UserMessageUtil.error("There was an error creating your project. Contact your Jira Admin")
} else {
UserMessageUtil.success("$targetKey project created successfully")
}
Fidelidade JIRA Admin August 4, 2022

Hi Peter-Dave,


Thanks for your quick turnaround.
I made the changes you indicated and I no longer have errors in the Validator. But in Post-Function I have these errors:
What will be missing?
Thanks again for the help.

Capturar_06.JPGCapturar_05.JPGCapturar_04.JPGCapturar_03.JPG
Emanuel

Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
August 4, 2022

I can't see the full script, but the second error reads "the [adminUser] variable is undeclared"

Are you sure you have the following line above the start of the screenshot?

def adminUser = 'admin' //or other user name with permission to create projects

The other errors can probably be safely ignored. Some errors are just warning to tell you that the editor/compiler isn't sure if that will work, but the script may run fine at runtime

If you really want them to go away, you can do the following:

def cpOutput = copyProject.doScript(inputs as Map<String, Object>)

But I must warn you of something I encountered recently. If you have multiple postfunctions, using setLoggedInUser(adminUser) in the first one, will cause all subsequent post functions to to be executed as that user.

So it's better to reset the user after the copy project action.

//store the current user before changing using to proviledged user
def jiraAuthContext =ComponentAccessor.jiraAuthenticationContext
def curretnUser = jiraAuthContext.loggedInuser
jiraAuthContext.loggedInUser = ComponentAccessor.userManager.getUserByName(adminUser)

//execute the copy action
def
cpOutput = copyProject.doScript(inputs)

//change the effective user back to the stored current useer
jiraAuthContext.loggedInUser = currentUser

//continue with the rest of the script
def newProject = ComponentAccessor.projectManager.getProjectObjByKeyIgnoreCase(targetKey)
if (!newProject) {
UserMessageUtil.error("There was an error creating your project. Contact your Jira Admin")
} else {
UserMessageUtil.success("$targetKey project created successfully")
}
Fidelidade JIRA Admin August 8, 2022

Hi Peter-Dave,

Thanks again for the feedback,
I don't see where to make the changes you suggested. So I put all my code here:

"Post Functions" Code

 

import com.onresolve.scriptrunner.canned.jira.admin.CopyProject
import com.onresolve.scriptrunner.runner.util.UserMessageUtil
import com.atlassian.jira.component.ComponentAccessor

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.IssueFactory
import com.atlassian.jira.project.ProjectManager
import groovy.transform.Field

def adminUser = 'admin'
def sourceKey = 'TNT'
def targetKey = 'COPYTNT'
def targetName = 'Team Network Template 01'

def copyProject = new CopyProject()
def inputs = [
    (CopyProject.FIELD_SOURCE_PROJECT) : sourceKey,
    (CopyProject.FIELD_TARGET_PROJECT) : targetKey,
    (CopyProject.FIELD_TARGET_PROJECT_NAME) : targetName,
    (CopyProject.FIELD_COPY_VERSIONS) : false,
    (CopyProject.FIELD_COPY_COMPONENTS) : false,
    (CopyProject.FIELD_COPY_ISSUES) : false,
    (CopyProject.FIELD_COPY_DASH_AND_FILTERS): false
]


ComponentAccessor.getJiraAuthenticationContext().setLoggedInUser(ComponentAccessor.userManager.getUserByName(adminUser))
def cpOutput = copyProject.doScript(inputs)
def newProject = ComponentAccessor.projectManager.getProjectObjByKeyIgnoreCase(targetKey)
if (!newProject) {
   UserMessageUtil.error("There was an error creating your project. Contact your Jira Admin")
} else {
   UserMessageUtil.success("$targetKey project created successfully")
}
"Validators" Code:
import com.onresolve.scriptrunner.canned.jira.admin.CopyProject
import com.opensymphony.workflow.InvalidInputException

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.IssueFactory
import com.atlassian.jira.project.ProjectManager
import groovy.transform.Field

def sourceKey = 'TNT'
def targetKey = 'COPYTNT'
def targetName = 'Team Network Template 01'

def copyProject = new CopyProject()
def inputs = [
    (CopyProject.FIELD_SOURCE_PROJECT)       : sourceKey,
    (CopyProject.FIELD_TARGET_PROJECT)       : targetKey,
    (CopyProject.FIELD_TARGET_PROJECT_NAME)  : targetName,
    (CopyProject.FIELD_COPY_VERSIONS)        : false,
    (CopyProject.FIELD_COPY_COMPONENTS)      : false,
    (CopyProject.FIELD_COPY_ISSUES)          : false,
    (CopyProject.FIELD_COPY_DASH_AND_FILTERS): false
]

def errorCollection = copyProject.doValidate(inputs, false)
if (errorCollection.hasAnyErrors()) {
    log.warn("CopyProject input invalid: $errorCollection")
    throw new InvalidInputException(errorCollection)
}
Thank you very much,
Emanuel
Fidelidade JIRA Admin August 12, 2022

Hi Peter-Dave,

This is how I have my script, where should I implement the changes you indicated?

Thank you,

Emanuel

Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
August 15, 2022

Here is an updated version of your PostFunction script:

import com.onresolve.scriptrunner.canned.jira.admin.CopyProject
import com.onresolve.scriptrunner.runner.ScriptRunnerImpl
import com.onresolve.scriptrunner.runner.util.UserMessageUtil
import com.atlassian.jira.component.ComponentAccessor

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.IssueFactory
import com.atlassian.jira.project.ProjectManager
import groovy.transform.Field

def adminUserName = 'admin'
def sourceKey = 'TNT'
def targetKey = 'COPYTNT'
def targetName = 'Team Network Template 01'

def copyProject = ScriptRunnerImpl.scriptRunner.createBean(CopyProject)
def inputs = [
(CopyProject.FIELD_SOURCE_PROJECT) : sourceKey,
(CopyProject.FIELD_TARGET_PROJECT) : targetKey,
(CopyProject.FIELD_TARGET_PROJECT_NAME) : targetName,
(CopyProject.FIELD_COPY_VERSIONS) : false,
(CopyProject.FIELD_COPY_COMPONENTS) : false,
(CopyProject.FIELD_COPY_ISSUES) : false,
(CopyProject.FIELD_COPY_DASH_AND_FILTERS): false
]

def currentUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser
def adminUser = ComponentAccessor.userManager.getUserByName(adminUserName)
ComponentAccessor.jiraAuthenticationContext.loggedInUser = adminUser
def cpOutput = copyProject.doScript(inputs)
ComponentAccessor.jiraAuthenticationContext.loggedInUser = currentUser
def newProject = ComponentAccessor.projectManager.getProjectObjByKeyIgnoreCase(targetKey)
if (!newProject) {
UserMessageUtil.error("There was an error creating your project. Contact your Jira Admin")
} else {
UserMessageUtil.success("$targetKey project created successfully")
}

And a full version of your validator script

import com.onresolve.scriptrunner.canned.jira.admin.CopyProject
import com.onresolve.scriptrunner.runner.ScriptRunnerImpl
import com.opensymphony.workflow.InvalidInputException

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.IssueFactory
import com.atlassian.jira.project.ProjectManager
import groovy.transform.Field

def sourceKey = 'TNT'
def targetKey = 'COPYTNT'
def targetName = 'Team Network Template 01'

def copyProject = ScriptRunnerImpl.scriptRunner.createBean(CopyProject)
def inputs = [
(CopyProject.FIELD_SOURCE_PROJECT) : sourceKey,
(CopyProject.FIELD_TARGET_PROJECT) : targetKey,
(CopyProject.FIELD_TARGET_PROJECT_NAME) : targetName,
(CopyProject.FIELD_COPY_VERSIONS) : false,
(CopyProject.FIELD_COPY_COMPONENTS) : false,
(CopyProject.FIELD_COPY_ISSUES) : false,
(CopyProject.FIELD_COPY_DASH_AND_FILTERS): false
]

def errorCollection = copyProject.doValidate(inputs as Map<String, String>, false)
if (errorCollection.hasAnyErrors()) {
log.warn("CopyProject input invalid: $errorCollection")
throw new InvalidInputException(errorCollection)
}
Fidelidade JIRA Admin September 12, 2022

Hi Peter-Dave,
First of all thank you very much for rewriting the code.
I was absent, just now I picked up the topic again.
I copied-past the code, the "Validator" seems to be OK, but the Post Fuction still has an error.
I have attached a screenshot, can you see why this error occurs?


Thank you Dave

Emanuelpostfunction_error.JPG

Fidelidade JIRA Admin September 12, 2022

Hi Dave,

I commented out this line to see what happens,
and ran the script.
However I got this error:

Thank you

Emanuel

run_script_error.JPG

Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
September 12, 2022

Many static type checking error can be ignored. That's just the editor's syntax checking telling you it can't be sure if this will work or not.

Did you try run the code as is without commenting that line out?

You might be able to make the error go away by telling the editor's syntax checking routine what to expect from "inputs

copyProject.doScript(inputs as Map<String, Object>)
Fidelidade JIRA Admin September 28, 2022

Hi,
I made the changes you suggested, I no longer have an error in the code but after running the script, I have this error:

 

-----------------------------------------------------------------------------

2022-09-28 15:39:33,298 ERROR [workflow.AbstractScriptWorkflowFunction]: Workflow script has failed on issue CPBS-4 for user 'admin'. View here: https://devjira.befig.net/secure/admin/workflows/ViewWorkflowTransition.jspa?workflowMode=live&workflowName=Software+Simplified+Workflow+for+Project+CPBS&descriptorTab=postfunctions&workflowTransition=61&highlight=1
java.lang.Exception: Could not create project: Errors: {}
Error Messages: [You must have global administrator rights in order to modify projects.]
at com.onresolve.scriptrunner.canned.jira.admin.CopyProject.doCopyProject(CopyProject.groovy:402)
at com.onresolve.scriptrunner.canned.jira.admin.CopyProject$doCopyProject.callCurrent(Unknown Source)
at com.onresolve.scriptrunner.canned.jira.admin.CopyProject.execute(CopyProject.groovy:369)
at com.onresolve.scriptrunner.canned.jira.admin.CopyProject.execute(CopyProject.groovy)
at com.onresolve.scriptrunner.canned.AbstractCannedScript.doScript(AbstractCannedScript.groovy:81)
at Script40.run(Script40.groovy:31)

----------------------------------------------------------------------------------------------

Fidelidade JIRA Admin September 28, 2022

My code in Post Functions looks like this now:

 

import com.onresolve.scriptrunner.canned.jira.admin.CopyProject import com.onresolve.scriptrunner.runner.ScriptRunnerImpl import com.onresolve.scriptrunner.runner.util.UserMessageUtil import com.atlassian.jira.component.ComponentAccessor import com.atlassian.jira.component.ComponentAccessor import com.atlassian.jira.issue.IssueFactory import com.atlassian.jira.project.ProjectManager import groovy.transform.Field def adminUserName = 'admin' def sourceKey = 'TNT' def targetKey = 'COPYTNT' def targetName = 'Team Network Template 01' def copyProject = ScriptRunnerImpl.scriptRunner.createBean(CopyProject) def inputs = [ (CopyProject.FIELD_SOURCE_PROJECT) : sourceKey, (CopyProject.FIELD_TARGET_PROJECT) : targetKey, (CopyProject.FIELD_TARGET_PROJECT_NAME) : targetName, (CopyProject.FIELD_COPY_VERSIONS) : false, (CopyProject.FIELD_COPY_COMPONENTS) : false, (CopyProject.FIELD_COPY_ISSUES) : false, (CopyProject.FIELD_COPY_DASH_AND_FILTERS): false ] def currentUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser def adminUser = ComponentAccessor.userManager.getUserByName(adminUserName) ComponentAccessor.jiraAuthenticationContext.loggedInUser = adminUser //def cpOutput = copyProject.doScript(inputs) copyProject.doScript(inputs as Map) ComponentAccessor.jiraAuthenticationContext.loggedInUser = currentUser def newProject = ComponentAccessor.projectManager.getProjectObjByKeyIgnoreCase(targetKey) if (!newProject) { UserMessageUtil.error("There was an error creating your project. Contact your Jira Admin") } else { UserMessageUtil.success("$targetKey project created successfully") }

Fidelidade JIRA Admin September 28, 2022

Post Fuction CODE.JPG

Fidelidade JIRA Admin September 28, 2022

Hi Peter,

Do you have time for a meeting to help me with this topic?

I think it would be easier for you to help me that way.

Thank you

BR

Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
September 28, 2022

That error is telling me that your "admin" user possibly doesn't have global admin permission. Make sure you supply an active user with the global admin permission in line 11.

I don't work for either Atlassian or Adaptavist. So I'm not really in a position to provide more direct help. Answering questions here is not part of my job. I do this strictly on a voluntary basis.

Fidelidade JIRA Admin September 29, 2022

Hi Dave,

How are you?

I have global permission in Jira. I'm an application administrator, and I've been checking.

I know you're not from atlassian, I appreciate all the help and support you've given me. I just really wanted to get over this issue.
I'll keep trying to figure out where I'm going wrong, and why the script doesn't work.
If you have another solution please let me know. And if I manage to get past this issue I will give you feedback.

Thank you so much

BR

Emanuel

Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
September 29, 2022

It's not about your own personal permissions.

def adminUserName = 'admin'
def currentUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser
def adminUser = ComponentAccessor.userManager.getUserByName(adminUserName)
ComponentAccessor.jiraAuthenticationContext.loggedInUser = adminUser

These lines will change who the script thinks is currently logged in. It changes to a user with the username 'admin'.

And after the execution, it changes back to the current user.

This will allow non-admins to use the workflow to trigger a task reserved to admins.

Try changing "def adminUserName = 'admin'" to another user such as yourself. If that works, then examine the admin user permission and status carefully. Or create a brand new user. Something like "Automation Project Creator".

Fidelidade JIRA Admin October 10, 2022

Hi Dave,

As you indicated, I used my user administrator(jiraadmin), and I replacd it as shown below, but the script still does not generate projects:

 

def adminUserName = 'jiraadmin'
def sourceKey = 'TNT'
def targetKey = 'COPYTNT'
def targetName = 'Team Network Template 01'
I also used my own user, the result is always the same:
def adminUserName = 'emanuel.lima@altran.com'
def sourceKey = 'TNT' def targetKey = 'COPYTNT'
def targetName = 'Team Network Template 01'

 

Thank you

BR

Emanuel

Fidelidade JIRA Admin April 28, 2023

Hi Peter,
SHow are you?


Look I still need help with this topic.
My code doesn't work even with the changes you suggested.
Is there any way you can, from the code that I put here, rewrite it so that it works please?

Thank you very much
Emanuel

Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
April 28, 2023

Can you post your full script again? Not as images, please post as text with and correctly formatted as "Code Block". Make sure all the carriage returns are correct (sometimes, in copying code to the rich text in the community, some lines get smooshed together).

Also post the detailed logs that get posted to the post function after the script runs.

Then I can try to help.

Fidelidade JIRA Admin July 3, 2023

Hi Dave,

First of all I apologize for my late reply.

 

This is the workflow I created.
In the transition "Done" I should run my script, and generate a copy of my template.

wf_copy_project.JPG

 

This is my code that still doesn't work:

import com.onresolve.scriptrunner.canned.jira.admin.CopyProject
import com.onresolve.scriptrunner.runner.ScriptRunnerImpl
import com.onresolve.scriptrunner.runner.util.UserMessageUtil
import com.atlassian.jira.component.ComponentAccessor

import com.atlassian.jira.component.ComponentAccessor
import com.atlassian.jira.issue.IssueFactory
import com.atlassian.jira.project.ProjectManager
import groovy.transform.Field

def adminUserName = 'emanuel.lima@altran.com'
def sourceKey = 'TNT'
def targetKey = 'COPYTNT'
def targetName = 'Team Network Template 01'

def copyProject = ScriptRunnerImpl.scriptRunner.createBean(CopyProject)
def inputs = [


           (CopyProject.FIELD_SOURCE_PROJECT) : sourceKey,
           (CopyProject.FIELD_TARGET_PROJECT) : targetKey,
           (CopyProject.FIELD_TARGET_PROJECT_NAME) : targetName,
           (CopyProject.FIELD_COPY_VERSIONS) : false,
           (CopyProject.FIELD_COPY_COMPONENTS) : false,
           (CopyProject.FIELD_COPY_ISSUES) : false,
           (CopyProject.FIELD_COPY_DASH_AND_FILTERS): false


]

def currentUser = ComponentAccessor.jiraAuthenticationContext.loggedInUser
def adminUser = ComponentAccessor.userManager.getUserByName(adminUserName)
ComponentAccessor.jiraAuthenticationContext.loggedInUser = adminUser
//def cpOutput = copyProject.doScript(inputs)
copyProject.doScript(inputs as Map)
ComponentAccessor.jiraAuthenticationContext.loggedInUser = currentUser
def newProject = ComponentAccessor.projectManager.getProjectObjByKeyIgnoreCase(targetKey)
if (!newProject) {
UserMessageUtil.error("There was an error creating your project. Contact your Jira Admin")
} else {
UserMessageUtil.success("$targetKey project created successfully")
}

 

 

Here is the Error Log when I transition "Done" to copy the project:

2023-07-03 16:04:54,562 ERROR [workflow.AbstractScriptWorkflowFunction]: Workflow script has failed on issue CPBS-4 for user 'emanuel.lima@altran.com'. View here: https://devjira.befig.net/secure/admin/workflows/ViewWorkflowTransition.jspa?workflowMode=live&workflowName=Software+Simplified+Workflow+for+Project+CPBS&descriptorTab=postfunctions&workflowTransition=61&highlight=1
java.lang.Exception: Could not create project: Errors: {projectLead=You must specify a valid project lead.}
Error Messages: []
at com.onresolve.scriptrunner.canned.jira.admin.CopyProject.doCopyProject(CopyProject.groovy:410)
at com.onresolve.scriptrunner.canned.jira.admin.CopyProject$doCopyProject.callCurrent(Unknown Source)
at com.onresolve.scriptrunner.canned.jira.admin.CopyProject.execute(CopyProject.groovy:377)
at com.onresolve.scriptrunner.canned.jira.admin.CopyProject.execute(CopyProject.groovy)
at com.onresolve.scriptrunner.canned.AbstractCannedScript.doScript(AbstractCannedScript.groovy:76)
at Script2.run(Script2.groovy:31)

 

Thanks again for your help

BR

Emanuel

Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
July 5, 2023

Maybe check that the source project has a valid project lead.

Fidelidade JIRA Admin July 11, 2023

Hi Dave,

We are almost there.
You were right, the error was really in the Project Lead. I was using a project lead that already didn't have a Jira license.

The script already copies the project, but the problem now is that it doesn't copy the project boards, which is the main objective.
This is the result log, no more errors.
How can I make the script copy the boards of my template and not just the project, as scriptrunner already does?

Thanks a lot Dave,
We are almost there

BR

Emanuel

 

 

 

2023-07-11 15:25:11,376 INFO [CachingProjectKeyStore.cache]: Cache com.atlassian.jira.project.util.CachingProjectKeyStore.cache was flushed
2023-07-11 15:25:11,392 INFO [CachingProjectRoleAndActorStore.projectRoleActors]: Cache com.atlassian.jira.security.roles.CachingProjectRoleAndActorStore.projectRoleActors was flushed
2023-07-11 15:25:11,392 INFO [CachingProjectKeyStore.cache]: Cache com.atlassian.jira.project.util.CachingProjectKeyStore.cache was flushed
2023-07-11 15:25:11,392 INFO [CachingProjectKeyStore.cache]: Cache com.atlassian.jira.project.util.CachingProjectKeyStore.cache was flushed
2023-07-11 15:25:11,392 INFO [CachingProjectManager.cache]: Cache com.atlassian.jira.project.CachingProjectManager.cache was flushed
2023-07-11 15:25:11,642 INFO [CachingProjectKeyStore.cache]: Cache com.atlassian.jira.project.util.CachingProjectKeyStore.cache was flushed
2023-07-11 15:25:11,642 INFO [CachingProjectManager.cache]: Cache com.atlassian.jira.project.CachingProjectManager.cache was flushed
2023-07-11 15:25:11,657 INFO [WorkflowBasedPermissionSchemeManager.projectSchemeCache]: Cache com.atlassian.jira.permission.WorkflowBasedPermissionSchemeManager.projectSchemeCache was flushed
2023-07-11 15:25:11,689 INFO [DefaultNotificationSchemeManager.projectSchemeCache]: Cache com.atlassian.jira.notification.DefaultNotificationSchemeManager.projectSchemeCache was flushed
2023-07-11 15:25:11,704 INFO [DefaultWorkflowSchemeManager.projectSchemeCache]: Cache com.atlassian.jira.workflow.DefaultWorkflowSchemeManager.projectSchemeCache was flushed
2023-07-11 15:25:11,704 INFO [DefaultWorkflowSchemeManager.workflowSchemeEntityCache]: Cache com.atlassian.jira.workflow.DefaultWorkflowSchemeManager.workflowSchemeEntityCache was flushed
2023-07-11 15:25:11,704 INFO [completions.ActionDetailsProvider]: Cache com.adaptavist.hapi.jira.issues.editor.completions.ActionDetailsProvider.com.adaptavist.hapi.jira.issues.editor.completions.ActionDetailsProvider was flushed
2023-07-11 15:25:11,736 INFO [CachedFieldConfigSchemePersister.fieldConfigSchemesById]: Cache com.atlassian.jira.issue.fields.config.persistence.CachedFieldConfigSchemePersister.fieldConfigSchemesById was flushed
2023-07-11 15:25:11,736 INFO [CachedFieldConfigSchemePersister.fieldConfigSchemeIssueTypesBySchemeId]: Cache com.atlassian.jira.issue.fields.config.persistence.CachedFieldConfigSchemePersister.fieldConfigSchemeIssueTypesBySchemeId was flushed
2023-07-11 15:25:12,017 INFO [FieldConfigContextPersisterWorker.configContextsBySchemeId]: Cache com.atlassian.jira.issue.context.persistence.FieldConfigContextPersisterWorker.configContextsBySchemeId was flushed
2023-07-11 15:25:12,158 INFO [CachedFieldConfigSchemePersister.fieldConfigSchemesById]: Cache com.atlassian.jira.issue.fields.config.persistence.CachedFieldConfigSchemePersister.fieldConfigSchemesById was flushed
2023-07-11 15:25:12,158 INFO [CachedFieldConfigSchemePersister.fieldConfigSchemeIssueTypesBySchemeId]: Cache com.atlassian.jira.issue.fields.config.persistence.CachedFieldConfigSchemePersister.fieldConfigSchemeIssueTypesBySchemeId was flushed
2023-07-11 15:25:12,158 INFO [CachedFieldConfigSchemePersister.cacheById]: Cache com.atlassian.jira.issue.fields.config.persistence.CachedFieldConfigSchemePersister.cacheById was flushed
2023-07-11 15:25:12,158 INFO [CachedFieldConfigSchemePersister.cacheByCustomField]: Cache com.atlassian.jira.issue.fields.config.persistence.CachedFieldConfigSchemePersister.cacheByCustomField was flushed
2023-07-11 15:25:12,158 INFO [CachedFieldConfigSchemePersister.cacheByFieldConfig]: Cache com.atlassian.jira.issue.fields.config.persistence.CachedFieldConfigSchemePersister.cacheByFieldConfig was flushed
2023-07-11 15:25:12,158 INFO [DefaultSearchHandlerManager.helperResettableLazyReference]: Cache com.atlassian.jira.issue.search.managers.DefaultSearchHandlerManager.helperResettableLazyReference was flushed
2023-07-11 15:25:12,158 INFO [FieldIndexerManagerImpl.customFieldIndexers]: Cache com.atlassian.jira.issue.index.managers.FieldIndexerManagerImpl.customFieldIndexers was flushed
2023-07-11 15:25:12,158 INFO [FieldIndexerManagerImpl.allIssueIndexers]: Cache com.atlassian.jira.issue.index.managers.FieldIndexerManagerImpl.allIssueIndexers was flushed
2023-07-11 15:25:12,158 INFO [DefaultFieldLayoutManager.fieldSchemeCache]: Cache com.atlassian.jira.issue.fields.layout.field.DefaultFieldLayoutManager.fieldSchemeCache was flushed
2023-07-11 15:25:12,158 INFO [DefaultFieldLayoutManager.fieldConfigurationSchemeCache]: Cache com.atlassian.jira.issue.fields.layout.field.DefaultFieldLayoutManager.fieldConfigurationSchemeCache was flushed
2023-07-11 15:25:12,158 INFO [AbstractFieldLayoutManager.fieldLayoutCache]: Cache com.atlassian.jira.issue.fields.layout.field.AbstractFieldLayoutManager.fieldLayoutCache was flushed
2023-07-11 15:25:12,158 INFO [DefaultColumnLayoutManager.userColumnLayoutCache]: Cache com.atlassian.jira.issue.fields.layout.column.DefaultColumnLayoutManager.userColumnLayoutCache was flushed
2023-07-11 15:25:12,158 INFO [DefaultColumnLayoutManager.filterColumnLayoutCache]: Cache com.atlassian.jira.issue.fields.layout.column.DefaultColumnLayoutManager.filterColumnLayoutCache was flushed
2023-07-11 15:25:12,189 INFO [CachedFieldConfigSchemePersister.fieldConfigSchemesById]: Cache com.atlassian.jira.issue.fields.config.persistence.CachedFieldConfigSchemePersister.fieldConfigSchemesById was flushed
2023-07-11 15:25:12,189 INFO [CachedFieldConfigSchemePersister.fieldConfigSchemeIssueTypesBySchemeId]: Cache com.atlassian.jira.issue.fields.config.persistence.CachedFieldConfigSchemePersister.fieldConfigSchemeIssueTypesBySchemeId was flushed
2023-07-11 15:25:12,220 INFO [FieldConfigContextPersisterWorker.configContextsBySchemeId]: Cache com.atlassian.jira.issue.context.persistence.FieldConfigContextPersisterWorker.configContextsBySchemeId was flushed
2023-07-11 15:25:12,346 INFO [DefaultWorkflowSchemeManager.workflows]: Cache com.atlassian.jira.workflow.DefaultWorkflowSchemeManager.workflows was flushed
2023-07-11 15:25:12,346 INFO [DefaultWorkflowSchemeManager.workflowSchemeEntityCache]: Cache com.atlassian.jira.workflow.DefaultWorkflowSchemeManager.workflowSchemeEntityCache was flushed
2023-07-11 15:25:12,502 INFO [DefaultNotificationSchemeManager.projectSchemeCache]: Cache com.atlassian.jira.notification.DefaultNotificationSchemeManager.projectSchemeCache was flushed
2023-07-11 15:25:12,502 INFO [IssueSecuritySchemeManagerImpl.projectSchemeCache]: Cache com.atlassian.jira.issue.security.IssueSecuritySchemeManagerImpl.projectSchemeCache was flushed
2023-07-11 15:25:12,502 INFO [IssueSecuritySchemeManagerImpl.schemeIdToSecuritiesCache]: Cache com.atlassian.jira.issue.security.IssueSecuritySchemeManagerImpl.schemeIdToSecuritiesCache was flushed
2023-07-11 15:25:12,502 INFO [security.IssueSecuritySchemeManagerImplsecurityLevelToPermissionsCache]: Cache com.atlassian.jira.issue.security.IssueSecuritySchemeManagerImplsecurityLevelToPermissionsCache was flushed
2023-07-11 15:25:12,549 INFO [DefaultWorkflowSchemeManager.projectSchemeCache]: Cache com.atlassian.jira.workflow.DefaultWorkflowSchemeManager.projectSchemeCache was flushed
2023-07-11 15:25:12,549 INFO [DefaultWorkflowSchemeManager.workflowSchemeEntityCache]: Cache com.atlassian.jira.workflow.DefaultWorkflowSchemeManager.workflowSchemeEntityCache was flushed
2023-07-11 15:25:12,549 INFO [completions.ActionDetailsProvider]: Cache com.adaptavist.hapi.jira.issues.editor.completions.ActionDetailsProvider.com.adaptavist.hapi.jira.issues.editor.completions.ActionDetailsProvider was flushed
2023-07-11 15:25:12,580 INFO [CachingProjectKeyStore.cache]: Cache com.atlassian.jira.project.util.CachingProjectKeyStore.cache was flushed
2023-07-11 15:25:12,580 INFO [CachingProjectManager.cache]: Cache com.atlassian.jira.project.CachingProjectManager.cache was flushed
2023-07-11 15:25:12,815 INFO [CachedFieldConfigSchemePersister.fieldConfigSchemesById]: Cache com.atlassian.jira.issue.fields.config.persistence.CachedFieldConfigSchemePersister.fieldConfigSchemesById was flushed
2023-07-11 15:25:12,815 INFO [CachedFieldConfigSchemePersister.fieldConfigSchemeIssueTypesBySchemeId]: Cache com.atlassian.jira.issue.fields.config.persistence.CachedFieldConfigSchemePersister.fieldConfigSchemeIssueTypesBySchemeId was flushed
2023-07-11 15:25:12,815 INFO [CachedFieldConfigSchemePersister.cacheById]: Cache com.atlassian.jira.issue.fields.config.persistence.CachedFieldConfigSchemePersister.cacheById was flushed
2023-07-11 15:25:12,815 INFO [CachedFieldConfigSchemePersister.cacheByCustomField]: Cache com.atlassian.jira.issue.fields.config.persistence.CachedFieldConfigSchemePersister.cacheByCustomField was flushed
2023-07-11 15:25:12,815 INFO [CachedFieldConfigSchemePersister.cacheByFieldConfig]: Cache com.atlassian.jira.issue.fields.config.persistence.CachedFieldConfigSchemePersister.cacheByFieldConfig was flushed
2023-07-11 15:25:12,815 INFO [CachingCustomFieldManager.cache]: Cache com.atlassian.jira.issue.managers.CachingCustomFieldManager.cache was flushed
2023-07-11 15:25:12,815 INFO [DefaultSearchHandlerManager.helperResettableLazyReference]: Cache com.atlassian.jira.issue.search.managers.DefaultSearchHandlerManager.helperResettableLazyReference was flushed
2023-07-11 15:25:12,815 INFO [FieldIndexerManagerImpl.customFieldIndexers]: Cache com.atlassian.jira.issue.index.managers.FieldIndexerManagerImpl.customFieldIndexers was flushed
2023-07-11 15:25:12,815 INFO [FieldIndexerManagerImpl.allIssueIndexers]: Cache com.atlassian.jira.issue.index.managers.FieldIndexerManagerImpl.allIssueIndexers was flushed
2023-07-11 15:25:12,830 INFO [CachingProjectRoleAndActorStore.projectRoleActors]: Cache com.atlassian.jira.security.roles.CachingProjectRoleAndActorStore.projectRoleActors was flushed
2023-07-11 15:25:12,846 INFO [CachingProjectRoleAndActorStore.projectRoleActors]: Cache com.atlassian.jira.security.roles.CachingProjectRoleAndActorStore.projectRoleActors was flushed
2023-07-11 15:25:12,846 INFO [IssueSecurityLevelManagerImpl.projectAndUserToSecurityLevelCache]: Cache com.atlassian.jira.issue.security.IssueSecurityLevelManagerImpl.projectAndUserToSecurityLevelCache was flushed
2023-07-11 15:25:12,893 INFO [DefaultNotificationSchemeManager.projectSchemeCache]: Cache com.atlassian.jira.notification.DefaultNotificationSchemeManager.projectSchemeCache was flushed
2023-07-11 15:25:12,893 INFO [DefaultNotificationSchemeManager.projectSchemeCache]: Cache com.atlassian.jira.notification.DefaultNotificationSchemeManager.projectSchemeCache was flushed
2023-07-11 15:25:12,893 INFO [IssueSecuritySchemeManagerImpl.projectSchemeCache]: Cache com.atlassian.jira.issue.security.IssueSecuritySchemeManagerImpl.projectSchemeCache was flushed
2023-07-11 15:25:12,893 INFO [IssueSecuritySchemeManagerImpl.schemeIdToSecuritiesCache]: Cache com.atlassian.jira.issue.security.IssueSecuritySchemeManagerImpl.schemeIdToSecuritiesCache was flushed
2023-07-11 15:25:12,893 INFO [security.IssueSecuritySchemeManagerImplsecurityLevelToPermissionsCache]: Cache com.atlassian.jira.issue.security.IssueSecuritySchemeManagerImplsecurityLevelToPermissionsCache was flushed
Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
July 11, 2023

Set the 

 (CopyProject.FIELD_COPY_DASH_AND_FILTERS): false

to true

Fidelidade JIRA Admin July 12, 2023

Hi Dave,

I set this line to true, but the script didn't copy the board.

I added these new lines, and the script already makes a copy of the board.
But my difficulty now is that it only copies one board from the template, but the template has more than one board.

And another concern of mine is that every time I run the script, I have to change it to make a new copy. To me, it doesn't make sense. This should have a way to increment the key and name so as not to give the error that the project with that name already exists.

Can you help me with this?

 

def adminUserName = 'ana.santos.almeida@fidelidade.pt'

def sourceKey = 'TNT'

def targetKey = 'COPYTNT04'

def targetName = 'Team Network Template 04'

def copyProject = ScriptRunnerImpl.scriptRunner.createBean(CopyProject)

def inputs = [

        (CopyProject.FIELD_SOURCE_PROJECT) : sourceKey,

        (CopyProject.FIELD_TARGET_PROJECT) : targetKey,

        (CopyProject.FIELD_TARGET_PROJECT_NAME) : targetName,

        (CopyProject.FIELD_COPY_VERSIONS) : true,

        (CopyProject.FIELD_COPY_COMPONENTS) : false,

        (CopyProject.FIELD_COPY_ISSUES) : false,

        (CopyProject.FIELD_COPY_DASH_AND_FILTERS): true,

       

        (CopyProject.FIELD_CLONE_BOARD_NAME): 3115,

        (CopyProject.FIELD_TARGET_BOARD_NAME): 'TNT Global Board',

        (CopyProject.FIELD_TARGET_BOARD_NAME): 'TNT Team Board'

 

Thank you,
BR

Emanuel

Peter-Dave Sheehan
Community Leader
Community Leader
Community Leaders are connectors, ambassadors, and mentors. On the online community, they serve as thought leaders, product experts, and moderators.
July 12, 2023

In my many responses to this post, I've shown how a built-in script can be called from a post function.

All the fields populated in the script correspond to fields in the built-in script form.

It's up to you to figure out how to supply different values to these fields.

If you are triggering from a post function, then you should be asking users to provide the input in the form of custom field and passing those over to the script.

Or if you want an algorithm for automatically incrementing the project key, you'll have to figure that one out.

As for the built-in script not copying all the boards, I'm not sure what to tell you. Does it work when you call the copy project script manually from the built-in script screen? If not, then that should be a question for scriptrunner support. 

Like Cornelius Gillner likes this

Suggest an answer

Log in or Sign up to answer