Du ser en gammel version af denne side. Se den nuværende version.

Sammenlign med nuværende Vis sidehistorik

Version 1 Næste »

https://marketplace.atlassian.com/apps/6820/scriptrunner-for-jira?hosting=server&tab=overview


  • Side:
    Copy a Jira Project with Scriptrunner REST

    The builtin Script "Copy Project" can be used with REST:

    curl -u admin:Welcome1 -H "Content-Type: application/json" -H "X-Atlassian-Token: nocheck" -d @copyProject.json http://jira.server.dk/rest/scriptrunner/latest/canned/com.onresolve.scriptrunner.canned.jira.admin.CopyProject

    The Json Payload:

  • Side:
    Copy a Confluence Space with Scriptrunner REST

    The builtin Script "Copy Space" can be used with REST:

    curl -u admin:Welcome1 -H "Content-Type: application/json" -H "X-Atlassian-Token: nocheck" -d @copySpace.json http://confluence.server.dk/rest/scriptrunner/latest/canned/com.onresolve.scriptrunner.canned.confluence.admin.CopySpace

    The Json Payload:

  • Side:
    Search Jira fields for a Key=Value entry

    I am always missing a Custom Field that can handle Key=Value entried; combined with multiple entries, so I use a multiline Text Field:

    Service Level=AppDrift
    CustomerNumber=1043
    Othername=Myhost

    Lets call the field "VC Tags". Issues with a Key=Value can be found with a JQL like:

  • Side:
    Reindex a controlled number of issues in Jira

    This can be achived via the ScriptRunner Console:

    import com.atlassian.jira.component.ComponentAccessor
    import com.atlassian.jira.issue.search.SearchException
    import com.atlassian.jira.issue.search.SearchResults
    import com.atlassian.jira.issue.search.SearchProvider
    import com.atlassian.jira.web.bean.PagerFilter
    import com.atlassian.jira.security.JiraAuthenticationContext
    import com.atlassian.jira.bc.issue.search.SearchService.ParseResult
    import com.atlassian.jira.bc.issue.search.SearchService
    import com.atlassian.jira.issue.index.IssueIndexingService
    import com.atlassian.jira.util.ImportUtils
    
    JiraAuthenticationContext authenticationContext = ComponentAccessor.getJiraAuthenticationContext()
    def authContext = ComponentAccessor.getJiraAuthenticationContext()
    def issueIndexingService = ComponentAccessor.getComponent(IssueIndexingService)
    def issueManager = ComponentAccessor.getIssueManager()
    
    String jql="project=TEST and status not in (Closed,Resolved)"
    Number maxIndexCount = 600
    
    SearchService searchService = ComponentAccessor.getComponentOfType(SearchService .class)
    ParseResult parseResult = searchService.parseQuery(authenticationContext.getLoggedInUser(), jql)
    int totalIssues = 0
    
    if (parseResult.isValid())
    {
        SearchResults results = searchService.search(authenticationContext.getLoggedInUser(), parseResult.getQuery(), PagerFilter.getUnlimitedFilter())
        final List issues = results?.results
    
        //Loop all issues
        issues.each { theIssue ->
    
            if (totalIssues < maxIndexCount)
            {
                boolean wasIndexing = ImportUtils.isIndexIssues()
                ImportUtils.setIndexIssues(true)
                issueIndexingService.reIndex(issueManager.getIssueObject(theIssue.id))
                ImportUtils.setIndexIssues(wasIndexing)
                totalIssues= totalIssues +1
    
                log.warn "Indexed: " + theIssue.getKey()
            }
        }
    }
  • Side:
    ScriptRunner for JIRA plugin

    This Plugin gives some extremely nice features, like:

    • Using prebuilt-in functions/tasks
    • Running scripts in Transitions.
  • Side:
    Add Organisations to the Issue for JIRA Service Desk (4.x)

    This script adds all Organisations for a User to a Ticket that is being created in Jira service Desk - Created via JIRA, not the Portal. It uses the Reporter.

    Notice, a User can belong to several Organisations, all will be added to the Ticket:

    Find v3.x of the script here

  • Side:
    Add Organisations to the Issue for JIRA Service Desk (3.x)

    This script adds all Organisations for a User to a Ticket that is being created in Jira service Desk - Created via JIRA, not the Portal. It uses the Reporter.

    Notice, a User can belong to several Organisations, all will be added to the Ticket:

    Find v4.x of the script here

  • Side:
    Elevation of Rights in Groovy

    This sample disables a user - by setting the JIRA Context to a user with higher Level:

    This is a potential thread, as its possible for anyone who can create and execure groovy scripts to elevate rights, just by knowing an admin username

  • Side:
    Howto Change a Project (or multiple projects) outgoing email

    Via Scriptrunner for all projects:

    import com.atlassian.core.ofbiz.util.OFBizPropertyUtils
    import com.atlassian.jira.component.ComponentAccessor
    
    def newAddress = "newEmail@example.com"
    ComponentAccessor.projectManager.projects.each {
     def email = OFBizPropertyUtils.getPropertySet(it.getGenericValue())
     email.setString("jira.project.email.sender", newAddress)
    }
  • Side:
    JIRA Event Ids

    Can be examined from a Listener:

    package com.netic.eventlistener
    
    import com.atlassian.jira.component.ComponentAccessor
    import com.atlassian.jira.issue.link.IssueLink;
    import com.atlassian.jira.issue.comments.CommentManager
    import com.atlassian.jira.util.JiraUtils;
    import com.opensymphony.workflow.WorkflowContext;
    import com.atlassian.jira.event.issue.AbstractIssueEventListener
    import com.atlassian.jira.event.issue.IssueEvent
    
    class EventListener extends AbstractIssueEventListener {
        
        @Override
        void workflowEvent(IssueEvent event) {
            String IssueType      = event.issue.getIssueType().name
            String ProjectName    = event.issue.getProjectObject().name
            String IssueKey       = event.issue.key
            String EventId        = event.getEventTypeId()
            System.out.println("Event: " + EventId)
    
        }
    }
  • Side:
    Deactivate a User via REST

    As the official API does not have this function (currently), we can accomplish it via Adaptavist Scriptrunner.

    Add a REST endpoint and use the code:

    import com.onresolve.scriptrunner.runner.rest.common.CustomEndpointDelegate
    import groovy.transform.BaseScript
    import com.atlassian.jira.component.ComponentAccessor
    import com.atlassian.jira.issue.Issue
    import com.atlassian.jira.issue.IssueManager
    import com.atlassian.jira.issue.issuetype.IssueType
    import com.atlassian.jira.project.ProjectManager
    import com.atlassian.jira.issue.CustomFieldManager
    import javax.ws.rs.core.MultivaluedMap
    import javax.servlet.http.HttpServletRequest
    import javax.ws.rs.core.Response
    import com.atlassian.crowd.embedded.api.CrowdService
    import com.atlassian.crowd.embedded.api.UserWithAttributes
    import com.atlassian.crowd.embedded.impl.ImmutableUser
    import com.atlassian.jira.bc.user.UserService
    import com.atlassian.jira.component.ComponentAccessor
    import com.atlassian.jira.user.ApplicationUser
    import com.atlassian.jira.user.ApplicationUsers
    import com.atlassian.jira.user.util.UserUtil
    
    @BaseScript CustomEndpointDelegate delegate
    
    deactivateuser(httpMethod: "GET", groups: ["jira-administrators"]) { MultivaluedMap queryParams ->
    
        def issueManager = ComponentAccessor.getIssueManager()
        def userManager = ComponentAccessor.getUserManager()
    
        String userName = queryParams.getFirst("username") as String
        def builder = new groovy.json.JsonBuilder()
    	UserUtil userUtil = ComponentAccessor.userUtil
    	CrowdService crowdService = ComponentAccessor.crowdService
    	UserService userService = ComponentAccessor.getComponent(UserService)
    	ApplicationUser updateUser
    	UserService.UpdateUserValidationResult updateUserValidationResult
    
        // Get user
        UserWithAttributes user = crowdService.getUserWithAttributes(userName)
        
        if (user)
        {
            updateUser = ApplicationUsers.from(ImmutableUser.newUser(user).active(false).toUser())
            updateUserValidationResult = userService.validateUpdateUser(updateUser) 
            if (updateUserValidationResult.isValid()) 
            {
            	userService.updateUser(updateUserValidationResult)
                builder { result "User Deactivated"}
                return Response.status(201).entity(builder.toString()).build()
            } 
            else
            {
               	builder { result "Update of ${user.name} failed: ${updateUserValidationResult.getErrorCollection().getErrors().entrySet().join(',')}"}
            	return Response.status(400).entity(builder.toString()).build()
            }
        }
        else
        {
            //No such username
            builder { result "User did not exist"}
            return Response.status(400).entity(builder.toString()).build()
        }
    }
  • Side:
  • Side:
    Set or Clear Customer Request Type field

    To Set it:

    import com.atlassian.jira.component.ComponentAccessor
    def customFieldManager = ComponentAccessor.customFieldManager
    def crtField = customFieldManager.getCustomFieldObjects(issue).find{it.name == "Customer Request Type"}
    issue.setCustomFieldValue(crtField, "Desired Request Type")

    To Clear it:

  • Side:
    JIRA Workflow Plugins

    A brief summary of some Workflow enhancements plugins.

    The main focusing is primarily on what they contribute on the Post-Function side of a Transition.

    Workflow Enhancer for JIRA

  • Side:
    Logging PageEvents to Statsd (Datadog)

    A possible way to Log User- and Page-Access to statsd is via the Event system - using Adaptavist's Scriptrunner for Confluence, se https://scriptrunner.adaptavist.com/latest/confluence/ConfluenceEventHandlers.html#_collecting_stats

    Read Access Logging in Confluence for good reasons to log via the Event system.

  • Side:
    Logging PageEvents to Elasticsearch

    A possible way to Log User- and Page-Access in Confluence is via the Event system - using Adaptavist's Scriptrunner for Confluence

    This ways has Pros and Cons - read Access Logging in Confluence. On Pro is that the POST to Splunk in in the backend; so we dont need to open for the receiving system in the Firewall

  • Side:
    PUT'ing with Groovy

    This is how to make PUTs and POSTs:

    def requestMethod = "PUT";
    def URLParam = []
    def baseURL = "http://myserver.domain.dk/"
    
    
    def url = new java.net.URL(baseURL);
    URLConnection connection = url.openConnection();
    connection.setRequestMethod(requestMethod);
    connection.doOutput = true
    connection.setUseCaches(false);
    connection.setRequestProperty("Content-Type", "text/html");
    connection.setRequestProperty('Authorization', 'Basic ' + 'username:password'.bytes.encodeBase64().toString());
    
    //PUT Content
    OutputStreamWriter out = new OutputStreamWriter(
        connection.getOutputStream());
        out.write("type=0");
        out.write("&format=0");
        out.write("&content_id=" + ListId);
        out.write("&jira_key=" + IssueKey);
        //out.write("options={\"status\":\"" + issueStatus + "\"}");
        out.close();
    
    //try
    //{
      log.info "Script=MakeReport.groovy IssueKey=" + IssueKey + " ScriptRunIdent=" + scriptRunIdent + " URL=" + baseURL
      log.info "Script=MakeReport.groovy IssueKey=" + IssueKey + " ScriptRunIdent=" + scriptRunIdent + " Action=GetHttpsConnection"
      connection.connect();
      try
      {
        connection.getContent()
      }
      catch (Exception ex)
      {
        log.info "Script=MakeReport.groovy IssueKey=" + IssueKey + " ScriptRunIdent=" + scriptRunIdent + " Error=ConnectionError Message="+ ex.getMessage()
      }
      String Status=connection.getResponseCode()
      String Message=connection.getResponseMessage()
    
    
  • Side:
    Logging PageEvents to Splunk

    A possible way to Log User- and Page-Access in Confluence is via the Event system - using Adaptavist's Scriptrunner for Confluence

    This ways has Pros and Cons - read Access Logging in Confluence. One Pro is that the POST to Splunk in in the backend; so we dont need to open for the receiving system in the Firewall for the world.

  • Side:
    Scripted field: Last updated in short

    The goal is to replace the long "Days since Last Comment" with the short "D:HH:MM:

    This can be done via a Scripted Field from JIRA Scriprunner:

    import com.atlassian.jira.component.ComponentAccessor
    import com.atlassian.jira.issue.Issue
    import com.atlassian.jira.issue.IssueManager
    import java.text.SimpleDateFormat
    
    // https://docs.atlassian.com/jira/server/com/atlassian/jira/issue/Issue.html
    // https://www.tutorialspoint.com/groovy/groovy_operators.htm
    
    long updatedDateTime;
    
    // If No Comments, use:
    updatedDateTime = issue.updated.getTime()
    
    // If has Comments, use date of Last Comment:
    def comments = ComponentAccessor.commentManager.getComments(issue)
    if (comments) {
        updatedDateTime = comments.last().getUpdated().getTime()
    }
    
    // Find Now
    long Now = System.currentTimeMillis()
    
    if (updatedDateTime)
    {
    
      // 1s = 1000 ms
      // Diff is positive, its now-lastupdated in seconds
      int Diff= (Now-updatedDateTime)/1000
    
      // 1d = 86400s
      // Get Remains in seconds
      int Remains = Diff%86400
      int Days = (Diff-Remains)/86400
      String sDays = String.valueOf(Days)
    
      // 1h = 3600s
      int Remains2 = Remains%3600
      int Hours = (Remains-Remains2)/3600
      String sHours = "0" + String.valueOf(Hours)
    
      int Mins =Remains2/60
      String sMins = "0" + String.valueOf(Mins)
    
      return sDays + ":" + sHours.reverse().take(2).reverse() + ":" + sMins.reverse().take(2).reverse()
    }
    else
    {
      return "0:00:00"
    }
  • Side:
    Run groovy script from linux command line
    curl -u admin:admin --header "X-Atlassian-token: nocheck" -X POST --data "scriptFile=$FilePathRelativeToSourcepath$" http://localhost:8080/jira/rest/scriptrunner/latest/user/exec/
  • Side:
    Script Runner Listener

    To Create a Listener, create a directory structure to match below <jira-home>/data/scripts, like:

    cd /opt/jira-data/data/script
    mkdir com com/firm com/firm/listener

    go to the directory and make a class file:

  • Ingen etiketter