为什么我在使用 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"
我猜这是一个权限问题。我知道 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"