【问题标题】:Get real source branch name in VSTS Pull Request在 VSTS 拉取请求中获取真实的源分支名称
【发布时间】:2016-06-27 06:47:26
【问题描述】:

我们将 Visual Studio Team Systems 与 Git 和 Team System Build(以前的 Build vNext)一起使用。 当我们执行拉取请求时,会触发一个新的构建,用于运行单元测试并部署到一个隔离的测试系统。 要执行对隔离系统的部署,我需要在构建过程中获取真实的源分支名称。 然而Build.SourceBranchName 变量总是“合并”,

例如:

将请求从源 FOO 拉到目标 BAR Build.SourceBranch 是“refs/pull/1/merge”,因此 Build.SourceBranchName 是“合并”。 但我需要以某种方式获得“FOO”来运行我的 Power Shell 脚本来配置系统。

有没有办法在 VSTS 中的 Git 拉取请求中获取真正的源分支名称?

【问题讨论】:

    标签: git azure-devops azure-pipelines


    【解决方案1】:

    VSTS 现在有 System.PullRequest.SourceBranch 和 System.PullRequest.TargetBranch 变量。 这应该可以解决您的问题而无需编写任何自定义脚本

    Build Variables

    【讨论】:

    • 不幸的是,如果使用构建策略开始构建拉取请求,则无法在发布管道中获取拉取请求 ID。这些变量只会让你“合并”给定“refs/pull/165/merge”developercommunity.visualstudio.com/content/problem/529341/…
    • 该链接指向Build.SourceBranch 变量。我推荐System.PullRequest.XxxBranch。这是我在 PR 构建中得到的:system.pullRequest.pullRequestId : {numeric id of PR}system.pullRequest.sourceBranch : refs/heads/{PR source branch name}system.pullRequest.targetBranch : refs/heads/{PR target branch name (master)}
    • 请注意,System.PullRequest 变量不会被设置,除非它被拉取请求排队。
    【解决方案2】:

    这没有任何变量,但您可以创建一个 power-shell 脚本来通过Rest API 获取它。

    [String]$projecturi = "$env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI"
    [String]$sourcebranch = "$env:BUILD_SOURCEBRANCH"
    [String]$repoid = "$env:BUILD_REPOSITORY_ID"
    
    $username="alternativeusername"
    $password="alternativepassword"
    
    $basicAuth= ("{0}:{1}"-f $username,$password)
    $basicAuth=[System.Text.Encoding]::UTF8.GetBytes($basicAuth)
    $basicAuth=[System.Convert]::ToBase64String($basicAuth)
    $headers= @{Authorization=("Basic {0}"-f $basicAuth)}
    
    #get pull request ID via regex
    $pullrequest = "refs/pull/+(?<pullnumber>\w+?)/merge+"
    if($sourcebranch -match $pullrequest){        
            $pullrequestid = $Matches.pullnumber;
        }
    else { write-host "Cannot find pull request ID" }
    
    #get pull request information via API
    $url= $projecturi + "_apis/git/repositories/" + $repoid + "/pullRequests/" + $pullrequestid + "?api-version=1.0-preview.1"
    
    Write-Host $url
    
    $getpullrequest = Invoke-RestMethod -Uri $url -headers $headers -Method Get
    
    #get sourcebranch and targetbranch
    $sourceref = $getpullrequest.sourceRefName
    $targetref = $getpullrequest.targetRefName
    

    【讨论】:

    • 谢谢,脚本就像一个魅力。我对其进行了一些修改,以便更容易调试并设置一个变量以在以后的构建任务中使用。
    【解决方案3】:

    您可以创建一个 bash 脚本,将较短的分支名称分配给一个变量。

    # Bash script
    BRANCH_NAME=$(echo "$(System.PullRequest.TargetBranch)" | awk -F/ '{print $NF}')
    echo "##vso[task.setvariable variable=PullRequest_Target_Branch;]$BRANCH_NAME"
    

    然后您可以在管道中引用 $(PullRequest_Target_Branch)

    【讨论】:

    • 很棒的脚本!谢谢!
    【解决方案4】:

    如果在构建任务中使用,此脚本将从环境变量中读取参数,如果在构建任务外部使用,则使用提供的参数。变量 $sourcebranch 将被设置为在以后的构建任务中使用。

    [CmdletBinding()]
    param (
        [Parameter(Mandatory=$false)][string]$projectUri = "$env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI",
        [Parameter(Mandatory=$false)][string]$branch = "$env:BUILD_branch",
        [Parameter(Mandatory=$false)][string]$repositoryName = "$env:BUILD_REPOSITORY_NAME",
        [Parameter(Mandatory=$false)][string]$projectName = "$env:SYSTEM_TEAMPROJECT",
        [Parameter(Mandatory=$false)][string]$oAuthToken = "$env:SYSTEM_ACCESSTOKEN",
        [Parameter(Mandatory=$false)][string]$username,
        [Parameter(Mandatory=$false)][string]$password
    )
    
    #check all parameters
    if(!$oAuthToken) {
        if(!$username -or !$password) {
            throw "You must either supply an OAuth Token or a username and a password. You can supply the token via the environment variable SYSTEM_ACCESSTOKEN"
        }
    
        $basicAuth= ("{0}:{1}"-f $username,$password)
        $basicAuth=[System.Text.Encoding]::UTF8.GetBytes($basicAuth)
        $basicAuth=[System.Convert]::ToBase64String($basicAuth)
        $headers= @{Authorization=("Basic {0}"-f $basicAuth)}
    }
    else {
        $headers= @{Authorization="Bearer $oAuthToken"}
    }
    
    if(!$projectUri) {
        throw "You must supply a project uri or set the Environment variable SYSTEM_TEAMFOUNDATIONCOLLECTIONURI"
    }
    
    if(!$branch) {
        throw "You must supply a branch or set the Environment variable BUILD_branch"
    }
    
    if(!$repositoryName) {
        throw "You must supply a repository name or set the Environment variable BUILD_REPOSITORY_NAME"
    }
    
    if(!$projectName) {
        throw "You must supply a project name or set the Environment variable SYSTEM_TEAMPROJECT"
    }
    
    #get pull request ID via regex
    $pullrequest = "refs/pull/+(?<pullnumber>\w+?)/merge+"
    if($branch -match $pullrequest) {        
        $pullrequestid = $Matches.pullnumber;
        Write-Output "Pull request ID is $pullrequestid"
    }
    else { 
        Write-Output "Cannot find pull request ID" 
    }
    
    #get pull request information via API
    $url= $projectUri + "DefaultCollection/$projectName/_apis/git/repositories/$repositoryName/pullRequests/$pullrequestid\?api-version=1.0-preview.1"
    Write-Output "Getting info from $url"
    $getpullrequest = Invoke-RestMethod -Uri $url -headers $headers -Method Get
    
    #get sourcebranch and targetbranch ref
    $sourceref = $getpullrequest.sourceRefName
    $targetref = $getpullrequest.targetRefName
    
    #get the branch name via regex
    $branchref = "refs/heads/(?<realBranchname>.*)"
    if($sourceref -match $branchref) {        
        $sourcebranch = $Matches.realBranchname;
        Write-Output "Real source branch is $sourcebranch"
    }
    else { 
        Write-Output "Cannot find real source branch" 
    }
    if($targetref -match $branchref) {        
        $targetbranch = $Matches.realBranchname;
        Write-Output "Real target branch is $targetbranch"
    }
    else { 
        Write-Output "Cannot find real target branch" 
    }
    
    #set a variable "sourcebranch" to use it in another build task
    Write-Output "##vso[task.setvariable variable=sourcebranch;]$sourcebranch"
    

    【讨论】:

      【解决方案5】:

      如果没有此错误,您仍然无法在构建定义中使用 $(System.PullRequest.SourceBranch) BuildNumberFormat:

      内部版本号格式字符串$(BuildDefinitionName)-$(System.PullRequest.SourceBranch)-$(Date:yyyyMMdd)$(Rev:.r) 生成了内部版本号“MyBuildName-refs/heads/myBranch-20190831.1”,其中包含无效字符、太长或以 ' 结尾。 '。

      【讨论】:

        【解决方案6】:

        现在好像你可以使用Build.SourceBranchName

        构建排队的触发存储库中的分支名称。 Git repo 分支或拉取请求:参考中的最后一个路径段。例如,在refs/heads/master 中,此值为master。在refs/heads/feature/tools 中,此值为tools。

        Source

        【讨论】:

          猜你喜欢
          • 2023-02-24
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-05-26
          • 1970-01-01
          • 2019-02-16
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多