简体   繁体   English

如何根据 Azure DevOps 中的分支部署到不同的环境?

[英]How to deploy to different environment depending on the branch in Azure DevOps?

I would like to have the following pipeline implemented in Azure DevOps:我想在 Azure DevOps 中实现以下管道:

  • One Build stage that builds the main artifact一个构建主要工件的Build阶段
  • 3 deployment stages for Dev Preprod and Prod that would deploy the artifact built in the previous stage to their respective environments Dev PreprodProd的 3 个部署阶段,将前一阶段构建的工件部署到各自的环境中

I can do that using Azure DevOps Multistage Pipelines and conditions on the branch name.我可以使用 Azure DevOps 多级管道和分支名称上的conditions来做到这一点。 However, when I push first to dev branch and it builds successfully, and then I push to say preprod branch as a Fast-forward , I would expect the pipeline to reuse the already built artifacts from the Build stage run in the dev branch, because those are the same commits.但是,当我首先推送到dev分支并且它构建成功,然后我推送说preprod分支作为Fast-forward时,我希望管道能够重用在dev分支中运行的Build阶段已经构建的工件,因为这些是相同的提交。

What I observe in DevOps is that the Build stage is rerun even for the same commit, when I push to each different branch.我在 DevOps 中观察到的是,即使对于相同的提交,当我推送到每个不同的分支时, Build阶段也会重新运行。 Is it possible to achieve what I am trying to do using YAML-based pipelines?是否可以使用基于 YAML 的管道来实现我想要做的事情?

Edit编辑

The whole point of this workflow is not branching but rather staged deployment, from continuous deployment of latest and greatest dev commits down to rolling-out production-ready software for our 500+ internal users.这个工作流程的重点不是分支,而是分阶段部署,从持续部署最新和最伟大的开发提交到为我们的 500 多个内部用户推出生产就绪软件。 What I am trying to achieve is something called build promotion where one and the same build artifact gets promoted to an increasingly large circle of users.我想要实现的是一种称为构建提升的东西,其中一个相同的构建工件被提升到越来越大的用户圈子。 I would be happy to achieve this without fiddling with git branches.我很乐意在不摆弄 git 分支的情况下实现这一目标。

This should be rather a comment (since it is more idea, than a real working solution) than answer but I'm afraid that I will extend limit.这应该是一个评论(因为它更多的是想法,而不是一个真正的工作解决方案)而不是答案,但我担心我会扩大限制。

In my opinion this is impossible but let me explain this in details.在我看来这是不可能的,但让我详细解释一下。 Becuase what you actually need is a pipeline controller by commit flow.因为您实际需要的是提交流的管道 controller。 What you need is gate/approval based on appearance of commit in certain branch.您需要的是基于某个分支中提交的外观的门/批准。 This kind of approval is possible.这种认可是可能的。

Imagine you made a commit to Dev branch.想象一下,您向Dev分支提交了一个提交。 Your pipeline starts, deployment to Dev envrionment finishes and not is time for Preprod but before this an approval with call to Azure Function is made.您的管道开始,部署到Dev环境完成,而不是Preprod的时间,但在此之前,通过调用 Azure Function 进行批准。 You will pass this headers您将传递此标头

{
"Content-Type":"application/json", 
"PlanUrl": "$(system.CollectionUri)", 
"ProjectId": "$(system.TeamProjectId)", 
"HubName": "$(system.HostType)", 
"PlanId": "$(system.PlanId)", 
"JobId": "$(system.JobId)", 
"TimelineId": "$(system.TimelineId)", 
"TaskInstanceId": "$(system.TaskInstanceId)", 
"AuthToken": "$(system.AccessToken)",
"BuildId":"$(Build.BuildId)",
"StageName":"$(System.StageName)"
}

In Azure Function you will get build id and stage name.在 Azure Function 中,您将获得构建 ID 和阶段名称。 With build id you can call REST API to get changes and check if they already in stageName branch (in this case it is Preprod . Since they are not there, stage will fail.使用 build id,您可以调用 REST API 来获取更改并检查它们是否已经在stageName分支中(在这种情况下它是Preprod 。由于它们不存在,因此阶段将失败。

Once you move this commit to PreProd branch you should trigger previously failed build to check condition again and pick up already created artifact.将此提交移至PreProd分支后,您应该触发先前失败的构建以再次检查条件并获取已创建的工件。 You need to probably do with some kind of web hook and what is worse this is not possible at the moment.您可能需要使用某种 web 钩子,更糟糕的是,目前这是不可能的。 You cannot trigger a specific stage (please check documentation ).您无法触发特定阶段(请查看文档)。 You may try to get build with failing stage and queue them again, but in this case you will deploy again to Dev .您可以尝试使用失败的阶段进行构建并再次将它们排队,但在这种情况下,您将再次部署到Dev

So you see this is extremly difficult to achieve this.所以你看到这是非常难以实现的。 But maybe someone will get with a better idea.但也许有人会有更好的主意。

Is it possible to achieve what I am trying to do using YAML-based pipelines?是否可以使用基于 YAML 的管道来实现我想要做的事情?

Agree with Krzysztof Madej, I do not think it is impossible to achieve your request by using YAML-based pipelines .同意 Krzysztof Madej 的观点,我认为使用基于 YAML 的管道实现您的要求并非不可能。

To achieve it, we must ensure that every commit on the Preprod branch is the same as every commit on the dev branch before we can use conditions on the branch name to skip build stage为了实现它,我们必须确保Preprod分支上的每个提交都与dev分支上的每个提交相同,然后我们才能使用分支名称上的条件来跳过构建阶段

stages:
-stage: Build
   displayName: Build
   and(succeeded(), eq(variables['CommitBranchName'], 'refs/heads/dev'))

Then we could get the CommitBranchName by the git command git branch --contains .然后我们可以通过 git 命令git branch --contains 获取 CommitBranchName CommitBranchName

However, we cannot guarantee that each branch is the same as the dev commit, and azure devops cannot determine whether the two commits are the same.但是,我们不能保证每个分支都与 dev 提交相同,azure devops 无法确定这两个提交是否相同。 The event that triggered the build is commit, not content of commit.触发构建的事件是提交,而不是提交的内容。

Hope this helps.希望这可以帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM