为什么我在使用 VSTS API 完成拉取请求时收到 400 - 错误请求

Why am I getting a 400 - Bad Request when completing a pull request using the VSTS API

我猜这是一个权限问题。我知道 URI 和 body 等都是正确的,因为它在 header.

中的不同授权下工作正常

我尝试将 _admin/_versioncontrol 下的权限调整为“允许”,根据创建拉取请求时对我有用的内容。参考:

虽然我可以 create/abandon 请求,但我似乎无法 auto-complete 他们。

我错过了什么?

编辑 1(根据 starian chen-MSFT 的要求):

当我在我的 powershell 脚本中捕获异常并执行 Write-Output $_.Exception 时,我得到:

The remote server returned an error: (400) Bad Request.

当我从 try-catch 块中删除 Invoke-RestMethod 时,我将其打印到合并输出中:

2018-03-10T03:22:13.3706092Z Calling https://<my_vsts_account>.visualstudio.com/DefaultCollection/_apis/git/repositories/<my_git_repo_id>/pullRequests/<my_pr_id>?api-version=3.0 with body:
2018-03-10T03:22:13.3727606Z {
2018-03-10T03:22:13.3727838Z     "autoCompleteSetBy":  {
2018-03-10T03:22:13.3728135Z                               "id":  "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
2018-03-10T03:22:13.3728388Z                           },
2018-03-10T03:22:13.3728593Z     "completionOptions":  {
2018-03-10T03:22:13.3728942Z                               "mergeCommitMessage":  "Auto completing pull request",
2018-03-10T03:22:13.3729252Z                               "squashMerge":  "false",
2018-03-10T03:22:13.3729845Z                               "deleteSourceBranch":  "false"
2018-03-10T03:22:13.3730053Z                           }
2018-03-10T03:22:13.3730229Z }
2018-03-10T03:22:13.6040452Z ##[error]Invoke-RestMethod : {"$id":"1","innerException":null,"message":"Invalid argument value.\r\nParameter name: Invalid 
pull request auto complete set by id. Valid values are either the current user identity id, or an empty guid (to unset 
auto complete).","typeName":"Microsoft.TeamFoundation.SourceControl.WebServer.InvalidArgumentValueException, 
Microsoft.TeamFoundation.SourceControl.WebServer","typeKey":"InvalidArgumentValueException","errorCode":0,"eventId":0}
At C:\Development\.agent\scripts\do-ci.ps1:562 char:33
+ ... ry_result = Invoke-RestMethod -Uri $uri -Method Patch -UseDefaultCred ...
+                 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-RestMethod], WebExc 
   eption
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeRestMethodCommand

再一次,当我将上面的 URI 和 body 复制粘贴到 Postman 中时,它工作得很好。看到我的 Powershell 脚本和 Postman 调用的唯一区别是授权 header,这意味着这是一个权限问题,而且是单独的权限问题。

你需要指定相同的用户id(当前授权用户)通过REST API("autoCompleteSetBy":{"id":xxx})更新pull request到Auto-Complete,否则你会得到400错误。

如果您只想完成拉取请求,可以通过 REST API 将拉取请求状态更新为已完成。

更新:

创建拉取请求和获取用户 ID 的简单代码:

param(
[string]$project,
[string]$repo,
[string]$sourceBranch,
[string]$targetBranch,
[string]$title,
[string]$des,
[string]$token
)
$bodyObj=@{
  "sourceRefName"="refs/heads/$sourceBranch";
  "targetRefName"= "refs/heads/$targetBranch";
  "title"= "$title";
  "description"="$des";
}
$bodyJson=$bodyObj| ConvertTo-Json
$uri="https://XXX.visualstudio.com/DefaultCollection/$project/_apis/git/repositories/$repo/pullRequests?api-version=3.0"
Write-Output $bodyJson
Write-Output $uri
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f "test",$token)))
$result=Invoke-RestMethod -Method POST -Uri $Uri -ContentType "application/json" -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} -Body $bodyJson
$serviceId=$result.createdBy.id
Write-Host $serviceId
Write-Host "##vso[task.setvariable variable=userId;]$serviceId"