Wednesday, April 3, 2019

Creating and Updating Jira Issues with PowerShell

In attempting to find a way to programmatically manipulate Jira, I discovered that the information out there on the Internet is somewhat scattered. I couldn't find one central location that gave me everything I needed to move forward. After a period of trial and error, I managed to piece together the disparate parts into a PowerShell solution.

This is my basic function for getting a user's name and password.

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

function IdentifyUser
    {
    # Prompt user for logon credentials.
    $script:MyCredential = Get-Credential -Message "Please enter your network user ID and password:" -UserName $env:UserName
    if ($script:MyCredential)
        {
        $script:attemptConnection = $true
        $script:username = $script:MyCredential.Username
        $script:password = $script:MyCredential.GetNetworkCredential().password
        }
    else
        {
        Write-Host ""
        Write-Host $script:equalsLine
        Write-Host "Logon canceled by user."
        Write-Host $script:equalsLine
        }
    }  #IdentifyUser


This function contains many of the fields associated with a Jira issue. This is where values would be altered for creating or updating a specific case.

function InitializeVariables
    {
    $script:target = "https://[your Jira base URL]"
    $script:projectKey = "[your Jira project key]";

#===================================
#   Available variables/Jira fields
#-----------------------------------

    $script:createOrUpdate = "update"
    $script:issueKey = "$script:projectKey-1" # this is ignored if creating an issue

    $script:acceptanceCriteria = "If you build it, they will come."
    $script:assignee = "[a Jira user name]"
    $script:description = "This issue was created from PowerShell using Jira REST API."
    $script:dueDate = "2020-01-01"
    $script:issueType = "Task"
    $script:label_1 = "Development"
    $script:label_2 = "Request"
    $script:priority = "Lowest"
    $script:summary = "Jira workflow examination"

#===================================

    $script:attemptConnection = $false
    $script:equalsLine = "=" * 130

    if ($script:createOrUpdate.ToLower() -eq "create")
        {
        $script:method = "POST"
        $script:requestUri = "$script:target/jira/rest/api/latest/issue"
        }
    elseif ($script:createOrUpdate.ToLower() -eq "update")
        {
        $script:method = "PUT"
        $script:requestUri = "$script:target/jira/rest/api/latest/issue/$script:issueKey"
        }
    else
        {
        $script:method = "[ error ]"
        $script:requestUri = "[ error ]"
        }
    }  #InitializeVariables


Here I create the JSON structure containing the field values and submit it to my Jira instance. The REST method invoked is POST for creating an issue, and PUT for updating one (this has been established in the InitializeVariables function.).

function PerformOperation
    {
    if ($script:attemptConnection)
        {
        $bodyString = @{
            update = @{
            }

            fields=@{

            project=@{key="$script:projectKey"} # can be omitted when updating an issue; or it can just "change" it to the value it already has

            #assignee = @{name = "$script:assignee"}
            description = "$script:description"
            duedate = "$script:dueDate"
            issuetype = @{name = "$script:issueType"}
            labels =  [string[]]"$script:label_1"
            priority = @{name = "$script:priority"}
            summary = "$script:summary"
            
            # comment out a line to omit it from item creation/update

            }}

        $bodyJSON = $bodyString | ConvertTo-Json -Depth 2 #-Compress

        try {
            $basicAuth = "Basic " + [System.Convert]::ToBase64String([System.Text.Encoding]::ASCII.GetBytes("$($script:Username):$script:password"))
            $headers = @{
                "Authorization" = $basicAuth
                "Content-Type"="application/json"
                }

            $response = Invoke-RestMethod -Uri $script:requestUri -Method $script:method -Headers $headers -Body $bodyJSON -UseBasicParsing

            if ($script:createOrUpdate.ToLower() -eq "create")
                {
                Write-Output "ID: $($response.id)"
                Write-Output "Key: $($response.key)"
                Write-Output "Self: $($response.self)"    
                }
            }
        catch {
            Write-Warning "Remote Server Response: $($_.Exception.Message)"
            Write-Output "Status Code: $($_.Exception.Response.StatusCode)"
            }
        }
    }  #PerformOperation


All that's left is to call these functions in sequence.

InitializeVariables
IdentifyUser
PerformOperation

No comments:

Post a Comment