How to add project to custom field's context using Script Runner

ARM Ltd. (old account) January 14, 2015

Hi

I am wondering if anyone had an experience of Custom Field context manipulations using Script Runner?

I have context named "AAA Bug Configuration" in 48 custom fields and 5 Projects added to that context.

 

Now I need to add additional 4 projects to the same context.

I don't want to walk through all 48 CF's and add them to the list manually.

 

Is there any way to automate somehow this - it is quite huge and unpleasant work actually smile

 

Regards,

Areg

6 answers

5 votes
Clemens Luebbers January 25, 2015

I finally found the problem:

At the end of the script the refresh() method needs to be from CustomFieldManager NOT FieldManager.

I learned that from CopyProject script code from Script runner - thanks, Jamie. See also hint below.

I.e. the following script does the job:

import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.fields.CustomField;
import com.atlassian.jira.issue.fields.ConfigurableField;
import com.atlassian.jira.issue.CustomFieldManager;
import com.atlassian.jira.issue.fields.config.FieldConfigScheme;
import com.atlassian.jira.issue.fields.config.manager.FieldConfigSchemeManager;
import com.atlassian.jira.issue.fields.FieldManager;
import com.atlassian.jira.issue.context.ProjectContext;
import com.atlassian.jira.issue.context.JiraContextNode;
import java.util.ArrayList;
    CustomFieldManager customFieldManager = ComponentAccessor.getCustomFieldManager();
    FieldConfigSchemeManager fieldConfigSchemeManager = ComponentAccessor.getFieldConfigSchemeManager();
    FieldManager fieldManager = ComponentAccessor.getFieldManager();
    
    ArrayList<CustomField> customFields = new ArrayList<CustomField>();
    
    customFields.add(customFieldManager.getCustomFieldObject(10401L));
    
    ProjectContext newProjectContext = new ProjectContext(10100L);
    
    for (customField in customFields) {
        println customField.getId();
        List<FieldConfigScheme> fieldConfigSchemes = customField.getConfigurationSchemes();
        
        FieldConfigScheme firstScheme = fieldConfigSchemes.get(0);
        
        List<JiraContextNode> existingSchemes = firstScheme.getContexts();
        JiraContextNode newContextNode = (JiraContextNode) newProjectContext;
        
        List<JiraContextNode> updatedSchemes = new ArrayList<JiraContextNode>();
        for (scheme in existingSchemes) {
            updatedSchemes.add(scheme);
        }
        updatedSchemes.add(newContextNode);
        
        fieldConfigSchemeManager.updateFieldConfigScheme(firstScheme, updatedSchemes, (ConfigurableField) customField);
        
    }
    customFieldManager.refresh();

Another hint: if you need a more general or more flexible approach have a look at the source code of the built-in script "Copy Project" from script runner. E.g. that code handles several configurations for 1 customfield, while code above is limited to 1 (first) configuration.

Jonnada Kiran November 5, 2019

@Clemens Luebbers Hi, Do you know how to set 

GlobalIssueContext to false ? 

 

Thanks,

Kiran.

Helmy Ibrahim _Adaptavist_
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.
March 4, 2021

Hi @Jonnada Kiran 

You could do something like this:

for (scheme in existingSchemes) {
if (!scheme.projectId){
continue
}
updatedSchemes.add(scheme) } 
1 vote
Clemens Luebbers January 21, 2015

I currently have the same problem.

I have a Jelly script that did this for JIRA 4.1. We now migrated to JIRA 6.2 and the script seems not to work properly now.

The script uses class FieldConfigSchemeManager and method  updateFieldConfigScheme(FieldConfigScheme newScheme, List<JiraContextNode> contexts, ConfigurableField field).

Current bug:
The list of projects within each context has 2 parts: first are the projects listed, which are NOT selected for this context and then follows the second part with all the selected projects.

When I run the script the project which should be added to the context is listed TWICE in the list of projects in the context:

  • in part 1 (but it is marked as selected)
  • AND in part 2 (of course also marked as selected).

In fact, the project is not added correctly to the context. If I look at list of customfields, the new project is not listed at the relevant fields. And if I rerun the script and check for the existing projects in the context prior adding any project, the project is also not in the list.

If I deselect manually the project in part 1 and store the change, everything is fine - but that is not the purpose of a script smile

