在 Azure YAML Devops Pipelines 中管理依赖项
Manage dependencies in Azure YAML Devops Pipelines
我们的解决方案由几个互相调用和支持的微服务组成。
为简化起见,请考虑此依赖关系图:
MS1 --> MS2
--> MS3 --> MS4
- MS1 依赖于 MS2 和 MS3
- MS3 依赖于 MS4
- MS4 独立
目标:部署期间零停机
目前我们正在分析解决下面描述的几个场景的可能方法:
按顺序部署所有微服务,确保所有端到端测试通过。这意味着首先部署 MS4,然后是 MS3、MS2、MS1,然后 运行 测试(所有这些都在插槽中),然后如果一切通过则切换插槽
单独部署任何服务(其他的根本没有改变),运行测试(再次插槽),如果一切成功则切换插槽
我们的第一种方法是拥有一个(大)管道,每个微服务都有单独的阶段,并检查该微服务是否已更改以部署它。如果微服务没有检测到变化,那么我们想取消这个阶段并继续下一个阶段。
此管道包含每个阶段的模板,例如:
- stage: MS1
jobs:
- job: CheckMS1Changes
steps:
- template: templates/ms1-check-changes.yml
- job: BuildMS1
dependsOn: CheckMS1Changes
displayName: Build MS1
- template: templates/ms1-build.yml
- job: ReleaseMS1
dependsOn: BuildMS1
displayName: Release MS1
- template: templates/ms1-release.yml
我们认为这将涵盖所描述的场景。 “取消命令”应该放在 templates/ms1-check-changes.yml 文件中
问题是我们没有在文档中找到如何取消一个完整的舞台。这让我觉得也许我们的完整方法是错误的。
我们也没有找到如何取消一个作业或一组作业,因为我们也怀疑我们是否应该为每个微服务设置阶段。
你可以看到,我们是新手。
对于所描述的场景,您能否就什么是好的策略提出一些建议?
基于您的管道。我认为您可以将 CheckChanges
作业移动到一个单独的阶段。然后使用 logging commands ##vso[task.setvariable variable=MS1;isOutput=true]true
设置输出标志变量(即 MS1
),指示是否检测到每个微服务的更改。然后你可以在条件表达式 dependencies.dependencyStageName.outputs['dependencyStageJobName.taskName.varialbeName']
中使用这些标志
您可以让以下阶段 dependsOn this stage. And add conditions 决定跳过或 运行 这个阶段。请参阅下面的简单示例:
stages:
- stage: ChangeStage
pool:
vmImage: windows-latest
jobs:
- job: ChangeJob
steps:
- powershell: |
echo "##vso[task.setvariable variable=MS1;isOutput=true]true" #set MS1 flag to true if changes made to MS1
echo "##vso[task.setvariable variable=MS2;isOutput=true]true"
echo "##vso[task.setvariable variable=MS3;isOutput=true]true"
name: ChangeTask
- stage: MS3Stage
dependsOn: ChangeStage
condition: eq(dependencies.ChangeStage.outputs['ChangeJob.ChangeTask.MS3'], 'true')
pool:
vmImage: windows-latest
jobs:
- template: ...
- stage: MS2Stage
dependsOn:
- MS3Stage
- ChangeStage
condition: |
and
(
eq(dependencies.ChangeStage.outputs['ChangeJob.ChangeTask.MS2'], 'true'),
in(dependencies.MS3Stage.result, 'Succeeded', 'Canceled', 'Skipped')
)
pool:
vmImage: windows-latest
jobs:
- template: ...
- stage: MS1Stage
dependsOn:
- MS2Stage
- ChangeStage
condition: |
and
(
eq(dependencies.ChangeStage.outputs['ChangeJob.ChangeTask.MS1'], 'true'),
in(dependencies.MS2Stage.result, 'Succeeded', 'Canceled', 'Skipped')
)
pool:
vmImage: windows-latest
jobs:
- template: ...
在上面的管道中。顶层(即 ChangeStage
)将首先 运行 并检查是否对微服务进行了更改,并相应地将输出变量设置为 true。
MS2Stage 依赖于 MS3Stage。 MS2Stage 的条件如下: 这意味着 MS2Stage 仅在输出标志 MS2
为真且 MS3Stage 成功,跳过或取消的条件下 运行。
MS3Stage 和 MS1Stage 与 MS2Stage 类似。
condition: |
and
(
eq(dependencies.ChangeStage.outputs['ChangeJob.ChangeTask.MS2'], 'true'),
in(dependencies.MS3Stage.result, 'Succeeded', 'Canceled', 'Skipped')
)
我们的解决方案由几个互相调用和支持的微服务组成。
为简化起见,请考虑此依赖关系图:
MS1 --> MS2
--> MS3 --> MS4
- MS1 依赖于 MS2 和 MS3
- MS3 依赖于 MS4
- MS4 独立
目标:部署期间零停机
目前我们正在分析解决下面描述的几个场景的可能方法:
按顺序部署所有微服务,确保所有端到端测试通过。这意味着首先部署 MS4,然后是 MS3、MS2、MS1,然后 运行 测试(所有这些都在插槽中),然后如果一切通过则切换插槽
单独部署任何服务(其他的根本没有改变),运行测试(再次插槽),如果一切成功则切换插槽
我们的第一种方法是拥有一个(大)管道,每个微服务都有单独的阶段,并检查该微服务是否已更改以部署它。如果微服务没有检测到变化,那么我们想取消这个阶段并继续下一个阶段。 此管道包含每个阶段的模板,例如:
- stage: MS1
jobs:
- job: CheckMS1Changes
steps:
- template: templates/ms1-check-changes.yml
- job: BuildMS1
dependsOn: CheckMS1Changes
displayName: Build MS1
- template: templates/ms1-build.yml
- job: ReleaseMS1
dependsOn: BuildMS1
displayName: Release MS1
- template: templates/ms1-release.yml
我们认为这将涵盖所描述的场景。 “取消命令”应该放在 templates/ms1-check-changes.yml 文件中
问题是我们没有在文档中找到如何取消一个完整的舞台。这让我觉得也许我们的完整方法是错误的。 我们也没有找到如何取消一个作业或一组作业,因为我们也怀疑我们是否应该为每个微服务设置阶段。
你可以看到,我们是新手。
对于所描述的场景,您能否就什么是好的策略提出一些建议?
基于您的管道。我认为您可以将 CheckChanges
作业移动到一个单独的阶段。然后使用 logging commands ##vso[task.setvariable variable=MS1;isOutput=true]true
设置输出标志变量(即 MS1
),指示是否检测到每个微服务的更改。然后你可以在条件表达式 dependencies.dependencyStageName.outputs['dependencyStageJobName.taskName.varialbeName']
您可以让以下阶段 dependsOn this stage. And add conditions 决定跳过或 运行 这个阶段。请参阅下面的简单示例:
stages:
- stage: ChangeStage
pool:
vmImage: windows-latest
jobs:
- job: ChangeJob
steps:
- powershell: |
echo "##vso[task.setvariable variable=MS1;isOutput=true]true" #set MS1 flag to true if changes made to MS1
echo "##vso[task.setvariable variable=MS2;isOutput=true]true"
echo "##vso[task.setvariable variable=MS3;isOutput=true]true"
name: ChangeTask
- stage: MS3Stage
dependsOn: ChangeStage
condition: eq(dependencies.ChangeStage.outputs['ChangeJob.ChangeTask.MS3'], 'true')
pool:
vmImage: windows-latest
jobs:
- template: ...
- stage: MS2Stage
dependsOn:
- MS3Stage
- ChangeStage
condition: |
and
(
eq(dependencies.ChangeStage.outputs['ChangeJob.ChangeTask.MS2'], 'true'),
in(dependencies.MS3Stage.result, 'Succeeded', 'Canceled', 'Skipped')
)
pool:
vmImage: windows-latest
jobs:
- template: ...
- stage: MS1Stage
dependsOn:
- MS2Stage
- ChangeStage
condition: |
and
(
eq(dependencies.ChangeStage.outputs['ChangeJob.ChangeTask.MS1'], 'true'),
in(dependencies.MS2Stage.result, 'Succeeded', 'Canceled', 'Skipped')
)
pool:
vmImage: windows-latest
jobs:
- template: ...
在上面的管道中。顶层(即 ChangeStage
)将首先 运行 并检查是否对微服务进行了更改,并相应地将输出变量设置为 true。
MS2Stage 依赖于 MS3Stage。 MS2Stage 的条件如下: 这意味着 MS2Stage 仅在输出标志 MS2
为真且 MS3Stage 成功,跳过或取消的条件下 运行。
MS3Stage 和 MS1Stage 与 MS2Stage 类似。
condition: |
and
(
eq(dependencies.ChangeStage.outputs['ChangeJob.ChangeTask.MS2'], 'true'),
in(dependencies.MS3Stage.result, 'Succeeded', 'Canceled', 'Skipped')
)