我如何让审阅者自动批准功能测试完成的拉取请求?

How do I have a reviewer automatically approve a pull request on functional test completion?

我有一个 Azure DevOps Git 存储库,它位于云端的 Azure DevOps 中。 我们正在使用 Pull Requests 来管理代码合并到我们的发布分支。

功能分支分配了一个自动审阅者,其唯一目的是在我们的持续部署环境中成功完成功能测试时添加批准票。我们的想法是,这将对自动合并到我们的发布分支提供更强大的检查。

我有一个部分 Powershell API 命中 Azure DevOps REST API 会让我参考 pull request 上的审阅者,但我尝试投射失败通过 API.

对审阅者进行投票或批准

文档建议我需要将审阅者 ID 传递到以下 URI

https://dev.azure.com/$organization/$projectId/_apis/git/repositories/$repositoryId/pullrequests/$pullRequestId/reviewers/$reviewerId?api-version=5.0

当我使用从拉取请求中获得的审阅者 ID 时

https://dev.azure.com/$organization/$projectId/_apis/git/repositories/$repositoryId/pullrequests

reviewerUrl : https://dev.azure.com/my-organization/be283e5e-0466-41ef-aeb7-24264e12f6d6/_apis/git/repositories/3c4b0093-30fc-4652-a39e-08bb442b1879/pullRequests/2/reviewers/a72ce17b-22de-41a0-b6a5-49e5ba189826
vote        : 10
isRequired  : True
displayName : testaccount@xxxxxxx.com
url         : https://spsprodcca1.vssps.visualstudio.com/A41d8d933-620f-4153-952c-4ee19c0e4c0b/_apis/Identities/a72ce17b-22de-41a0-b6a5-49e5ba189826
_links      : @{avatar=}
id          : a72ce17b-22de-41a0-b6a5-49e5ba189826
uniqueName  : testaccount@xxxxxxx.com
imageUrl    : https://dev.azure.com/my-organization/_api/_common/identityImage?id=a72ce17b-22de-41a0-b6a5-49e5ba189826

我收到以下错误

"Invalid argument value.\r\nParameter name: A valid reviewer ID must be supplied."

我不确定我的做法是否正确,但我希望我的 Octopus 部署在我们的目标环境中启动功能测试,然后在成功完成测试后,授予拉取请求批准自动测试审查者 通过 REST API.

我能找到的所有文档最终都将我指向该文档,但我终究无法了解如何为我的审阅者申请批准。

https://docs.microsoft.com/en-us/rest/api/azure/devops/git/pull%20request%20reviewers/create%20pull%20request%20reviewer?view=azure-devops-rest-5.0

我不认为使用虚假的拉取请求审阅者是可行的方法。相反,我建议考虑使用 Pull Request status.

扩展拉取请求工作流程

您使用 Status API 将自定义状态添加到您的拉取请求。您可以在开始测试(处于挂起状态)之前调用它,并在测试完成(成功或失败)后调用它。

注意几点:

  1. 只有审阅者可以 post 状态更新,因此 API 调用必须为希望批准拉取请求的审阅者使用 PAT。

  2. 批准拉取请求的审阅者必须具有存储库的贡献者访问权限才能批准拉取请求。否则,您将收到错误消息。

  3. 确保审阅者已添加到拉取请求中。例如,将其添加为文件夹的自动审阅者,以便所有拉取请求自动添加它。

  4. 在拉取请求 ($pullRequest.reviewers) 上找到的审阅者似乎与您使用 API 调用直接获取拉取请求审阅者有所不同。

  5. 用于更新拉取请求审阅者的 PATCH 版本在尝试更新现有审阅者时似乎会导致错误。您必须使用 PUT 更新现有审阅者的拉取请求批准。

这就是我为让它工作所做的:

管理的东西:

  • 确保审阅者在 Azure DevOps 中拥有帐户并且具有基本访问级别

  • 确保审阅者是项目团队的一部分,因此具有项目的贡献者访问权限,最重要的是可以批准拉取请求。

  • 确保审阅者拥有可用于 API 访问的 PAT 令牌。

