【问题标题】:How to allow tags in Azure DevOps environment branch control如何在 Azure DevOps 环境分支控制中允许标记
【发布时间】:2021-01-15 03:48:53
【问题描述】:

我们希望限制与主分支的产品级服务连接作为保护,因此我们只部署经过审查的代码。现在我们在“Approvals and Checks”中将生产环境的主分支控制设置为refs/heads/master

这行得通,所以如果管道引用来自另一个存储库的任何模板,如果 ref 属性不是 master,这将失败。

现在我们还希望为自定义管道模板版本控制添加标签,以便管道可以按标签引用模板。我们可以这样做

 repositories:
    - repository: templates
      name: RepositoryWithTemplates
      type: git
      ref: refs/tags/0.0.1

但是,我们不想允许所有标签,而只允许提交的标签,它们已经在 master 上。

我们尝试通过在环境的“Approvals and Checks”中使用“Invoke Azure Function”来做到这一点,以便在 azure 中执行我们的自定义分支控制功能。此函数将需要检查每个存储库引用,如果存在标签,则运行 git 命令以检查此标签是否指向 master 上的提交。

但我们还没有找到一种方法来获取管道的所有资源/存储库以作为参数传递给函数,或从 Azure DevOps API 查询它们。

有人知道是否可以从环境变量或 API 中获取管道中使用的所有资源和存储库?不知何故,标准的“分支控制”检查对所有存储库都进行了检查,但它甚至暴露给自定义控制检查吗?

【问题讨论】:

  • 嗨 Andriy,这个问题有更新吗?
  • 嗨。我们将在星期一尝试建议的解决方案,然后当然会在这里写更新:)
  • 期待您的好消息。
  • 成功了! :) 在下面发布详细信息。

标签: git azure-devops azure-pipelines


【解决方案1】:

如何从 REST API 获取管道中使用的所有存储库:

您可以使用以下 REST API:

GET https://dev.azure.com/{Organization}/{Project}/_build/results?buildId={Build ID}&__rt=fps&__ver=2

它的响应体相当庞大,多个仓库的信息在:

fps -> dataProviders -> data -> ms.vss-build-web.run-details-data-provider -> repositoryResources

它显示所有源存储库,包括它们的名称、ID、版本等。

此 REST API 未记录在案,我从开发者控制台获取。

【讨论】:

  • 非常感谢!这看起来像我们需要的。我们会尝试的。
  • 现在我们正在尝试从 powershell 获取此请求,因为普通的令牌身份验证似乎不适用于未记录的 api。例如,此代码有效: $uri = "dev.azure.com{organization}/{project}/_apis/build/builds/21?api-version=6.1-preview.6" Invoke-RestMethod -Uri $uri -Method get - Headers $AzureDevOpsAuthenicationHeader 但同样不适用于您提供的 url,返回 401 错误。可能这个 API 需要一些其他的身份验证方式。
  • 我们找到了获得它的方法。实际上它适用于普通访问令牌,但我们现在必须将令牌权限设置为完全访问权限。
【解决方案2】:

谢谢你,简,这个解决方案终于对我们有用了!我们不需要创建任何访问令牌,我们只需使用来自 azure devops 的 system.AuthToken 中的一个。如果有人需要整个函数来检查标签是否在 master 上,代码如下:

# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)

function Output-Result([HttpStatusCode] $status, $text) {
    Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
        StatusCode = $status
        Body = $text
    })
}

function Call-Uri($uri, $authHeader) {
    try {
        $result = Invoke-RestMethod -Uri $uri -Method get -Headers $authHeader
    }
    catch {
        Output-Result -status ([HttpStatusCode]::InternalServerError) -text "Failed to call $($uri)"
        return $null    
    }
    return $result
}

# Write to the Azure Functions log stream.
Write-Host "PowerShell HTTP trigger function processed a request."

$organization = "ate-test-83"

$token = $Request.headers.AuthToken

$buildId = $Request.Body.BuildId
$projectName = $Request.Body.ProjectName

$authHeader = @{Authorization = 'Basic ' + [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(":$($token)")) }
$baseUri = "https://dev.azure.com/$($organization)/$($projectName)/"

$result = Call-Uri -uri ($baseUri + "_build/results?buildId=$($buildId)&__rt=fps&__ver=2") -authHeader $authHeader
if ($result -eq $null) {
    return
} 

$resources = $result.fps.dataProviders.data."ms.vss-build-web.run-details-data-provider".repositoryResources;
if ($resources.count -eq 0) {
    Output-Result -status ([HttpStatusCode]::BadRequest) -text "No repository resources found. Check function parameters and headers are correct"
    return
}

foreach ($resource in $resources) {
    if ($resource.refName -eq "refs/heads/master") {
        continue
    }
    elseif ($resource.refName -match "^refs/tags/") {
        $result = Call-Uri -uri ($baseUri + "_apis/git/repositories/$($resource.id)/commits?searchCriteria.itemVersion.version=master&searchCriteria.toCommitId=$($resource.version)&searchCriteria.fromCommitId=$($resource.version)&api-version=6.1-preview.1") -authHeader $authHeader
        if ($result -eq $null) {
            return
        } 

        if ($result.count -ne 1) {
            Output-Result -status ([HttpStatusCode]::BadRequest) -text "The ref $($resource.refName) to the repository $($resource.name) is not on master branch"
            return
        }
    }
    else {
        Output-Result -status ([HttpStatusCode]::BadRequest) -text "The ref $($resource.refName) to the repository $($resource.name) is not allowed. Only master or tags from master are allowed}"
        return
    }
}

Output-Result -status ([HttpStatusCode]::Ok) -text "Ok"

【讨论】:

    猜你喜欢
    • 2023-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-24
    • 1970-01-01
    • 2020-10-04
    • 1970-01-01
    相关资源
    最近更新 更多