Public/Set-JiraIssueLabel.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
function Set-JiraIssueLabel {
    <#
    .Synopsis
        Modifies labels on an existing JIRA issue
    .DESCRIPTION
        This function modifies labels on an existing JIRA issue. There are
        four supported operations on labels:
 
        * Add: appends additional labels to the labels that an issue already has
        * Remove: Removes labels from an issue's current labels
        * Set: erases the existing labels on the issue and replaces them with
        the provided values
        * Clear: removes all labels from the issue
    .EXAMPLE
        Set-JiraIssueLabel -Issue TEST-01 -Set 'fixed'
        This example replaces all existing labels on issue TEST-01 with one
        label, "fixed".
    .EXAMPLE
        Get-JiraIssue -Query 'created >= -7d AND reporter in (joeSmith)' | Set-JiraIssueLabel -Add 'enhancement'
        This example adds the "enhancement" label to all issues matching the JQL - in this case,
        all issues created by user joeSmith in the last 7 days.
    .EXAMPLE
        Get-JiraIssue TEST-01 | Set-JiraIssueLabel -Clear
        This example removes all labels from the issue TEST-01.
    .INPUTS
       [JiraPS.Issue[]] The JIRA issue that should be modified
    .OUTPUTS
        If the -PassThru parameter is provided, this function will provide a reference
        to the JIRA issue modified. Otherwise, this function does not provide output.
    #>

    [CmdletBinding(
        SupportsShouldProcess = $true,
        DefaultParameterSetName = 'ReplaceLabels'
    )]
    param(
        # Issue key or JiraPS.Issue object returned from Get-JiraIssue
        [Parameter(
            Position = 0,
            Mandatory = $true,
            ValueFromPipeline = $true,
            ValueFromPipelineByPropertyName = $true
        )]
        [Alias('Key')]
        [Object[]] $Issue,

        # List of labels that will be set to the issue.
        # Any label that was already assigned to the issue will be removed.
        [Parameter(
            Mandatory = $true,
            ParameterSetName = 'ReplaceLabels'
        )]
        [Alias('Label', 'Replace')]
        [String[]] $Set,

        # Existing labels to be added.
        [Parameter(ParameterSetName = 'ModifyLabels')]
        [String[]] $Add,

        # Existing labels to be removed.
        [Parameter(ParameterSetName = 'ModifyLabels')]
        [String[]] $Remove,

        # Remove all labels.
        [Parameter(ParameterSetName = 'ClearLabels')]
        [Switch] $Clear,

        # Credentials to use to connect to JIRA.
        # If not specified, this function will use anonymous access.
        [Parameter(Mandatory = $false)]
        [System.Management.Automation.PSCredential] $Credential,

        # Whether output should be provided after invoking this function.
        [Switch] $PassThru
    )

    begin {
    }

    process {
        foreach ($i in $Issue) {
            Write-Debug "[Set-JiraIssueLabel] Obtaining reference to issue"
            $issueObj = Get-JiraIssue -InputObject $i -Credential $Credential

            if ($issueObj) {
                $currentLabels = @($issueObj.labels)
                $url = $issueObj.RestURL
                $isDirty = $true

                # As of JIRA 6.4, the Add and Remove verbs in the REST API for
                # updating issues do not support arrays of parameters - you
                # need to pass a single label to add or remove per API call.

                # Instead, we'll do some fancy footwork with the existing
                # issue object and use the Set verb for everything, so we only
                # have to make one call to JIRA.

                if ($Clear) {
                    Write-Debug "[Set-JiraIssueLabel] Clearing all labels"
                    $newLabels = @()
                }
                elseif ($PSCmdlet.ParameterSetName -eq 'ReplaceLabels') {
                    Write-Debug "[Set-JiraIssueLabel] Set parameter was used; existing labels will be overwritten"
                    $newLabels = $Set
                }
                elseif ($null -eq $currentLabels -or $currentLabels.Count -eq 0) {
                    Write-Debug "[Set-JiraIssueLabel] Issue currently has no labels"
                    if ($Add) {
                        Write-Debug "[Set-JiraIssueLabel] Setting labels to Add parameter"
                        $newLabels = $Add
                    }
                    else {
                        Write-Debug "[Set-JiraIssueLabel] No labels were specified to be added; nothing to do"
                        $isDirty = $false
                    }
                }
                else {
                    Write-Debug "[Set-JiraIssueLabel] Calculating new labels"
                    # If $Add is not provided (null), this can end up with an
                    # extra $null being added to the array, so we need to
                    # account for that in the Where-Object as well as the
                    # Remove parameter.
                    $newLabels = $currentLabels + $Add | Where-Object -FilterScript {$_ -ne $null -and $Remove -notcontains $_}
                }

                if ($isDirty) {
                    Write-Debug "[Set-JiraIssueLabel] New labels for the issue: [$($newLabels -join ',')]"

                    $props = @{
                        'update' = @{
                            'labels' = @(
                                @{
                                    'set' = @($newLabels);
                                }
                            );
                        }
                    }

                    Write-Debug "[Set-JiraIssueLabel] Converting labels to JSON"
                    $json = ConvertTo-Json -InputObject $props -Depth 4

                    Write-Debug "[Set-JiraIssueLabel] JSON:`n$json"
                    Write-Debug "[Remove-JiraGroup] Checking for -WhatIf and Confirm"
                    if ($PSCmdlet.ShouldProcess($Issue, "Updating Issue [labels] from JIRA")) {
                        Write-Debug "[Set-JiraIssueLabel] Preparing for blastoff!"
                        # Should return no results
                        Invoke-JiraMethod -Method Put -URI $url -Body $json -Credential $Credential
                    }
                }
                else {
                    Write-Debug "[Set-JiraIssueLabel] No changes are necessary."
                }

                if ($PassThru) {
                    Write-Debug "[Set-JiraIssue] PassThru was specified. Obtaining updated reference to issue"
                    Get-JiraIssue -Key $issueObj.Key -Credential $Credential
                }
            }
            else {
                Write-Debug "[Set-JiraIssue] Unable to identify issue [$i]. Writing error message."
                Write-Error "Unable to identify issue [$i]"
            }
        }
    }

    end {
        Write-Debug "[Set-JiraIssueLabel] Complete"
    }
}