|
| 1 | +function Set-AzDoPullRequest { |
| 2 | + <# |
| 3 | +.SYNOPSIS |
| 4 | + Retrieves pull request information from Azure DevOps. |
| 5 | +
|
| 6 | +.DESCRIPTION |
| 7 | + This function fetches pull request details using Azure DevOps REST API. |
| 8 | +
|
| 9 | +.PARAMETER CollectionUri |
| 10 | + The base URL of the Azure DevOps organization (e.g., https://dev.azure.com/my-org). |
| 11 | +
|
| 12 | +.PARAMETER ProjectName |
| 13 | + The name of the Azure DevOps project. |
| 14 | +
|
| 15 | +.PARAMETER RepositoryName |
| 16 | + The name of the repository (optional for project-wide pull request queries). |
| 17 | +
|
| 18 | +.PARAMETER PullRequestId |
| 19 | + The ID of a specific pull request (optional for listing all pull requests). |
| 20 | +
|
| 21 | +.PARAMETER Status |
| 22 | + The new status of the pull request. Allowed values: active, abandoned, completed. |
| 23 | +
|
| 24 | +.PARAMETER Title |
| 25 | + The new title for the pull request (max 256 characters). |
| 26 | +
|
| 27 | +.PARAMETER Description |
| 28 | + The new description for the pull request (max 4000 characters). |
| 29 | +
|
| 30 | +.PARAMETER CompletionOptions |
| 31 | + Specifies how the PR should be completed. Example: @{ deleteSourceBranch = $true; mergeCommitMessage = "Merged PR" } |
| 32 | +
|
| 33 | +.PARAMETER MergeOptions |
| 34 | + Specifies how the PR should be merged. Allowed values: noMerge, squash, rebase, rebaseMerge. |
| 35 | +
|
| 36 | +.PARAMETER AutoCompleteSetBy |
| 37 | + The Azure DevOps user ID who sets the PR to auto-complete. |
| 38 | +
|
| 39 | +.PARAMETER TargetRefName |
| 40 | + The new target branch for the pull request. Example: "main" (automatically prefixed with "refs/heads/"). |
| 41 | + Retargeting a pull request means changing the destination branch where the pull request will be merged. |
| 42 | +
|
| 43 | +.EXAMPLE |
| 44 | + # Update only the title and description of a pull request |
| 45 | + Set-AzDoPullRequest -CollectionUri "https://dev.azure.com/my-org" -ProjectName "MyProject" -RepositoryName "Repo" -PullRequestId "123" -Title "Updated PR Title" -Description "New description" |
| 46 | +
|
| 47 | +.EXAMPLE |
| 48 | + # Set auto-complete with completion options |
| 49 | + $completionOptions = @{ |
| 50 | + deleteSourceBranch = $true |
| 51 | + mergeCommitMessage = "Auto-merging PR" |
| 52 | + } |
| 53 | + Set-AzDoPullRequest -CollectionUri "https://dev.azure.com/my-org" -ProjectName "MyProject" -RepositoryName "Repo" -PullRequestId "123" -AutoCompleteSetBy "user-id-123" -CompletionOptions $completionOptions |
| 54 | +
|
| 55 | +.EXAMPLE |
| 56 | + # Change the merge strategy to squash and complete the PR |
| 57 | + Set-AzDoPullRequest -CollectionUri "https://dev.azure.com/my-org" -ProjectName "MyProject" -RepositoryName "Repo" -PullRequestId "123" -MergeOptions "squash" -Status "completed" |
| 58 | +
|
| 59 | +.EXAMPLE |
| 60 | + # Retarget a pull request to a different branch |
| 61 | + Set-AzDoPullRequest -CollectionUri "https://dev.azure.com/my-org" -ProjectName "MyProject" -RepositoryName "Repo" -PullRequestId "123" -TargetRefName "develop" |
| 62 | +
|
| 63 | +.EXAMPLE |
| 64 | + # Set auto-complete for a pull request with a transition work item option |
| 65 | + $completionOptions = @{ |
| 66 | + transitionWorkItems = $true |
| 67 | + deleteSourceBranch = $true |
| 68 | + } |
| 69 | + Set-AzDoPullRequest -CollectionUri "https://dev.azure.com/my-org" -ProjectName "MyProject" -RepositoryName "Repo" -PullRequestId "123" -AutoCompleteSetBy "user-id-123" -CompletionOptions $completionOptions |
| 70 | +
|
| 71 | +
|
| 72 | +.OUTPUTS |
| 73 | + PSCustomObject with pull request details. |
| 74 | +
|
| 75 | +.NOTES |
| 76 | + Requires authentication with Azure DevOps REST API. |
| 77 | +
|
| 78 | + I have currently added the 'extra parameters' to the function, that are registered in the first paragraph on this page: |
| 79 | + https://learn.microsoft.com/en-us/rest/api/azure/devops/git/pull-requests/update?view=azure-devops-rest-7.2&tabs=HTTP#request-body |
| 80 | +
|
| 81 | + With the text currently being: |
| 82 | + These are the properties that can be updated with the API: |
| 83 | + Status |
| 84 | + Title |
| 85 | + Description (up to 4000 characters) |
| 86 | + CompletionOptions |
| 87 | + MergeOptions |
| 88 | + AutoCompleteSetBy.Id |
| 89 | + TargetRefName (when the PR retargeting feature is enabled) Attempting to update other properties outside of this list will either cause the server to throw an InvalidArgumentValueException, or to silently ignore the update. |
| 90 | +
|
| 91 | +.LINK |
| 92 | + https://learn.microsoft.com/en-us/rest/api/azure/devops/git/pull-requests/update?view=azure-devops-rest-7.2&tabs=HTTP#request-body |
| 93 | +#> |
| 94 | + [CmdletBinding(SupportsShouldProcess)] |
| 95 | + param ( |
| 96 | + [Parameter(Mandatory, ValueFromPipelineByPropertyName)] |
| 97 | + [ValidateScript({ Validate-CollectionUri -CollectionUri $_ })] |
| 98 | + [string] |
| 99 | + $CollectionUri, |
| 100 | + |
| 101 | + [Parameter(Mandatory, ValueFromPipelineByPropertyName, ValueFromPipeline)] |
| 102 | + [string] |
| 103 | + $ProjectName, |
| 104 | + |
| 105 | + [Parameter(Mandatory, ValueFromPipelineByPropertyName, ValueFromPipeline)] |
| 106 | + [string] |
| 107 | + $RepositoryName, |
| 108 | + |
| 109 | + [Parameter(Mandatory, ValueFromPipelineByPropertyName, ValueFromPipeline)] |
| 110 | + [string] |
| 111 | + $PullRequestId, |
| 112 | + |
| 113 | + [Parameter( ValueFromPipelineByPropertyName, ValueFromPipeline)] |
| 114 | + [ValidateSet('active', 'abandoned', 'completed', 'all')] |
| 115 | + [string] |
| 116 | + $Status, |
| 117 | + |
| 118 | + [Parameter( ValueFromPipelineByPropertyName, ValueFromPipeline)] |
| 119 | + [ValidateLength(0, 256)] |
| 120 | + [string] |
| 121 | + $Title, |
| 122 | + |
| 123 | + [Parameter( ValueFromPipelineByPropertyName, ValueFromPipeline)] |
| 124 | + [ValidateLength(0, 4000)] |
| 125 | + [string] |
| 126 | + $Description, |
| 127 | + |
| 128 | + [Parameter( ValueFromPipelineByPropertyName, ValueFromPipeline)] |
| 129 | + [ValidateSet('setAutoComplete', 'setAutoCompleteSetBy')] |
| 130 | + [string] |
| 131 | + $CompletionOptions, |
| 132 | + |
| 133 | + [Parameter( ValueFromPipelineByPropertyName, ValueFromPipeline)] |
| 134 | + [ValidateSet('noMerge', 'squash', 'rebase', 'rebaseMerge')] |
| 135 | + [string] |
| 136 | + $MergeOptions, |
| 137 | + |
| 138 | + [Parameter( ValueFromPipelineByPropertyName, ValueFromPipeline)] |
| 139 | + [string] |
| 140 | + $AutoCompleteSetBy, |
| 141 | + |
| 142 | + [Parameter( ValueFromPipelineByPropertyName, ValueFromPipeline)] |
| 143 | + [string] |
| 144 | + $TargetRefName |
| 145 | + ) |
| 146 | + |
| 147 | + begin { |
| 148 | + $result = @() |
| 149 | + Write-Verbose "Starting function: Set-AzDoPullRequest" |
| 150 | + } |
| 151 | + |
| 152 | + process { |
| 153 | + $uriBase = "$CollectionUri/$ProjectName/_apis/git" |
| 154 | + $apiVersion = "7.2-preview.2" |
| 155 | + |
| 156 | + $body = @{} |
| 157 | + |
| 158 | + if ($Status) { $body["status"] = $Status } |
| 159 | + if ($Title) { $body["title"] = $Title } |
| 160 | + if ($Description) { $body["description"] = $Description } |
| 161 | + if ($MergeOptions) { $body["mergeOptions"] = $MergeOptions } |
| 162 | + if ($TargetRefName) { $body["targetRefName"] = "refs/heads/$TargetRefName" } |
| 163 | + |
| 164 | + if ($CompletionOptions -and $CompletionOptions.Count -gt 0) { |
| 165 | + $body["completionOptions"] = $CompletionOptions |
| 166 | + } |
| 167 | + |
| 168 | + if ($AutoCompleteSetBy) { |
| 169 | + $body["autoCompleteSetBy"] = @{ id = $AutoCompleteSetBy } |
| 170 | + } |
| 171 | + |
| 172 | + if ($PSCmdlet.ShouldProcess($CollectionUri, "Get Pull Request from: $ProjectName")) { |
| 173 | + Write-Verbose "Calling API: $uri" |
| 174 | + |
| 175 | + $InvokeAzDoRestMethodSplat = @{ |
| 176 | + Uri = "$uriBase/repositories/$RepositoryName/pullrequests/$PullRequestId" |
| 177 | + Method = "PATCH" |
| 178 | + Version = $apiVersion |
| 179 | + Body = $Body |
| 180 | + } |
| 181 | + $response = Invoke-AzDoRestMethod @InvokeAzDoRestMethodSplat |
| 182 | + if ($response.value) { |
| 183 | + $result += $response.value |
| 184 | + } else { |
| 185 | + $result += $response |
| 186 | + } |
| 187 | + if ($result) { |
| 188 | + $result | ForEach-Object { |
| 189 | + [PSCustomObject]@{ |
| 190 | + CollectionUri = $CollectionUri |
| 191 | + ProjectName = $ProjectName |
| 192 | + RepoName = $RepoName |
| 193 | + PullRequest = $PSItem |
| 194 | + } |
| 195 | + } |
| 196 | + } |
| 197 | + } |
| 198 | + } |
| 199 | +} |
0 commit comments