是否可以在资源的 ref 属性中使用变量:Azure DevOps YAML 的存储库?

Posted

技术标签:

【中文标题】是否可以在资源的 ref 属性中使用变量:Azure DevOps YAML 的存储库?【英文标题】:Is it possible to use a variable in the ref property of resources:repository for Azure DevOps YAML? 【发布时间】:2019-11-09 17:00:26 【问题描述】:

我有两个 AzureDevOps Git 分支:

master
feature/mybranch

我在 yaml 中定义了一个多阶段构建管道,其中一些步骤被模板化为单独的 .yml 文件。

在我的外部 azure-pipelines.yml 中,我引用了我的模板 .yml 所在的存储库:

resources:
  repositories:
    - repository: templates
      type: git
      name: MyProject/MyRepo

当我在“master”分支中构建时,一切都很好,因为默认情况下,存储库将在 refs/heads/master 中查找。

当我在功能分支中工作并且想测试对模板 .yml 文件的实验性更改时,我不希望它从主分支中获取它们,我希望它使用分支中的文件我在工作。

以下工作并允许我这样做:

resources:
  repositories:
    - repository: templates
      type: git
      name: MyProject/MyRepo
      ref: refs/heads/feature/mybranch

但是,当我将它合并回 master 时,我显然不希望 'ref:' 仍然指向功能分支,所以我想使用变量动态生成 'ref:' 的值。

我尝试使用ref: $(Build.SourceBranch),其中$(Build.SourceBranch) 应该扩展为'refs/heads/feature/mybranch'

但它不起作用。错误:

62638: "/azure-pipelines.yml: Could not get the latest source version for repository MySolution hosted on Azure Repos using ref refs/heads/$(Build.SourceBranch)."

【问题讨论】:

“当前”分支是什么意思?如果您对构建进行排队,则可以选择分支。如果构建由 CI 触发器触发,它将自动使用触发 CI 的分支。在 YAML 中,您无需为此行为指定任何内容。 Daniel Mann - 我已经更新了问题,希望能更清楚地说明我想要实现的目标 您的问题现在解决了吗?随时告诉我们最新状态。 【参考方案1】:

不要在资源中引用 repo,而是使用此处所述的内联结帐

https://docs.microsoft.com/en-us/azure/devops/pipelines/repos/multi-repo-checkout?view=azure-devops#checking-out-a-specific-ref

- checkout: git://MyProject/MyRepo@features/tools

这个 yaml 元素允许使用模板表达式使用变量、参数,例如

- checkout: git://$(System.TeamProject)/$(repoName)@$ variables.branchRef 

 - checkout: git://$(System.TeamProject)/$(repoName)@$ parameters.branchRef 

你可以动态改变它

或者另一种选择是使用下面的脚本任务

- script: |
      # note checkout: git://$(System.TeamProject)/$ parameters.repoName @$ parameters.repoRef  this does not work if this task is run multiple times in same pipeline
      # see here for more details :https://developercommunity.visualstudio.com/t/checkout-fails-with-an-error-occurred-while-loadin/1005991#T-N1270459
      repoDir=$(Agent.BuildDirectory)/$ parameters.repoName 
      /bin/rm -rf $repoDir
      url_with_token=$(echo $(System.CollectionUri) | sed -e "s/https\:\/\//https\:\/\/$(System.AccessToken)\@/g")
      git clone $url_with_token/$(System.TeamProject)/_git/$ parameters.repoName  $repoDir
      cd $repoDir
      git fetch origin '$ parameters.repoRef ':'localBranch'
      git checkout localBranch
    name: clone_script
    displayName: Checkout using script $ parameters.repoName @$ parameters.repoRef 
    

【讨论】:

这太棒了。我需要能够加载与我的主存储库具有相同分支名称的不同存储库,并且在此之前无法找到解决方案来允许它。希望他们能尽快实现直接使用它的能力,但在那之前,这应该可以完成工作。 注意一个问题developercommunity.visualstudio.com/t/… 还添加了替代结帐 如果我没看错,看起来问题出在 repo URI 的运行时解释上。在这种情况下,使用“编译”时语法 $ 可能会起作用。只需要确保其内容中没有运行时评估。至少这是 Andy Li 的帖子让我期待的。 System.CollectionUri 是相等的,例如:dev.azure.com/fabrikamfiber,所以你不能在这个表单中和 System 一起使用。访问令牌。见docs.microsoft.com/en-us/azure/devops/pipelines/build/…【参考方案2】:

是否可以在 ref 属性中使用变量 资源:Azure DevOps YAML 的存储库?

对于这个问题,答案是肯定的,有可能。

关于您收到该错误消息的原因,只是您使用的变量($(Build.SourceBranch))不正确。你应该使用$(Build.SourceBranchName)

正常情况下,对于 ref,我们应该输入 master 或任何其他功能分支。比如

ref: refs/heads/master

这可能会让你认为这与$(Build.SourceBranch) 的值相同。它看起来一样,我知道,但不同。事实上,对于服务器,它会读取确切的分支名称而不是分支路径,我们可以通过经典的编辑器类型清楚地弄清楚:

根据经典编辑器类型,我们可以知道我们应该在这里输入准确的分支名称。

所以,正如Predefined variables 定义的那样,$(Build.SourceBranch) 的值是分支路径,但对于$(Build.SourceBranchName),它代表一个确切的分支名称。

所以,如果你想成功执行,你需要使用:$(Build.SourceBranchName)。它对我有用。

希望这也可以帮助您远离错误消息。

编辑:

对我有用的完整脚本是:

resources:
  repositories:
    - repository: templates
      type: git
      name: MyApp/MyconApp
      ref: $(Build.SourceBranchName)

【讨论】:

非常感谢您为我调查此问题。不幸的是,您提出的解决方案对我不起作用:63049:“/DevOps/DevOps.Pipeline/azure-pipelines.yml: 无法使用 ref refs/heads/$( Build.SourceBranchName)。” 那是有线的。你的剧本是什么样的?对我来说,工作脚本是 ref:$(Build.SourceBranchName)。我更新了我的答案,请检查一下。 @MerlinLiang-MSFT - 我很想知道这种方法是否仍然适合您。我正在使用您概述的方法,但遇到了 MarkdotH 描述的相同错误。 好像还不支持,正在审核中developercommunity.visualstudio.com/idea/816606/…【参考方案3】:

The azure docs state

变量不能用于在 YAML 语句中定义存储库。

因此,这似乎对您可以在此处执行的操作设置了一些限制。也许有一种解决方法仍然可以让你做你想做的事。

【讨论】:

以上是关于是否可以在资源的 ref 属性中使用变量:Azure DevOps YAML 的存储库?的主要内容,如果未能解决你的问题,请参考以下文章

是否可以将属性作为“out”或“ref”参数传递?

RAML 资源类型和特征 VS Swagger $ref

vue3 ref函数

无法读取未定义的属性“ref”

vue composition API - ref变量内的计算属性

ref关键字的作用