【问题标题】:How to count all Pull Requests with Azure DevOps REST API如何使用 Azure DevOps REST API 计算所有拉取请求
【发布时间】:2019-12-03 02:04:26
【问题描述】:

我正在尝试使用 Azure DevOps REST API 来计算我们存储库中拉取请求的总数,并最终使用它来希望从 git 数据中获得一些更有用的信息。

我尝试使用对存储库的 GET 请求来返回拉取请求列表,但 Azure API 将响应限制为每个请求 101 个。您可以使用 $top 和 $skip 来更改返回的响应数量和响应,并使用 $count 来计算返回的响应。然而,这仍然将结果限制为 1,000 的绝对最大值并返回 PR 中包含的整个数据集,当我真的只需要知道其中的实例数时,我不需要它的数据完全返回,因为这会在大型回购中产生巨大的结果。

这是我正在使用的 GET 请求:

https://dev.azure.com/{organization}/{project}/_apis/git/repositories/{repository}/pullrequests?$top=999&$count=true&searchCriteria.status=all&api-version=5.0

这是我用来返回项目计数的测试脚本,使用 Postman

var body = JSON.parse(responseBody);
tests[body.value.length + " Pull Requests in this Repository" ] = true;

这会返回 101 的响应计数,正如预期但不希望的那样。非常感谢任何提示和技巧!

【问题讨论】:

  • 每个“页面”是否只限制 101 个结果?如,如果返回对象中存在 101 个结果的“下一页”,是否没有链接可以获取它们?
  • 一种解决方法可能是一个 powershell 脚本,它通过$top = 100$skip=0 检查从 1 到 100 的范围,然后通过 $top = 100$skip=100 等检查从 101 到 200 的范围......如果你这样做直到你得到一个小于 100 的响应,你知道你已经到了最后,可以工作还是?
  • @MarTin 您能否提供一个 powershell 脚本来执行此操作?我通过一个接一个地发送请求来实现这个概念,同时使用 $top=1000 代替它,它工作得很好,谢谢你。我的 powershell 经验很少,所以我不知道如何自动化它而不是手动发送请求,直到我看到响应
  • @Shepsims 我认为starian chen-MSFT 用他的回答解决了你的问题,对吗? :-)
  • 是的,成功了,谢谢你们的帮助!

标签: git azure-devops postman azure-devops-rest-api


【解决方案1】:

powershell的简单示例代码:

function GetPullRequest{
    param(
[string]$org,
[string]$project,
[string]$repo,
[string]$token
)
    $base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f "test",$token)))
    $count=0
    $i=0
    do{
        $uri="https://dev.azure.com/$org/$project/_apis/git/repositories/$repo/pullRequests?api-version=5.0&`$top=100&`$skip=$i"
        $i+=100
        Write-Output $uri
        $result= Invoke-RestMethod -Method Get -Uri $Uri -ContentType "application/json" -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} -Body $bodyJson
        Write-Output $result.Count
        $count+=$result.Count
        if($result.Count-lt 100){
            break;
        }
    }while($true)
    write-output "Finish. Total Pull Request count: $count";
}

GetPullRequest -org "your organization" -project "your teamproject" -repo "your repository" -token "your personal access token"

【讨论】:

  • 需要投入一点 &searchCriteria.status=all 让它返回,但除此之外,这是完美的,非常感谢!
【解决方案2】:

我在 python 中提供了一个答案,因为我相信这对某些人来说可能比 powershell 或 postman 脚本更有用,因为这是我最终在我的最终实现中使用的。

希望它可以帮助其他人!

首先是代码...

def count_PRs():
   skip = 0
   count = 0
   while True:
        # Retrieve next Pull Requests based on pager value, or all remaining if less than value
        req_url=("https://%s/%s//%s/_apis/git/repositories/%s/pullrequests?$top=%s&$skip=%s&searchCriteria.status=all&api-version=%s" % (instance, organization, project, repository, pager, skip, api_version))
        response = requests.get(req_url, auth=(username, password)).json()

        # If no data returned, break out of loop, otherwise count items returned
        if len(response["value"]) == 0:
            break
        else:
            count += len(response["value"])
            skip += pager

   return count

现在解释一下这里发生了什么,这样你就可以理解它,而不是盲目地使用它......

首先,请求 URL 是使用您之前应该定义的变量创建的。

req_url=("https://%s/%s//%s/_apis/git/repositories/%s/pullrequests?$top=%s&$skip=%s&searchCriteria.status=all&api-version=%s" % (instance, organization, project, repository, pager, skip, api_version))

它们是:实例、组织、项目、存储库、寻呼机、跳过、api_version

实例、组织、项目和存储库基于您的用例,因此我无法为您提供帮助。

“寻呼机”值是每次调用返回的项目数,从我的使用中我注意到 Azure API 当前将其上限设置为 1,000,但将来可能会改变,如果我注意到,我会尝试更新它。

“skip”值表示已经计算了哪些拉取请求,因此它从 0 开始,然后在循环中的每次迭代中递增 pager 值,这样它就不会多次计算同一个 PR。