If you accept a solution with Jelly script (or you would "translate" to Groovy) we might share experience in locating the problem of the script.

ARM Ltd. (old account) January 21, 2015

Hi I will be happy to have a look to script and see how it can be translated or changed to be improved. By the way I have requested Atlassian Support for help and they raised a Suggestion if you would like to have a look - https://jira.atlassian.com/browse/JRA-41736 Regards, Areg

Like Jean-Philippe Comeau likes this
0 votes
Tomáš Vrabec October 16, 2020

Script runner "Copy Project" will copy also the Custom Field Context. 

0 votes
Clemens Luebbers January 22, 2015

Hi Areg,

I created according Groovy script for Script Runner, but it shows the same problem as the Jelly script ...

import com.atlassian.jira.component.ComponentAccessor;
import com.atlassian.jira.issue.fields.CustomField;
import com.atlassian.jira.issue.fields.ConfigurableField;
import com.atlassian.jira.issue.CustomFieldManager;
import com.atlassian.jira.issue.fields.config.FieldConfigScheme;
import com.atlassian.jira.issue.fields.config.manager.FieldConfigSchemeManager;
import com.atlassian.jira.issue.fields.FieldManager;
import com.atlassian.jira.issue.context.ProjectContext;
import com.atlassian.jira.issue.context.JiraContextNode;
import java.util.ArrayList;
    CustomFieldManager customFieldManager = ComponentAccessor.getCustomFieldManager();
    FieldConfigSchemeManager fieldConfigSchemeManager = ComponentAccessor.getFieldConfigSchemeManager();
    FieldManager fieldManager = ComponentAccessor.getFieldManager();
    
    ArrayList&lt;CustomField&gt; customFields = new ArrayList&lt;CustomField&gt;();
    
    customFields.add(customFieldManager.getCustomFieldObject(10401L));
    
    ProjectContext newProjectContext = new ProjectContext(10100L);
    
    for (customField in customFields) {
        println customField.getId();
        List&lt;FieldConfigScheme&gt; fieldConfigSchemes = customField.getConfigurationSchemes();
        
        FieldConfigScheme firstScheme = fieldConfigSchemes.get(0);
        
        List&lt;JiraContextNode&gt; existingSchemes = firstScheme.getContexts();
        JiraContextNode newContextNode = (JiraContextNode) newProjectContext;
        
        List&lt;JiraContextNode&gt; updatedSchemes = new ArrayList&lt;JiraContextNode&gt;();
        for (scheme in existingSchemes) {
            updatedSchemes.add(scheme);
        }
        updatedSchemes.add(newContextNode);
        
        fieldConfigSchemeManager.updateFieldConfigScheme(firstScheme, updatedSchemes, (ConfigurableField) customField);
        
    }
    fieldManager.refresh();
M Vijay Kumar February 18, 2020

Hi,

We are still facing the issue; Were you able to resolve the issue?

 

Thanks,

Vijay 

0 votes
Clemens Luebbers January 21, 2015

Hi Areg,

here is the Jelly code:

