Scripts in Visual Mode

    This article applies to Exalate Classic only. For New Exalate, refer to this documentation

    Script rules can be used in Visual Mode when the standard mapping rules are not sufficient to cover the use case.
    Creating a script rule is straightforward.

    • Edit your visual connection
    • Select the rules
    • Select the 'Add script'

    How does it work?

    The scripts are groovy-based, meaning that all groovy structures can be used to define the behavior of the mapping. For instance, if a mapping is needed between the assignees of one side with the instance name 'left' and another side with the instance name 'right', the following code snippet implements the mapping:

    // define the mapping
     
    def leftToRightAssignee = [
        // left Assignee ---> right Assignee
        "peter@acme.com" : "peter.pan@acme.com",
        "cinderella@acme.com" : "cinderalla.white@acme.com",
    ]
     
     
    // look up the corresponding email, default to team@acme.com
    def targetUserEmail = leftToRightAssignee[left.issue.assignee?.email] ?: "team@acme.com"
     
    // assign to right issue
     
    right.issue.assignee = nodeHelper.getUserByEmail(targetUserEmail)

    Examples

    Labels

    your_instance_shortname.issue.labels = remote_instance_shortname.issue.labels

    Components

    your_instance_shortname.issue.components = remote_instance_shortname.issue.components.collect { component ->
    def remoteComponentLeadEmail = component.lead?.email
    def localComponentLeadName = nodeHelper.getUserByEmail(remoteComponentLeadEmail)
    nodeHelper.createComponent(
        issue,
        component.name,
        component.description, // can also be null
        localComponentLeadName?.key, // can also be null
        component.assigneeType?.name() // can also be null
        )
    }
    
    

    Resolution

    Set the local resolution same as on the remote side, if there's no such resolution on your side don't set anything

    if(nodeHelper.getResolution(remote_instance_shortname.issue.resolution?.name)) {
         your_instance_shortname.issue.resolution = remote_instance_shortname.issue.resolution   
    }

    Versions

    // assign fix versions from JIRA A to JIRA B
    your_instance_shortname.issue.fixVersions = remote_instance_shortname.
      .fixVersions
      // ensure that all the fixVersions are available on B
      .collect { v -> nodeHelper.createVersion(issue, v.name, v.description) }
    // assign affected versions from JIRA A to JIRA B
    your_instance_shortname.issue.affectedVersions = remote_instance_shortname
      .affectedVersions
      .collect { v -> nodeHelper.createVersion(issue, v.name, v.description) }
    
    

    User fields

    Assignee

    your_instance_shortname.issue.assignee = nodeHelper.getUser(remote_instance_shortname.issue.assignee?.key)
    
    

    Reporter

    your_instance_shortname.issue.reporter = nodeHelper.getUser(remote_instance_shortname.issue.reporter?.key)
    
    

    Custom fields

    Text/String custom fields

    Sync value from "remote side select list custom field" to the local "select list custom field"

    your_instance_shortname.issue.customFields."text custom field".value = remote_instance_shortname.issue.customFields."remote side text custom field".value

    Set a fixed value in the local custom field 

    Single select list/radio button

    Sync value from "remote side select list custom field" to the local "select list custom field"

    your_instance_shortname.issue.customFields."select list custom field".value = remote_instance_shortname.issue.customFields."remote side select list custom field".value

    Set a fixed value in the local custom fields "My select list"

    your_instance_shortname.issue.customFields."My Select list".value = "Red"

    Multi-select list/Checkbox

    // sync value from "remote multi-select list custom field" to the local "select list multiple choice"
    your_instance_shortname.issue.customFields."select list multiple choice".value = remote_instance_shortname.issue.customFields."remote multi-select list custom field".value?.value
    // Add "Red" as a value in the custom fields "My multi-select list"
    your_instance_shortname.issue.customFields."My multi-select list".value += nodeHelper.getOption("Red")

    Multi-cascade custom fields

    Sync only existing option values 

    def sourceRegion = remote_instance_shortname.issue.customFields."Source Region/Country"?.value?.parent?.value
    def sourceCountry = remote_instance_shortname.issue.customFields."Source Region/Country"?.value?.child?.value
      
    def region = nodeHelper.getOption(
      issue,
      "Destination Region/Country",
      sourceRegion
    )
    def country = region.childOptions.find{it.value == sourceCountry}
    if ( region != null && (sourceCountry == null || country != null)) {
      your_instance_shortname.issue.customFields."Destination Region/Country"?.value = nodeHelper.getCascadingSelect(
                  region,
                  country
      )
    } else if (sourceRegion == null) {
      your_instance_shortname.issue.customFields."Destination Region/Country"?.value = null
    }

    Date/DateTime custom fields

    // if you have a custom field called "My Date" (of type Date Picker or Date Time Picker)
    // on your Side and you'd like to populate it from
    // "Their Date" of remote Side (of type Date Picker or Date Time Picker)
    your_instance_shortname.issue.customFields."My Date".value = remote_instance_shortname.issue.customFields."Their Date".value
    // or if you'd like to assign a fixed moment in time:
    your_instance_shortname.issue.customFields."My Date".value = new java.text.SimpleDateFormat("yyyy-MM-dd HH:mm:ss z")
        .parse("2019-10-24 13:30:59 EET")

    URL custom fields

    // sync value from "remote side url custom field" to the local "url custom field"
    your_instance_shortname.issue.customFields."url custom field".value = remote_instance_shortname.issue.customFields."remote side url custom field".value
     
    // Set a fixed value "https://exalate.com" in the custom field with name  "My url custom field"
    your_instance_shortname.issue.customFields."My url custom field".value = "https://exalate.com"

    Label custom fields

    // sync value from "remote side labels" to the local "My labels"
    your_instance_shortname.issue.customFields."My labels".value = remote_instance_shortname.issue.customFields."remote side labels".value
    // add "attention" to the custom field "My labels"
    your_instance_shortname.issue.customFields."My labels".value += nodeHelper.getLabel("attention")

    User picker custom fields

    // sync value from "remote side user picker custom field" to the local "user picker custom field"
    your_instance_shortname.issue.customFields."user picker custom field".value = nodeHelper.getUser(remote_instance_shortname.issue.customFields."remote side user picker custom field".value)
    // Set a fixed value "557358:bda57a72g56a9-4219-9c29-7d666481388f" (id for a user in your system) in the custom field with name  "My user picker"
    your_instance_shortname.issue.customFields."My user picker".value = "557358:bda57a72g56a9-4219-9c29-7d666481388f"

    Number custom fields

    your_instance_shortname.issue.customFields."numeric custom field".value = remote_instance_shortname.issue.customFields."remote side numeric custom field".value

    Advanced Scripts

    Set a custom field with the issue key of the remote twin in the Visual mode

    How to set a custom field like 'Remote Key' with the key of the twin issue.  This example shows how to implement it on a Jira Cloud to Jira Cloud, but the approach can also be used on other permutations.

    Assume you have set up a connection using the visual configuration mode between 'local' and 'remote'.



    You have the requirement that a text field 'Remote Key' on the local issue must contain the issue key of the remote twin.

    Approach

    What needs to happen is that

    • once the remote issue is created, a message is sent back from the remote to the local, containing the issue key of the remote.
    • this incoming message on the local can then be used to populate the local custom field.

    Triggering a message back can be done using the syncBackAfterProcessing function.

    Implementation

    Add the following script rule to the connection.

    • Line 1 - limit the sync back to the first sync transaction.
      Warning:  This must be done, otherwise it creates a loop that sends messages back and forth continuously.
    • Line 2 - trigger the sync back transaction using the syncHelper.syncBackAfterProcessing.
    • Line 5 - assign the value of the remote key to the local customfield 'Remote Key'.