API 东西

  • 使用分配给审阅者的 PAT 获取已知拉取请求的审阅者:

  • 更新审稿人票数为10

  • 确保评论者数据正确转换为 JSON 格式。

  • 确保您通过 PUT API 调用传递的 headers 具有正确的授权和 Content-Type。 "Basic <Base64String>""application/json"

function ConvertTo-Base64 {

    [CmdletBinding()]
    param([Parameter(Mandatory=$true)][System.String]$input)

    $inputBytes = [System.Text.Encoding]::ASCII.GetBytes($input);
    $inputBase64 = [System.Convert]::ToBase64String($inputBytes);
    return $inputBase64
}

function Get-AzureDevOpsPullRequestReviewer {

    [CmdletBinding()]
    param([Parameter(Mandatory=$true)][System.String]$token,
          [Parameter(Mandatory=$true)][System.String]$organization,
          [Parameter(Mandatory=$true)][System.String]$projectId,
          [Parameter(Mandatory=$true)][System.String]$repositoryId,
          [Parameter(Mandatory=$true)][System.String]$pullRequestId,
          [Parameter(Mandatory=$false)][System.String]$reviewerId=$null)

    $uri = "https://dev.azure.com/$organization/$projectId/_apis/git/repositories/$repositoryId/pullrequests/$pullrequestId/reviewers";

    if ($reviewerId) { $uri = "$uri/$reviewerId" }

    $uri = "$uri`?api-version=5.0";

    $tokenBase64 = ConvertTo-Base64(":$token");

    $headers = @{
        "Accept" = "application/json";
        "Authorization" = "Basic $tokenBase64";
    }

    $response = Invoke-WebRequest -Uri $uri -headers $headers;

    $content = ConvertFrom-Json($response.Content);
    if ($reviewerId) { return $content } else { return $content.value }
}

function Approve-AzureDevOpsPullRequest {

    [CmdletBinding()]
    param([Parameter(Mandatory=$true)][System.String]$token,
          [Parameter(Mandatory=$true)][System.String]$organization,
          [Parameter(Mandatory=$true)][System.String]$projectId,
          [Parameter(Mandatory=$true)][System.String]$repositoryId,
          [Parameter(Mandatory=$true)][System.String]$pullRequestId,
          [Parameter(Mandatory=$true)]$reviewer)

    $uri = "https://dev.azure.com/$organization/$projectId/_apis/git/repositories/$repositoryId/pullrequests/$pullRequestId/reviewers/$($reviewer.id)`?api-version=5.0"

    $tokenBase64 = ConvertTo-Base64(":$token");

    $headers = @{
        "Accept" = "application/json";
        "Authorization" = "Basic $tokenBase64";
        "Content-Type" = "application/json";
    }

    $body = ConvertTo-Json($reviewer);

    $response = Invoke-WebRequest -Uri $uri -headers $headers -body $body -Method Put

    return $response;
}

$myOrganization  = "benco-devops";
$myProjectId     = "47b0a6fc-a58f-4bbf-9950-2d5e33ae0587";
$myRepositoryId  = "1582ab2b-ae01-41e1-9695-f9966fdd7985";
$myReviewerId    = "ben-project-pipeline@benco-devops.com";
$myReviewerPAT   = "1z3xq9zmw1syznfhqzoeaoppbx2xsowvqscgnowuin7xkxk5fy7c";
$myPullRequestId = 2;

$reviewer = Get-AzureDevopsPullRequestReviewer -token $myReviewerPAT -organization $myOrganization -projectId $myProjectId -repositoryId $myRepositoryId -pullRequestId $myPullRequestId | ? uniqueId -eq $myReviewerId;

$reviewer.votes = 10;

Approve-AzureDevOpsPullRequest -token $myReviewerPAT -organization $myOrganization -projectId $myProjectId -repositoryId $myRepositoryId -pullRequestId $myPullRequestId -reviewer $reviewer;