下一行发送请求并将回复保存到响应变量中:

response = requests.get(req_url, auth=(username, password)).json()

有一个包含用户名和密码的身份验证标头。我之前通过 Azure DevOps 页面设置了个人访问令牌,并且您应该在此处使用 PAT 作为密码,这比尝试使用 OAuth2.0 进行身份验证要容易得多,我建议先这样做。

本部分检查您是否仍然在响应中收到新的拉取请求,如果没有,它会跳出 while 循环以返回计数。

if len(response["value"]) == 0:
    break

如果您确实收到了响应,本节将对拉取请求进行计数并将其添加到计数中,然后在进入下一次迭代之前增加 skip 变量

else:
    count += len(response["value"])
    skip += pager

这花了我很长时间才弄清楚,我真的希望它可以在将来对您有所帮助,如果可以,请考虑投票!您有任何问题都可以在 cmets 中留言,我会尽快为您提供帮助。

【讨论】:

    【解决方案3】:

    Azure API 将每个请求的响应限制为 101 个

    这是设计的默认限制。由于您可能在单个 API 请求中检索数千条记录,并且它分页以仅在每次调用时提供一定数量的结果。因此,您需要使用topskip 对其余部分进行分页。

    此外,如果您不想查看其返回的数据,因为这会在 repos 上产生巨大的结果,这里有一个脚本可以帮助您直接实现计数:

      var body = JSON.parse(responseBody);
      tests["Count: "  + body.value.length] = true;
    

    将此脚本添加到test中,执行api后结果会显示在Test result中,参考下图:

    这个时候,我不会被大数据结果所困扰。

    希望能给你一些帮助。

    【讨论】:

    • 我可能应该将它包含在原始问题中,现在将添加它,但我使用的脚本几乎与已经相同,它计算返回的实例而不是总数。使用 $top 设置为 10,000 应该可以解决问题,因为我知道有大约 5,000 个实例,但似乎它仍然将返回的项目限制在最多 1,000 个(比 101 好,但仍然没有帮助)没有有什么关系。有什么技巧可以解决这个问题?
    • 此外,在 Postman 控制台中,它现在甚至不显示计数,而是简单地说,“不显示大于 1MB 的响应”
    • @Shepsims workaound 为它复制从邮递员控制台返回超过 1 mb 数据的 url 并在浏览器地址栏中运行它
    【解决方案4】:

    以下代码可能会有所帮助。 在这里,我正在提取针对项目的所有拉取请求。输出将被推送到 excel 中。请关注 cmets inline

    #+++Declaring all the parameters+++
    Param(
       [string]$collectionurl = "https://dev.azure.com/<organizationname>",
       [string]$project = "<Projectname>",
       [string]$token = "<PAT>",
       [string]$Filename = '<local path>'
    )
    
    #++PassingToken as Base 64++
    $auth = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f "",$token)))
    
    #++Generating Pull Request Base URL++
    $pullRequestURL = "$collectionurl/$project/_apis/git/pullrequests?searchCriteria.status=all&&api-version=5.1"
    
    #++Passing Respone in variable++           
    $pullRequest = (Invoke-RestMethod -Uri $pullRequestURL -Method Get -Headers @{Authorization=("Basic {0}" -f $auth)}).value
    
    #++Displaying result on screen( this step can be avoided )++
    Write-Output $pullRequest
    #++Counting Active vs Completed Request++
    Write-host "Count of active pull request:" ($pullRequest | where({$_.status -eq 'active'})).count
    Write-host "Count of completed pull request:" ($pullRequest | where({$_.status -eq 'completed'})).count
    
    #++Temporary Object to store varaible values"
    $output = @()
    Write-Output $output
    
    #++Extracting Values and storing in Object++
    foreach ($request in $pullRequest) {
        $customObject = new-object PSObject -property @{
              "RepositoryName" = $request.repository.name
              "Status" = $request.status
              "PullRequestId" = $request.pullRequestId
              "SourceBranch" = $request.sourceRefName
              "TargetBranch" = $request.targetRefName
              "CreatedBy" = $request.createdBy.displayName
              "Reviewers" = $request.reviewers.displayName
              "CreatedDate" = $request.creationDate
              "ClosedDate" = $request.closedDate
              "MergeStrategy" = $request.completionOptions.mergeStrategy
            }
            $output += $customObject
            }
    #++Generating excel out of Object++     
    $output | Select `
                RepositoryName,
                Status,
                PullRequestId,
                SourceBranch,
                TargetBranch,
                CreatedBy,
                Reviewers,
                CreatedDate,
                ClosedDate,
                MergeStrategy | export-csv -Path $Filename -NoTypeInformation
    

    【讨论】:

      猜你喜欢
      • 2021-03-08
      • 2021-01-15
      • 1970-01-01
      • 2021-04-20
      • 2020-06-27
      • 2022-01-11
      • 1970-01-01
      • 2022-07-11
      • 1970-01-01
      相关资源
      最近更新 更多