如何解决如何在Azure DevOps Server 2019中使用YAML版本从多个发行分支配置CI版本?
我们的产品中有多个发行分支(当前这是不可避免的)。对于这个问题,假设我们有两个:
- 主人
- release / r-858
两者都有经典的CI版本。现在,我想用YAML版本替换它们。我们的要求很简单-有两个指向YAML脚本的不同构建定义-一个用于 master ,一个用于 release / r-858
一开始我以为这是一个琐碎的练习:
- 在 master 中创建YAML构建脚本。将CI触发器设置为 master 。
- Cherry-pick(不要介意为什么不合并)到 release / r-858 -将CI触发器设置为 release / r-858 。
不理想,因为这两个脚本的CI触发器仅不同。但是“我正在学习,到目前为止已经足够好了。”我对自己说。
但是,这种简单的方案不起作用!我为release / r-858 创建的版本是在master更改时触发的!
我仔细检查了我所知道的有关构建的所有设置-看起来都很正确。
请注意:
主版本
版本/ r-858版本
哦,看那个。它显示了master分支上的YAML!好吧,也许这是一个无辜的演示错误?让我们检查一下我应该从中建立的分支:
是的,文件是不同的-我正在尝试使用触发器来解决此问题所涉及的相同问题。原始代码使用release/r-858
代替$(Build.SourceBranch)
作为CI触发器,但是由于它没有帮助,所以我开始使用各种触发器值。
为消除任何疑问,这是分支对应于release / r-858的证明:
C:\xyz\58 [arch/shelve/798914 ≡ +0 ~17 -0 !]> git lg -2
cfdb6a9a86a | (HEAD -> arch/shelve/798914,origin/arch/shelve/798914) Rename azure-pipelines-ci-58.yml to azure-pipelines-ci.yml and sync it with the master version (68 seconds ago) [Kharitonov,Mark] (2020-08-14 09:09:46 -0400)
a931e3bd96b | (origin/release/r-858,release/r-858) Merged PR 90230: 793282 Work Assignments Merge (28 minutes ago) [Mihailichenco,Serghei] (2020-08-14 12:02:20 -0400)
C:\xyz\58 [arch/shelve/798914 ≡ +0 ~17 -0 !]>
无论如何,更多的构建属性:
问题
因此,开发人员将一些代码推送到了主服务器上,现在release / r-858内部版本正在运行:
这是为什么?我们中的一个人在Microsoft Developer Community forum中提出了类似的问题,但该话题对我而言没有意义。
我在做什么错了?
编辑1
想象一个大型企业的整体应用程序。它已在生产版本858上进行了部署。与此同时,开发人员将开发下一个版本,并针对已经在产品中部署的版本进行修补程序和Service Pack。
只能在master或仅在release / r-858或两者中进行更改(但是不能同时进行)。许多团队在同一时间处理应用程序的许多不同方面,因此QA有许多用于部署应用程序的Pod。正如我在上文中提到的那样-大约有150个Pod用于前沿(主节点),而大约相同的数量用于已发布的代码,因为正在进行积极的工作来测试修补程序和Service Pack。
我知道这种安排并不理想。之所以如此,并不是因为我们喜欢它,而是因为必须处理数十年的决策。我们正在努力进行更改,但这需要时间。
无论如何,当前的过程是要有2个构建定义(实际上,由于不同的原因,还有更多的定义)。到目前为止,我们已经使用了经典的CI构建,现在我们想要迁移到YAML(我们已经将其用于微服务,但还没有用于整体)。
现在,我了解到我们可以基于相同的构建定义具有不同的发布管道,但是分支过滤器也不同。
也许我们会的。但是我不明白为什么在这里拥有不同的构建定义是错误的,因为每个分支都是长期存在的发行分支。
编辑2
您可以忽略$(Build.SourceBranch)
并成像release/r-858
。最终结果是完全相同的。在这种情况下,我将上面的代码提交给master,而不是release / r-858。
编辑3
这很令人困惑。假设我正在创建一个新的YAML构建。该对话框显示“在任何分支中选择YAML”,但他们指出,一旦选择此分支,便成为构建的默认分支。那是我们可以在这里看到的分支:
如果在master分支中只有一个YAML文件,则具有默认分支release/r-858
的版本甚至无法使用它,除非将其合并到release / r-858中。我尝试过-我:
- 创建了一个新的YAML版本
- 从master分支中选择了YAML文件
- 马上就取消了构建
- 然后去编辑构建并将构建的分支从master更改为release / r-858-即使该分支中不存在YAML,它也允许我保存构建
但是当我再次尝试运行构建时,我得到了:
An error occurred while loading the YAML build pipeline. File /Build/azure-pipelines-ci.yml not found in repository bla-bla-bla branch refs/heads/release/r-858 version 5893f559292e56cf6db48687fd910bd2916e3cef.
实际上,查看原始的构建定义,process部分包含YAML文件路径,但不包含分支:
"process": {
"yamlFilename": "Build/azure-pipelines-ci.yml","type": 2,"resources": {},"target": null
},
该分支仅出现在定义的“存储库”部分:
"repository": {
"defaultBranch": "refs/heads/release/r-858",...
},
对我来说很明显,可以使用单个构建定义来CI构建许多分支。但是我需要实现的模型是每个发布分支的构建定义。由于以下原因,我无法使用单个构建定义:
- 由于开发强度不同,不同的发行分支具有不同的代理库。请记住,这是在具有自托管代理的本地Azure DevOps服务器上。我们可以用一个构建定义表达这一要求吗?
- 我们希望在不向YAML文件存储库发送“拉取请求”的情况下控制的不同构建变量值。您如何使用单个构建定义来做到这一点?例如,变量之一控制版本Major.Minor。它们在每个发行分支中都不同。
因此,在我们的情况下,我看不出有任何方法可以避免使用多个构建定义。造成这种情况的根本原因是发行分支,但我们不能在不久的将来将其丢弃。
因此,我们有2个构建定义。这迫使我们拥有2个YAML-每个分支一个,因为带有release / r-858默认分支的构建定义希望在该分支中找到YAML,否则我们无法手动触发构建。即使构建具有CI触发器,这也是必须的。
因此,有2个构建定义,2个YAML(每个分支一个)。到目前为止,我的双手被迫。 但是现在我被告知,发布分支构建将由主YAML触发,因为发布分支构建链接到相同的YAML文件名,而忽略了构建的默认分支!
因为这是发生的情况-在master分支中签入了一次提交,并调用了release分支构建!两种构建定义都使用主YAML脚本构建完全相同的分支(主)。但是由于release分支构建具有不同的变量集,所以最终结果是完全错误的。
这不合理。我将创建一个虚拟仓库以清楚地复制它并发布在这里。
编辑4
如所承诺-琐碎的复制。鉴于:
- master分支构建test-master-CI
- 发布分支版本号test-r58-CI
由于具有两个内部定义,因此必然意味着两个YAML(每个分支一个),它们是:
C:\xyz\DevOps\Test [master ≡]> cat .\azure-pipelines.yml
trigger:
branches:
include:
- master
name: $(BuildVersionPrefix).$(DayOfYear)$(Date:HH)
steps:
- script: echo master
C:\xyz\DevOps\Test [master ≡]> git co release/r-858
Switched to branch 'release/r-858'
Your branch is up to date with 'origin/release/r-858'.
C:\xyz\DevOps\Test [release/r-858 ≡]> cat .\azure-pipelines.yml
trigger:
branches:
include:
- release/r-858
name: $(BuildVersionPrefix).$(DayOfYear)$(Date:HH)
steps:
- script: echo release/r-858
C:\Dayforce\DevOps\Test [release/r-858 ≡]>
其中 BuildVersionPrefix = 59.0(对于master)和58.3(对于release / r-858)
当我手动触发每个版本时,我会得到:
现在我将更改提交给master。瞧,瞧,这两个版本都会被触发:
在两种情况下,都使用master分支中的YAML。但是release分支定义了BuildVersionPrefix = 58.3,因此由release分支构建定义执行的主构建具有伪造的版本。
这真的应该是该功能的工作方式吗?这使得CI YAML触发器对我的场景无用。谢谢马特(Matt)帮助我实现这一目标。
解决方法
我想我知道混乱的来源。在配置管道时,您要指定分支(注意说明中指出该分支中的文件)和文件名。
您正在做的只是复制监视。如果您真的要检查它,我想您会看到,当您按下发布分支时,它并不会触发主YAML管道……它只是第二次触发了发布YAML步骤。这是因为管道仅监视仓库的更改并基于YAML配置进行响应。在这种情况下,您推动发布,并评估是否存在一个与该触发器(发布分支的副本)相匹配并针对两个构建定义都被触发的YAML。
我在模拟管道上对此进行了验证。我在创建时选择了不同的分支,但是我认为真正影响的唯一一件事是它将用于计划构建的默认分支。我在这两种情况下都使用发布分支YAML配置创建了一个简单的echo语句。
我认为,如果您确实想获得期望的结果,则将需要使用在定义中定义的替代触发器,而不是依赖YAML触发器中的内容。
,我遇到了同样的问题,Matt 帮我解决了这个问题。
我写这个只是因为让这个对我有用的唯一方法是在一个分支上创建一个构建 YAML 文件(使用正确的配置)。然后在另一个分支上创建另一个 YAML 文件。然后然后在 Devops 中全新闪亮的 YAML 编辑器中创建管道。
关键是,在新管道的“配置”部分中,选择: “现有 Azure Pipelines YAML 文件”,它允许您选择一个分支和该分支内的一个 YAML 文件。
这让我可以让 SystemOne 分支构建和测试系统一站点,让 SystemTwo 分支构建和测试系统二站点。
我还在 SystemOne.yml 中使用通配符添加了触发器。 EG
trigger:
batch: true
branches:
include:
- SystemOne/*
SystemTwo.yml 也是一样。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。