You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Azure DevOps自动创建develop到main的PR及脚本故障排查

问题分析与修复方案

问题1:误判已有活跃PR

原因

  1. 未过滤PR状态:你调用的检查PR的API默认返回所有状态的PR(包括已关闭、已完成的历史PR),而非仅活跃状态。即使当前没有活跃PR,只要历史上存在过develop到main的PR,$resultActivePR.count就会大于0,触发误判。
  2. 判断逻辑不准确:Azure DevOps API返回的PR列表结构包含count和value数组,直接使用$resultActivePR.count可能受历史数据影响,应基于value数组的实际长度判断活跃PR数量。

修复

  • 修改检查PR的API地址,添加searchCriteria.status=active参数过滤仅活跃PR:
    $uriCheckActivePR = "https://dev.azure.com/$organization/$teamProject/_apis/git/repositories/$repoName/pullrequests?searchCriteria.targetRefName=$branchTarget&searchCriteria.sourceRefName=$branchSource&searchCriteria.status=active&api-version=5.1"
    
  • 更新判断逻辑,基于value数组长度判断:
    if ($resultActivePR.value.Count -gt 0) 
    {
        Write-Host "PR exists already"
        Return
    }
    

问题2:无法创建PR

原因

  1. JSON格式错误:手动拼接的请求体使用了单引号,但JSON规范要求属性名和值必须用双引号,导致API无法解析请求。
  2. Token未正确接收:脚本未声明参数接收传入的-token值,$token变量未定义,生成的认证信息无效,API请求因权限不足被拒绝。
  3. (可选)权限不足:构建服务账号(如[项目名] Build Service)可能没有创建PR的权限,需确保其拥有Contributor或更高级别的权限。

修复

  1. 添加参数声明:在脚本开头添加参数定义,接收传入的token:
    param(
        [Parameter(Mandatory=$true)]
        [string]$token
    )
    
  2. 用ConvertTo-Json生成合法请求体:避免手动拼接JSON的错误:
    $prBody = @{
        sourceRefName = $branchSource
        targetRefName = $branchTarget
        title = "Sync changes from $branchSource"
    } | ConvertTo-Json
    
    $result = Invoke-RestMethod -Uri $uriCreatePR -Method Post -ContentType "application/json" -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} -Body $prBody
    
  3. 验证权限:在Azure DevOps项目设置的「权限」中,确保构建服务账号拥有创建PR的权限(可添加到Contributor组)。

完整修改后的脚本片段

param(
    [Parameter(Mandatory=$true)]
    [string]$token
)

$user = "PrivateToken"
$branchTarget = "refs/heads/main"
$branchSource = "refs/heads/develop"
$branchTragetPath = $branchTarget -replace "refs/heads/", ""
$teamProject = "team"
$repoName = "$(Build.Repository.Name)"
$organization = "org"

$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $user,$token)))
 
$uriBranchStatus = "https://dev.azure.com/$organization/$teamProject/_apis/git/repositories/$repoName/stats/branches?name=$branchTragetPath&api-version=5.1"
$uriCheckActivePR = "https://dev.azure.com/$organization/$teamProject/_apis/git/repositories/$repoName/pullrequests?searchCriteria.targetRefName=$branchTarget&searchCriteria.sourceRefName=$branchSource&searchCriteria.status=active&api-version=5.1"
$uriCreatePR = "https://dev.azure.com/$organization/$teamProject/_apis/git/repositories/$repoName/pullrequests?api-version=5.1"

$resultStatus = Invoke-RestMethod -Uri $uriBranchStatus -Method Get -ContentType "application/json" -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)}

if ($resultStatus.behindCount -eq 0)
{
    Write-Host "Current branch contains last changes from main"
    Return
}

$resultActivePR = Invoke-RestMethod -Uri $uriCheckActivePR -Method Get -ContentType "application/json" -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)}

if ($resultActivePR.value.Count -gt 0) 
{
    Write-Host "PR exists already"
    Return
}

$prBody = @{
    sourceRefName = $branchSource
    targetRefName = $branchTarget
    title = "Sync changes from $branchSource"
} | ConvertTo-Json

$result = Invoke-RestMethod -Uri $uriCreatePR -Method Post -ContentType "application/json" -Headers @{Authorization=("Basic {0}" -f $base64AuthInfo)} -Body $prBody

Write-Host "Created PR" $result.pullRequestId

内容的提问来源于stack exchange,提问作者user989988

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 09:37:05