&lt;JiraJelly xmlns:jira="jelly:com.atlassian.jira.jelly.JiraTagLib" xmlns:core="jelly:core"&gt;
 
    &lt;core:invokeStatic className="com.atlassian.jira.component.ComponentAccessor" method="getCustomFieldManager" var="customFieldManager"/&gt;
    &lt;core:invokeStatic className="com.atlassian.jira.component.ComponentAccessor" method="getFieldManager" var="fieldManager"/&gt;
    &lt;core:invokeStatic className="com.atlassian.jira.component.ComponentAccessor" method="getFieldConfigSchemeManager" var="schemeManager"/&gt;
        
     &lt;core:new className="java.util.ArrayList" var="customFields"/&gt;
     
     &lt;!-- customfield1 to change --&gt;
     &lt;core:invoke on="${customFields}" method="add"&gt;
        &lt;core:arg type="com.atlassian.jira.issue.fields.CustomField"&gt;            
            &lt;core:invoke on="${customFieldManager}" method="getCustomFieldObject"&gt;
                &lt;core:arg type="java.lang.Long" value="10401"/&gt;
            &lt;/core:invoke&gt;  
        &lt;/core:arg&gt;
    &lt;/core:invoke&gt; 
    
    &lt;!-- By copy &amp; paste (plus other value) of above block add further fields to the list when needed --&gt;
            
    &lt;!-- PROJECT which should be added  --&gt;
    &lt;core:new className="com.atlassian.jira.issue.context.ProjectContext" var="jiraContextNode"&gt;
        &lt;core:arg type="java.lang.Long" value="10100"/&gt;
    &lt;/core:new&gt;    
    
        
    &lt;core:forEach var="customField" items="${customFields}"&gt;
        
        &lt;!-- Get all configuration schemes for the custom field --&gt;
        &lt;core:invoke on="${customField}" method="getConfigurationSchemes" var="schemes"/&gt;
        
        &lt;!-- Get first configuration scheme --&gt;
        &lt;core:invoke on="${schemes}" method="get" var="scheme"&gt;
            &lt;core:arg type="int" value="0"/&gt;
        &lt;/core:invoke&gt; 
        
        &lt;!-- Get existing contexts for the customfield  --&gt;
        &lt;core:invoke on="${scheme}" method="getContexts" var="existingContexts"/&gt;
        existing context for customfield ${customField}    :     
        ${existingContexts} 
        
        &lt;!-- Building list(context) with the new project --&gt;
        &lt;core:invokeStatic var="newContext" className="com.atlassian.core.util.collection.EasyList" method="build"&gt;
            &lt;core:arg type="java.lang.Object" value="${jiraContextNode}"/&gt;
        &lt;/core:invokeStatic&gt;
                
        &lt;!-- Merging lists of projects which should be in the new context - existing(existingContexts) + new one(newContext) --&gt;
        &lt;core:invokeStatic var="contexts" className="com.atlassian.core.util.collection.EasyList" method="mergeLists"&gt;
            &lt;core:arg type="java.util.List" value="${existingContexts}"/&gt;
            &lt;core:arg type="java.util.List" value="${newContext}"/&gt;            
            &lt;core:arg type="java.util.List"/&gt;
        &lt;/core:invokeStatic&gt;
        
        changing context for customfield ${customField}    :     
        ${contexts} 
        
        &lt;!-- Update FieldConfigScheme --&gt;
        &lt;core:invoke on="${schemeManager}" method="updateFieldConfigScheme"&gt;
            &lt;core:arg type="com.atlassian.jira.issue.fields.config.FieldConfigScheme" value="${scheme}"/&gt;
            &lt;core:arg type="java.util.List" value="${contexts}"/&gt;
            &lt;core:arg type="com.atlassian.jira.issue.fields.ConfigurableField" value="${customField}"/&gt;
        &lt;/core:invoke&gt; 
    &lt;/core:forEach&gt;        
    &lt;!-- Save changes (means clean caches related to fields) --&gt;
    &lt;core:invoke on="${fieldManager}" method="refresh"/&gt;    
    
&lt;/JiraJelly&gt;

I run this on JIRA 6.2. To adapt to your test environment you will need to replace the id of the customfield (value 10401 in line 13) and the id of the project that should be added (value 10100 in line 22).

Fieldconfiguration before running the script:

2015-01-22 09_04_32-Modify configuration scheme context.png

 

The script should add project VSG-Test (id 10100) to the context. After running the script context appears as:

2015-01-22 09_07_46-Modify configuration scheme context.png

As you can see VSG-Test appears twice. And it is not really added to the context.

In the view of all customfields project VSG-Test does not appear as project in context.
If I deselect the first VSG-Test entry and store the change, everything seems to be fine.

 

Here the output of the Jelly script from its run:

 

2015-01-22 09_06_49-Jelly Runner.png

It looks as if the ProjectContext for the project 10100 is added correctly to the list.

 Could not yet figure out, what is going wrong here.

0 votes
JamieA
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 14, 2015

Normally you would avoid that by using the "Copy Project" script, which will add it to all those contexts.

I do have examples of it, but piecing it together is going to be at least as hard as doing it manually. If you can, I'd delete those projects and recreating them by copying an existing one.

ARM Ltd. (old account) January 14, 2015

The problem is that 4 projects are have a lot of issues in them and it will be quite problematic to delete and create them again. So I would like to add them to the existing context some kind automatically rather than manually.

Suggest an answer

Log in or Sign up to answer