Azure-DevOps-详解-全-

Azure DevOps 详解(全)

原文:annas-archive.org/md5/b9af5174af71449b8d6f11a56dee9821

译者:飞龙

协议:CC BY-NC-SA 4.0

前言

DevOps 在近年来已经成为一个热门词汇。DevOps 是一种结合了文化理念、实践和工具的模式,能够提高组织以高速度和高质量交付应用程序和服务的能力。Azure DevOps 是微软提供的软件即服务SaaS)平台,提供一整套工具,用于通过应用 DevOps 技术开发和部署软件。本书首先概述了 Azure DevOps 平台,然后深入探讨了各种工具和功能,如项目管理的看板、源代码管理的代码库、构建和发布管道、测试计划、工件等。

阅读本书后,您将对 Azure DevOps 能够为您提供的提升开发生命周期的工具和功能有一个完整清晰的认识。

本书适合谁阅读

本书面向希望将 DevOps 技术应用到项目中,并使用 Azure DevOps 来管理整个应用开发过程的解决方案开发人员/架构师和项目经理。

本书涵盖的内容

第一章Azure DevOps 概述,为您提供了 Azure DevOps 的完整概述,包括看板、代码库、管道、测试计划和工件等工具集。

第二章使用 Azure DevOps 看板管理项目,详细解释了 Azure DevOps 的项目管理功能,并展示了如何使用看板和工作项、如何创建冲刺、如何管理待办事项以及如何跟踪所有活动。

第三章使用 Azure DevOps 进行源代码管理,解释了如何使用 Azure DevOps Repos 功能和 Git 进行源代码控制。它展示了如何创建代码库、如何处理提交、推送和拉取、如何处理分支等内容。

第四章理解 Azure DevOps 管道,展示了如何为代码创建构建管道,并使用 Azure Pipelines 最佳地处理持续集成。

第五章在构建管道中运行质量测试,解释了如何在构建管道中创建和执行代码质量测试。

第六章托管您自己的 Azure 管道代理,展示了如何创建自己的构建代理并将其用于构建管道中。

第七章在 Azure DevOps 中使用工件,解释了如何使用工件(软件包源)创建和共享软件包,并将完全集成的软件包管理功能添加到您的持续集成/持续交付管道中。

第八章使用 Azure DevOps 部署应用程序,解释了如何使用发布管道处理代码的持续部署,并展示如何在将代码发布到生产环境之前使用阶段和审批。

第九章将 Azure DevOps 与 GitHub 集成,向你展示如何将 Azure DevOps 工具与 GitHub 集成,并在你的持续集成/持续交付过程中使用这两个应用程序。

第十章在 Azure DevOps 中使用测试计划,展示了如何在 Azure DevOps 中使用测试计划管理项目的测试生命周期。

第十一章使用 Azure DevOps 的真实世界 CI/CD 场景,向你展示了如何使用 Azure DevOps 处理真实世界中的持续集成/持续交付场景。

为了充分利用本书

要跟随本书中描述的主题,你需要拥有有效的 Azure DevOps 订阅。你可以通过以下链接激活免费账户:

azure.microsoft.com/en-us/services/devops/

如果你正在使用本书的数字版,我们建议你亲自输入代码或通过 GitHub 仓库访问代码(链接将在下一节提供)。这样做可以帮助你避免复制粘贴代码时可能出现的错误

下载示例代码文件

你可以从 GitHub 下载本书的示例代码文件:github.com/PacktPublishing/Learning-Azure-DevOps---B16392。如果代码有更新,将会在现有的 GitHub 仓库中更新。

我们还提供了来自我们丰富书籍和视频目录的其他代码包,您可以在github.com/PacktPublishing/查看!

下载彩色图片

我们还提供了一个 PDF 文件,其中包含本书中使用的截图/图表的彩色图片。你可以在这里下载:www.packtpub.com/sites/default/files/downloads/9781800563513_ColorImages.pdf

使用的约定

本书中使用了多种文本约定。

文本中的代码:表示文本中的代码词汇、数据库表名、文件夹名、文件名、文件扩展名、路径名、虚拟 URL、用户输入和 Twitter 用户名。比如:“你可以下载名为node-v6.12.3-x64.msi的文件,并使用交互式安装程序安装它。”

一段代码块设置如下:

using System;
using PartsUnlimited.Models;
namespace AzureArtifacts
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine('Hello World!');
            CartItem caritem = new CartItem()

当我们希望引起你对某个代码块中特定部分的注意时,相关的行或项目会用粗体显示:

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
Install-Module AzureRM -AllowClobber

任何命令行输入或输出均按以下格式编写:

docker run \
  -e VSTS_ACCOUNT=<name> \
  -e VSTS_TOKEN=<pat> \
  -it mcr.microsoft.com/azure-pipelines/vsts-agent

粗体:表示新术语、重要词汇或你在屏幕上看到的词汇。例如,菜单或对话框中的词汇会以这种方式显示。这里有个例子:‘使用你的微软账户登录,在左侧菜单中选择Artifacts’。

提示或重要说明

如此显示。

联系我们

我们欢迎读者的反馈。

一般反馈:如果你对本书的任何部分有疑问,请在邮件主题中注明书名,并通过 customercare@packtpub.com 与我们联系。

勘误:虽然我们已尽力确保内容的准确性,但错误仍有可能发生。如果你在本书中发现错误,我们将非常感激你向我们报告。请访问 www.packtpub.com/support/errata,选择你的书籍,点击“勘误提交表单”链接并填写相关信息。

盗版:如果你在互联网上发现任何非法复制我们的作品的形式,我们将非常感激你提供相关地址或网站名称。请通过 copyright@packt.com 与我们联系,并附上该材料的链接。

如果你有兴趣成为作者:如果你在某个领域拥有专业知识并且有兴趣写作或为书籍做贡献,请访问 authors.packtpub.com

评价

请留下评价。阅读并使用本书后,为什么不在购买网站上留下评价呢?潜在读者可以参考你的公正意见来做购买决定,我们在 Packt 可以了解你对我们产品的看法,作者也可以看到你对他们书籍的反馈。谢谢!

欲了解更多关于 Packt 的信息,请访问 packt.com

第一部分:DevOps 原则与 Azure DevOps 项目管理

本节将涵盖 DevOps 原则、Azure DevOps 关键概念以及项目管理内容。

本节包含以下章节:

  • 第一章Azure DevOps 概述

  • 第二章使用 Azure DevOps Boards 管理项目

第一章:Azure DevOps 概述

本章介绍了本书的第一个主题:DevOps原则和Azure DevOps项目管理。在本章中,我们将从介绍 DevOps 开始,并概述不同的 DevOps 原则。接下来,我们将介绍 Azure DevOps 的关键概念及其提供的不同服务。最后,我们将介绍本书将使用的场景。

本章将覆盖以下主题:

  • 介绍 DevOps

  • 理解 DevOps 原则

  • 介绍 Azure DevOps 关键概念

  • 探索 Azure DevOps 服务

  • 介绍场景

让我们开始吧!

介绍 DevOps

长时间以来,开发和运维一直被分割成相互独立的模块,双方各自有着不同的关注点和责任。开发人员编写代码并确保其在开发系统上正常运行,而系统管理员则负责在组织的 IT 基础设施中进行实际的部署和集成。

由于这两个独立模块之间的沟通有限,两支团队大多是分开工作的。然而,他们又非常依赖对方,因为不同团队之间缺乏跨平台的知识。

这一方法与大多数项目中使用的瀑布模型非常契合。瀑布模型基于软件开发生命周期SDLC),它有明确的流程来创建软件。瀑布模型将项目交付物分解为线性顺序的阶段,每个阶段依赖于前一个阶段的交付物。这个事件序列可能如下所示:

图 1.1 – 瀑布模型

图 1.1 – 瀑布模型

瀑布模型非常适合以下情况下的项目:

  • 在开发生命周期的早期,客户和开发人员就要达成一致,确定交付内容,并在项目开发过程中尽量避免修改。

  • 对于与外部系统的集成,通常需要多个软件组件并行设计。在这种情况下,尽早完成设计文档是理想的做法。

  • 各个团队成员通常也会同时参与其他项目。例如,业务分析师可以收集需求并创建设计,而开发人员则在处理另一个项目。

  • 当无法将需求阶段分解时,客户无法充分参与到较小的交付物中。

然而,客户在看到可工作的软件之前,可能并不完全知道他们的需求。这可能导致需求的变更,从而引发重新设计、重新实现和重新验证。这会显著增加项目的成本。

因此,敏捷和 DevOps 于 2009 年被引入,并慢慢地在软件开发界占据主导地位。它们取代了大多数项目中使用的瀑布模型。DevOps 是敏捷和持续交付方法的自然延伸,代表了开发和运维。它是一种将开发、IT 运维和质量保证融合为一个连续过程的实践。

以下图表展示了 DevOps 的不同组成部分:

图 1.2 – DevOps 方法论

图 1.2 – DevOps 方法论

这是一种基于团队的迭代式开发方法,所有利益相关者,如开发人员、管理员、测试人员以及客户代表,都属于同一个团队。应用程序以功能组件的形式交付,而不是在项目开始时创建时间表和任务,项目被划分为较小的阶段,称为冲刺。每个冲刺的持续时间在前期定义,并在每个冲刺开始时规划好交付物的清单。所有这些交付物都是与客户一起定义的,并由客户按照业务价值进行优先级排序。在每个冲刺结束时,完成的工作将通过日常构建和冲刺结束时的演示进行团队评审和评估。

这带来了以下优势:

  • 通过在整个项目过程中与项目团队直接合作,客户将体验到更强的归属感。

  • 客户有机会在项目的早期阶段查看交付的工作,并可以对此做出适当的决策和调整。

  • 开发更加注重业务和价值。这是与客户更紧密合作并更好地理解其需求的结果。

  • 敏捷工作方式使我们能够迅速创建产品的基础版本,并在后续迭代中进行构建。

在简要介绍完 DevOps 后,我们将探讨不同的 DevOps 原则。

理解 DevOps 原则

关于 DevOps 有很多不同的定义。它们大多数擅长解释在交付软件和 IT 项目中寻找合适流程的不同方面。在接下来的章节中,我们将重点介绍我们认为在采用 DevOps 工作方式时至关重要的六个 DevOps 原则。

原则 1 – 以客户为中心的行动

如今,软件开发项目需要具有短周期和反馈循环,并将最终用户和真实客户融入团队。为了充分满足客户的需求,所有与构建软件和产品相关的活动必须涉及这些客户。DevOps 团队和组织必须持续投资于产品和服务,以便让客户获得最大的成果,同时保持尽可能精简,以便在策略不再有效时持续创新并进行调整。

原则 2 – 以终为始

组织需要更像产品公司一样运作。他们应该更多地关注构建可以销售给真实客户的可用产品。这种工程思维需要被所有员工共享,才能实现这些产品。这意味着他们应该放弃那种每个部门只关注特定角色并承担独立责任的做法。

原则 3 – 端到端责任

在大多数传统软件开发项目中,开发的软件和服务会交给运维部门,由他们在初始开发过程后进行部署和维护。通过采用 DevOps 工作方式,DevOps 团队将对他们交付的项目承担完全的责任和义务。这意味着,一旦产品由团队交付并需要维护,它仍然由团队负责。团队还将为该产品提供支持,直到它达到生命周期的终点。这大大增加了团队的责任感,并提高了开发产品的质量。

原则 4 – 跨职能自治团队

与垂直和完全负责的团队合作的组织,需要让这些团队在整个生命周期中完全独立工作。为了使这些团队能够完全独立工作,需要具备广泛且均衡的技能组合。团队成员需要具备 T 型技能,而不是只擅长自己角色的老派 IT 专家。每个团队成员应该具备的技能包括开发、需求分析、测试和管理技能等。

原则 5 – 持续改进

端到端责任的另一个部分是,对于组织来说,持续适应变化非常重要。可能会有许多变化的情况,比如发布了新技术、客户需求变化等。持续改进是 DevOps 中的一个重要关注点,旨在优化速度和成本,减少浪费,简化交付,并持续改进构建和发布的软件和服务。一个重要的活动是将实验融入这些循环中,这将使团队能够从失败中学习,这对于持续改进至关重要。

原则 6 – 自动化一切

要完全采纳并在组织内部嵌入持续改进文化,大多数组织需要消除大量浪费和技术债务。为了实现高循环率并尽早处理来自客户和最终用户的即时反馈,自动化一切变得至关重要。这意味着,不仅软件开发过程应使用持续交付自动化(包括持续开发和集成),而且整个基础设施环境也需要自动化。基础设施还需要为新的工作方式做好准备。从这个角度来看,自动化就是推动团队更新向客户交付服务方式的同义词。

在本节中,我们介绍了采纳或迁移到 DevOps 工作方式时非常重要的六个原则。在接下来的几个章节中,我们将讨论 Azure DevOps 作为支持团队以 DevOps 方式工作的工具所提供的功能。

引入 Azure DevOps 关键概念

Azure DevOps 为 DevOps 团队提供了多种服务,使他们能够规划、工作、协作开发代码,并构建和部署软件和服务。大多数 DevOps 团队依赖于多种工具,并为应用生命周期的每个阶段构建自定义工具链。

以下图表展示了定义在应用生命周期中的各个阶段:

图 1.3 – 应用生命周期阶段

图 1.3 – 应用生命周期阶段

在接下来的章节中,我们将详细解释这些阶段以及相应的 Microsoft 工具和产品。

规划

在规划阶段,团队可以使用看板和待办事项列表在 Azure Boards 中定义、跟踪并安排需要完成的工作。他们也可以使用 GitHub 进行此操作。在 GitHub 中,可以通过建议一个新想法或表示需要追踪一个 bug 来创建一个 issue。这些问题可以进行组织并分配给团队。

开发

开发阶段由 Visual Studio Code 和 Visual Studio 支持。Visual Studio Code 是一个跨平台编辑器,而 Visual Studio 是仅限 Windows 和 Mac 的 IDE。你可以使用 Azure DevOps 进行自动化测试,并使用 Azure Pipelines 创建自动构建来编译源代码。代码可以通过 Azure DevOps 或 GitHub 在团队之间共享。

交付

交付阶段是关于将应用程序和服务部署到目标环境的过程。你可以使用 Azure Pipelines 自动将代码部署到任何 Azure 服务或本地环境。你可以使用 Azure Resource Manager 模板或 Terraform 来为你的应用程序或基础设施组件创建环境。你还可以将 Jenkins 和 Spinnaker 集成到 Azure DevOps Pipelines 中。

运维

在这一阶段,你会为监控你的应用程序和服务实现全栈监控。你还可以使用不同的自动化工具来管理你的云环境,如 Azure Automation、Chef 等。保持你的应用程序和服务的安全也是这一阶段的一部分。因此,你可以使用诸如 Azure 策略和 Azure 安全中心等功能和服务。

为了支持分析、设计、构建、部署和维护软件及基础设施产品和服务的完整生命周期,Azure DevOps 提供了集成的功能,可以通过任何网络浏览器访问。

Azure DevOps 提供了一套解决方案和工具的组合,可用于在每个应用程序生命周期阶段创建独特且定制的工作流。这些解决方案将在接下来的章节中描述。

持续集成和持续交付(CI/CD)

你可以通过 CI/CD(以及持续部署)在 Azure DevOps 中自动化每个 DevOps 流程。CI 用于项目的开发阶段,指的是以完全自动化的方式构建和测试代码。每当你提交更改到主分支时,变更将会被验证,并自动打包成构建工件。使用 CD 时,交付阶段也会自动化。每当构建工件可用时,工件会自动部署到所需的环境中。当开发团队同时使用持续集成和持续部署时,代码始终可以随时准备好进行生产部署。团队部署一个可工作的应用程序到生产环境中所需做的唯一事情,就是触发从开发到部署的过渡。这将使自动化构建工件变得可用进行部署。这一触发过程可以简单到按下一个按钮。

使用 Azure DevOps,你还可以实现持续部署。将其添加到你的开发生命周期中意味着你可以自动化整个过程,从代码提交到生产部署。开发和交付阶段之间的触发过程是完全自动化的。因此,当代码更改经过验证并通过开发阶段进行的所有测试后,变更将自动发布到生产环境。这意味着客户会在新版本和相应的改进一经发布时就能立刻收到。

敏捷开发支持

Azure DevOps 支持采用敏捷开发方法的团队,提供计划、跟踪和报告功能。这将导致更短的发布周期和软件开发过程的完全可见性。你可以使用 Azure Boards(将在本章的下一部分详细介绍)来管理待办事项并定义、分配和跟踪工作项。你还可以使用高级分析和报告功能,创建自定义仪表板来跟踪进度。

版本控制

版本控制系统,也称为源代码控制系统,是多开发者项目的基本工具。它允许开发者在代码上进行协作并跟踪更改。所有代码文件的历史也会保存在版本控制系统中。这使得在出现错误或 bug 时,能够轻松回退到代码文件的其他版本。

Azure DevOps 支持两种不同类型的源代码管理:Git(分布式)和团队基础版本控制TFVS)。使用 Git 时,每个开发者在其开发机器上都有一份源代码库的副本。所有的分支和历史信息都包含在源代码库中。每个开发者直接与自己本地的代码库副本进行工作,所有的更改通过一个单独的步骤在本地和源代码库之间共享。可以在本地文件系统上提交更改,并且可以在没有网络连接的情况下执行版本控制操作。开发者可以在开发机器上轻松创建分支,之后可以将其合并、发布或单独处理。使用 TFVC 时,开发者的本地开发机器上只有每个文件的一个版本。所有其他的文件以及历史数据都仅保存在服务器上。分支也在服务器上创建。

基础设施即代码

团队还可以在 Azure DevOps 中管理基础设施。项目中使用的基础设施组件,如网络、虚拟机和负载均衡器,可以使用与源代码相同的版本控制功能和能力进行管理。

与持续交付一起使用时,基础设施即代码IaC)模型每次部署时都会生成相同的环境。如果没有 IaC,团队需要手动配置和维护所有单独部署环境的设置,这是一项耗时且容易出错的任务。最可能的结果是,随着时间推移,每个环境都会成为一个独一无二的配置,这种配置不再能被自动重现。环境之间的不一致性将在部署阶段导致问题。

配置管理

配置管理指的是与项目相关的所有项和工件,以及它们之间的关系。这些项会被存储、检索、唯一标识并修改。这包括源代码、文件和二进制文件等项。配置管理系统是唯一真正的配置项来源。

使用 Azure DevOps,团队可以管理整个系统中的资源配置,推出配置更新、强制执行所需的状态,并自动解决意外的变更和问题。Azure 提供了多种 DevOps 工具和功能来进行配置管理,例如 Chef、Puppet、Ansible 和 Azure Automation。

监控

你可以使用 Azure Monitor 来进行全栈持续监控。你的基础设施和应用程序的健康状况可以集成到 Grafana、Kibana 和 Azure 门户中的现有仪表盘中。你还可以监控应用程序的可用性、性能和使用情况,无论它们是托管在本地还是在 Azure 中。Azure Monitor 支持大多数流行的编程语言和框架,如 .NET、Java 和 Node.js,并与 Azure DevOps 中的 DevOps 流程和工具集成。

探索 Azure DevOps 服务

在本节中,我们将介绍 Azure DevOps 提供的不同服务。这些服务可以在整个生命周期中支持团队实现客户的业务价值。

Azure Boards

Azure Boards 可以用于使用可用的敏捷规划工具计划、跟踪和讨论跨团队的工作。通过 Azure Boards,团队可以管理他们的软件项目。它还提供了一套独特的功能,包括对 Scrum 和 Kanban 的原生支持。你还可以创建可定制的仪表盘,并提供集成的报告和与 Microsoft Teams 和 Slack 的集成。

你可以使用 Azure Boards 创建并跟踪与项目相关的用户故事、待办事项、任务、特性和缺陷。

以下屏幕截图展示了一个 Azure Board 的示例:

图 1.4 – Azure Boards

图 1.4 – Azure Boards

Azure Repos

Azure Repos 提供对私有 Git 仓库托管和团队基础服务器控制TFSC)的支持。它提供了一套版本控制工具,可以用于管理每个开发项目的源代码,无论项目大小。当你编辑代码时,你要求源代码管理系统创建文件的快照。这个快照会被永久保存,以便以后在需要时可以调用。

如今,Git 是开发人员中使用最广泛的版本控制系统。Azure Repos 提供标准的 Git,使得开发人员可以使用他们选择的工具和客户端,例如 Git for Windows、Mac、第三方 Git 服务,以及像 Visual Studio 和 Visual Studio Code 这样的工具。

以下屏幕截图展示了你可以推送到 Azure 仓库的提交示例:

图 1.5 – Azure Repos

图 1.5 – Azure Repos

Azure Pipelines

你可以使用 Azure Pipelines 自动构建、测试和部署代码,使其可以供其他用户使用,并将其部署到不同的目标,如开发、测试、验收和生产DTAP)环境。它结合了 CI/CD,自动构建和部署你的代码。

在您可以使用 Azure Pipelines 之前,应该将代码放入版本控制系统中,例如 Azure Repos。Azure Pipelines 可以与多种版本控制系统集成,如 Azure Repos、Git、TFVS、GitHub、GitHub Enterprise、Subversion 和 Bitbucket Cloud。您还可以将 Pipelines 与大多数应用程序类型一起使用,如 Java、JavaScript、Node.js、Python、.NET、C++、Go、PHP 和 XCode。应用程序可以部署到多个目标环境,包括容器注册表、虚拟机、Azure 服务或任何本地或云端目标。

以下截图展示了一个 Azure Pipeline 运行的示例:

图 1.6 – Azure Pipelines

图 1.6 – Azure Pipelines

Azure 测试计划

使用 Azure 测试计划,团队可以通过 Azure DevOps 中的计划测试和探索性测试服务提高代码质量。Azure 测试计划提供了计划手动测试、探索性测试、用户验收测试和收集利益相关者反馈的功能。通过手动测试,测试人员和测试主管将测试组织到测试计划和测试套件中。团队可以直接从看板或工作中心开始测试。通过用户验收测试,可以验证为满足客户需求所交付的价值。通常由指定的测试人员执行。探索性测试包括由整个开发团队执行的测试,开发人员、产品负责人和测试人员都会参与。软件测试通过探索软件系统进行,而不使用测试计划或测试套件。利益相关者反馈收集通常由市场或销售团队在开发团队外部完成。开发人员可以从 Azure DevOps 请求对其用户故事和功能的反馈,利益相关者可以直接回复反馈项。

以下截图展示了一个 Azure 测试计划的示例:

图 1.7 – Azure 测试计划

图 1.7 – Azure 测试计划

Azure Artifacts

使用 Azure Artifacts,您可以从私有和公共源与 Azure DevOps 中的团队创建和共享 NuGet、npm、Python 和 Maven 包。这些包可以在源代码中使用,并可以在 CI/CD 管道中使用。通过 Azure Artifacts,您可以创建多个源,使用它们来组织和控制对包的访问。

以下截图展示了 Azure Artifacts 中一个源的示例:

图 1.8 – Azure Artifacts

图 1.8 – Azure Artifacts

扩展市场

您可以从 Visual Studio Marketplace 下载 Azure DevOps 的扩展。这些扩展是简单的插件,可以用来定制和扩展您团队在 Azure DevOps 中的使用体验。它们可以通过扩展工作项的规划和跟踪、代码测试和跟踪、管道构建和发布流程,以及团队成员之间的协作来提供帮助。这些扩展由微软和社区创建。

以下截图展示了可以从市场下载的一些扩展:

图 1.9 – 扩展市场

图 1.9 – 扩展市场

我们在前面章节中介绍的服务将在本书接下来的章节中得到更深入的讲解。在下一节中,我们将介绍本书将使用的场景。

介绍场景

本书中,我们将使用两种不同的场景进行演示。我们将使用可以通过 DevOps 生成器在您的 Azure DevOps 环境中生成和安装的示例项目。对于本书,我们将安装 Tailwind Traders 和 Parts Unlimited。Tailwind Traders 是一个示例零售公司,展示了智能应用体验的未来,而 Parts Unlimited 是一个示例电子商务网站。

创建启动项目

为了创建场景项目,我们将使用 Azure DevOps 演示生成器,它将为我们生成示例项目。这些项目可以免费使用。在生成项目之前,您需要从市场安装两个不同的 Azure DevOps 扩展,它们都被 Tailwind Traders 项目所使用。以下是这些扩展:

安装完成后,您可以在 Azure DevOps 组织中生成示例项目:

  1. 首先,访问以下网站:azuredevopsdemogenerator.azurewebsites.net/

  2. 点击登录按钮。如果您还没有 Azure 账户,可以点击免费开始按钮注册试用账户:图 1.10 – Azure DevOps 演示生成器

    图 1.10 – Azure DevOps 演示生成器

  3. 将项目命名为Tailwind Traders,选择一个组织,并通过点击选择模板按钮来选择一个模板。从列表中选择Tailwind Traders并点击选择模板

  4. 填写完这些信息后,页面应如下所示:图 1.11 – 创建新项目

    图 1.11 – 创建新项目

  5. 点击创建项目按钮。

  6. 创建项目后,导航到dev.azure.com/

  7. 使用您的凭据登录,并选择您创建项目的组织。选择Tailwind Traders项目查看是否有任何内容生成。

  8. 重复这些步骤,在您的 DevOps 环境中创建Parts Unlimited项目。

    小贴士

    有关 Tailwind Traders 示例项目的更多信息,请参阅以下网站:github.com/Microsoft/TailwindTraders。有关 Parts Unlimited 示例的更多信息,请参阅microsoft.github.io/PartsUnlimited/

小结

本章中,我们介绍了 DevOps 的一些基础知识,并涵盖了六个不同的 DevOps 原则。接着,我们介绍了 Azure DevOps 的关键概念,以及 Azure DevOps 提供的不同解决方案,以支持团队在应用生命周期的各个阶段。之后,我们查看了 Azure DevOps 提供的不同功能,并介绍并创建了将在本书接下来的章节中使用的两个场景。

在下一章中,我们将介绍如何使用 Azure Boards 管理项目。

深入阅读

请查看以下链接,了解更多本章涵盖的主题:

第二章:

第二章:使用 Azure DevOps Boards 管理项目

在上一章中,我们介绍了 DevOps,并讲解了六个原则。我们还简要介绍了 Azure DevOps 的关键概念和不同的服务。最后,我们介绍了本书将贯穿使用的场景。

在本章中,我们将更详细地讲解Azure Boards。我们将从 Azure DevOps 中可用的不同流程和过程模板开始。接着,我们将在 Azure DevOps 中创建一个新组织。我们在上一章中导入了一个名为 Tailwind Traders 的示例项目和组织。我们将在本章其余部分中使用这个示例。我们将使用 Tailwind Traders 项目创建一个新项目,并学习如何使用 Azure Boards 创建和管理不同的项目活动。

本章将涵盖以下内容:

  • 理解过程和过程模板

  • 创建一个组织

  • 创建一个项目

  • 创建和管理项目活动

技术要求

要跟随本章内容,你需要有一个有效的 Azure DevOps 组织。本章中我们将使用的组织是在第一章中创建的,名为Azure DevOps 概述

理解过程和过程模板

使用 Azure Boards,你可以管理软件项目的工作。团队需要支持他们的工具,这些工具必须具有可扩展性和灵活性。这包括对 Scrum 和看板(Kanban)的原生支持,以及可定制的仪表板、集成报告能力和工具。

在项目开始时,团队必须决定使用哪种过程和过程模板来支持所采用的项目模型。过程和模板定义了 Azure Boards 中使用的工作项跟踪系统的基本构件。

Azure DevOps 支持以下流程:

  • 基本:这是团队可以选择的最简单的模型。它使用史诗问题任务来跟踪工作。创建新基础项目时,这些工件会被创建,具体如下:

图 2.1 – 基本过程

图 2.1 – 基本过程

  • 敏捷:当你的团队使用敏捷计划过程时,选择敏捷。你可以跟踪不同类型的工作项,例如特性用户故事任务。这些工件是在使用敏捷流程创建新项目时生成的。开发和测试活动在这里是分开追踪的,敏捷使用看板(Kanban)来跟踪用户故事和缺陷。你也可以在任务看板上跟踪它们:

图 2.2 – 敏捷过程

图 2.2 – 敏捷过程

  • Scrum:当你的团队实践 Scrum 方法论时,选择 Scrum 流程。这将创建产品待办项PBIs)、任务缺陷以及更多的工件供团队使用。你可以使用看板跟踪工件,或者将 PBIs 和缺陷拆解为任务,在任务板上进行管理。Scrum 流程如下面的图所示:图 2.3 – Scrum 流程

图 2.3 – Scrum 流程

  • CMMI:当你的团队遵循一个更正式的项目方法,需要一个框架来进行过程改进,并且需要可审计的决策记录时,能力成熟度模型集成CMMI)流程更为适用。使用此流程模板,你可以跟踪需求、变更请求、风险和审查:

图 2.4 – CMMI 流程

图 2.4 – CMMI 流程

现在我们已经介绍了有关 Azure DevOps 中不同流程和流程模板的一些基本信息,接下来将讲解如何创建一个新组织。

创建组织

在 Azure DevOps 中,组织用于连接相关项目组。你可以在这里规划和跟踪工作,并在开发应用时与他人协作。从组织级别,你还可以与其他服务集成,根据权限设置相应的权限,并设置持续集成和部署。

在上一章中,我们介绍了本书中使用的场景。Tailwind Traders 是一个示范零售公司,展示了智能应用体验的未来。通过使用 DevOps 生成器创建项目,组织和项目被自动创建。

然而,也有一些情况你可能需要手动创建组织,例如当你第一次在一个组织中使用 Azure DevOps 时,或者当基于权限要求创建一个独立的组织时。因此,我们也将涵盖这个步骤。请按以下步骤操作:

  1. 打开一个网页浏览器,访问dev.azure.com/

  2. 使用你的 Microsoft 账户登录,然后从左侧菜单点击新建组织图 2.5 – 创建新组织

    图 2.5 – 创建新组织

  3. 在向导中,给组织命名,例如PacktLearnDevOps,并选择你希望托管项目的位置:图 2.6 – 命名项目

    图 2.6 – 命名项目

  4. 点击继续

到此,组织已创建。在下一节中,我们将学习如何将新项目添加到该组织。

创建项目

创建新组织后,Azure DevOps 会自动为你提供创建新项目的功能。请按以下步骤操作:

  1. 一旦您创建了新组织,创建项目的向导将自动显示。在这里,您可以指定项目的名称。在我的例子中,我将其命名为 LearnDevOps

  2. 您还可以选择将您的项目设置为公开,让互联网的所有人都能查看,或者私密。如果选择后者,您需要手动授予用户访问权限。我们将在本演示中选择私密图 2.7 – 创建一个新项目

    图 2.7 – 创建新项目

  3. 点击 + 创建项目 来创建新项目。它将被添加到我们在前一步创建的组织中。

  4. 还有另一种创建新项目的方法。您也可以在不创建组织的情况下单独创建项目。在很多情况下,您可能希望向现有组织中添加一个新项目。为此,请点击左侧菜单中的组织名称。您将被重定向到组织的概览页面。在那里,点击右上角的 + 新建项目图 2.8 – 向现有组织添加新项目

    图 2.8 – 向现有组织添加新项目

  5. 从这里开始,将显示用于创建新项目的相同向导。

我们已经介绍了如何创建一个新的组织并向其中添加项目。在本章的其余部分,我们将保持这个组织和项目不变,并使用我们在第一章**、Azure DevOps 概述中导入的 Tailwind Traders 项目。

在接下来的章节中,我们将介绍如何创建和管理不同的项目活动。

创建和管理项目活动

Azure DevOps 提供了不同的项目功能,团队可以利用这些功能来管理他们的软件开发项目,例如工作项、待办事项、冲刺、看板和查询。以下章节将介绍这些功能。

工作项

团队使用工作项来跟踪团队的所有工作。在这里,您将描述软件开发项目所需的内容。您可以跟踪功能和需求、代码缺陷或错误,以及其他所有项。可用的工作项取决于在创建项目时选择的流程。

工作项有三种不同的状态:新建激活关闭。在开发过程中,团队可以相应地更新这些项,以便每个人都能完整了解与项目相关的工作。

现在,让我们创建一个新的工作项。

创建新的工作项

从现在开始,我们将使用在前一章中生成的Tailwind Traders示例项目。我们将在这个项目中创建一个新的工作项。为此,请执行以下步骤:

  1. 打开一个网页浏览器并导航至 dev.azure.com/

  2. 使用您的凭据登录。

  3. 导航到创建了 Tailwind Traders 项目的组织,并选择该项目,如下图所示:图 2.9 – 在 Azure DevOps 中选择 Tailwind Traders 项目

    图 2.9 – 在 Azure DevOps 中选择 Tailwind Traders 项目

  4. 接下来,从左侧菜单选择 看板,然后选择 工作项图 2.10 – 导航到工作项

    图 2.10 – 导航到工作项

  5. 在下一个屏幕上,你将看到所有在创建 Tailwind Traders 项目时自动生成的工作项概览:图 2.11 – 所有示例工作项的概览

    图 2.11 – 所有示例工作项的概览

  6. 要创建一个新的工作项,请从顶部菜单点击 + 新建工作项。在那里,你将看到根据项目类型选择的不同工作项类型。对于 Tailwind Traders,使用的是敏捷类型(有关更多细节,请参见本章开头的 理解流程和流程模板 部分):

图 2.12 – 工作项类型

图 2.12 – 工作项类型

现在,让我们创建一个新的用户故事。为此,从列表中点击 用户故事。然后,按照以下步骤操作:

  1. 一个新窗口将打开,你可以在其中为用户故事指定相关的值。请添加以下内容:

    a) 标题:作为用户,我想编辑我的用户资料。

    b) 分配:在这里,你可以将工作项分配给特定的人员。

    c) 添加标签:你还可以向这个工作项添加标签。以后可以用这些标签进行搜索。我添加了一个名为 Profile Improvements 的标签。

    d) 状态:因为这是一个新创建的项目,状态自动设置为 新建

    e) 迭代:在这里,你可以指定将此用户故事添加到哪个冲刺中。你也可以稍后从待办事项中进行此操作。我已将其添加到第 2 次迭代。

    f) 描述:作为用户,我想编辑我的用户资料。这是一个富文本编辑器,你也可以根据需要格式化描述。

    g) 讨论:在这里,你可以添加与此工作项相关的附加评论。你可以使用 "#" 后接“工作项名称”来链接到另一个工作项,使用 "!" 后接“拉取请求名称”来链接特定的拉取请求,或者使用 "@" 后接“人员名称”来提及某个人。

    h) 优先级:在这里,你可以为你的用户故事设置优先级。这里的优先级仅是一个数字,用来表示工作项的重要性,而不是它的处理优先级。你可以通过拖动用户故事上下调整优先级。

    i) 分类:你也可以对这个项目进行分类。生成器为 Tailwind Traders 项目创建了两个不同的类别。在这里,你可以选择 业务架构。在这种情况下,该项目更偏向业务相关。

    j) 开发:在这里,你可以将项目与特定的分支、构建、拉取请求等关联。

    k) 故事点:使用故事点,你可以估算完成一个用户故事所需的工作量,可以使用任何数字单位进行度量。此字段中的值基于团队的工作速度:

    图 2.13 – 将项目与特定的开发流程关联

    ](https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/az-dop-expl/img/Figure_2.13_B16392.jpg)

    图 2.13 – 将项目与特定的开发流程关联

  2. 相关工作:你还可以将项目与其他项目或 GitHub 问题关联,如父子关系、已测试重复项等:图 2.14 – 将项目与相关工作关联

    ](https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/az-dop-expl/img/Figure_2.14_B16392.jpg)

    图 2.14 – 将项目与相关工作关联

  3. 填写完这些字段后,点击屏幕右上角的保存按钮:

图 2.15 – 保存你的工作项

图 2.15 – 保存你的工作项

我们现在已经成功创建了一个新的工作项。我强烈建议你创建一些不同的工作项,比如缺陷、功能、任务等。这样,你将熟悉每种工作项表单的不同类型。

重要提示

有关如何创建不同工作项的更多信息,请参见以下网站:docs.microsoft.com/en-us/azure/devops/boards/work-items/about-work-items?view=azure-devops&tabs=agile-process。有关工作项表单中使用的不同字段的更多信息,请参阅此网站:docs.microsoft.com/en-us/azure/devops/boards/work-items/guidance/work-item-field?view=azure-devops

在接下来的章节中,我们将更详细地了解待办事项和迭代。

待办事项

产品待办事项是团队计划交付内容的路线图。通过将用户故事、需求或待办事项添加到其中,你可以概览需要为项目开发的所有功能。

从待办事项中,工作项可以轻松地重新排序、优先级排序并添加到迭代中。

让我们来看一下待办事项是如何工作的:

  1. 在 Azure DevOps 中,再次打开Tailwind Traders项目。

  2. 接下来,从左侧菜单选择看板,然后选择待办事项。接着,选择Tailwind Traders 团队待办事项图 2.16 – 导航至项目的待办事项

    ](https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/az-dop-expl/img/Figure_2.16_B16392.jpg)

    图 2.16 – 导航至项目的待办事项

  3. 在这里,你将看到该项目的所有不同用户故事,包括我们在前一个演示中创建的那个。从右上角,你可以选择与项目模板一起提供的不同类型的工作项:图 2.17 – 不同类型的工作项

    ](https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/az-dop-expl/img/Figure_2.17_B16392.jpg)

    图 2.17 – 不同类型的工作项

  4. 目前,我们将继续使用用户故事视图。你也可以在这里重新排序和优先排序工作项。让我们通过将新创建的用户故事在列表中的第 2 和第 3 项之间拖动来重新优先排序它:图 2.18 – 重新优先排序用户故事

  5. 从待办事项中,你还可以将工作项添加到不同的迭代中。在创建工作项时,我们将这个用户故事添加到迭代 2 中。从这里,如果我们想的话,也可以将此项拖动到其他迭代中:图 2.19 – 将用户故事拖到另一个迭代

    图 2.19 – 将用户故事拖到另一个迭代

  6. 你还可以更改视图,查看与这些用户故事相关的更多工作项。通过点击屏幕左侧显示的视图选项,你可以启用不同的视图。启用父项,该视图显示史诗和特性:图 2.20 – 显示父项

    图 2.20 – 显示父项

  7. 通过拖动不同类型的工作项,你还可以轻松创建不同类型的父子关系。例如,你可以将新创建的用户故事拖动到会员注册特性上,并在它们之间创建关系:图 2.21 – 创建父子关系

图 2.21 – 创建父子关系

在本节中,我们介绍了待办事项和如何优先排序用户故事,以及如何将它们添加到迭代中。你还可以根据不同的工作项创建具有父子关系的视图。

在下一节中,我们将更详细地了解看板。

看板

查看不同工作项的另一种方式是使用看板。每个项目都带有一个预配置的看板,可以用来管理和可视化工作的流动。

这个看板有不同的列,代表不同的工作阶段。在这里,你可以全面了解所有需要完成的工作以及工作项的当前状态。

让我们更详细地了解 Azure DevOps 中的看板:

  1. 在左侧菜单中,选择看板,然后选择看板。在这里,你将看到不同工作项的概览,这些工作项已被添加到看板上的卡片中,如下图所示:图 2.22 – Tailwind Traders 看板概览

    图 2.22 – Tailwind Traders 看板概览

    工作项根据项的状态进行显示。在新建列中,显示团队尚未承诺的项目。接下来,是当前正在由团队进行处理的项目,这些项目显示在进行中列。

    还有一些工作项处于解决中状态,这意味着开发部分已经完成,但仍需进行测试。通过测试并符合完成定义的项目会被移到已关闭列。

  2. 在这里,你还可以将项目拖动到不同的列中,查看待办事项中的项目,并通过点击项目右上角的三个点()来对其进行更改,具体如下:

图 2.23 – 与看板互动

图 2.23 – 与看板互动

到这里,我们已经提供了一个关于看板的概述。在接下来的部分,我们将更详细地讨论迭代。

迭代

根据所选的项目模板,迭代的名称可能不同。在我们的 Tailwind Traders 项目中,使用的是敏捷项目模板。这将名称更改为迭代。然而,Azure DevOps 将这些视为与迭代相同的内容。

迭代或迭代用于将工作分割成特定数量的(通常是)周。这是基于团队可以处理的速度,也就是团队完成用户故事的速率。

让我们更详细地看一下 Azure DevOps 中的迭代视图:

  1. 从左侧菜单中,在看板下选择迭代。默认情况下,会显示待办事项视图。在这里,你将再次看到用户故事的概览,只不过这次是当前迭代的,具体如下图所示:图 2.24 – 当前迭代的概览

    图 2.24 – 当前迭代的概览

    你还可以将用户故事拖动到另一个迭代中,并在需要时重新排序它们。

  2. 通过点击顶部菜单中的任务板,你将看到与看板中工作项相似的不同视图。此时,当前迭代中的项目以待办任务级别显示:图 2.25 – 看板中的迭代

    图 2.25 – 看板中的迭代

  3. 在这里,你可以将项目拖动到不同的列中,必要时创建新的工作项,并筛选不同的迭代:

图 2.26 – 与迭代中的工作项互动

图 2.26 – 与迭代中的工作项互动

迭代看板主要在团队日常站会上使用。项目会根据团队的进展拖动到不同的列中。团队还会简要讨论这些项目,并在需要时请求帮助执行或创建它们。在迭代结束时,大多数项目将被移至已关闭列。

在这个演示中,我们查看了如何在 Azure 看板中管理和创建项目活动。在本章的最后一节中,我们将讨论 Azure DevOps 中的查询。

查询

你可以根据 Azure DevOps 中提供的筛选条件来过滤工作项。这样,你可以轻松查看所有处于特定类型、状态或具有特定标签的工作项。这可以在项目内部进行,也可以跨不同的项目进行。

要创建不同的查询并搜索工作项,请执行以下步骤:

  1. 从左侧菜单中,在Boards下选择Queries。然后,从顶部菜单中选择+ 新建查询图 2.27 – 创建新查询

    图 2.27 – 创建新查询

  2. 接下来,让我们创建一个查询,搜索具有Profile Improvements标签的用户故事。在查询屏幕上,选择下图所示的选项:图 2.28 – 创建查询

    图 2.28 – 创建查询

  3. 然后,点击运行查询。结果将显示我们在本节第一步中创建的工作项:图 2.29 – 搜索结果

图 2.29 – 搜索结果

重要提示

这是一个可以创建的搜索查询的基本示例。如需更深入的信息,您可以参考docs.microsoft.com/en-us/azure/devops/project/search/overview?view=azure-devops

这样,我们已经涵盖了如何运行查询以筛选工作项的基础知识。本章到此结束。

总结

在本章中,我们深入探讨了 Azure Boards。我们首先查看了根据组织采用的方法论可以选择的不同项目模板。根据该项目模板,创建了不同的工作项,这些工作项可用于项目规划。这些工作项可以添加到待办事项列表中,并可以创建关联关系,以便从逻辑上查看项目项。它们也可以添加到冲刺中。

在下一章中,我们将重点讲解 Azure DevOps 中的源代码管理。

进一步阅读

查看以下链接,获取有关本章所涵盖主题的更多信息:

第二部分:源代码与构建

本节将介绍 Azure 构建以及如何在 Azure DevOps 中管理源代码。

本节包含以下章节:

  • 第三章使用 Azure DevOps 进行源代码管理

  • 第四章理解 Azure DevOps 管道

  • 第五章在构建管道中运行质量测试

  • 第六章托管你自己的 Azure Pipeline 代理

第三章:

第三章:使用 Azure DevOps 进行源代码管理

源代码管理 (SCM) 是每个专业从事软件开发的公司以及每个想要安全存储和管理代码的开发者不可或缺的一部分。

在团队合作时,绝对有必要拥有一个安全的中央仓库来存储所有代码。同时,还必须有一个系统来保证代码在开发者之间的安全共享,并且每一次修改都能够经过检查并合并,不会产生冲突。

在本章中,我们将学习 Azure DevOps 如何帮助你专业且安全地管理源代码。本章将涵盖以下内容:

  • 理解源代码管理

  • 分支策略概述

  • 使用 Azure DevOps 和 Repos 处理源代码管理

  • 如何处理提交、推送和分支

  • 使用拉取请求

  • 处理拉取请求

  • 如何标记特定的代码发布

到本章结束时,你将了解所有可以应用 SCM 技术到你团队的概念,并且使用 Azure DevOps。

技术要求

要跟随本章内容,你需要在开发机器上安装一个有效的 Azure DevOps 组织和 Visual Studio 或 Visual Studio Code。

理解 SCM

源代码管理(或版本控制)是一种用于跟踪和管理源代码变化的软件实践。这是一个极为重要的实践,因为它可以确保不同开发人员之间维护同一份代码源,并有助于在单一软件项目中进行协作(即不同开发者在同一代码库上工作)。

SCM 是任何 DevOps 流程中的核心实践。要采用源代码管理策略,你应该做以下操作:

  • 选择一个源代码管理系统来采用(例如,在服务器上安装 Git 或使用基于云的 SCM,如 Azure DevOps Repos 或 GitHub)

  • 将你的代码库存储在由源代码管理系统管理的仓库中

  • 通过获取中央仓库中存储的最新代码版本(拉取),将仓库克隆到本地进行开发

  • 提交并推送你发布的代码到中央仓库

  • 使用不同的仓库副本进行并行开发(分支)

以下是一个 SCM 流程的示意图:

图 3.1 – 源代码管理流程

图 3.1 – 源代码管理流程

Git 无疑是市场上最受欢迎的 SCM 系统之一。Git 由 Linus Torvalds 于 2005 年创建,用于帮助 Linux 内核的开发。Git 是免费的、开源的,并且完全基于文件,因此除了 Git 引擎本身,不需要额外的软件来处理 SCM。

Git 的工作流程可以总结如下(并可以使用之前的图示表示):

  1. 你在 Git 托管系统中为你的项目创建一个仓库。

  2. 将仓库复制(或克隆)到你的本地开发机器上。

  3. 你在本地仓库中创建一个新文件,然后将更改保存在本地(暂存并提交)。

  4. 你将更改推送到远程仓库(push)。

  5. 你从远程仓库拉取更改到本地仓库(以便将代码与远程仓库同步,如果其他开发者做了修改的话)。

  6. 你将更改与本地仓库合并。

在使用 Git 作为 SCM 系统时,你需要记住一些关键概念:

  • 快照是 Git 用来跟踪代码历史的方式。快照本质上记录了在某一时刻所有文件的样子。你决定何时以及对哪些文件进行快照。

  • 提交是创建快照的行为。在一个项目中,你会创建不同的提交。一个提交包含三组信息:

    -- 详细描述文件如何从之前的版本发生变化

    -- 指向父提交的引用(之前发生的提交)

    -- 一个哈希代码名称

  • 仓库是所有必要文件及其历史记录的集合。仓库可以位于本地计算机或远程服务器上。

  • 克隆是从远程服务器复制仓库的操作。

  • 拉取是从远程仓库下载本地没有的提交的过程。

  • 推送是将本地更改添加到远程仓库的过程。

  • master

Git 流程由以下操作组成:

图 3.2 – Git 流程

图 3.2 – Git 流程

让我们来看一下 Git 中如何发生提交流。要在 Git 上创建一个提交,你需要对文件进行一些更改,然后使用 git add 命令将这些文件放入暂存环境。之后,使用 git commit 命令创建一个新的提交。这个流程可以表示如下:

图 3.3 – Git 提交

图 3.3 – Git 提交

作为示例,这里是一些你可以使用的 Git 命令来激活前述 SCM 流程:

  1. 克隆远程仓库到本地:

    git clone https://github.com/user/yourRemoteRepo.git
    
  2. 继续进行项目开发。

  3. 将工作保存在本地:

    git add .
    git commit -m "my commit message"
    
  4. 检查远程服务器是否有更新:

    git pull
    
  5. 将工作保存到远程服务器:

    git push
    

使用分支时,请遵循以下步骤:

  1. 创建一个新分支并切换到该分支:

    git checkout -b "branch1"
    
  2. 开发新功能。

  3. 将工作保存在本地:

    git add .
    git commit -m "update from branch1"
    
  4. 将工作保存到远程服务器:

    git push
    
  5. 切换到你想要合并工作的分支:

    git checkout master
    
  6. branch1 合并到 master 分支并将其保存到远程服务器:

    git merge branch1
    git push
    

一旦你掌握了这些命令,你就可以开始使用 Git。在接下来的部分中,我们将概述分支和你可以使用的分支策略。

探索分支策略

分支是存储在 SCM 系统中的代码版本。在使用 Git 的 SCM 系统时,选择最适合你团队的分支策略至关重要,因为它有助于你保持可靠的代码库和快速交付。

在使用 SCM 时,如果你没有使用分支管理,你将始终只有一个版本的代码(master分支),并且你总是向这个分支提交代码:

图 3.4 – 单一工作流

图 3.4 – 单一工作流

这种“单一工作流”方式不推荐使用,因为它无法保证master分支的稳定性,特别是当多个开发人员在同一代码上工作时。

有许多不同的分支工作流(策略),你可以为团队选择采用,通常我建议从简单的策略开始。在 Git 中,你可以采用三种主要的分支策略:

  • GitHub 流

  • GitLab Flow

  • Git Flow

在接下来的章节中,我们将探讨这些策略的每一个。

GitHub 流

GitHub Flow 是最广泛使用的分支策略之一,并且相对容易采用。

根据此工作流程,你从master分支开始(该分支始终包含可部署的代码)。当你开始开发新功能时,你会创建一个新的分支,并定期向此分支提交代码。当开发工作完成时,你会创建一个 pull 请求,将该子分支与master分支合并:

图 3.5 – GitHub Flow

图 3.5 – GitHub Flow

这个工作流简单易于采用,适用于你需要在生产环境中维护单一版本的代码。唯一的缺点是你需要仔细检查提交到master分支的内容。如果你需要在生产环境中维护多个版本的应用程序,通常不推荐使用这种方式。

GitLab 流

GitLab Flow 是另一种流行的分支策略,广泛应用,尤其是在你需要支持多个环境(例如生产、预发布、开发等)时,特别适用于 SCM 流程。以下图示表示该工作流:

图 3.6 – GitLab Flow

图 3.6 – GitLab Flow

根据此工作流程,你应该至少有三个分支:

  • 主分支:这是每个人的本地版本代码。

  • 预发布:这是用于测试目的的分支,master分支会被分叉到这里。

  • 生产:这是已发布的生产代码(预发布已经合并到这里)。

如果你想保持稳定的生产发布,并分别在新功能上工作(这些功能可以移至测试环境进行测试),然后在测试完成后将该环境合并到生产发布中,这种工作流非常有用。

Git Flow

Git Flow 是一种用于有定期发布周期的工作流。以下图示表示该工作流:

图 3.7 – Git Flow

图 3.7 – Git Flow

根据此工作流程,你有一个master分支和一个develop分支,它们始终处于活动状态,另外一些分支并非总是处于活动状态(可以删除)。master分支包含已发布的代码,而develop分支包含你正在开发的代码。

每次向你的代码库添加新功能时,你会从develop分支创建一个feature分支,然后当实现完成时,将feature分支合并到develop。在这里,你永远不会合并到master分支。

当你需要发布一组功能时,你会从develop分支创建一个发布分支。release分支中的代码必须经过测试(可能包含合并的 bug 修复),当你准备好发布代码时,你将release分支合并到master分支,然后再合并到develop分支。

如果在生产中出现严重 bug,此流程建议你可以从master分支创建一个fix分支,修复 bug,然后直接将此分支合并回master。如果存在release分支,你也可以将其合并到release分支,否则合并到develop分支。如果你将代码合并到release分支,当你将release分支合并回develop分支时,develop分支将包含修复。

处理 Azure DevOps 中的源代码控制

Azure DevOps 支持以下源代码管理类型:

  • Git:这是一个分布式版本控制系统,在创建新项目时是 Azure DevOps 的默认版本控制提供程序。

  • Team Foundation Version Control (TFVC):这是一个集中式版本控制系统,在这里开发者本地只有一个文件版本,数据存储在服务器上,并且分支是在服务器上创建的(基于路径)。

使用 Azure DevOps 的第一步是在你的组织内创建一个新项目。当你使用 Azure DevOps 创建新项目时,系统会提示你选择要使用的版本控制系统(如下截图中的红框所示):

![Figure 3.8 – 创建新项目Figure 3.08_B16392.jpg

图 3.8 – 创建新项目

点击确定按钮,新项目将在你的 Azure DevOps 组织中创建。

项目创建完成后,你可以通过进入 Azure DevOps 左侧导航栏中的仓库中心来管理你的存储库(见下面的截图)。这里是你的文件存储位置,你可以开始创建存储库并管理分支、拉取请求等等:

![Figure 3.9 – ReposFigure 3.09_B16392.jpg

图 3.9 – 仓库

仓库开始,每个开发者都可以在本地克隆存储库,并直接从 Visual Studio 或 Visual Studio Code 进行工作,同时连接到 Azure DevOps,以便推送代码修改、拉取和创建分支、进行提交,并发起拉取请求。

当你从头开始启动一个新项目时,Azure DevOps 会为你创建一个空的存储库。你可以手动将代码加载到这个存储库中(通过上传),或者你可以从远程存储库(例如 GitHub)克隆到 Azure DevOps。

在一个项目中,你可以创建不同的仓库,每个仓库都有自己的权限、分支和提交记录。要创建新仓库,只需选择 Repos 中心并点击 New repository,如下一张截图所示:

图 3.10 – 新仓库

图 3.10 – 新仓库

仓库可以从 Azure DevOps 中轻松重命名或删除。

在本节中,我们学习了如何在 Azure DevOps 中创建新项目以及如何为你的项目创建代码仓库。

在接下来的章节中,我们将学习如何使用 Azure DevOps 管理完整的源代码管理流程,从克隆远程仓库到提交代码。

克隆远程仓库

为了展示如何在 Azure DevOps 中使用代码仓库,我将从一个包含我 Web 应用源代码的 Git 仓库项目开始。下图显示了托管在 master 分支上的远程代码:

图 3.11 – 主分支

图 3.11 – 主分支

每个必须使用此代码的开发人员都需要在本地克隆该仓库。你可以点击 Clone 按钮,如下图所示:

图 3.12 – 克隆仓库

图 3.12 – 克隆仓库

从这里,你将看到一个显示克隆仓库 URL 的窗口。你可以使用 git clone <Repository URL> 命令来克隆这个仓库,或者通过在 Visual Studio 或 Visual Studio Code 中选择下方截图中显示的选项来直接克隆:

图 3.13 – 克隆选项

图 3.13 – 克隆选项

在这里,我正在将项目克隆到 Visual Studio Code。Azure DevOps 会提示我选择一个文件夹来保存该项目(开发机器上的本地文件夹),然后打开 Visual Studio Code 并开始克隆远程仓库:

图 3.14 – 在 Visual Studio Code 中克隆

图 3.14 – 在 Visual Studio Code 中克隆

在 Visual Studio Code 中,你也可以通过打开命令面板(Ctrl + Shift + P),选择 Git:Clone 命令,然后将仓库 URL 粘贴到提示窗口中来克隆仓库:

图 3.15 – Git:Clone 命令

图 3.15 – Git:Clone 命令

一旦克隆过程完成,你将会在选定的文件夹中拥有远程仓库 master 分支的本地副本:

图 3.16 – 远程仓库的本地副本

图 3.16 – 远程仓库的本地副本

为了更高效地使用 Visual Studio Code 与 Azure DevOps 上的远程仓库工作,我建议你安装一个名为 Azure Repos 的扩展(来自 Visual Studio Code 市场):

图 3.17 – Azure Repos 扩展

图 3.17 – Azure Repos 扩展

一旦 Azure Repos 安装完成,如果你进入命令面板并搜索 teams,你将看到一组新的可用命令来与 Azure DevOps 进行交互,如下所示:

图 3.18 – Azure Repos 命令

图 3.18 – Azure Repos 命令

在本章的后续部分,我们将使用其中的一些命令。

在下一节中,我们将学习如何将 GitHub 仓库导入到 Azure DevOps。

将 GitHub 仓库导入到 Azure DevOps

使用 Azure DevOps,你还可以在 Repos 中导入 GitHub 仓库。如果你选择了一个在 Azure DevOps 项目中创建的空仓库,你将可以看到导入仓库的选项,如以下截图所示:

图 1.19 – 导入一个仓库

图 1.19 – 导入一个仓库

在这里,你可以选择要导入的 GitHub 仓库(通过输入源类型和 GitHub 仓库的克隆 URL):

图 1.20 – 导入 Git 仓库

图 1.20 – 导入 Git 仓库

当你点击 导入 按钮时,远程 GitHub 仓库的导入过程将开始,你将看到显示进度的图像:

图 3.21 – 正在处理导入仓库请求

图 3.21 – 正在处理导入仓库请求

一旦导入过程完成,你将在 Azure Repos 中获得代码。请记住,当从 GitHub 导入仓库时,历史记录和修订信息也会被导入到 Azure DevOps 中,以实现完整的可追溯性:

图 3.22 – 导入的仓库历史

图 3.22 – 导入的仓库历史

使用提交、推送和分支

一旦你将远程仓库克隆到本地 Git 仓库,你就可以开始编码(创建新文件或修改现有文件)。

每次你创建或修改一个文件时,Git 会记录本地仓库中的更改。你会看到 Visual Studio Code 的源代码控制图标开始提示文件已被修改。例如,在下面的截图中,我向项目中的一个文件添加了评论。保存文件后,Git 引擎会提示我有一个未提交的文件:

图 3.23 – 未提交文件警告

图 3.23 – 未提交文件警告

如果你点击左侧栏中的 源代码控制 图标,你将看到未提交的文件。在这里,你可以选择你想提交的更改并将其暂存。每次提交都是在本地进行的。你可以通过点击 + 图标来暂存修改,然后通过点击顶部工具栏中的 提交 按钮来提交所有暂存的文件。每次提交都必须有一条信息,解释这次提交的原因:

图 3.24 – 提交信息

图 3.24 – 提交信息

现在,文件已经本地提交到你的本地 master 分支(虽然不推荐这样做,稍后会解释)。要将这些修改同步到 Azure DevOps 中的线上仓库,你可以点击 Visual Studio Code 底部栏上的 Synchronize Changes 按钮(这会以红色高亮显示,表明你有需要推送到线上的修改),如下图所示:

图 3.25 – 需要推送到线上修改

图 3.25 – 需要推送到线上修改

另外,你可以从命令栏选择 Git : push 命令,如下所示:

图 3.26 – Git:Push 命令

图 3.26 – Git:Push 命令

现在,所有代码修改都已经推送到 master 分支。如果你进入 Azure DevOps 的 Repos 中心并选择 Commits 菜单,你将看到所选分支的每一次提交历史:

图 3.27 – 提交历史

图 3.27 – 提交历史

这样,我们直接在 master 分支上工作。这不是实际开发团队中常用的工作方式,因为如果每个开发者都直接提交到 master 分支,就无法保证该分支始终稳定。最好的做法是使用之前提到的 GitHub Flow。因此,你应该创建一个新分支,在这个新分支上工作,只有在工作完成后,才创建一个 pull 请求将分支合并到 master 分支。

你可以在 Azure DevOps 中或直接在 Visual Studio Code 中创建新分支。创建新分支的步骤如下:

  1. 从 Azure DevOps 中选择 Branches,然后点击 New branch图 3.28 – 新分支

    图 3.28 – 新分支

  2. 然后,提供一个分支名称。你需要选择新分支将从哪个分支创建,如下图所示:图 3.29 – 创建分支

    图 3.29 – 创建分支

    要直接从 Visual Studio Code 创建新分支,只需点击底部栏上的分支名称,然后选择 Create new branch…

    图 3.30 – 在 Visual Studio Code 中创建新分支…选项

    图 3.30 – 在 Visual Studio Code 中创建新分支…选项

  3. 现在,选择新分支的名称(这里称为 development):图 1.31 – 分配分支名称

    图 1.31 – 分配分支名称

    这样,分支将被创建在本地仓库中,Visual Studio Code 将自动开始在该分支上工作:

    图 3.32 – 在新分支上工作

    图 3.32 – 在新分支上工作

  4. 现在,您可以在此新分支上继续进行代码开发(可能是为了开发一组新的功能),并进行提交,而不会影响 master 分支(它将继续保持代码库的实际发布版本)。

    例如,在这里,我已向 MedicineController.cs 文件添加了一个新的修改。我可以在本地对 development 分支进行暂存和提交此修改:

    图 3.33 – 暂存更改

    图 3.33 – 暂存更改

  5. 然后,我可以将这些修改推送到 Azure DevOps 上的远程仓库。当在线推送时,如果这是第一次创建 development 分支,您将收到如下消息:图 3.34 – 自动分支创建和发布

    图 3.34 – 自动分支创建和发布

  6. 完成后,development 分支将在远程仓库中创建,并且您的代码将被推送到线上:图 3.35 – 在远程仓库上创建的分支

    图 3.35 – 在远程仓库上创建的分支

  7. 如果您在 Azure DevOps 中的 Repos 中进入 Commits 部分,您将看到提交历史记录。通过选择特定的提交,您可以查看所做的文件更改(通过将之前的版本与该提交后的当前版本进行比较):

图 3.36 – 提交的详细信息

图 3.36 – 提交的详细信息

这个操作也可以通过 Visual Studio Code 中的 Team:View History 命令直接完成:

图 3.37 – 来自 Visual Studio Code 的 Team:View History 命令

图 3.37 – 来自 Visual Studio Code 的 Team:View History 命令

分支可以被删除(手动删除或在拉取请求后自动删除)、从意外删除中恢复,还可以被锁定(使其进入只读状态,或防止此分支上的新提交影响当前合并)。要锁定特定分支,只需在 Azure DevOps 中选择该分支,然后从菜单中选择 Lock 选项:

图 3.38 – 锁定分支

图 3.38 – 锁定分支

要解锁已锁定的分支,只需选择 Unlock 操作。需要注意的是,锁定分支并不妨碍克隆或拉取此分支到本地。

通过策略保护分支

在与不同的开发人员协作并使用分支时,保护仓库中关键的分支(例如 master 分支)非常重要,可以通过规则确保这些分支始终保持健康状态。

对于这个范围,Azure DevOps 允许您为关键分支指定一组策略。

Azure DevOps 中的分支策略允许您执行以下操作:

  • 限制特定分支的贡献者

  • 指定谁可以创建分支

  • 为分支指定一组命名约定

  • 自动为分支中的每个代码更改包括代码审阅者

  • 强制使用拉取请求

  • 在提交代码到分支之前启动构建管道

要为特定分支指定分支策略,请转到 Azure DevOps 中的分支部分,选择您的分支,然后选择分支策略菜单:

图 3.39 – 分支策略

图 3.39 – 分支策略

在这里,您可以设置一组选项来控制所选分支。我们将在以下部分详细查看这些选项。

要求最少审阅者数量

该选项允许您指定可以批准代码修改的审阅者数量。如果任何审阅者拒绝代码更改,则修改不会被批准,且代码更改会被丢弃。如果选择允许即使一些审阅者选择等待或拒绝也可以完成,那么拉取请求可以完成。请求者可以批准自己的更改选项允许拉取请求的创建者批准自己的代码更改:

图 3.40 – 要求最少审阅者数量选项

图 3.40 – 要求最少审阅者数量选项

检查关联的工作项

该选项允许您要求将工作项与特定拉取请求关联,以便实现活动和任务的完整可追溯性。如果您使用的是项目规划功能(如本书中的第二章《使用 Azure DevOps Boards 管理项目》所示),这将非常有用:

图 3.41 – 检查关联的工作项选项

图 3.41 – 检查关联的工作项选项

检查评论解决情况

该选项允许您指定一条规则,要求所有评论必须解决,才能执行拉取请求:

图 3.42 – 检查评论解决选项

图 3.42 – 检查评论解决选项

限制合并类型

该选项允许您在完成拉取请求时强制执行分支策略。可用的选项如下:

  • 基本合并(无快速转发):此选项合并源分支的提交历史,并在目标分支中创建一个合并提交。开发过程中发生的完整非线性提交历史将被保留。

  • Squash 合并:通过压缩源分支的提交(线性历史),在目标分支中创建一个单一提交。

  • master 分支。拉取请求中的每个提交都将单独合并到目标分支中(线性历史)。

  • 使用合并提交的变基:通过将源分支的提交替换为目标分支中的提交,然后创建合并提交,从而创建半线性历史。

所有这些选项可以在以下屏幕截图中查看:

图 3.43 – 限制合并类型选项

图 3.43 – 限制合并类型选项

构建验证

本节允许您为构建代码指定一组规则,在拉取请求完成之前(有助于及早发现问题)。点击 添加构建策略 后,将出现一个新面板:

图 3.44 – 添加构建策略

图 3.44 – 添加构建策略

在这里,您可以指定要应用的构建管道定义,以及它是否必须在分支更新时自动触发,或者手动触发。我们将在 第四章**,理解 Azure DevOps Pipelines 中详细讨论构建管道。

需要额外服务的批准

该选项允许您连接外部服务(通过 Azure DevOps 拉取请求 API),以便参与拉取请求流程:

图 3.45 – 添加状态策略

图 3.45 – 添加状态策略

自动包含代码审查者

此策略允许您将特定用户或组包含在代码审查过程中:

图 3.46 – 添加自动审查者

图 3.46 – 添加自动审查者

跨仓库策略

不必为每个您手动创建的分支定义一个策略,Azure DevOps 允许您定义跨仓库策略(这些策略将自动应用于您为项目创建的所有分支)。

要定义一个适用于您将创建的每个仓库的策略,您需要进入 项目设置,然后选择 跨仓库策略,如下面的截图所示:

图 3.47 – 跨仓库策略

图 3.47 – 跨仓库策略

在这里,您可以添加一个分支保护策略并选择以下选项之一:

  • master 分支的每个仓库)。

  • 保护当前和未来匹配指定模式的分支。在这里,您可以定义一个过滤分支的模式,策略将应用于所有符合该模式的分支。

举个例子,如果您想定义一个策略,该策略将自动应用于您为项目创建的所有分支,请按以下步骤操作:

图 3.48 – 添加分支保护

图 3.48 – 添加分支保护

如您所见,在这里,我们选择了 *** key 作为模式来识别我们项目中的所有分支。

使用拉取请求

拉取请求 允许您通知团队成员,表明一个新实现已完成并必须与指定的分支合并。通过使用拉取请求,团队成员可以审查您的代码(逐步查看文件并查看特定提交所做的修改),对小问题提供审查评论,并批准或拒绝这些修改。这是使用 Azure DevOps 进行源代码管理时推荐的做法。

你可以通过选择 Repos 中心的 拉取请求 菜单,查看 Azure DevOps 中特定仓库的所有传入拉取请求,如下图所示:

图 3.49 – 拉取请求视图

图 3.49 – 拉取请求视图

你还可以筛选此列表,仅查看你的拉取请求,或仅查看 ActiveCompletedAbandoned 状态的拉取请求。

拉取请求可以通过以下几种方式创建:

  • 手动从 Azure DevOps 拉取请求页面创建

  • 从与分支关联的工作项(开发标签)

  • 当你向功能分支推送更新时

  • 从 Visual Studio Code 或 Visual Studio 直接启动

  • 从 Azure DevOps Services CLI 启动

在接下来的章节中,我们将学习如何在这些情况下启动拉取请求。

从 Azure DevOps 拉取请求页面创建拉取请求

你可以直接从 Azure DevOps 拉取请求菜单(位于 Repos 中心)创建一个新的拉取请求。在这里,只需点击 新建拉取请求 按钮:

图 3.50 – 新建拉取请求

图 3.50 – 新建拉取请求

你现在可以输入关于你希望创建的拉取请求的详细信息(我们将在本章后面讨论这一部分)。

从工作项创建拉取请求

在你团队的工作项 待办事项 视图中,你可以选择一个与分支关联的工作项(一个与分支提交关联的工作项),进入所选工作项的 开发 区域,并创建一个 创建拉取请求 操作:

图 3.51 – 从工作项创建拉取请求

图 3.51 – 从工作项创建拉取请求

在推送分支后创建拉取请求

当你将代码提交到 Azure DevOps 的 development(次级)分支时,系统会自动提示你创建一个拉取请求(你可以通过转到 文件拉取请求 菜单,在 Repos 中心查看此提示)。如你所知,我之前将新代码提交到了名为 development 的分支。现在,如果我们进入 文件 | 历史记录 部分,我们会看到创建新拉取请求的提示:

图 3.52 – 在分支上提交后创建拉取请求

图 3.52 – 在分支上提交后创建拉取请求

从 Visual Studio Code 或 Visual Studio 创建拉取请求

你可以直接从 Visual Studio Code 或 Visual Studio 启动拉取请求,只要你的项目已经加载。

要从 Visual Studio Code 启动拉取请求,请从命令面板中启动 Team:Create pull request 命令(Ctrl + Shift + P):

图 3.53 – 从 Visual Studio Code 创建拉取请求

图 3.53 – 从 Visual Studio Code 创建拉取请求

这将提示你打开 Azure DevOps。确认后,拉取请求窗口将会打开。

在 Visual Studio 中,选择 Team Explorer 面板。从这里,你可以点击 Pull Requests 来开始一个拉取请求:

图 3.54 – 从 Visual Studio 创建拉取请求

图 3.54 – 从 Visual Studio 创建拉取请求

处理拉取请求

我们描述的处理拉取请求的所有不同方法汇聚到一个唯一的点:在 Azure DevOps 中,Pull requests 窗口会打开,你需要填写你的拉取请求活动的详细信息。举个例子,这是我们在 development 分支上进行上次提交后开始的拉取请求:

图 3.55 – 新建拉取请求窗口

图 3.55 – 新建拉取请求窗口

在这里,你可以立即看到拉取请求将一个分支合并到另一个分支(在我的例子中,development 将被合并到 master)。你需要提供这个拉取请求的标题和描述(清晰地描述你在合并过程中所做的更改和实现),并附上链接以及添加将负责审查此拉取请求的团队成员(用户或组)。你还可以包括工作项(如果你之前已完成与工作项相关的提交,系统会自动包含这个选项)。

Files 部分,你可以看到此拉取请求将在目标分支中做什么(每个文件)。举个例子,这就是我的拉取请求展示的内容:

图 3.56 – 拉取请求中的代码修改视图

图 3.56 – 拉取请求中的代码修改视图

在左边,你可以看到在 master 分支中提交的文件,而在右边,你可以看到合并阶段后的同一文件(显示了每个修改的详细信息)。

如果你指定了一些审阅者,他们将看到代码修改的详细信息,这意味着他们可以添加评论并与开发人员进行互动。

要创建拉取请求流程,只需点击 Create 按钮。

一旦拉取请求创建完成,你可以通过点击拉取请求窗口右上角的 Complete 按钮来完成拉取请求(你可以在可选的批准阶段之后以及通过分支规则后进行此操作):

图 3.57 – 完成拉取请求

图 3.57 – 完成拉取请求

在这里,你可以执行以下操作:

  • 完成 拉取请求。

  • 标记为草稿:这就像是“进行中的工作”。如果拉取请求被标记为草稿,所需的审阅者不会自动添加,投票也不被允许,如果启用了构建策略,它们不会自动执行。

  • 放弃:拉取请求将被关闭,你的代码不会被合并。

当你点击 Complete 时,你会被提示填写 Complete pull request 窗口,内容如下:

图 3.58 – 完成拉取请求

图 3.58 – 完成拉取请求

在这里,你可以插入合并操作的标题和描述,选择应用的合并类型,并选择完成后操作(如果关联的工作项应该在合并后标记为已完成,以及合并操作后是否必须删除源分支)。

关于要应用的合并操作类型,你可以从以下选项中选择:

  • 合并(无快进):保留所有提交的非线性历史

  • Squash 提交:仅在目标上保留一个提交的线性历史

  • 变基和快进:将源提交变基到目标,并进行快进合并

  • 半线性合并:将源提交变基到目标,并创建一个双父合并

Azure DevOps 为你提供了一个漂亮的动画图表,以显示合并的最终结果。要完成拉取请求,点击完成合并。如果发生任何合并冲突,你需要先解决它们。这样,合并阶段就开始了:

图 3.59 – 完成拉取请求。

图 3.59 – 完成拉取请求。

如果目标分支(这里是master分支)上有自动构建策略,构建管道会被执行,然后完成合并操作:

图 3.60 – 拉取请求已完成

图 3.60 – 拉取请求已完成

在下一部分中,我们将学习如何在分支上使用标签,以便立即识别代码库中的代码状态。

标记发布

Git 标签是指向 Git 历史中特定点的引用。标签在 Azure DevOps 中用于标记特定的发布(或分支),并用一个标识符共享给团队内部,以便识别,例如,你的代码库的“版本”。

作为例子,在前面的章节中,我们使用 master 分支将 development 分支合并到 master 分支,master 分支包含我们最新的代码发布,现在我们准备好在内部共享它。

要在分支上使用标签,在 Azure DevOps 中的Repos中心,进入标签菜单:

图 3.61 – 标签

图 3.61 – 标签

从这里,你可以通过进入标签并点击新建标签来为此次发布创建标签。

在这里,你将被提示插入一个标签名称(一个不能包含空格的标识符),为此标签提供描述,并选择标签将应用于的分支:

图 3.62 – 创建标签

图 3.62 – 创建标签

当你点击创建时,标签将应用到你的分支上:

图 3.63 – 标签应用于分支

图 3.63 – 标签应用于分支

总结

在本章中,我们学习了如何使用 Azure DevOps 处理源代码管理,以及在团队开发代码时它为何如此重要。

我们了解了源代码管理和 Git 的基本概念,合并代码时可能应用的策略,如何使用 Azure DevOps 来应用 SCM,以及如何通过 Azure DevOps 和开发工具(如 Visual Studio Code 和 Visual Studio)来处理仓库、提交、分支和拉取请求。我们还学习了如何应用更好的策略来控制源代码发布,以便改进 SCM 生命周期,如何保护分支,以及如何为分支使用标签。

在下一章,我们将学习如何使用 Azure DevOps 创建构建管道,以实施 CI/CD 实践。

第四章:

第四章:了解 Azure DevOps Pipelines

在组织中采用 Azure DevOps 时,您必须做出的一个主要决策是如何定义您的开发过程的 流水线。流水线是一个公司定义的模型,描述了从构建到最终发布阶段代码库必须支持的步骤和操作。它是任何 DevOps 架构的关键部分。

在本章中,我们将学习如何定义和使用 Azure DevOps 管道来构建代码。

我们将涵盖以下主题:

  • 实现 CI/CD 流程

  • Azure Pipelines 概述

  • 创建和使用构建代理

  • YAML 格式概述

  • 在 Azure DevOps 中创建 CI/CD 流水线

  • 构建的保持

  • 多阶段管道

  • 使用 GitHub 仓库构建管道

  • 在 Azure Pipelines 中使用容器作业

  • 开始吧!

技术要求

要跟随本章,您需要具备以下内容:

  • Azure DevOps 中的有效组织

  • 一个 Azure 订阅,您可以在这些环境中的一个上创建 Azure 虚拟机或本地机器,以便安装构建代理软件

  • Visual Studio 或 Visual Studio Code 作为您的开发环境

  • 访问以下 GitHub 仓库以克隆项目:github.com/Microsoft/PartsUnlimited

实现 CI/CD 流程

在公司采用 DevOps 时,实现正确的 DevOps 工具和 DevOps 流程至关重要。DevOps 实现中的一个基本流程是 持续集成CI)和 持续交付CD)过程,它可以帮助开发人员以更快速、结构化和安全的方式构建、测试和分发代码库。

CI 是一种软件工程实践,开发团队中的开发人员每天会多次将代码修改集成到中央代码库中。当代码修改被集成到特定分支时(通常通过拉取请求,正如前一章所述),会触发一个新的构建,以便快速检查代码并发现集成错误。此外,在此阶段还会执行自动化测试(如果可用),以检查是否存在故障。

CD 是在 CI 过程之后的一个过程。在此过程中,CI 阶段的输出被打包并交付到生产阶段,无错误。这对于确保我们始终拥有经过测试、一致且准备好部署的主分支非常有帮助。

在 DevOps 中,您还可以实现 持续部署 过程,在此过程中,您可以自动将代码修改部署到最终的生产环境中,而无需手动干预。

典型的 DevOps CI/CD 循环在以下著名的“循环”图中表示:

图 4.1 – DevOps CI/CD 循环

图 4.1 – DevOps CI/CD 循环

一个典型的 CI/CD 流水线实现包含以下阶段:

  • 提交阶段:在此阶段,新代码修改会被集成到代码库中,并执行一系列单元测试,以检查代码的完整性和质量。

  • 构建阶段:在此阶段,代码会自动构建,然后将构建过程的最终结果(构建产物)推送到最终的注册表。

  • 测试阶段:构建的代码将部署到预生产环境,在那里执行最终的测试,然后进入生产部署阶段。在这里,代码通过采用 Alpha 和 Beta 部署进行测试。Alpha 部署阶段是开发人员检查新构建的性能和构建之间的交互的地方。在 Beta 部署阶段,开发人员执行手动测试,以再次检查应用程序是否正常工作。

  • 生产部署阶段:这是最终应用程序在成功通过所有测试要求后,推送到生产阶段的地方。

在您的组织中实现 CI/CD 流程有很多好处。主要好处如下:

  • 提高代码质量和早期发现漏洞:通过采用自动化测试,您可以在早期发现漏洞和问题,并进行修复。

  • 完整的可追溯性:整个构建、测试和部署过程都被跟踪,并且可以稍后进行分析。这确保您可以检查特定构建中的哪些更改被包含,并了解这些更改对最终测试或发布的影响。

  • 更快的测试和发布阶段:自动化每次新提交(或发布前)的代码库构建和测试。

在下一节中,我们将概述 Azure 平台提供的用于实现 CI/CD 的服务:Azure Pipelines。

Azure Pipelines 概述

Azure Pipelines 是 Azure 平台提供的云服务,可以自动化您的开发生命周期中的构建、测试和发布阶段(CI/CD)。Azure Pipelines 可以与任何语言或平台一起使用,集成在 Azure DevOps 中,您可以在 Windows、Linux 或 macOS 机器上构建代码。

Azure Pipelines 对于公共项目是免费的,而对于私有项目,每月提供最多 1,800 分钟(30 小时)的免费管道使用时间。有关定价的更多信息,请访问这里:

azure.microsoft.com/en-us/pricing/details/devops/azure-devops-services/

Azure Pipelines 的一些重要特性可以总结如下:

  • 它是平台和语言独立的,这意味着您可以在任何平台上使用所需的代码库构建代码。

  • 它可以与不同类型的代码库(Azure Repos、GitHub、GitHub Enterprise、BitBucket 等)集成。

  • 有许多扩展(标准和社区驱动)可供构建代码和处理自定义任务。

  • 允许将代码部署到不同的云供应商。

  • 您可以使用容器化应用程序,如 Docker、Azure Container Registry 或 Kubernetes。

要使用 Azure Pipelines,您需要以下内容:

  • 在 Azure DevOps 中的组织,您可以创建公开或私有项目

  • 存储在版本控制系统中的源代码(如 Azure DevOps Repos 或 GitHub)

Azure Pipelines 使用以下架构:

图 4.2 – Azure Pipelines 架构

图 4.2 – Azure Pipelines 架构

当您的代码提交到仓库中的特定分支时,构建管道引擎启动,构建和测试任务执行,如果一切顺利完成,您的应用程序将被构建,您将得到最终输出(工件)。您还可以创建一个发布管道,将构建的输出发布到目标环境(预发布或生产)。

要开始使用 Azure Pipelines,您需要创建一个管道。Azure DevOps 中的管道可以通过以下两种方式创建:

  • 使用经典界面:这允许您从可能的任务列表中可视化选择一些任务,您只需填写这些任务的参数。

  • 使用名为 YAML 的脚本语言:可以通过在仓库中创建一个 YAML 文件,定义所有需要的步骤来定义管道。

使用经典界面初始阶段可能更简单,但请记住,许多功能仅在 YAML 管道中可用。YAML 管道定义是一个文件,这个文件可以像仓库中的其他文件一样进行版本控制和管理。您可以轻松地在项目之间迁移管道定义(这在经典界面中是不可能的)。

Azure Pipelines 可以表示为如下所示(感谢 Microsoft 提供):

图 4.3 – Azure Pipelines 的表示

图 4.3 – Azure Pipelines 的表示

一个管道从触发器开始(手动触发、仓库中的推送、拉取请求或计划任务)。管道通常由一个或多个阶段组成(管道中的逻辑分离,例如构建、测试、部署等;它们可以并行运行),每个阶段包含一个或多个作业(一组步骤,这些步骤也可以并行运行)。每个管道至少包含一个阶段,除非您明确创建了多个阶段。每个作业在代理上运行(执行作业的服务或软件)。每个步骤由任务组成,任务对代码执行某些操作(按顺序执行)。管道的最终输出是一个工件(构建发布的文件或包的集合)。

创建管道时,您需要定义一组作业和任务,以自动化您的构建(或多阶段构建)。您可以获得对测试集成、发布门、自动报告等的原生支持。

当在管道中定义多个作业时,这些作业是并行执行的。包含多个作业的管道被称为扇出场景:

图 4.4 – 扩展管道

图 4.4 – 扩展管道

一个包含多个任务的单阶段管道可以表示如下:

pool:
  vmImage: 'ubuntu-latest'
jobs:
- job: job1
  steps:
  - bash: echo "Hello!"
  - bash: echo "I'm job 1"
- job: job2
  steps:
  - bash: echo "Hello again…"
  - bash: echo "I'm job 2"

如果你在定义管道时使用阶段,那么这就是所谓的扩展/合并场景:

图 4.5 – 扩展管道

图 4.5 – 扩展管道

在这里,每个阶段都是一个合并操作,阶段中的所有任务(这些任务可以是按顺序运行的多个任务)必须完成后,下一个阶段才能触发(每次只能有一个阶段在执行)。我们将在本章后面讨论多阶段管道。

理解构建代理

要使用 Azure Pipelines 构建和部署代码,你至少需要一个代理。代理是运行你管道中定义的任务的服务。这些任务的执行可以直接在代理的主机机器上,或在容器中进行。

在为管道定义代理时,你基本上有两种代理类型可选:

  • Microsoft 托管代理:这是一个完全由 Microsoft 管理的服务,每次执行管道时都会清除(每次管道执行时,你都会获得一个全新的环境)。

  • 自托管代理:这是一个需要你自己设置和管理的服务。它可以是 Azure 上的自定义虚拟机,或者是你基础设施内的自定义本地机器。在自托管代理中,你可以安装所有需要的构建软件,并且这些软件会在每次管道执行时得到保留。自托管代理可以运行在 Windows、Linux、macOS 或 Docker 容器中。

Microsoft 托管代理

Microsoft 托管代理是定义管道代理的最简单方法。Azure Pipelines 默认提供一个名为 Azure Pipelines 的 Microsoft 托管代理池:

图 4.6 – Azure Pipelines 默认代理池

图 4.6 – Azure Pipelines 默认代理池

通过选择此代理池,你可以为执行管道创建不同的虚拟机类型。在撰写本文时,提供的标准代理类型如下:

表 1.1

表 1.1

这些图像中的每一张都有自己的软件自动安装。你可以通过在管道定义中使用预定义的工具安装器任务来安装额外的工具。更多信息请见这里:

https://docs.microsoft.com/en-us/azure/devops/pipelines/tasks/?view=azure-devops#tool。

当你使用 Microsoft 托管代理创建管道时,只需要指定要用于代理的虚拟机镜像名称,如前表所示。举例来说,这是一个使用 Windows Server 2019 和 Visual Studio 2019 镜像的托管代理定义:

- job: Windows
  pool:
    vmImage: 'windows-latest'

使用 Microsoft 托管代理时,需要记住以下几点:

  • 你无法在代理机器上登录。

  • 该代理运行在标准 DS2v2 Azure 虚拟机上,并且无法增加其容量。

  • 它在 Windows 平台上以管理员用户身份运行,在 Linux 平台上以无密码的 sudo 用户身份运行。

  • 对于公共项目,你可以获得 10 个免费的 Microsoft 托管并行作业,每个作业最多运行 360 分钟,且每月没有整体时间限制。

  • 对于私有项目,你可以获得一个免费的并行作业,每次运行最多 60 分钟,每月的最大时长为 1,800 分钟(30 小时)。如果需要更多容量,你可以支付额外费用来增加并行作业数量。这样,你可以让每个作业运行最多 360 分钟。

  • Microsoft 托管代理在与 Azure DevOps 组织相同的 Azure 地理区域内运行,但不保证它也会在相同的区域运行(一个 Azure 地理区域包含一个或多个区域)。

自托管代理

虽然 Microsoft 托管代理是一个 SaaS 服务,但自托管代理是你可以根据需要配置的私有代理,使用 Azure 虚拟机或直接使用你自己的本地基础设施。你负责提供执行管道所需的所有软件和工具,并且你负责维护和升级代理。

自托管代理可以安装在以下平台上:

  • Windows

  • Linux

  • macOS

  • Docker

创建自托管代理包括完成以下活动:

  • 准备环境

  • 在 Azure DevOps 上准备权限

  • 下载并配置代理

  • 启动代理

这些步骤在所有环境中都类似。接下来,我们将学习如何创建一个自托管的 Windows 代理。

创建自托管 Windows 代理

自托管 Windows 代理用于构建和部署基于 Microsoft 平台(如 .NET 应用、Azure 云应用等)构建的应用程序,也适用于其他平台类型,如 Java 和 Android 应用。

创建代理时的第一步是将代理注册到你的 Azure DevOps 组织中。为此,你需要以管理员身份登录到你的 DevOps 组织,并从用户设置菜单中点击个人访问令牌

图 4.7 – 个人访问令牌

图 4.7 – 个人访问令牌

在这里,你可以为你的组织创建一个新的个人访问令牌,设置过期日期,并选择完全访问或自定义访问级别(如果选择自定义访问范围,则需要为每个范围选择所需的权限)。要查看可用范围的完整列表,请点击此窗口底部的显示所有范围链接:

图 4.8 – 创建新的个人访问令牌

图 4.8 – 创建新的个人访问令牌

请检查是否已启用代理池范围的读取和管理权限。

完成后,点击创建,然后在关闭窗口之前复制生成的令牌(它只会显示一次)。

重要提示

你将用于代理程序的用户必须是具有注册代理程序权限的用户。你可以通过进入组织设置 | 代理池,选择默认池,然后点击安全性来检查这一点。

现在,你需要下载代理软件并进行配置。从组织设置 | 代理池,选择默认池,在代理选项卡中点击新代理

图 4.9 – 创建新代理

图 4.9 – 创建新代理

获取代理窗口将打开。选择Windows作为目标平台,选择x64x86作为目标代理平台(机器),然后点击下载按钮:

图 4.10 – 代理软件下载页面

图 4.10 – 代理软件下载页面

该过程会下载一个包(通常名为vsts-agent-win-x64-2.166.4.zip)。你需要在代理机器上运行这个包(config.cmd)(可以是 Azure 虚拟机或你的本地服务器,它将作为你构建的代理程序):

图 4.11 – 代理软件包

图 4.11 – 代理软件包

安装程序会询问你以下内容:

  • 你的 Azure DevOps 组织的 URL (dev.azure.com/)

  • 要使用的个人访问令牌(之前创建的)

在运行代理程序时(无论是交互式还是作为服务),如果你希望自动化构建,推荐以服务的方式运行它。

在插入这些参数后,安装程序会注册代理程序:

图 4.12 – 代理注册

图 4.12 – 代理注册

要注册代理程序,你需要插入代理池、代理名称和工作文件夹(你可以保持默认值不变)。

最后,你需要决定你的代理程序是必须以交互式方式执行,还是作为服务运行。正如我们之前提到的,推荐以服务的方式运行代理程序,但在很多情况下,交互式选项会很有帮助,因为它可以为你提供一个控制台,你可以在其中查看状态和运行中的 UI 测试。

在这两种情况下,请注意你为运行代理程序选择的用户帐户。默认帐户是内建的网络服务用户,但这个用户通常没有本地文件夹所需的所有权限。使用管理员帐户可以帮助你解决很多问题。

如果安装成功,你应该能在代理机器上看到一个正在运行的服务,并且在 Azure DevOps 的代理池中弹出一个新代理:

4.13 – 新代理已创建

4.13 – 新代理已创建

如果你选择了代理程序,然后进入功能部分,你将能够看到它的所有功能(操作系统版本、操作系统架构、计算机名称、安装的软件等):

图 4.14 – 代理功能

图 4.14 – 代理功能

代理的能力可以由代理软件自动发现,也可以通过你(用户自定义的能力)添加,如果你点击添加新能力操作。能力用于管道引擎,根据管道所需的能力(需求)将特定的构建重定向到正确的代理。

当代理在线时,它已准备好接受你的代码构建,该构建应该排队等待。

请记住,你也可以在同一台机器上安装多个代理(例如,如果你希望执行核心管道或并行处理作业),但仅在代理不会共享资源的情况下推荐这种方案。

何时使用 Microsoft 托管代理或自托管代理

当你有一个标准的代码库并且不需要特定的软件或环境配置来构建代码时,Microsoft 托管的代理通常很有用。如果你处于这种情况,推荐使用 Microsoft 托管的代理,因为你不必担心创建环境。例如,如果你需要构建一个 Azure Function 项目,通常情况下,你不需要在构建代理上安装自定义软件,Microsoft 托管的代理可以完美工作。

当你需要特定的环境配置,或者需要在代理上安装特定的软件或工具,或者需要更多的构建计算能力时,自托管代理是最佳选择。自托管代理也是当你需要在每次构建运行之间保持环境一致时的首选。当你需要更好地控制代理或希望将构建部署到本地环境(外部无法访问)时,自托管代理通常是正确的选择。它也通常能帮你节省成本。

现在我们已经讨论了可以用于构建管道的可能构建代理,在接下来的部分中,我们将概述 YAML,这是一种允许你定义管道的脚本语言。

YAML 语言概述

YAML,即YAML 不只是标记语言,是一种人类可读的脚本语言,用于数据序列化,通常用于处理应用程序的配置定义。它可以视为 JSON 的超集。

YAML 使用缩进来处理对象定义的结构,并且对引号和大括号不敏感。它只是一个数据表示语言,不用于执行命令。

在 Azure DevOps 中,YAML 极为重要,因为它允许你使用脚本定义来定义管道,而不是使用图形界面(图形界面无法在项目之间移植)。

官方 YAML 网站可以在这里找到:

yaml.org/

YAML 结构基于键值元素:

Key: Value # 这是一个注释

在接下来的部分中,我们将学习如何在 YAML 中定义对象。

标量

作为示例,以下是 YAML 中已定义的标量变量:

Number: 1975 quotedText: "some text description"notQuotedtext: strings can be also without quotes boolean: true nullKeyValue: null

你还可以通过使用?后跟一个空格来定义多行键,如下所示:

? |
  This is a key
  that has multiple lines
: and this is its value

集合和列表

这是一个集合对象的 YAML 定义:

Cars:
   - Fiat
   - Mercedes
   - BMW

你还可以定义嵌套集合:

- Drivers:
      name: Stefano Demiliani
      age: 45
      Driving license type:
          - type: full car license
            license id: ABC12345
            expiry date: 2025-12-31

字典

你可以通过以下方式使用 YAML 定义一个Dictionary对象:

CarDetails:
     make: Mercedes
     model: GLC220
     fuel: Gasoline

文档结构

YAML 使用三个短横线---来分隔指令与文档内容,并标识文档的开始。作为示例,以下 YAML 定义了一个文件中的两个文档:

---# Products purchased
- item    : Surface Book 2
  quantity: 1
- item    : Surface Pro 7
  quantity: 3
- item    : Arc Mouse
  quantity: 1
# Product out of stock
---
- item    : Surface 4
- item    : Microsoft Trackball

复杂对象定义

作为如何在 YAML 中定义复杂对象的示例,以下是用于表示Invoice对象的方式:

--- 
invoice: 20-198754
date   : 2020-05-27
bill-to: C002456
    Name  : Stefano Demiliani
    address:
        lines: 
            Viale Pasubio, 21
            c/o Microsoft House
        city    : Milan
        state   : MI
        postal  : 20154
ship-to: C002456
product:
    - itemNo      : ITEM001
      quantity    : 1
      description : Surface Book 2
      price       : 1850.00
    - sku         : ITEM002
      quantity    : 2
      description : Arc Mouse
      price       : 65.00
tax  : 80.50
total: 1995.50
comments:
    Please deliver on office hours.
    Leave on the reception.

现在我们已经提供了 YAML 语法的快速概述,在下一部分,我们将学习如何使用 Azure DevOps 创建构建管道。

使用 Azure DevOps 创建构建管道

如果你想为代码实现持续集成(每次提交时自动构建和测试代码),那么设置构建管道是一个基本步骤。

使用 Azure DevOps 创建构建管道的先决条件显然是需要将代码存储在一个代码库中。

要使用 Azure DevOps 创建构建管道,你需要进入管道中心并选择管道操作:

图 4.15 – 构建管道创建

图 4.15 – 构建管道创建

从这里,你可以通过选择新建管道按钮来创建一个新的构建管道。点击后,你将看到以下屏幕,要求你提供一个代码库:

图 4.16 – 选择一个代码库

图 4.16 – 选择一个代码库

这个屏幕非常重要。从这里,你可以通过两种可能的方式开始创建构建管道(如前所述):

  1. 使用 YAML 文件创建管道定义。这就是当你在此窗口中选择代码库时发生的情况。

  2. 使用经典编辑器(图形用户界面)。当你点击页面底部的使用经典编辑器链接时,就会发生这种情况。

在下一部分,我们将学习如何使用这两种方法创建构建管道。

使用经典编辑器定义管道

经典编辑器允许你通过选择预定义的操作,图形化地定义项目的构建管道。如前所述,以这种方式创建的管道定义不受源代码控制。

当你点击使用经典编辑器链接时,你需要选择存放代码的代码库(Azure Repos GitGitHubGitHub 企业服务器SubversionTFVCBitbucket Cloud其他 Git)以及构建管道将连接的分支:

图 4.17 – 经典编辑器管道定义

图 4.17 – 经典编辑器管道定义

然后,您需要选择正在构建的应用程序类型的模板。您有一组预定义的模板可供选择(稍后可以自定义),但您也可以从空模板开始:

图 4.18 – 管道模板选择

图 4.18 – 管道模板选择

如果预定义的模板符合您的需求,您可以开始使用它们;否则,建议通过选择您需要的操作来创建自定义管道。

在这里,我的应用程序存储在 Azure DevOps 项目存储库中,是一个 ASP.NET Web 应用程序(名为PartsUnlimited的电子商务网站项目;您可以在以下 URL 找到公共存储库:github.com/Microsoft/PartsUnlimited),因此我选择了 ASP.NET 模板。

当选择时,这是将自动为您创建的管道模板:

图 4.19 – 从模板创建的管道

图 4.19 – 从模板创建的管道

让我们详细检查管道的每个部分。

管道(这里称为PartsUnlimited-demo-pipeline)在 Microsoft 托管的代理(Azure 管道代理池)上运行,基于vs2017-win2016模板(Windows Server 2016 与 Visual Studio 2017),如下截图所示:

图 4.20 – 管道上的代理规范

图 4.20 – 管道上的代理规范

代理作业从安装 NuGet 软件包管理器开始,并恢复所选存储库中构建项目所需的软件包。对于这些操作,管道定义包含您可以在以下截图中看到的任务:

图 4.21 – NuGet 任务

图 4.21 – NuGet 任务

然后,有一个构建解决方案的任务:

图 4.22 – 构建解决方案任务

图 4.22 – 构建解决方案任务

还有一个任务是测试解决方案并发布测试结果:

图 4.23 – 测试组件任务

图 4.23 – 测试组件任务

最后几步是将构建过程的源发布为工件(构建的输出):

图 4.24 – 发布任务

图 4.24 – 发布任务

如果选择变量选项卡,您将看到在构建过程中使用的一些参数。在这里,如果需要,您可以创建自己的变量以在管道内部使用:

图 4.25 – 管道变量

图 4.25 – 管道变量

接下来的部分称为触发器。在这里,您可以定义触发器何时启动您的管道。默认情况下,最初没有触发器发布,但在这里,您可以启用 CI 以在所选分支上的每次提交时自动启动您的管道:

图 4.26 – 管道触发器

图 4.26 – 管道触发器

重要提示

启用 CI 是一种推荐做法,如果你希望每次在某个分支上提交的代码(例如在 master 分支上)都经过测试并得到安全控制。这样,你可以确保代码始终按预期工作。

选项 选项卡中,你可以设置一些与构建定义相关的选项。例如,在这里,你可以创建与所有工作项的链接,使它们在构建成功完成时与相关更改关联,构建失败时创建工作项,设置管道的状态徽章,指定超时时间等:

图 4.27 – 管道选项

图 4.27 – 管道选项

保留 选项卡用于配置这个特定管道的保留策略(例如,保留工件多少天,保留运行和拉取请求多少天等)。这样做将覆盖一般的保留设置。我们将在后面的 构建保留 部分讨论这些设置。

一旦完成定义管道,你可以点击 保存并排队 来保存你的定义。通过点击 保存并运行,管道将被放入队列并等待代理:

图 4.28 – 运行管道

图 4.28 – 运行管道

当找到代理时,管道将被执行,且你的代码会被构建:

图 4.29 – 管道执行开始

图 4.29 – 管道执行开始

你可以跟踪管道每个步骤的执行,并查看相关的日志。如果管道成功结束,你可以查看其执行摘要:

图 4.30 – 管道 – 最终结果

图 4.30 – 管道 – 最终结果

你还可以选择 测试 选项卡,查看测试执行状态:

图 4.31 – 管道测试结果

图 4.31 – 管道测试结果

在下一节中,我们将学习如何为这个应用程序创建一个 YAML 管道。

YAML 管道定义

如前所述,当你开始使用 Azure DevOps 创建构建管道时,向导默认会创建一个基于 YAML 的管道。

要开始创建 YAML 管道,进入 Azure DevOps 的 管道 部分并点击 新建管道

在这里,不要选择经典编辑器(正如我们在前一节中所做的),只需选择你的代码所在的仓库类型(Azure Repos GitGitHubBitBucket等):

图 4.32 – YAML 管道定义

图 4.32 – YAML 管道定义

然后,从可用的仓库列表中选择你的仓库:

图 4.33 – YAML 管道 – 仓库选择

图 4.33 – YAML 管道 – 仓库选择

系统现在会分析你的代码库,并根据库中存储的代码建议一组可用的模板。你可以从一个空白的 YAML 模板开始,或者选择一个模板。这里,我选择了 ASP.NET 模板:

图 4.34 – YAML 管道 – 模板选择

图 4.34 – YAML 管道 – 模板选择

系统会创建一个 YAML 文件(名为 azure-pipelines.yml),如以下截图所示:

图 4.35 – YAML 管道定义

图 4.35 – YAML 管道定义

生成的 YAML 定义包含了一组任务,就像前面的示例一样,但这些任务在它们的 YAML 定义中。完整的生成文件如下:

# ASP.NET
# Build and test ASP.NET projects.
# Add steps that publish symbols, save build artifacts, deploy, and more:
# https://docs.microsoft.com/azure/devops/pipelines/apps/aspnet/build-aspnet-4
trigger:
- master
pool:
  vmImage: 'windows-latest'
variables:
  solution: '**/*.sln'
  buildPlatform: 'Any CPU'
  buildConfiguration: 'Release'
steps:
- task: NuGetToolInstaller@1
- task: NuGetCommand@2
  inputs:
    restoreSolution: '$(solution)'
- task: VSBuild@1
  inputs:
    solution: '$(solution)'
    msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactStagingDirectory)"'
    platform: '$(buildPlatform)'
    configuration: '$(buildConfiguration)'
- task: VSTest@2
  inputs:
    platform: '$(buildPlatform)'
    configuration: '$(buildConfiguration)'
Here I add two more tasks for publishing the symbols and the final artifacts of the pipeline:
task: PublishSymbols@2
  displayName: 'Publish symbols path'
  inputs:
    SearchPattern: '**\bin\**\*.pdb'
    PublishSymbols: false
  continueOnError: true
- task: PublishBuildArtifacts@1
  displayName: 'Publish Artifact'
  inputs:
    PathtoPublish: '$(build.artifactstagingdirectory)'
    ArtifactName: '$(Parameters.ArtifactName)'
  condition: succeededOrFailed()

如你所见,YAML 文件包含了启动管道的触发器(这里是主分支上的提交)、使用的代理池、管道变量,以及每个任务执行的顺序(以及它的具体参数)。

点击保存并运行,如前面截图所示,这将排队执行管道。以下截图显示了执行后的 YAML 管道。

图 4.36 – 执行的 YAML 管道

图 4.36 – 执行的 YAML 管道

若要添加新任务,使用编辑器框右侧的助手工具非常有用。它允许你查看任务列表,你可以在其中搜索任务,填写必要的参数,然后生成最终的 YAML 定义:

图 4.37 – YAML 管道任务选择

图 4.37 – YAML 管道任务选择

当你选择使用 YAML 创建管道时,Azure DevOps 会在与你的代码存储在同一代码库中创建一个文件:

图 4.38 – 创建的 YAML 管道文件

图 4.38 – 创建的 YAML 管道文件

这个文件在源控制下,并且每次修改时都会版本控制。

要了解管道的完整 YAML 模式,建议点击以下链接:

docs.microsoft.com/zh-cn/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema%2Cparameter-schema

构建保留

当你运行管道时,Azure DevOps 会记录每个步骤的执行情况,并存储每次运行的最终工件和测试结果。

Azure DevOps 对管道执行有一个默认的保留策略,保留时间为 30 天。你可以通过进入项目设置 | 管道 | 设置来更改这些默认值:

图 4.39 – 管道保留策略

图 4.39 – 管道保留策略

你还可以使用复制文件任务,将构建和工件数据存储到外部存储中,这样你就可以将它们保存得比保留策略中指定的时间更长:

图 4.40 – 复制文件任务

图 4.40 – 复制文件任务

此任务的 YAML 定义如下:

- task: CopyFiles@2
  displayName: 'Copy files to shared network'
  inputs:
    SourceFolder: '$(Build.SourcesDirectory)'
    Contents: '**'
    TargetFolder: '\\networkserver\storage\$(Build.BuildNumber)'

重要提示

请记住,任何通过发布构建构件任务保存为构件的数据都会定期删除。

关于复制文件任务的更多信息,请参见此处:

docs.microsoft.com/en-us/azure/devops/pipelines/tasks/utility/copy-files?view=azure-devops&tabs=yaml

多阶段流水线

正如我们之前所解释的,您可以将流水线中的工作划分为stagesStages是在流水线流程中的逻辑边界(可以分配给代理的工作单元),它们允许您隔离工作、暂停流水线并执行检查或其他操作。默认情况下,每个流水线由一个阶段组成,但您可以创建多个阶段,并将这些阶段安排成依赖图。

多阶段流水线的基本 YAML 定义如下:

stages:  
	- stage: Build  
	  jobs:  
	  - job: BuildJob  
	    steps:  
	    - script: echo Build!  
	- stage: Test  
	  jobs:  
	  - job: TestOne  
	    steps:  
	    - script: echo Test 1  
	  - job: TestTwo 
	    steps:  
	    - script: echo Test 2  
	- stage: Deploy  
	  jobs:  
	  - job: Deploy  
	    steps:  
	    - script: echo Deployment

作为创建多阶段流水线的示例,假设我们有一个流水线,它使用 .NET Core SDK 在您的仓库中构建代码,并将构件发布为 NuGet 包。流水线定义如下。该流水线使用stages关键字来标识这是一个多阶段流水线。

在第一阶段定义(Build)中,我们有用于构建代码的任务:

trigger:
	- master
	stages:
	- stage: 'Build'
	  variables:
	    buildConfiguration: 'Release'
	  jobs:
	  - job:
	    pool:
	      vmImage: 'ubuntu-latest'
	    workspace:
	      clean: all
	    steps:
	    - task: UseDotNet@2
	      displayName: 'Use .NET Core SDK'
	      inputs:
	        packageType: sdk
	        version: 2.2.x
	        installationPath: $(Agent.ToolsDirectory)/dotnet
	    - task: DotNetCoreCLI@2
	      displayName: "NuGet Restore"
	      inputs:
	        command: restore
	        projects: '**/*.csproj'
	    - task: DotNetCoreCLI@2
	      displayName: "Build Solution"
	      inputs:
	        command: build
	        projects: '**/*.csproj'
	        arguments: '--configuration (buildConfiguration)'

在这里,我们使用 Azure DevOps 中可用的UseDotnet标准任务模板安装了 .NET Core SDK(更多信息请参见:docs.microsoft.com/en-us/azure/devops/pipelines/tasks/tool/dotnet-core-tool-installer?view=azure-devops))。之后,我们还原了所需的 NuGet 包并构建了解决方案。

现在,我们需要创建 NuGet 包的发布版本。此包保存在构件暂存目录的 packages/release 文件夹中。在这里,我们将使用nobuild = true,因为在此任务中,我们不需要再次构建解决方案(不再进行编译):

    - task: DotNetCoreCLI@2
      displayName: 'Create NuGet Package - Release Version'
      inputs:
        command: pack
        packDirectory: '$(Build.ArtifactStagingDirectory)/packages/releases'
        arguments: '--configuration $(buildConfiguration)'
        nobuild: true

接下来的步骤是创建 NuGet 包的预发布版本。在此任务中,我们使用buildProperties选项将构建号添加到包版本中(例如,如果包版本为 2.0.0.0,构建号为 20200521.1,则包版本将为 2.0.0.0.20200521.1)。在这里,必须构建包(用于获取构建 ID):

    - task: DotNetCoreCLI@2
      displayName: 'Create NuGet Package - Prerelease Version'
      inputs:
        command: pack
        buildProperties: 'VersionSuffix="$(Build.BuildNumber)"'
        packDirectory: '$(Build.ArtifactStagingDirectory)/packages/prereleases'
        arguments: '--configuration $(buildConfiguration)'

下一任务将包发布为构件:

    - publish: '$(Build.ArtifactStagingDirectory)/packages'
      artifact: 'packages'

接下来,我们需要定义第二阶段,称为PublishPrereleaseNuGetPackage。在这里,我们跳过仓库的检出步骤,下载步骤将下载我们在前一个构建阶段发布的packages构件。然后,NuGetCommand任务将预发布包发布到 Azure DevOps 中的内部源,称为Test

- stage: 'PublishPrereleaseNuGetPackage'
  displayName: 'Publish Prerelease NuGet Package'
  dependsOn: 'Build'
  condition: succeeded()
  jobs:
  - job:
    pool:
      vmImage: 'ubuntu-latest'
    steps:
    - checkout: none
    - download: current
      artifact: 'packages'
    - task: NuGetCommand@2
      displayName: 'Push NuGet Package'
      inputs:
        command: 'push'
        packagesToPush: '$(Pipeline.Workspace)/packages/prereleases/*.nupkg'
        nuGetFeedType: 'internal'
        publishVstsFeed: 'Test'

现在,我们需要定义第三个阶段,称为PublishReleaseNuGetPackage,该阶段用于为 NuGet 创建我们的包的发布版本:

- stage: 'PublishReleaseNuGetPackage'
  displayName: 'Publish Release NuGet Package'
  dependsOn: 'PublishPrereleaseNuGetPackage'
  condition: succeeded()
  jobs:
  - deployment:
    pool:
      vmImage: 'ubuntu-latest'
    environment: 'nuget-org'
    strategy:
     runOnce:
       deploy:
         steps:
         - task: NuGetCommand@2
           displayName: 'Push NuGet Package'
           inputs:
             command: 'push'
             packagesToPush: '$(Pipeline.Workspace)/packages/releases/*.nupkg'
             nuGetFeedType: 'external'
             publishFeedCredentials: 'NuGet'

这个阶段使用部署作业将包发布到配置的环境(在这里,称为nuget-org)。环境是管道内资源的集合。

NuGetCommand 任务中,我们指定了要推送的包,并且指定了我们推送包的源是外部的(nuGetFeedType)。通过使用publishFeedCredentials属性来获取该源,该属性设置为我们创建的服务连接名称。

对于这个阶段,我们创建了一个新的环境:

图 4.41 – 创建一个新环境

图 4.41 – 创建一个新环境

一旦环境创建完成,为了将其发布到 NuGet,您需要通过以下路径创建一个新的服务连接:项目设置 | 服务连接 | 创建服务连接,从可用服务连接类型的列表中选择NuGet,然后根据您的 NuGet 账户配置连接:

图 4.42 – 新的 NuGet 服务连接

图 4.42 – 新的 NuGet 服务连接

至此,我们已经创建了一个多阶段构建管道。当管道执行并且所有阶段都成功终止时,您将看到如下所示的结果图:

图 4.43 – 执行的多阶段构建管道

图 4.43 – 执行的多阶段构建管道

现在我们已经理解了什么是多阶段管道,接下来我们将在下一部分中使用 GitHub 仓库创建一些管道。

使用 GitHub 仓库构建管道

GitHub 是最流行的源代码管理平台之一,通常情况下,会有许多场景,其中代码存储在 GitHub 仓库中,而您希望使用 Azure DevOps 来管理 CI/CD。

通过使用 Azure DevOps 和 Azure Pipeline 服务,您还可以为存储在 GitHub 上的仓库创建管道,从而在 GitHub 仓库的每次提交时触发构建管道。我们将通过以下步骤来实现:

  1. 要使用 Azure Pipelines 构建您的 GitHub 仓库,您需要添加Azure Pipelines。选择Azure Pipelines扩展并点击设置计划,如以下截图所示:图 4.44 – GitHub 上的 Azure Pipelines – 设置

    图 4.44 – GitHub 上的 Azure Pipelines – 设置

  2. 选择免费计划,点击免费安装按钮,然后点击完成订单并开始安装

  3. 现在,Azure Pipelines 安装程序会询问您该应用程序是否应该对所有仓库可用,还是仅对选定的仓库可用。选择所需的选项,然后点击安装图 4.45 – GitHub 上的 Azure Pipelines – 安装

    图 4.45 – GitHub 上的 Azure Pipelines – 安装

  4. 您现在将被重定向到 Azure DevOps,在那里您可以创建一个新项目(或选择现有项目)来处理构建过程。在这里,我将创建一个新项目:图 4.46 – 设置您的 Azure Pipelines 项目

    图 4.46 – 设置您的 Azure Pipelines 项目

  5. 现在,您需要授权 Azure Pipelines 以访问您的 GitHub 账户:图 4.47 – 授权 Azure Pipelines 访问 GitHub

    图 4.47 – 授权 Azure Pipelines 访问 GitHub

    给定必要的授权后,将为您在 Azure DevOps 上创建项目,并启动管道创建过程。您将立即被提示从账户中的可用 GitHub 存储库列表中选择一个用于构建的 GitHub 存储库:

    图 4.48 – 选择 GitHub 存储库

    图 4.48 – 选择 GitHub 存储库

  6. 在这里,我正在选择一个我有 Azure 函数项目的存储库。正如您所见,Azure Pipelines 已识别出我的项目,并为管道提供了一组可用模板(但您也可以从空白模板或存储库任何分支中的 YAML 文件开始)。在这里,我将选择azure-pipelines.yml) 在您的 GitHub 存储库内:图 4.50 – 多阶段 YAML 管道定义

    图 4.50 – 多阶段 YAML 管道定义

    此管道在主分支上的每次提交时触发。

  7. 单击保存并运行按钮。在这里,管道将排队等待一个代理,然后执行。

    每次在您的 GitHub 存储库中提交代码时,Azure DevOps 上的构建管道将自动触发。

    如果您在 GitHub 上构建一个公共存储库,展示这个存储库中的代码已经通过构建管道检查和测试是非常有用的。然后,您可以展示构建的结果。您可以通过在存储库中放置一个徽章来实现这一点。

    徽章是一个动态生成的图像,反映了构建的状态(从未构建、成功或失败),并且它托管在 Azure DevOps 上。

  8. 为此,请在 Azure DevOps 中选择您的管道,在右侧点击三个点,然后选择状态徽章图 4.51 – 状态徽章定义

    图 4.51 – 状态徽章定义

  9. 从这里,您可以复制Readme.md文件到您的 GitHub 存储库中:

图 4.52 – 构建状态徽章 markdown

图 4.52 – 构建状态徽章 markdown

每当用户访问您的存储库时,他们将能够通过图形徽章看到最新构建的状态:

图 4.53 – 构建管道状态徽章

图 4.53 – 构建管道状态徽章

接下来,让我们看看如何并行执行作业。

在 Azure Pipeline 中并行执行作业

在 Azure 流水线中,你还可以并行执行任务。每个任务可以独立于其他任务执行,也可以在不同的代理上执行。这将帮助你加速构建时间并提高流水线的性能。

作为如何在流水线中处理并行任务的示例,考虑一个简单的流水线,其中你需要执行三个 PowerShell 脚本,分别叫做任务 1任务 2最终任务任务 1任务 2可以并行执行,而最终任务只能在前两个任务完成后执行。

当你开始创建一个新的流水线时(为了简单起见,我这里使用经典编辑器),Azure DevOps 会创建一个代理任务(这里称为代理任务 1)。你可以将任务添加到此代理上。通过选择代理任务,你可以指定该任务运行的代理池。在这里,我希望这个任务在 Microsoft 托管的代理池上执行:

图 4.54 – 代理规格

图 4.54 – 代理规格

然后,为了将新的代理池添加到你的流水线中(用于独立执行其他任务),点击流水线旁边的三个点并选择添加代理任务

图 4.55 – 添加代理任务

图 4.55 – 添加代理任务

现在,我们将添加第二个代理任务(这里称为代理任务 2),它运行在自托管代理上。这个任务将执行任务 2的 PowerShell 脚本:

图 4.56 – 代理选择

图 4.56 – 代理选择

最后,我们将添加一个新的代理任务(这里称为代理任务 3),来执行将在 Microsoft 托管代理上运行的最终任务。然而,这个任务依赖于代理任务 1代理任务 2

图 4.57 – 代理任务依赖关系

图 4.57 – 代理任务依赖关系

这样,前两个任务将并行启动,最终任务将在前两个任务执行完毕后开始执行。

关于 Azure 流水线中的并行任务,建议你查看以下页面以获取更多信息:

docs.microsoft.com/en-us/azure/devops/pipelines/process/phases?view=azure-devops&tabs=yaml

运行在 Azure 容器实例上的代理

如果标准的 Microsoft 托管代理无法满足你的需求(例如要求、性能等),你还可以为 Azure DevOps 创建一个自托管代理,该代理在Azure 容器实例ACI)服务中的 Docker 容器内运行。

你可以通过使用自定义镜像或重新使用 Microsoft 提供的镜像来创建一个运行在 Azure 容器实例上的构建代理。

要创建一个运行在 ACI 上的构建代理,你需要为你的 Azure DevOps 组织创建一个个人访问令牌。为此,请从你的 Azure DevOps 组织主页,打开用户设置(右上角),然后选择个人访问令牌

当您拥有代理的个人访问令牌时,您可以通过执行以下命令从 Azure CLI 创建 ACI 上的代理(连接到 Azure 订阅后):

az container create -g RESOURCE_GROUP_NAME -n CONTAINER_NAME --image mcr.microsoft.com/azure-pipelines/vsts-agent --cpu 1 --memory 7 --environment-variables VSTS_ACCOUNT=AZURE_DEVOPS_ACCOUNT_NAME VSTS_TOKEN=PERSONAL_ACCESS_TOKEN VSTS_AGENT=AGENT_NAME VSTS_POOL=Default

这里我们有以下内容:

  • RESOURCE_GROUP_NAME 是您在 Azure 中创建此资源时所用的资源组名称。

  • CONTAINER_NAME 是 ACI 容器的名称。

  • AZURE_DEVOPS_ACCOUNT_NAME 是您的 Azure DevOps 账户名称。

  • PERSONAL_ACCESS_TOKEN 是您之前创建的个人访问令牌。

  • AGENT_NAME 是您要创建的构建代理的名称。它将显示在 Azure DevOps 上。

在此命令中,还有另外两个重要参数:

请记住,您可以通过使用 az container stopaz container start 命令来启动和停止 ACI 实例。这可以帮助您节省开支。

在 Azure Pipelines 中使用容器作业

在本章中,我们看到,当您创建管道时,您会定义作业,并且当管道执行时,这些作业将在安装代理的主机上运行。

如果您使用的是 Windows 或 Linux 代理,您还可以在容器中运行作业(与主机隔离)。要在容器中运行作业,您需要在代理上安装 Docker,并且您的管道必须具有访问 Docker 守护程序的权限。如果您使用的是 Microsoft 托管的代理,实际上在 windows-2019ubuntu-16.04 池镜像中支持在容器中运行作业。

例如,这是一个在 Windows 管道中使用容器作业的 YAML 定义:

pool:
  vmImage: 'windows-2019'
container: mcr.microsoft.com/windows/servercore:ltsc2019
steps:
- script: date /t
  displayName: Gets the current date
- script: dir  
  workingDirectory: $(Agent.BuildiDirectory)
  displayName: list the content of a folder

正如我们之前提到的,要在 Windows 容器中运行作业,您需要使用 windows-2019 镜像池。要求主机和容器的内核版本匹配,因此在这里,我们使用 ltsc2019 标签来获取容器的镜像。

对于基于 Linux 的管道,您需要使用 ubuntu-16.04 镜像:

pool:
  vmImage: 'ubuntu-16.04'
container: ubuntu:16.04
steps:
- script: printenv

如您所见,管道根据所选镜像创建一个容器,并在该容器内运行命令(步骤)。

摘要

在本章中,我们概述了 Azure Pipelines 服务,并展示了如何使用 Azure DevOps 实现 CI/CD 流程。我们还展示了如何通过图形界面和 YAML 创建托管在仓库中的代码流水线,以及如何使用和创建构建代理。接着,我们了解了如何使用经典编辑器和 YAML 定义创建构建流水线。我们还展示了一个多阶段流水线的示例,以及如何使用 Azure DevOps 流水线在 GitHub 仓库中构建代码,随后学习了如何在构建流水线中使用并行任务来提高构建性能。最后,我们学习了如何在 Azure 容器实例中创建构建代理,并如何使用容器的作业。

在下一章,我们将学习如何在构建流水线中执行代码库的质量测试。

第四章:

第五章:了解 Azure DevOps Pipelines

在您的组织中采用Azure DevOps时,必须做出的一个重要决定是如何定义您开发流程的流水线。流水线是公司定义的模型,描述了代码库必须支持的步骤和操作,从构建到最终发布阶段。它是任何 DevOps 架构中的关键部分。

在本章中,我们将学习如何使用 Azure DevOps 定义和使用流水线来构建代码。

我们将涵盖以下主题:

  • 实现 CI/CD 流程

  • Azure Pipelines 概述

  • 创建和使用构建代理

  • YAML 格式概述

  • 使用 Azure DevOps 创建 CI/CD 流水线

  • 保留构建记录

  • 多阶段流水线

  • 使用 GitHub 仓库构建流水线

  • 在 Azure Pipelines 中使用容器作业

  • 让我们开始吧!

技术要求

要学习本章内容,您需要具备以下条件:

  • 在 Azure DevOps 中的有效组织

  • 一个 Azure 订阅,您可以在其中创建 Azure 虚拟机或在这些环境中的本地计算机上安装构建代理软件

  • 使用 Visual Studio 或 Visual Studio Code 作为开发环境

  • 访问以下 GitHub 仓库以克隆项目:github.com/Microsoft/PartsUnlimited

实现 CI/CD 流程

在公司中采用 DevOps 时,实施正确的 DevOps 工具与正确的 DevOps 流程至关重要。DevOps 实施中的一个基本流程是持续集成CI)和持续交付CD)过程,这可以帮助开发者以更快、更结构化、更安全的方式构建、测试和分发代码库。

CI 是一种软件工程实践,开发团队中的开发者在中央仓库中每天多次集成代码修改。当代码修改集成到特定分支(通常通过拉取请求,如上一章所述)时,会触发新的构建,以便快速检查代码并检测集成错误。此外,在此阶段会执行自动化测试(如果有的话)以检查是否存在故障。

CD 是紧随 CI 流程之后的过程。在此过程中,CI 阶段的输出会被打包并无错误地交付到生产阶段。这非常有帮助,因为我们始终拥有一个经过测试、一致且准备部署的主分支。

在 DevOps 中,您还可以实施持续部署流程,在此流程中,您可以自动化将代码修改部署到最终生产环境,而无需人工干预。

典型的 DevOps CI/CD 循环在以下著名的“循环”图中表示:

图 4.1 – DevOps CI/CD 循环

图 4.1 – DevOps CI/CD 循环

一个典型的 CI/CD 流水线实现包含以下阶段:

  • 提交阶段:在这里,新的代码修改被集成到代码库中,并执行一组单元测试,以检查代码的完整性和质量。

  • 构建阶段:在这里,代码会自动构建,然后将构建过程的最终结果(构建产物)推送到最终的注册表。

  • 测试阶段:构建的代码将部署到预生产环境,在那里进行最终测试,然后再进行生产部署。在这里,代码会通过采用 Alpha 和 Beta 部署进行测试。Alpha 部署阶段是开发人员检查新构建的性能以及不同构建之间的交互。在 Beta 部署阶段,开发人员执行手动测试,以再次检查应用程序是否正常工作。

  • 生产部署阶段:这是最终应用程序在成功通过所有测试要求后,正式发布到生产环境的阶段。

在你的组织中实施 CI/CD 流程有很多好处,主要的好处如下:

  • 提高代码质量和早期发现 bug:通过采用自动化测试,你可以在早期发现 bug 和问题,并及时修复。

  • 完整的可追溯性:整个构建、测试和部署过程都被追踪,可以在之后进行分析。这确保了你可以检查特定构建中包含的哪些更改,以及这些更改对最终测试或发布的影响。

  • 更快的测试和发布阶段:自动化地在每次提交(或发布前)对代码库进行构建和测试。

在接下来的部分,我们将概述 Azure 平台提供的用于实现 CI/CD 的服务:Azure Pipelines。

Azure Pipelines 概述

Azure Pipelines 是 Azure 平台提供的一项云服务,允许你自动化开发生命周期的构建、测试和发布阶段(CI/CD)。Azure Pipelines 支持任何语言或平台,它集成在 Azure DevOps 中,你可以在 Windows、Linux 或 macOS 机器上构建你的代码。

Azure Pipelines 对于公共项目是免费的,而对于私有项目,每月提供最多 1,800 分钟(30 小时)的管道使用时间。有关定价的更多信息,请参见这里:

azure.microsoft.com/en-us/pricing/details/devops/azure-devops-services/

Azure Pipelines 的一些重要特性总结如下:

  • 它是平台和语言独立的,这意味着你可以在任何平台上使用你想要的代码库构建代码。

  • 它可以与不同类型的代码库集成(Azure Repos、GitHub、GitHub Enterprise、BitBucket 等)。

  • 有很多扩展(标准和社区驱动)可用于构建你的代码和处理自定义任务。

  • 允许你将代码部署到不同的云服务商。

  • 你可以处理容器化应用程序,如 Docker、Azure 容器注册表或 Kubernetes。

要使用 Azure Pipelines,你需要具备以下条件:

  • 一个 Azure DevOps 组织,你可以在其中创建公共或私有项目

  • 存储在版本控制系统中的源代码(如 Azure DevOps Repos 或 GitHub)

Azure Pipelines 按如下架构工作:

图 4.2 – Azure Pipelines 架构

图 4.2 – Azure Pipelines 架构

当你的代码提交到某个仓库中的特定分支时,构建管道引擎启动,构建和测试任务会执行,如果所有任务都成功完成,你的应用程序就会构建完成,并且你会得到最终的输出(工件)。你还可以创建一个发布管道,将构建的输出发布到目标环境(预发布或生产环境)。

要开始使用 Azure Pipelines,你需要创建一个管道。Azure DevOps 中的管道可以通过以下两种方式创建:

  • 使用经典界面:这允许你从可能的任务列表中以视觉方式选择一些任务。你只需要填写这些任务的参数。

  • 使用一种名为 YAML 的脚本语言:通过在你的仓库中创建一个 YAML 文件,并在其中定义所有需要的步骤来定义管道。

使用经典界面最初可能更为简单,但请记住,许多功能仅在 YAML 管道中可用。YAML 管道定义是一个文件,并且可以像仓库中的其他文件一样进行版本控制和管理。你可以轻松地在项目之间移动管道定义(经典界面无法实现此操作)。

一个 Azure Pipeline 可以如下表示(感谢 Microsoft):

图 4.3 – Azure Pipeline 表示

图 4.3 – Azure Pipeline 表示

一个管道从触发器(手动触发、仓库中的推送、拉取请求或计划任务)开始。管道通常由一个或多个阶段(管道中的逻辑分离,如构建、测试、部署等;它们可以并行运行)组成,每个阶段包含一个或多个作业(一组也可以并行运行的步骤)。每个管道至少包含一个阶段,如果你没有显式创建,它会自动创建。每个作业都在一个代理(执行作业的服务或软件)上运行。每个步骤由一个任务组成,该任务对你的代码执行某些操作(按顺序执行)。管道的最终输出是一个工件(构建过程中发布的文件或包的集合)。

在创建管道时,你需要定义一组任务和作业,用于自动化构建(或多阶段构建)。你可以原生支持集成测试、发布门、自动报告等功能。

在管道中定义多个作业时,这些作业会并行执行。包含多个作业的管道被称为扇出场景:

图 4.4 – 扩展管道

图 4.4 – 扩展管道

一个包含多个作业的单个阶段管道可以表示如下:

pool:
  vmImage: 'ubuntu-latest'
jobs:
- job: job1
  steps:
  - bash: echo "Hello!"
  - bash: echo "I'm job 1"
- job: job2
  steps:
  - bash: echo "Hello again…"
  - bash: echo "I'm job 2"

如果在定义管道时使用阶段,这就属于所谓的扩展/汇集场景:

图 4.5 – 扩展管道

图 4.5 – 扩展管道

在这里,每个阶段都是一个汇集操作,阶段中的所有作业(可以由多个顺序执行的任务组成)必须完成,才能触发下一个阶段(每次只能执行一个阶段)。我们将在本章后面讨论多阶段管道。

了解构建代理

要使用 Azure Pipelines 构建和部署代码,您至少需要一个代理。代理是一个运行管道中定义作业的服务。这些作业的执行可以直接发生在代理的主机机器上,也可以在容器中进行。

在为您的管道定义代理时,您基本上有两种类型的代理:

  • Microsoft 托管代理:这是一个完全由 Microsoft 管理的服务,在每次管道执行时都会清除(每次管道执行时,您都会获得一个全新的环境)。

  • 自托管代理:这是一个需要您自己设置和管理的服务。它可以是 Azure 上的自定义虚拟机,也可以是您基础设施内的自定义本地机器。在自托管代理中,您可以安装构建所需的所有软件,并且这些软件会在每次管道执行时保留下来。自托管代理可以运行在 Windows、Linux、macOS 或 Docker 容器中。

Microsoft 托管代理

Microsoft 托管代理是为您的管道定义代理的最简单方式。Azure Pipelines 默认提供一个名为Azure Pipelines的 Microsoft 托管代理池:

图 4.6 – Azure Pipelines 默认代理池

图 4.6 – Azure Pipelines 默认代理池

通过选择这个代理池,您可以为执行管道创建不同类型的虚拟机。截止到本文写作时,可用的标准代理类型如下:

表 1.1

表 1.1

每个镜像都具有一套自动安装的软件。您可以通过在管道定义中使用预定义的工具安装程序任务来安装额外的工具。更多信息请参阅:

https://docs.microsoft.com/en-us/azure/devops/pipelines/tasks/?view=azure-devops#tool.

当使用 Microsoft 托管代理创建管道时,您只需要从前面的表格中指定要为代理使用的虚拟机镜像的名称。例如,这是使用 Windows Server 2019 和 Visual Studio 2019 镜像的托管代理定义:

- job: Windows
  pool:
    vmImage: 'windows-latest'

使用 Microsoft 托管代理时,您需要记住以下几点:

  • 您不能在代理机器上登录。

  • 该代理运行在标准 DS2v2 Azure 虚拟机上,且无法增加该容量。

  • 它以管理员用户身份在 Windows 平台上运行,并以 无密码 sudo 用户身份在 Linux 平台上运行。

  • 对于公共项目,您有 10 个免费的 Microsoft 托管并行作业,每个作业最多可运行 360 分钟,每月没有总体时间限制。

  • 对于私人项目,您有一个免费的并行作业,每个作业最多可运行 60 分钟,每月最多为 1,800 分钟(30 小时)。如果您需要更多的容量,可以支付额外的并行作业费用。这样,每个作业的运行时间最多为 360 分钟。

  • Microsoft 托管代理运行在与您的 Azure DevOps 组织相同的 Azure 地理区域内,但不能保证它也会在相同的区域内运行(一个 Azure 地理区域包含一个或多个区域)。

自托管代理

虽然 Microsoft 托管代理是一个 SaaS 服务,但自托管代理是私有代理,您可以通过使用 Azure 虚拟机或直接使用本地基础设施来根据您的需求进行配置。您负责提供执行管道所需的所有软件和工具,并负责维护和升级代理。

自托管代理可以安装在以下平台上:

  • Windows

  • Linux

  • macOS

  • Docker

创建自托管代理包括完成以下活动:

  • 准备环境

  • 在 Azure DevOps 上准备权限

  • 下载并配置代理

  • 启动代理

这些步骤在所有环境中是相似的。接下来,我们将学习如何创建自托管 Windows 代理。

创建自托管 Windows 代理

自托管 Windows 代理用于构建和部署基于 Microsoft 平台(如 .NET 应用程序、Azure 云应用程序等)构建的应用程序,也可用于其他平台类型,如 Java 和 Android 应用程序。

创建代理时执行的第一步是将代理注册到您的 Azure DevOps 组织中。为此,您需要以管理员身份登录到您的 DevOps 组织,并从 用户设置 菜单中点击 个人访问令牌

图 4.7 – 个人访问令牌

图 4.7 – 个人访问令牌

在这里,您可以为您的组织创建一个新的个人访问令牌,设置过期日期,并选择完全访问或自定义定义的访问级别(如果选择自定义定义范围,您需要为每个范围选择所需的权限)。要查看可用范围的完整列表,请点击窗口底部的 显示所有范围 链接:

图 4.8 – 创建一个新的个人访问令牌

图 4.8 – 创建一个新的个人访问令牌

请确保 代理池 范围内启用了 读取和管理 权限。

完成后,点击 创建,然后在关闭窗口之前复制生成的令牌(它只会显示一次)。

重要提示

用于代理的用户必须具备注册代理的权限。你可以通过进入组织设置 | 代理池,选择默认池并点击安全来检查此权限。

现在,你需要下载代理软件并进行配置。从组织设置 | 代理池,选择默认池,在代理选项卡中点击新建代理

图 4.9 – 创建新代理

图 4.9 – 创建新代理

获取代理窗口将打开。选择Windows作为目标平台,根据你的目标代理平台(机器),选择x64x86,然后点击下载按钮:

图 4.10 – 代理软件下载页面

图 4.10 – 代理软件下载页面

这个过程将下载一个包(通常名为vsts-agent-win-x64-2.166.4.zip)。你需要在代理机器(一个 Azure 虚拟机或本地服务器,它将作为你的构建代理)上运行这个包(config.cmd):

图 4.11 – 代理软件包

图 4.11 – 代理软件包

设置将要求你输入以下内容:

  • 你的 Azure DevOps 组织的 URL(dev.azure.com/

  • 使用的个人访问令牌(之前创建的)

运行代理时(无论是交互式运行还是作为服务运行),如果你想自动化构建,建议将其作为服务运行。

输入这些参数后,设置将注册代理:

图 4.12 – 代理注册

图 4.12 – 代理注册

要注册代理,你需要插入代理池、代理名称和工作文件夹(你可以保持默认值不变)。

最后,你需要决定是否让代理以交互式作为服务的方式运行。正如我们之前提到的,建议将代理作为服务运行,但在很多情况下,交互式选项也很有帮助,因为它会给你一个控制台,便于查看状态并运行 UI 测试。

在这两种情况下,请注意你为运行代理所选择的用户帐户。默认帐户是内置的网络服务用户,但该用户通常没有本地文件夹的所有必需权限。使用管理员帐户可以帮助解决很多问题。

如果设置成功,你应该能看到在代理机器上运行的服务,并且在 Azure DevOps 中的代理池中弹出一个新代理:

4.13 – 新代理创建

4.13 – 新代理创建

如果你选择代理后进入功能部分,你将能够看到它的所有功能(操作系统版本、操作系统架构、计算机名称、已安装的软件等):

图 4.14 – 代理功能

图 4.14 – 代理功能

代理的能力可以通过代理软件自动发现,或者如果你点击添加新能力操作,你也可以由用户定义能力。能力被流水线引擎用于根据流水线所需的能力(需求)将特定构建重定向到正确的代理。

当代理在线时,它准备好接受你的代码构建,这些构建应该排队等待。

记住,你还可以在同一台机器上安装多个代理(例如,如果你希望能够执行核心流水线或并行处理任务),但这种情况仅建议在代理不共享资源时使用。

何时使用微软托管代理或自托管代理

微软托管代理通常在你有一个标准的代码库,且不需要特定软件或环境配置来构建代码时非常有用。如果你处于这种情况,建议使用微软托管代理,因为你不必担心创建环境。例如,如果你需要构建一个 Azure Function 项目,通常你不需要在构建代理上安装自定义软件,微软托管代理可以完美工作。

自托管代理是在需要特定环境配置时的最佳选择,尤其是当你需要在代理上安装特定的软件或工具,或者需要更强大的构建能力时。自托管代理也是在你需要在每次构建运行之间保持环境一致性时的理想选择。通常,当你需要更好地控制代理,或者希望将构建部署到本地环境(外部不可访问)时,自托管代理是正确的选择。它通常还可以帮助你节省成本。

现在我们已经讨论了可以用于构建流水线的可能代理,在接下来的部分中,我们将概述 YAML,这种脚本语言允许你定义流水线。

YAML 语言概述

YAML,即YAML 不是标记语言,是一种可读性强的脚本语言,通常用于数据序列化和处理应用程序配置定义。它可以视为 JSON 的超集。

YAML 使用缩进来处理对象定义的结构,并且对引号和大括号不敏感。它仅仅是一种数据表示语言,不能用于执行命令。

在 Azure DevOps 中,YAML 至关重要,因为它允许你通过使用脚本定义来定义流水线,而不是使用图形界面(图形界面无法在项目之间迁移)。

官方 YAML 网站可以在这里找到:

yaml.org/

YAML 结构是基于键值元素的:

Key: Value # 这是一个注释

在接下来的部分中,我们将学习如何在 YAML 中定义对象。

标量

例如,以下是已在 YAML 中定义的标量变量:

Number: 1975 quotedText: "some text description"notQuotedtext: strings can be also without quotes boolean: true nullKeyValue: null

你也可以通过使用 ?,后跟一个空格来定义多行键,如下所示:

? |
  This is a key
  that has multiple lines
: and this is its value

集合和列表

这是一个用于集合对象的 YAML 定义:

Cars:
   - Fiat
   - Mercedes
   - BMW

你还可以定义嵌套的集合:

- Drivers:
      name: Stefano Demiliani
      age: 45
      Driving license type:
          - type: full car license
            license id: ABC12345
            expiry date: 2025-12-31

字典

你可以通过以下方式使用 YAML 定义一个 Dictionary 对象:

CarDetails:
     make: Mercedes
     model: GLC220
     fuel: Gasoline

文档结构

YAML 使用三个破折号 --- 来分隔指令和文档内容,并标识文档的开始。例如,以下 YAML 定义了一个文件中的两个文档:

---# Products purchased
- item    : Surface Book 2
  quantity: 1
- item    : Surface Pro 7
  quantity: 3
- item    : Arc Mouse
  quantity: 1
# Product out of stock
---
- item    : Surface 4
- item    : Microsoft Trackball

复杂对象定义

作为定义复杂对象的示例,以下是 Invoice 对象使用的表示方式:

--- 
invoice: 20-198754
date   : 2020-05-27
bill-to: C002456
    Name  : Stefano Demiliani
    address:
        lines: 
            Viale Pasubio, 21
            c/o Microsoft House
        city    : Milan
        state   : MI
        postal  : 20154
ship-to: C002456
product:
    - itemNo      : ITEM001
      quantity    : 1
      description : Surface Book 2
      price       : 1850.00
    - sku         : ITEM002
      quantity    : 2
      description : Arc Mouse
      price       : 65.00
tax  : 80.50
total: 1995.50
comments:
    Please deliver on office hours.
    Leave on the reception.

现在我们已经简要概述了 YAML 语法,接下来的章节中,我们将学习如何使用 Azure DevOps 创建构建管道。

使用 Azure DevOps 创建构建管道

如果你想为代码实现持续集成(在每次提交时自动构建和测试代码),那么拥有一个构建管道是基础步骤。

使用 Azure DevOps 创建构建管道的前提条件显然是代码已经存储在一个仓库中。

要使用 Azure DevOps 创建构建管道,你需要进入 管道 中心并选择 管道 操作:

图 4.15 – 构建管道创建

图 4.15 – 构建管道创建

在这里,你可以通过选择 新建管道 按钮来创建一个新的构建管道。当点击此按钮时,你将看到以下界面,它会询问你代码仓库的信息:

图 4.16 – 选择一个仓库

图 4.16 – 选择一个仓库

这个屏幕非常重要。通过这个界面,你可以以两种可能的方式开始创建构建管道(如前所述):

  1. 使用 YAML 文件来创建你的管道定义。这是在此窗口中选择仓库时发生的事情。

  2. 使用经典编辑器(图形用户界面)。这是当你点击页面底部的 使用经典编辑器 链接时发生的事情。

在接下来的章节中,我们将学习如何通过这两种方法创建构建管道。

使用经典编辑器定义管道

经典编辑器允许你通过选择预定义的操作图形化地定义项目的构建管道。如前所述,使用这种方式创建的管道定义不在源代码管理之下。

当你点击 使用经典编辑器 链接时,你需要选择存储代码的仓库(Azure Repos GitGitHubGitHub Enterprise ServerSubversionTFVCBitbucket Cloud其他 Git)以及构建管道将连接的分支:

图 4.17 – 经典编辑器管道定义

图 4.17 – 经典编辑器管道定义

然后,您需要选择一个适合您正在构建的应用程序类型的模板。您可以选择一组预定义的模板(稍后可以自定义),也可以从空模板开始:

图 4.18 – 管道模板选择

图 4.18 – 管道模板选择

如果预定义模板满足您的需求,您可以直接使用它们;否则,建议通过选择所需的操作创建自定义管道。

在这里,我的应用程序存储在 Azure DevOps 项目仓库中,是一个 ASP.NET Web 应用程序(一个名为 PartsUnlimited 的电子商务网站项目;您可以在以下网址找到公共仓库:github.com/Microsoft/PartsUnlimited),因此我选择了 ASP.NET 模板。

选择后,这是将自动为您创建的管道模板:

图 4.19 – 从模板创建的管道

图 4.19 – 从模板创建的管道

让我们详细查看管道的每个部分。

该管道(在这里叫做 PartsUnlimited-demo-pipeline)基于vs2017-win2016模板(Windows Server 2016 和 Visual Studio 2017),在 Microsoft 托管的代理(Azure Pipelines 代理池)上运行,如下截图所示:

图 4.20 – 管道中的代理规格

图 4.20 – 管道中的代理规格

代理作业首先安装 NuGet 包管理器,并还原所需的包,以便在所选仓库中构建项目。对于这些操作,管道定义包含了您在以下截图中看到的任务:

图 4.21 – NuGet 任务

图 4.21 – NuGet 任务

然后,有一个用于构建解决方案的任务:

图 4.22 – 构建解决方案任务

图 4.22 – 构建解决方案任务

还有一个用于测试解决方案并发布测试结果的任务:

图 4.23 – 测试程序集任务

图 4.23 – 测试程序集任务

最后的步骤是将构建过程的源代码作为构件(构建输出)发布:

图 4.24 – 发布任务

图 4.24 – 发布任务

如果选择变量选项卡,您将看到在构建过程中使用的一些参数。在这里,您可以创建自己的变量,在需要时在管道中使用:

图 4.25 – 管道变量

图 4.25 – 管道变量

下一部分叫做触发器。在这里,您可以定义启动管道的触发条件。默认情况下,初始时没有发布任何触发器,但在这里,您可以启用 CI,以便在所选分支的每次提交时自动启动管道:

图 4.26 – 管道触发器

图 4.26 – 管道触发器

重要说明

启用 CI 是推荐的做法,如果您希望每次在分支(例如,master 分支)上提交的代码都能得到测试并安全控制。在这种方式下,您可以确保代码始终按预期工作。

选项选项卡中,您可以设置与构建定义相关的一些选项。例如,在这里,您可以创建指向所有工作项的链接,以便在构建成功完成时,它们与相关的更改进行关联,构建失败时创建工作项,设置管道的状态徽章,指定超时等:

图 4.27 – 管道选项

图 4.27 – 管道选项

保留选项卡则用于配置该特定管道的保留策略(例如,保持工件多少天,保持运行和拉取请求多少天等)。这样做会覆盖一般的保留设置。我们将在后面的构建的保留部分讨论这些内容。

完成管道定义后,您可以点击保存并排队以保存定义。点击保存并运行时,管道将被放入队列并等待代理:

图 4.28 – 运行管道

图 4.28 – 运行管道

当找到代理时,管道会被执行,您的代码将被构建:

图 4.29 – 管道执行开始

图 4.29 – 管道执行开始

您可以跟踪管道每个步骤的执行,并查看相关日志。如果管道成功结束,您可以查看其执行摘要:

图 4.30 – 管道 – 最终结果

图 4.30 – 管道 – 最终结果

您还可以选择测试选项卡以查看测试执行状态:

图 4.31 – 管道测试结果

图 4.31 – 管道测试结果

在下一部分,我们将学习如何为这个应用创建一个 YAML 管道。

YAML 管道定义

如前所述,当您开始使用 Azure DevOps 创建构建管道时,向导默认会创建一个基于 YAML 的管道。

要开始创建 YAML 管道,请转到 Azure DevOps 中的管道部分,并点击新建管道

在这里,您可以选择仓库类型,而不是像我们在上一部分中那样选择经典编辑器(Azure Repos GitGitHubBitBucket等):

图 4.32 – YAML 管道定义

图 4.32 – YAML 管道定义

然后,从可用的仓库列表中选择您的仓库:

图 4.33 – YAML 管道 – 仓库选择

图 4.33 – YAML 管道 – 仓库选择

系统现在分析您的代码库,并根据代码库中存储的代码推荐一组可用的模板。您可以从一个空白的 YAML 模板开始,也可以选择一个模板。在这里,我选择了 ASP.NET 模板:

图 4.34 – YAML 管道 – 模板选择

图 4.34 – YAML 管道 – 模板选择

系统创建了一个 YAML 文件(称为 azure-pipelines.yml),如以下截图所示:

图 4.35 – YAML 管道定义

图 4.35 – YAML 管道定义

生成的 YAML 定义包含了一组任务,就像前面的例子一样,但在这里,这些任务在它们的 YAML 定义中。完整的生成文件如下所示:

# ASP.NET
# Build and test ASP.NET projects.
# Add steps that publish symbols, save build artifacts, deploy, and more:
# https://docs.microsoft.com/azure/devops/pipelines/apps/aspnet/build-aspnet-4
trigger:
- master
pool:
  vmImage: 'windows-latest'
variables:
  solution: '**/*.sln'
  buildPlatform: 'Any CPU'
  buildConfiguration: 'Release'
steps:
- task: NuGetToolInstaller@1
- task: NuGetCommand@2
  inputs:
    restoreSolution: '$(solution)'
- task: VSBuild@1
  inputs:
    solution: '$(solution)'
    msbuildArgs: '/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactStagingDirectory)"'
    platform: '$(buildPlatform)'
    configuration: '$(buildConfiguration)'
- task: VSTest@2
  inputs:
    platform: '$(buildPlatform)'
    configuration: '$(buildConfiguration)'
Here I add two more tasks for publishing the symbols and the final artifacts of the pipeline:
task: PublishSymbols@2
  displayName: 'Publish symbols path'
  inputs:
    SearchPattern: '**\bin\**\*.pdb'
    PublishSymbols: false
  continueOnError: true
- task: PublishBuildArtifacts@1
  displayName: 'Publish Artifact'
  inputs:
    PathtoPublish: '$(build.artifactstagingdirectory)'
    ArtifactName: '$(Parameters.ArtifactName)'
  condition: succeededOrFailed()

如您所见,YAML 文件包含了触发器,它启动管道(在这里是主分支上的提交),使用的代理池,管道变量,以及每个任务执行的顺序(带有其特定参数)。

如前所示,点击“保存并运行”以排队执行管道。以下截图显示了已执行的 YAML 管道。

图 4.36 – 已执行的 YAML 管道

图 4.36 – 已执行的 YAML 管道

若要添加新任务,可以使用编辑框右侧的助手工具。它允许您拥有一个任务列表,您可以在其中搜索任务,填写必要的参数,然后获得最终的 YAML 定义:

图 4.37 – YAML 管道任务选择

图 4.37 – YAML 管道任务选择

当您选择使用 YAML 创建管道时,Azure DevOps 会创建一个文件,并将其存储在与您的代码相同的代码库中:

图 4.38 – 创建的 YAML 管道文件

图 4.38 – 创建的 YAML 管道文件

此文件在源代码管理中,并在每次修改时版本化。

有关管道 YAML 模式的完整参考,我建议访问以下链接:

docs.microsoft.com/en-us/azure/devops/pipelines/yaml-schema?view=azure-devops&tabs=schema%2Cparameter-schema

构建保留

当您运行管道时,Azure DevOps 会记录每个步骤的执行,并存储每次运行的最终工件和测试。

Azure DevOps 对管道执行的默认保留策略为 30 天。您可以通过进入项目设置 | 管道 | 设置来更改这些默认值:

图 4.39 – 管道保留策略

图 4.39 – 管道保留策略

您还可以使用复制文件任务将构建和工件数据存储到外部存储中,以便您可以将它们保存比保留策略中指定的时间更长:

图 4.40 – 复制文件任务

图 4.40 – 复制文件任务

该任务的 YAML 定义如下:

- task: CopyFiles@2
  displayName: 'Copy files to shared network'
  inputs:
    SourceFolder: '$(Build.SourcesDirectory)'
    Contents: '**'
    TargetFolder: '\\networkserver\storage\$(Build.BuildNumber)'

重要说明

请记住,任何通过发布构建工件任务保存的数据都会定期删除。

更多关于复制文件任务的信息可以在这里找到:

docs.microsoft.com/zh-cn/azure/devops/pipelines/tasks/utility/copy-files?view=azure-devops&tabs=yaml

多阶段流水线

正如我们之前解释的,你可以将流水线中的工作组织成 stagesStages 是流水线流中的逻辑边界(可以分配给代理的工作单元),它们允许你隔离工作、暂停流水线并执行检查或其他操作。默认情况下,每个流水线由一个阶段组成,但你可以创建多个阶段并将这些阶段安排成依赖关系图。

多阶段流水线的基本 YAML 定义如下:

stages:  
	- stage: Build  
	  jobs:  
	  - job: BuildJob  
	    steps:  
	    - script: echo Build!  
	- stage: Test  
	  jobs:  
	  - job: TestOne  
	    steps:  
	    - script: echo Test 1  
	  - job: TestTwo 
	    steps:  
	    - script: echo Test 2  
	- stage: Deploy  
	  jobs:  
	  - job: Deploy  
	    steps:  
	    - script: echo Deployment

作为如何使用 YAML 创建多阶段流水线的示例,让我们来看一个在你的代码库中构建代码(使用 .NET Core SDK)并将工件发布为 NuGet 包的流水线。流水线定义如下。该流水线使用 stages 关键字来标识这是一个多阶段流水线。

在第一个阶段定义(Build)中,我们有构建代码的任务:

trigger:
	- master
	stages:
	- stage: 'Build'
	  variables:
	    buildConfiguration: 'Release'
	  jobs:
	  - job:
	    pool:
	      vmImage: 'ubuntu-latest'
	    workspace:
	      clean: all
	    steps:
	    - task: UseDotNet@2
	      displayName: 'Use .NET Core SDK'
	      inputs:
	        packageType: sdk
	        version: 2.2.x
	        installationPath: $(Agent.ToolsDirectory)/dotnet
	    - task: DotNetCoreCLI@2
	      displayName: "NuGet Restore"
	      inputs:
	        command: restore
	        projects: '**/*.csproj'
	    - task: DotNetCoreCLI@2
	      displayName: "Build Solution"
	      inputs:
	        command: build
	        projects: '**/*.csproj'
	        arguments: '--configuration (buildConfiguration)'

在这里,我们使用了 Azure DevOps 中提供的UseDotnet标准任务模板安装了 .NET Core SDK(更多信息请参见:docs.microsoft.com/zh-cn/azure/devops/pipelines/tasks/tool/dotnet-core-tool-installer?view=azure-devops))。之后,我们恢复了所需的 NuGet 包并构建了解决方案。

现在,我们有创建 NuGet 包发布版本的任务。该包保存在工件暂存目录的 packages/release 文件夹中。在此任务中,我们将使用 nobuild = true,因为在此任务中,我们无需重新构建解决方案(无需再进行编译):

    - task: DotNetCoreCLI@2
      displayName: 'Create NuGet Package - Release Version'
      inputs:
        command: pack
        packDirectory: '$(Build.ArtifactStagingDirectory)/packages/releases'
        arguments: '--configuration $(buildConfiguration)'
        nobuild: true

下一步,我们需要创建 NuGet 包的预发布版本。在此任务中,我们使用 buildProperties 选项将构建号添加到包版本中(例如,如果包版本是 2.0.0.0,构建号是 20200521.1,则包版本为 2.0.0.0.20200521.1)。在这里,构建包是强制性的(用于获取构建 ID):

    - task: DotNetCoreCLI@2
      displayName: 'Create NuGet Package - Prerelease Version'
      inputs:
        command: pack
        buildProperties: 'VersionSuffix="$(Build.BuildNumber)"'
        packDirectory: '$(Build.ArtifactStagingDirectory)/packages/prereleases'
        arguments: '--configuration $(buildConfiguration)'

下一个任务将包作为工件发布:

    - publish: '$(Build.ArtifactStagingDirectory)/packages'
      artifact: 'packages'

接下来,我们需要定义第二个阶段,称为 PublishPrereleaseNuGetPackage。在这里,我们跳过了代码库的检出步骤,下载步骤下载了我们在先前构建阶段发布的 packages 工件。然后,NuGetCommand 任务将预发布包发布到 Azure DevOps 中的一个名为 Test 的内部源:

- stage: 'PublishPrereleaseNuGetPackage'
  displayName: 'Publish Prerelease NuGet Package'
  dependsOn: 'Build'
  condition: succeeded()
  jobs:
  - job:
    pool:
      vmImage: 'ubuntu-latest'
    steps:
    - checkout: none
    - download: current
      artifact: 'packages'
    - task: NuGetCommand@2
      displayName: 'Push NuGet Package'
      inputs:
        command: 'push'
        packagesToPush: '$(Pipeline.Workspace)/packages/prereleases/*.nupkg'
        nuGetFeedType: 'internal'
        publishVstsFeed: 'Test'

现在,我们必须定义第三个阶段,叫做 PublishReleaseNuGetPackage,它用于为 NuGet 创建我们的包的发布版本:

- stage: 'PublishReleaseNuGetPackage'
  displayName: 'Publish Release NuGet Package'
  dependsOn: 'PublishPrereleaseNuGetPackage'
  condition: succeeded()
  jobs:
  - deployment:
    pool:
      vmImage: 'ubuntu-latest'
    environment: 'nuget-org'
    strategy:
     runOnce:
       deploy:
         steps:
         - task: NuGetCommand@2
           displayName: 'Push NuGet Package'
           inputs:
             command: 'push'
             packagesToPush: '$(Pipeline.Workspace)/packages/releases/*.nupkg'
             nuGetFeedType: 'external'
             publishFeedCredentials: 'NuGet'

这个阶段使用一个部署任务将包发布到配置好的环境中(在此,我们称之为 nuget-org)。环境是管道内的一组资源。

NuGetCommand 任务中,我们指定要推送的包,并且我们推送包的源是外部的(nuGetFeedType)。该源通过使用 publishFeedCredentials 属性检索,该属性设置为我们创建的服务连接的名称。

对于这个阶段,我们已经创建了一个新的环境:

图 4.41 – 创建新的环境

图 4.41 – 创建新的环境

一旦创建了环境,为了将其发布到 NuGet,您需要通过以下步骤创建一个新的服务连接:进入 项目设置 | 服务连接 | 创建服务连接,从可用的服务连接类型列表中选择 NuGet,然后根据您的 NuGet 帐户配置连接:

图 4.42 – 新的 NuGet 服务连接

图 4.42 – 新的 NuGet 服务连接

通过这一方式,我们创建了一个多阶段构建管道。当管道执行并且所有阶段成功完成时,您将看到一个如下所示的结果图:

图 4.43 – 多阶段构建管道执行情况

图 4.43 – 多阶段构建管道执行情况

现在我们已经理解了什么是多阶段管道,我们将在下一节创建一些与 GitHub 仓库相关的管道。

使用 GitHub 仓库构建管道

GitHub 是最流行的源代码管理平台之一,通常,我们会遇到将代码存储在 GitHub 仓库中,并且希望使用 Azure DevOps 来管理 CI/CD 的场景。

通过使用 Azure DevOps 和 Azure Pipeline 服务,您还可以为存储在 GitHub 上的仓库创建管道,从而在 GitHub 仓库中的每次提交时触发构建管道。我们将通过以下步骤实现这一点:

  1. 要使用 Azure Pipelines 构建您的 GitHub 仓库,您需要添加 Azure Pipelines。选择 Azure Pipelines 扩展,并点击 设置计划,如以下截图所示:图 4.44 – GitHub 上的 Azure Pipelines – 设置

    图 4.44 – GitHub 上的 Azure Pipelines – 设置

  2. 选择 免费 计划,点击 免费安装 按钮,然后点击 完成订单并开始安装

  3. 现在,Azure Pipelines 安装将询问您是否希望此应用程序对所有仓库可用,还是仅对选定的仓库可用。选择所需的选项并点击 安装图 4.45 – GitHub 上的 Azure Pipelines – 安装

    图 4.45 – GitHub 上的 Azure Pipelines – 安装

  4. 你将被重定向到 Azure DevOps,在那里你可以创建一个新项目(或选择一个现有项目)来处理构建过程。在这里,我将创建一个新项目:图 4.46 – 设置 Azure Pipelines 项目

    图 4.46 – 设置 Azure Pipelines 项目

  5. 现在,你需要授权 Azure Pipelines 以便它可以访问你的 GitHub 账户:图 4.47 – 授权 Azure Pipelines 访问 GitHub

    图 4.47 – 授权 Azure Pipelines 访问 GitHub

    当获得必要的授权后,项目将在 Azure DevOps 上为你创建,管道创建过程将开始。你将立即被提示从你账户中的可用 GitHub 仓库列表中选择一个 GitHub 仓库作为构建来源:

    图 4.48 – 选择 GitHub 仓库

    图 4.48 – 选择 GitHub 仓库

  6. 在这里,我选择了一个包含 Azure Function 项目的仓库。正如你所见,Azure Pipelines 已经识别了我的项目,并为管道提供了一组可用的模板(但你也可以从空白模板开始,或者从仓库中任何分支的 YAML 文件开始)。在这里,我将选择 GitHub 仓库中的azure-pipelines.yml):图 4.50 – 多阶段 YAML 管道定义

    图 4.50 – 多阶段 YAML 管道定义

    该管道会在每次提交到主分支时触发。

  7. 点击保存并运行按钮。在这里,管道将被排队并等待代理,然后执行。

    每次你在 GitHub 仓库中提交代码时,Azure DevOps 上的构建管道将会自动触发。

    如果你正在构建一个公共 GitHub 仓库,展示所有用户该仓库中的代码已经通过构建管道检查和测试是非常有用的。然后,你可以展示构建结果。你可以通过在仓库中放置一个徽章来做到这一点。

    徽章是一个动态生成的图像,反映构建的状态(未构建、成功或失败),并托管在 Azure DevOps 上。

  8. 为此,选择 Azure DevOps 中的管道,点击右侧的三个点,并选择状态徽章图 4.51 – 状态徽章定义

    图 4.51 – 状态徽章定义

  9. 从这里,你可以复制 GitHub 仓库中的Readme.md文件:

图 4.52 – 构建状态徽章的 Markdown

图 4.52 – 构建状态徽章的 Markdown

每当用户访问你的仓库时,他们将能够通过图形徽章查看最新构建的状态:

图 4.53 – 构建管道状态徽章

图 4.53 – 构建管道状态徽章

接下来,让我们看看如何并行执行作业。

在 Azure Pipelines 中并行执行作业

在 Azure 管道中,您还可以并行执行作业。每个作业可以独立于其他作业运行,也可以在不同的代理上执行。这将帮助您加速构建时间并提升管道的性能。

作为如何在管道中处理并行作业的示例,考虑一个简单的管道,您需要执行三个 PowerShell 脚本,分别叫做 任务 1任务 2最终任务任务 1任务 2 可以并行执行,而 最终任务 只有在前两个任务完成后才能执行。

当您开始创建一个新的管道时(这里为了简便,我使用经典编辑器),Azure DevOps 会创建一个代理作业(这里称为 代理作业 1)。您可以将任务添加到此代理中。通过选择代理作业,您可以指定运行该任务的代理池。在这里,我希望此任务在 Microsoft 托管的代理池中执行:

图 4.54 – 代理规格

图 4.54 – 代理规格

然后,要将新的代理池添加到管道中(用于独立执行其他任务),请点击管道旁边的三个点,选择 添加代理作业

图 4.55 – 添加代理作业

图 4.55 – 添加代理作业

现在,我们将添加一个第二个代理作业(这里称为 代理作业 2),它运行在自托管代理上。此作业将执行 任务 2 PowerShell 脚本:

图 4.56 – 代理选择

图 4.56 – 代理选择

最后,我们将添加一个新的代理作业(这里称为 代理作业 3),用于执行 最终任务,该任务将运行在 Microsoft 托管的代理上。然而,此作业有来自 代理作业 1代理作业 2 的依赖:

图 4.57 – 代理作业依赖关系

图 4.57 – 代理作业依赖关系

通过这种方式,前两个任务将并行启动,最终作业将在前两个任务执行完成后再运行。

若要了解有关 Azure 管道中并行作业的更多信息,我建议查看以下页面:

docs.microsoft.com/en-us/azure/devops/pipelines/process/phases?view=azure-devops&tabs=yaml

运行在 Azure 容器实例上的代理

如果标准的 Microsoft 托管代理无法满足您的需求(如要求、性能等),您还可以为 Azure DevOps 创建一个自托管代理,运行在 Azure 容器实例 (ACI) 服务的 Docker 容器内。

您可以通过使用自定义镜像或重用 Microsoft 提供的镜像来创建一个运行在 Azure 容器实例上的构建代理。

要创建一个运行在 ACI 上的构建代理,您需要为您的 Azure DevOps 组织创建一个 个人访问令牌。为此,您需要从 Azure DevOps 组织的首页打开用户设置(右上角),并选择 个人访问令牌

当您拥有代理的个人访问令牌时,您可以通过执行以下 Azure CLI 命令(在连接到您的 Azure 订阅后)在 ACI 上创建代理:

az container create -g RESOURCE_GROUP_NAME -n CONTAINER_NAME --image mcr.microsoft.com/azure-pipelines/vsts-agent --cpu 1 --memory 7 --environment-variables VSTS_ACCOUNT=AZURE_DEVOPS_ACCOUNT_NAME VSTS_TOKEN=PERSONAL_ACCESS_TOKEN VSTS_AGENT=AGENT_NAME VSTS_POOL=Default

这里,我们有如下内容:

  • RESOURCE_GROUP_NAME 是您在 Azure 中用于创建此资源的资源组名称。

  • CONTAINER_NAME 是 ACI 容器的名称。

  • AZURE_DEVOPS_ACCOUNT_NAME 是您的 Azure DevOps 账户名称。

  • PERSONAL_ACCESS_TOKEN 是您之前创建的个人访问令牌。

  • AGENT_NAME 是您要创建的构建代理的名称。该名称将在 Azure DevOps 中显示。

在此命令中,还有另外两个重要的参数:

请记住,您可以通过使用 az container stopaz container start 命令来启动和停止 ACI 实例。这可以帮助您节省费用。

在 Azure Pipelines 中使用容器作业

在本章中,我们看到,当您创建流水线时,您定义了作业,而当流水线执行时,这些作业会在安装了代理的主机上运行。

如果您使用的是 Windows 或 Linux 代理,您也可以在容器中运行作业(与主机隔离)。要在容器中运行作业,您需要在代理上安装 Docker,并且流水线必须有权限访问 Docker 守护进程。如果您使用的是 Microsoft 托管的代理,实际上支持在 windows-2019ubuntu-16.04 池镜像上运行容器中的作业。

作为示例,这是在 Windows 流水线中使用容器作业的 YAML 定义:

pool:
  vmImage: 'windows-2019'
container: mcr.microsoft.com/windows/servercore:ltsc2019
steps:
- script: date /t
  displayName: Gets the current date
- script: dir  
  workingDirectory: $(Agent.BuildiDirectory)
  displayName: list the content of a folder

如前所述,要在 Windows 容器中运行作业,您需要使用 windows-2019 镜像池。要求主机和容器的内核版本匹配,因此这里我们使用 ltsc2019 标签来获取容器的镜像。

对于基于 Linux 的流水线,您需要使用 ubuntu-16.04 镜像:

pool:
  vmImage: 'ubuntu-16.04'
container: ubuntu:16.04
steps:
- script: printenv

如您所见,流水线基于选定的镜像创建一个容器,并在该容器内运行命令(步骤)。

摘要

在本章中,我们提供了 Azure Pipelines 服务的概述,并展示了如何通过使用 Azure DevOps 实现 CI/CD 流程。我们还演示了如何通过图形界面和 YAML 创建一个针对托管在仓库中的代码的流水线,以及如何使用和创建构建代理。接着,我们介绍了如何使用经典编辑器和 YAML 定义创建构建流水线。我们还展示了一个多阶段流水线的示例,以及如何使用 Azure DevOps 流水线在 GitHub 仓库中构建代码,然后讲解了如何在构建流水线中使用并行任务来提高构建性能。最后,我们学习了如何在 Azure 容器实例上创建构建代理,并如何使用容器的作业。

在下一章中,我们将学习如何在构建流水线中执行代码库的质量测试。

第五章:

第六章:在构建管道中运行质量测试

在上一章中,我们介绍了 Azure Pipelines,并学习了如何使用 Azure DevOps、GitHub 和容器实现 CI/CD 流程。

在本章中,我们将讲解如何在构建管道中运行质量测试。我们将首先解释自动化测试的好处。接着,我们将探讨如何在构建管道中运行单元测试,如何进行代码覆盖测试,以及如何查看测试结果。最后,我们将介绍如何使用特性标志在生产环境中测试代码。

本章将涵盖以下主题:

  • 自动化测试的好处

  • 单元测试介绍

  • 在构建管道中运行单元测试

  • 代码覆盖测试介绍

  • 执行代码覆盖测试

  • 将测试结果分配给工作项

  • 特性标志介绍

  • 使用特性标志在生产环境中测试

技术要求

要跟随本章内容,您需要有一个活跃的 Azure DevOps 组织。本章将使用的组织名为 Parts Unlimited 组织,它是在第一章**,Azure DevOps 概述中创建的。您还需要安装 Visual Studio 2019,可以从visualstudio.microsoft.com/downloads/下载。为了获得最新的演示,您需要安装 Visual Studio Code 并配置 C#扩展,以及安装.NET Core SDK 版本 3.1 或更高版本。

我们的示例应用程序的源代码可以从以下链接下载:

github.com/PacktPublishing/Learning-Azure-DevOps---B16392/tree/master/Chapter%205/RazorFeatureFlags

自动化测试的好处

在为应用程序添加新功能后,您希望知道它是否能够在所有可能的交互情况下正确运行。您还希望确保这个新功能不会破坏其他功能,并希望知道代码是否容易理解且可维护。

所有这些都可以手动测试。但是随着项目和代码库的不断增长,手动测试所有这些功能可能会变得重复且容易出错。这时,自动化测试就显得至关重要。

关于自动化测试一直存在许多争议。很多人认为测试创建和维护成本过高。的确,当测试创建不当时,这种观点是成立的。但如果自动化测试得当,它将大大降低与频繁手动测试或发布低质量软件相比的时间和成本。通过使用自动化测试,您的项目将能够更频繁地发布软件。它可以重复使用并反复运行,为团队提供更快的结果和反馈。问题越早被发现,修复的成本就越低。

与 CI 配合使用时,代码会自动推送到生产环境,自动测试将帮助团队避免在软件中发布漏洞。然而,这也有权衡。开发人员需要投入更多时间来编写和维护测试代码。然而,通过投入这额外的时间,最终的结果将是更高质量的代码,并且这些代码已经经过验证,能够完全按预期运行。

你可以执行不同类型的自动化测试;例如,你可以运行回归测试、验收测试和安全性测试。在本章中,我们将重点介绍开发测试,这也是 CI 中使用的,可以直接从构建流水线中完成。

Visual Studio 和 Azure DevOps 都提供了测试功能。它们与测试框架无关,因此你可以插入自己的框架并引入第三方工具。你可以轻松地添加测试适配器以便运行测试并查看结果。这可以使测试成为你日常软件构建过程的一部分。

在接下来的章节中,我们将介绍单元测试和代码覆盖率测试,这些都是开发测试的一部分。首先,我们将描述如何从构建流水线中运行自动单元测试,然后介绍如何从构建流水线中进行代码覆盖率测试和 UI 测试。

单元测试简介

使用单元测试,你将代码拆分成小块,称为单元,这些单元可以独立地进行测试。这些单元可以是类、方法或单行代码。这里越小越好。这样可以让你更好地了解代码的表现,并且测试可以快速运行。

在大多数情况下,单元测试是由编写代码的开发人员来编写的。编写单元测试有两种不同的方式:在编写实际的生产代码之前,或者之后。大多数程序员是在事后编写的,这是一种传统的做法,但如果你使用的是测试驱动开发TDD),你通常会在之前编写单元测试。单元测试还可以使代码文档变得更容易。它鼓励更好的编码实践,你可以在代码中留下描述代码功能的部分。这里,你将更多地关注更新检查系统。

在接下来的部分中,我们将介绍如何在构建流水线中运行单元测试。

在构建流水线中运行单元测试

我们的Parts Unlimited测试项目已经创建了单元测试。因此,这是进行演示的一个好选择。首先,我们将查看应用程序和已创建的测试。因此,我们需要将仓库克隆到本地文件系统并在 Visual Studio 中打开解决方案。

下载源代码

我们将为 Parts Unlimited 的 Web 应用程序创建单元测试。首先,我们需要将仓库从 Azure DevOps 克隆到本地文件系统。这将允许我们使用 Visual Studio Code 添加单元测试。因此,我们必须执行以下步骤:

  1. 打开网页浏览器,访问 dev.azure.com/

  2. 使用您的 Microsoft 帐户登录并选择Parts.Unlimited项目。然后,从左侧菜单中选择Repos。这样您就可以导航到项目的源代码。

  3. 从右上角菜单中,选择克隆图 5.1 – 搜索结果

    图 5.1 – 搜索结果

  4. 在下一个屏幕上,确保选择了在 Visual Studio 中克隆,然后点击如下所示的按钮:图 5.2 – 克隆仓库

    图 5.2 – 克隆仓库

  5. 现在,Visual Studio 将会打开。在这里,我们将简要查看已经存在于项目中的测试类。为此,请打开解决方案资源管理器窗口,并导航至test > PartsUnlimited.UnitTests图 5.3 – 单元测试项目

    图 5.3 – 单元测试项目

  6. 该项目中有不同的测试项目。花些时间熟悉一下实际测试的内容。这里使用的是 Visual Studio 的默认测试框架,即MS Test

  7. 在 Visual Studio 中,您可以构建并运行应用程序。为此,请按F5。或者,从顶部菜单中选择调试 > 开始调试图 5.4 – 单元测试项目

    图 5.4 – 单元测试项目

  8. 一旦项目构建完成,网站将如下所示:图 5.5 – 示例网站

    图 5.5 – 示例网站

  9. 返回 Visual Studio 并停止调试器。

现在一切都已正常工作,我们可以开始创建构建管道,其中包括运行单元测试项目。

创建管道

要创建管道,我们需要回到 Azure DevOps。在那里,按照以下步骤操作:

  1. 从左侧菜单中,选择管道(Pipelines)

  2. 在屏幕右上角,找到并点击新建管道图 5.6 – 创建新管道

    图 5.6 – 创建新管道

  3. 创建构建管道的向导将会出现。在第一个屏幕上,选择使用经典编辑器,以使用设计器创建管道:图 5.7 – 使用经典设计器选项

    图 5.7 – 使用经典设计器选项

  4. 在下一个屏幕上,确保选择了Azure Repos Git。保持默认设置不变,并点击继续图 5.8 – 管道源设置

    图 5.8 – 管道源设置

  5. 接下来,我们需要选择一个模板。从概览中选择ASP.NET,然后点击应用图 5.9 – 选择 ASP.NET 模板

    图 5.9 – 选择 ASP.NET 模板

  6. 这样,流水线就会创建完成。默认情况下,流水线会添加各种任务。我们将在这里使用这些任务。在本次演示中,我们将重点关注测试程序集任务。点击此任务并确保选择版本2。在测试选择下,您将看到以下设置:图 5.10 – 测试选择设置

    图 5.10 – 测试选择设置

  7. 默认情况下,在选择测试方式下会选择测试程序集。请保持选择此项。由于我们希望自动运行单元测试,这是我们需要选择的选项。单元测试通常存储在程序集内部。

  8. 此外,默认情况下,已经填充了一些程序集。如果需要,您可以更改它们。在本次演示中,我们将保持默认设置不变,因为任务会在不同的文件夹中查找包含test的程序集。我们的测试项目名为PartsUnlimited.UnitTests,所以任务会自动找到该程序集。

  9. 搜索文件夹是用来搜索测试程序集的文件夹。在这种情况下,这是默认的工作目录。

  10. 测试结果文件夹是存储测试结果的地方。测试运行之前,结果目录将始终被清空。

  11. 我们现在准备运行测试。点击顶部菜单中的保存并排队,然后再次点击保存并排队子菜单项以执行构建流水线:图 5.11 – 执行构建流水线

    图 5.11 – 执行构建流水线

  12. 运行流水线的向导将打开。在这里,您可以指定一个评论,然后选择代理池代理规范以及您希望使用的分支/标签图 5.12 – 运行流水线的参数

    图 5.12 – 运行流水线的参数

  13. 点击保存并运行以排队流水线。

    将显示作业的概览页面,在这里您可以查看执行状态:

    图 5.13 – 我们的作业概览

    图 5.13 – 我们的作业概览

  14. 几分钟后,流水线将完成。从右上角的菜单中,点击测试与覆盖率,您将能够看到此构建的测试通过百分比。点击此处可查看测试结果(另外,您也可以通过点击左上角的测试菜单来查看:图 5.14 – 测试概览

    图 5.14 – 测试概览

  15. 测试页面,您将看到测试数量,以及通过和失败的测试。您还可以看到运行的持续时间。

  16. 在屏幕底部,您可以按特定的测试进行筛选。例如,您可以筛选出通过失败中止的测试:

图 5.15 – 更详细的测试结果

图 5.15 – 更详细的测试结果

在这个演示中,我们创建了一个包含自动单元测试的构建管道,用于我们的源代码。在下一部分,我们将探讨代码覆盖率测试。

代码覆盖率测试简介

通过代码覆盖率测试,你可以衡量应用程序的哪些源代码将被测试。代码覆盖率测试衡量的是在运行自动化测试(如单元测试)时,执行了多少行代码、代码块和类。

测试的代码越多,团队对其代码更改的信心就越大。通过查看代码覆盖率测试的结果,团队可以识别出哪些代码没有被这些测试覆盖。这些信息非常有用,因为它有助于随着时间推移减少测试负担。

Azure DevOps 支持从构建管道执行代码覆盖率测试。测试程序集任务允许我们收集代码覆盖率测试结果。还有一个独立的任务,称为发布代码覆盖率结果,它也可以发布这些结果。该任务对流行的覆盖率结果格式(如 Cobertura 和 JaCoCo)提供开箱即用的支持。

重要提示

Cobertura 和 JaCoCo 都是计算测试访问的代码百分比的 Java 工具。有关 Cobertura 的更多信息,请参考 cobertura.github.io/cobertura/。有关 JaCoCo 的更多信息,请参考 www.eclemma.org/jacoco/

在下一部分,我们将讨论如何使用 Azure DevOps 执行代码覆盖率测试。

执行代码覆盖率测试

为了执行代码覆盖率测试,我们需要打开在前一演示中创建的构建管道。让我们开始吧:

  1. 打开构建管道后,选择右上角的编辑按钮:图 5.16 – 编辑前一演示中的管道

    图 5.16 – 编辑前一演示中的管道

  2. 导航到测试程序集任务以打开设置。

    执行设置中,勾选启用代码覆盖率框:

    图 5.17 – 启用代码覆盖率测试

    图 5.17 – 启用代码覆盖率测试

  3. 现在,.coverage 文件可以下载并用于在 Visual Studio 中进行进一步分析。

  4. 执行管道后,在构建概览页面上,选择.coverage 扩展名将被下载到你的本地文件系统。

  5. 双击下载的文件,这样它会在 Visual Studio 中打开。从这里,你可以深入查看不同的类和方法,获取测试结果的概览:

图 5.18 – Visual Studio 中的代码覆盖率测试结果

图 5.18 – Visual Studio 中的代码覆盖率测试结果

在这个演示中,我们从构建管道启用了代码覆盖率测试。在下一部分,我们将把这些测试结果分配到用户故事中。

将测试结果分配到工作项

一旦测试自动运行并且构建过程完成,你可以将结果分配给已添加到待办事项和冲刺中的工作项。为此,你需要执行以下步骤:

  1. 返回构建流水线,选择上次运行的流水线。在顶部菜单中点击测试

  2. 对于结果表格,确保选中了已通过,并且已失败已中止已被取消选择:图 5.19 – 选择所有通过的测试

    图 5.19 – 选择所有通过的测试

  3. 然后,选择几个测试。完成后,在顶部菜单中点击链接图 5.20 – 链接项目

    图 5.20 – 链接项目

  4. 搜索作为测试人员并选择显示为搜索结果的工作项:图 5.21 – 选择工作项

    图 5.21 – 选择工作项

  5. 点击关联以将工作项链接到测试结果。

  6. 现在,点击一个与工作项链接的测试结果。这将显示该项目的详细信息。在这里,你可以点击顶部菜单中的工作项,这将显示我们在前一步中链接的工作项:图 5.22 – 链接的工作项

    图 5.22 – 链接的工作项

  7. 通过点击该工作项,你可以查看它的详细信息。

在本示范中,我们讲解了如何将测试结果链接到工作项。在接下来的部分,我们将讲解如何使用功能标志在生产环境中进行测试。

功能标志简介

你可以使用功能标志来打开或关闭代码中的功能,比如特定的方法或代码段。当你想在解决方案中隐藏(禁用)或公开(启用)某些功能时,这非常有帮助。尚未完成并准备发布的功能可以被隐藏或公开。这使得我们可以在生产环境中针对一部分用户进行代码测试。例如,你可以基于用户的登录名为一部分用户启用代码,并让他们在将功能发布给其他用户之前进行测试。然而,功能标志也有一个缺点:它们会增加代码的复杂性,因此最好限制应用程序中切换标志的数量。

创建功能标志时,推荐的方法是将它们保存在应用程序外部。例如,网页或应用配置文件是添加功能标志的好地方,因为你可以轻松更改它们,而无需重新部署应用程序。

在接下来的部分,我们将实现一个 .NET Core 解决方案中的功能标志(Feature Flag)。

使用功能标志在生产环境中进行测试

在本示范中,我们将创建一个新的 .NET Core 应用程序,在 Visual Studio Code 中进行开发。然后,我们将为此应用程序实现功能标志。

我们将添加一个非常基本的功能标志,将欢迎信息从Welcome更改为Welcome to Learn Azure DevOps。这将仅对一部分用户进行测试。因此,我们需要打开带有.NET Core 的Razor应用程序。我在本地文件系统中创建了一个名为FeatureFlags的新文件夹用于此目的。在 Visual Studio Code 中打开该文件夹。有关详细步骤,请查看下一部分。

创建一个新的.NET Core 应用程序

创建一个新的.NET Core 应用程序,请按照以下步骤操作:

  1. Visual Studio Code打开时,从顶部菜单中点击终端 > 新终端

  2. 在终端中,添加以下代码行以创建一个新项目:

    dotnet new webapp -o RazorFeatureFlags
    code -r RazorFeatureFlags
    
  3. 新创建的项目现在将打开。再次打开终端,并将以下代码行添加到终端中测试项目:

    dotnet run
    

    运行此代码的输出如下所示:

    图 5.23 – 终端中的输出

    图 5.23 – 终端中的输出

  4. 通过点击终端输出中的本地主机 URL 之一,导航到.NET Core 应用程序。您将看到以下内容:图 5.24 – 运行新项目

    图 5.24 – 运行新项目

  5. 下一步是将Microsoft.FeatureManagement NuGet 包添加到项目中。因此,请将以下代码行添加到终端:

    dotnet add package Microsoft.FeatureManagement 
    
  6. 安装完该包后,打开Program.cs类,并添加以下using语句:

    using Microsoft.FeatureManagement;
    
  7. 现在,打开appsettings.json文件。我们将在此文件中创建一个FeatureManagement部分。将文件中的代码替换为以下内容:

      {
      'Logging': {
        'LogLevel': {
          'Default': 'Information',
          'Microsoft': 'Warning',
          'Microsoft.Hosting.Lifetime': 'Information'
        }
      },
      'FeatureManagement': {
        'ChangeBanner': false
      },  
      'AllowedHosts': '*'
    }
    
  8. 然后,打开Startup.cs类。在这里,再次添加using语句,并将以下内容添加到ConfigureServices方法中:

    public void ConfigureServices(IServiceCollection services)
        {
            //...
            services.AddFeatureManagement();
        }
    
  9. 现在,我们可以将其注入到一个控制器中。例如,打开应用程序首页背后的代码,代码可以在Index.cshtml.cs文件中找到,并再次添加using语句。然后,将IndexModel类替换为以下代码:

    public class IndexModel : PageModel
        {
         private readonly IFeatureManager _featureManager;
         public IndexModel(IFeatureManager featureManager)
         {
            _featureManager = featureManager;
         }
         public static string WelcomeMessage { get; set; }
         public async Task OnGetAsync() 
         {
            WelcomeMessage = await _featureManager.IsEnabledAsync('ChangeBanner') ? 'Welcome to Learn Azure DevOps' : 'Welcome';
         }
        }
    }
    
  10. Index.cshtml.cs类将如下所示:图 5.25 – 文件概览

    图 5.25 – Index.cshtml.cs文件概览

  11. 最后,打开Index.cshtml文件,并用以下内容替换其中的代码:

    <div class='text-center'>
        <h1 class='display-4'>@IndexModel.WelcomeMessage</h1>
        <p>Learn about <a href='https://docs.microsoft.com/aspnet/core'>building Web apps with ASP.NET Core</a>.</p>
    </div
    
  12. 这将把欢迎信息注入到网页中。

  13. 通过打开一个新的终端窗口并将以下代码行添加到终端来构建并运行代码:

    dotnet run
    
  14. 让应用程序在浏览器中打开,然后再次在 Visual Studio Code 中打开appsettings.json文件。将ChangeBanner功能标志更改为true,然后通过按F5重新加载浏览器中的网站。这样将会得到以下输出:

图 5.26 – 基于提供的功能标志更改的欢迎信息

图 5.26 – 基于提供的功能标志更改的欢迎信息

在这个演示中,我们使用 Microsoft 的 Featuremanagement NuGet 包向我们的应用程序添加了一些功能标志(Feature Flags)。通过这些功能标志,我们更改了应用程序首页的欢迎信息。本章到此结束。

总结

在本章中,我们更深入地讨论了如何在构建管道中运行质量测试。通过这些,你现在可以从构建管道中运行单元测试,并从 Azure DevOps 执行覆盖率测试。最后,我们讲解了如何在应用程序中创建未来标志(Future Flags),这些标志可以在你的未来项目中使用。

在下一章中,我们将专注于如何在 Azure Pipelines 中托管构建代理。

进一步阅读

查看以下链接以获取更多关于本章所涵盖主题的信息:

第六章:

第七章:托管你自己的 Azure 管道代理

在前两章中,我们看到了如何通过 Azure Pipelines 设置持续集成,并使用 Microsoft 托管的代理。在本章中,我们将建立一个自托管代理,并更新管道以使用我们自己的代理,而不是使用 Microsoft 托管的代理。

我们将首先查看可用的管道代理类型,然后深入探讨设置代理池的技术规格。我们还将了解如何使用 VM 扩展集来支持大规模的 Azure DevOps 项目。

我们将涵盖以下主题:

  • Azure 管道代理概述

  • 了解 Azure Pipelines 中代理的类型

  • 规划并设置你自己的 Azure 管道代理

  • 更新你的 Azure 管道以使用自托管代理

  • 使用容器作为自托管代理

  • 扩展规划 – 使用 Azure VM 扩展集作为自托管代理

技术要求

要跟随本章,你需要有一个有效的 Azure DevOps 组织和一个 Azure 订阅来创建虚拟机。

准备项目前提条件:本节要求你在自己的 DevOps 组织中准备好PartsUnlimited项目。如果你正在继续上一章内容,第五章在构建管道中运行质量测试,你应该已经有该项目了。

如果你在 DevOps 组织中没有准备好项目,可以使用 Azure DevOps Demo Generator 导入它 – azuredevopsdemogenerator.azurewebsites.net/

  1. 登录到Azure DevOps Demo Generator网站。

  2. 输入项目名称并选择你的DevOps 组织

  3. 点击选择模板并找到PartsUnlimited

  4. 一旦准备好,点击创建项目图 6.1 – 创建示例 DevOps 项目

    图 6.1 – 创建示例 DevOps 项目

    项目导入需要几分钟时间,你可以使用显示的进度条来监控进度。

  5. 完成后,点击导航到项目

图 6.2 – 项目成功创建

图 6.2 – 项目成功创建

我们将在本章中贯穿使用这个项目。

Azure 管道代理概述

Azure 管道代理是负责执行管道定义中任务的组件。这个代理通常运行在虚拟机或容器中,并包含成功运行管道所需的前提条件。

在大多数情况下,你需要一个代理来运行管道。随着项目规模和开发人员数量的增加,你将需要更多的代理来支持扩展。

每次执行管道时,都会在一个代理上启动一个作业,并且每个代理一次只能运行一个作业。Azure 管道代理可以托管在云端或本地的以下计算基础设施中:

  • 服务器或客户端主机(物理或虚拟)

  • 容器

  • Azure VM 扩展集(预览版)

Azure 管道代理被分组为 代理池。你可以根据需要创建任意数量的代理池。

重要提示

Azure Pipelines 支持运行基本任务,例如调用 REST API 或 Azure Function,而无需任何代理。有关无代理执行 Azure Pipelines 的更多详情,请参考 docs.microsoft.com/en-us/azure/devops/pipelines/process/phases?view=azure-devops&tabs=yaml#server-jobs

了解 Azure Pipelines 中代理的类型

Azure Pipelines 提供两种类型的代理:

  • Microsoft 托管代理

  • 自托管代理

让我们详细看一下它们。

Microsoft 托管代理

Microsoft 托管代理是完全托管的虚拟机,由 Microsoft 部署和管理。你可以选择使用 Microsoft 托管代理,无需任何额外的前置要求或配置。Microsoft 托管代理是最简单的,且无需额外费用。

每次执行管道时,你都会获得一个新的虚拟机来运行任务,且使用一次后就会被丢弃。

自托管代理

自托管代理是你拥有的服务器,运行在你拥有的任何云平台或数据中心中。由于安全性、可扩展性和性能等多种原因,自托管代理更受欢迎。

你可以配置自托管代理以预先安装所需的依赖项,这将帮助你减少管道执行的时间。

选择 Microsoft 托管代理和自托管代理取决于多种因素,以下是一些考虑因素:

  • 代码库的大小

  • 开发人员数量

  • 构建和发布的频率

  • 构建过程中所需的依赖项和包

  • 安全性和合规性要求

  • 性能

如果你的代码库较小且构建管道经过优化,最好使用 Microsoft 托管代理,因为下载所有依赖项所需的时间不多。然而,如果你有一个庞大的代码库和大量的依赖项,使用自托管代理会是一个更好的选择,因为你可以通过提前在自托管环境中配置它们,从而消除管道中的各种构建前期任务。如果你需要比 Microsoft 托管代理提供的更多 CPU 和内存,可以使用自托管代理并自定义大小。

推荐从 Microsoft 托管代理开始,等到 Microsoft 托管代理在你的构建和发布过程中成为瓶颈时,再转向自托管代理。

规划和设置你的自托管 Azure 管道代理

为了在 Azure Pipelines 中使用自托管代理,您需要设置一台机器并根据管道需求进行配置。通常,您会根据项目的框架、库和构建工具兼容性选择最适合的操作系统版本。

为了演示,我们将在 Azure 中设置一台虚拟机,并将其配置为使用自托管代理。您可以选择将代理服务器托管在任何云环境或本地环境中。

为代理虚拟机选择正确的操作系统/镜像

设置虚拟机时的第一个决定是选择操作系统/镜像,这取决于您的目标部署。如果您在本地环境中部署,您可以选择一个支持的操作系统版本(例如 Windows Server 2016)并安装必要的软件。对于云部署,您可以选择多种操作系统版本和预安装工具的组合镜像。

建议与开发人员共同规划代理虚拟机的规格,以确保其最适合您的项目需求。以下是一种推荐的做法:

  1. 确定您的应用程序是构建为运行在 Windows、Linux 还是 macOS 上。如果是跨平台的,请选择运行效果最佳且支持您正在使用的构建工具的操作系统。

  2. 列出所使用的底层框架和外部库/组件及其版本。

  3. 步骤 1中选择的顶层操作系统中选择最新版本的操作系统。

  4. 确定它是否与原始设备制造商OEM)支持的所有依赖项兼容,依赖项详见步骤 2

  5. 依次选择每个版本,直到选定一个与项目所需所有依赖项兼容的版本。

根据此过程确定的规格,您可以选择从原生操作系统开始,安装所需的框架和构建工具,或者在云中选择一个预创建的镜像。

安装 Azure Pipelines 代理的操作系统支持及前提条件

Azure 支持多种操作系统版本作为自托管代理使用;根据您选择的操作系统,您需要完成一组前提条件,才能在主机上安装 Azure Pipelines 代理。

支持的操作系统

以下是支持的操作系统列表:

  • 基于 Windows:

    a) Windows 7,8.1 或 10(如果您使用的是客户端操作系统)

    b) Windows Server 2008 R2 SP1 或更高版本(Windows Server 操作系统)

  • 基于 Linux:

    a) CentOS 7,6

    b) Debian 9

    c) Fedora 30,29

    d) Linux Mint 18,17

    e) openSUSE 42.3 或更高版本

    f) Oracle Linux 7

    g) Red Hat Enterprise Linux 8,7,6

    h) SUSE Enterprise Linux 12 SP2 或更高版本

    i) Ubuntu 18.04,16.04

  • ARM32:

    a) Debian 9

    b) Ubuntu 18.04

  • 基于 macOS:

    a) macOS Sierra(10.12)或更高版本

前提软件

根据您选择的操作系统,您必须在将主机设置为 Azure Pipeline 代理之前,先安装以下前提条件:

  • 基于 Windows:

    a) PowerShell 3.0 或更高版本

    b) .NET Framework 4.6.2 或更高版本

  • 基于 Linux/ARM/macOS:

    a) Git 2.9.0 或更高版本。

    b) RHEL 6 和 CentOS 6 需要安装专门的 RHEL.6-x64 版本的代理。

Linux 的代理安装程序包括一个脚本,用于自动安装所需的先决条件。您可以通过运行./bin/installdependencies.sh来完成先决条件安装,该脚本位于下载的代理目录中。下载代理的过程将在本章的后续部分中介绍。

重要提示

请注意,上述先决条件仅用于在主机上安装 Azure Pipelines 代理;根据您的应用程序开发需求,您可能需要安装其他工具,例如 Visual Studio 构建工具、Subversion 客户端以及您的应用程序可能需要的任何其他框架。

现在我们已经了解了先决条件,我们将为我们的示例项目PartsUnlimited创建一个代理虚拟机。

为您的项目在 Azure 中创建虚拟机

PartsUnlimited 项目使用 .NET Framework 4.5 和 Visual Studio 作为主要的 IDE 工具进行构建。您可以通过浏览 PartsUnlimited 项目的 Azure DevOps 仓库来查看该信息。

看来看去,我们最好的选择是使用基于 Visual Studio 的服务器操作系统。让我们在 Azure 中查看并探索我们在这方面的选择:

  1. 登录到 Azure 门户并点击+ 创建资源

  2. 搜索Visual Studio并选择Azure 的 Visual Studio 镜像选项:图 6.3 – Azure 门户中的 Visual Studio

    图 6.3 – Azure 门户中的 Visual Studio

  3. 现在,您将能够从各种可用组合中进行选择。我们将选择Visual Studio Community 2017 on Windows Server 2016(x64):图 6.4 – Azure 中可用的 Visual Studio 镜像

    图 6.4 – Azure 中可用的 Visual Studio 镜像

    重要提示

    基于 Visual Studio 2019 的镜像可以直接在 Azure 门户的搜索结果中找到。

  4. 点击创建开始创建虚拟机。根据您的偏好选择所需的订阅、资源组和其他设置。

  5. 在后续页面中,您可以修改设置以使用预先创建的虚拟网络,并自定义存储设置及其他管理方面的内容。请查看文档,了解更多关于在 Azure 中创建虚拟机的信息。

    重要提示

    请参考 Microsoft 文档,了解如何在 Azure 中创建虚拟机:docs.microsoft.com/en-us/azure/virtual-machines/windows/quick-create-portal

  6. 创建虚拟机后,登录并安装所需的先决条件。

现在我们已经准备好虚拟机,我们将其设置为我们项目的 Azure Pipelines 代理。

设置构建代理

在本节中,我们将配置新创建的虚拟机,以将其用作自托管的管道代理。

在 Azure DevOps 中设置代理池

您可以在 Azure DevOps 中将您的代理组织为 代理池代理池是您自托管代理的集合,它们帮助您在池级别组织和管理代理,而不是单独管理每个代理。

代理池 在组织级别进行管理,并可以同时供多个项目使用。让我们创建一个 代理池 来开始:

  1. 登录到 Azure DevOps 并点击 组织设置图 6.5 – Azure DevOps 组织设置

    图 6.5 – Azure DevOps 组织设置

  2. 管道 下点击 代理池图 6.6 – Azure DevOps 代理池

    图 6.6 – Azure DevOps 代理池

  3. 您会看到已创建了两个默认的代理池。点击 添加池 创建一个新池:图 6.7 – Azure DevOps – 添加代理池

    图 6.7 – Azure DevOps – 添加代理池

  4. 提供池类型、名称、描述和管道权限。在权限选项下,您可以选择让此池同时适用于所有管道和项目。准备好后点击 创建

    a) --池类型自托管

    b) --名称描述:为其起个有意义的名称,以便以后可以引用:

    图 6.8 – Azure DevOps – 添加代理池配置

    图 6.8 – Azure DevOps – 添加代理池配置

  5. 现在您的代理池应该已列在 代理池 下。

现在我们将为代理虚拟机设置访问令牌,以便其能够与 Azure DevOps 进行身份验证。

设置代理通信的访问令牌

在此任务中,您将创建一个个人访问令牌,Azure Pipelines 代理将使用它与您的 Azure DevOps 组织进行通信:

  1. 使用管理员用户帐户登录您的 Azure DevOps 组织。

  2. 转到您的用户个人资料并点击 个人访问令牌图 6.9 – 个人访问令牌

    图 6.9 – 个人访问令牌

  3. 点击 新建令牌

  4. 按照此处提供的令牌规格进行设置:

    --名称自托管代理令牌

    --组织:您的 Azure DevOps 组织。

    --到期时间:您可以根据需要选择一个日期。这只是一次性设置;一旦此令牌过期,您不需要重新配置代理。

    --范围自定义定义

  5. 范围 中,建议仅授予管理代理所需的权限。点击 显示所有范围 并选择 读取读取与管理 权限:图 6.10 – 代理池访问

    图 6.10 – 代理池访问

  6. 查看所有设置并点击 创建图 6.11 – 为代理池创建个人访问令牌

    图 6.11 – 为代理池创建个人访问令牌

  7. 一旦您点击创建,Azure DevOps 会显示个人访问令牌。请复制该令牌并将其保存在安全位置。如果您丢失了该令牌,必须为新代理的设置创建一个新的令牌。

    我们将在设置 Azure Pipelines 代理时使用此令牌。

    重要提示

    如果您计划使用部署组,创建令牌时需要赋予额外的权限(更多信息请参考:docs.microsoft.com/en-us/azure/devops/pipelines/release/deployment-groups/?view=azure-devops)。

现在我们已经在 Azure DevOps 中完成了代理池的设置,我们可以开始在之前创建的虚拟机上安装代理。

安装 Azure Pipelines 代理

现在,您可以在之前创建的虚拟机上安装 Azure Pipelines 代理。让我们下载 Azure Pipelines 代理。在开始之前,请使用远程桌面登录到之前创建的虚拟机:

  1. 在您的 Azure DevOps 账户中,浏览到 组织设置 > 代理池

  2. 选择您新创建的代理池并点击新建代理图 6.12 – 添加代理

    图 6.12 – 添加代理

  3. 在下一页,您可以根据操作系统和架构(x64/x32)下载代理安装程序。在我们的示例中,我们使用的是基于 Windows Server 2016 的虚拟机。我们将选择 Windows 和 x64 架构。您还可以复制下载 URL,并在您的自托管代理机器上直接下载代理。您也可以选择根据操作系统在 Azure DevOps 门户中提供的安装步骤来安装代理:图 6.13 – 代理命令

    图 6.13 – 代理命令

    提示

    如果您无法在 Visual Studio 机器上下载代理文件,您可以使用不同的浏览器(如非 Internet Explorer)或在服务器管理器中禁用增强的 IE 安全性配置。您可以参考 www.wintips.org/how-to-disable-internet-explorer-enhanced-security-configuration-in-server-2016/ 了解如何禁用 Internet Explorer 增强的安全性配置。

  4. 启动一个提升权限的 PowerShell 窗口,并通过运行 cd C:\ 命令更改到 C: 目录根目录:图 6.14 – 更改目录

    图 6.14 – 更改目录

  5. 运行以下 PowerShell 命令在 C 盘创建一个代理目录,并将代理文件提取到新目录中。请注意,您可能需要根据您下载的代理版本和保存下载文件的目录更改文件名/路径:

    mkdir agent ; cd agent
    Add-Type -AssemblyName System.IO.Compression.FileSystem ; [System.IO.Compression.ZipFile]::ExtractToDirectory("$HOME\Downloads\vsts-agent-win-x64-2.171.1.zip", "$PWD")
    
  6. 提取文件将需要一分钟左右的时间。完成后,请浏览到新的目录。您应该会看到如下截图中的文件:图 6.15 – 代理文件

    图 6.15 – 代理文件

  7. 您可以以两种模式运行 Azure 管道代理:

    --run 批处理文件存储在代理目录中。如果您停止交互式认证,您的代理将停止响应管道。

    --作为服务运行:在这个版本中,您将配置代理作为 Windows 服务运行,该服务将始终保持在线,并在重启时自动启动。这是生产环境推荐的设置。

  8. 让我们配置代理为服务运行。在您的 PowerShell 窗口中,运行 .\config.cmd

    这将询问有关您 Azure DevOps 组织的一系列问题。

  9. 输入您的 Azure DevOps 组织作为服务器 URL。通常,这将是 dev.azure.com/YourOrganizationName

  10. Enter 键选择 PAT个人访问令牌)作为 Azure DevOps 的认证机制。

  11. 提供您之前生成的个人访问令牌。

  12. 提供您之前创建的代理池名称。

  13. 为此代理提供一个名称。

  14. 为代理提供一个工作目录,作为默认目录。

  15. 最后,按 Y 并按 Enter 键,将代理配置为作为 Windows 服务运行。

  16. 您可以接受默认帐户来运行此服务。

  17. 这将完成代理设置;最后,您应该看到一条消息,表示服务已成功启动:

图 6.16 – 安装代理

图 6.16 – 安装代理

现在,如果您在 Azure DevOps 门户中的代理池下查看,应该会看到这个代理列出:

图 6.17 – Azure Pipelines 代理列出

图 6.17 – Azure Pipelines 代理列出

现在,您已经拥有一个可用的自托管代理来运行您的 Azure 管道!此自托管代理可用于运行您的 Azure 管道作业,并且您可以以类似的方式添加任意数量的代理。您可以在同一个池中拥有多种类型的托管代理;根据管道要求,系统会自动选择合适的代理,或者您也可以在执行时专门选择一个代理。通常,在大型环境中,您会预先创建一个代理服务器的镜像,以便在需要时能够更快地配置额外的代理。在接下来的章节中,我们将更新我们的管道,以利用新设置的自托管代理。如果您希望使用基于 Linux 的托管代理,请参考以下文档:docs.microsoft.com/en-us/azure/devops/pipelines/agents/v2-linux?view=azure-devops

请参考以下链接,了解基于 macOS 的代理:docs.microsoft.com/en-us/azure/devops/pipelines/agents/v2-osx?view=azure-devops

重要提示

如果你的自托管代理机器位于网络防火墙或代理后面,在安装 Azure 管道代理时,必须定义代理地址。你可以通过在配置命令中指定代理 URL、用户名和密码来完成此操作:

./config.cmd --proxyurl http://127.0.0.1:8888 --proxyusername "myuser" --proxypassword "mypass"

更新你的 Azure 管道以使用自托管代理

在本节中,我们将修改上几章中涵盖的 Azure 管道场景(PartsUnlimited),以使用我们新创建的自托管代理。这将使我们能够使用自托管代理来运行管道,而不是使用 Microsoft 提供的代理。

准备你的自托管代理来构建PartsUnlimited项目

在我们开始使用自托管代理之前,我们必须准备它以支持构建我们的示例项目PartsUnlimitedPartsUnlimited项目是使用 Visual Studio 构建的,依赖于 .NET Framework、Azure 开发工具和 .NET Core、Node.js 等技术。为了使用我们的自托管代理构建解决方案,我们必须在运行管道作业之前安装所需的依赖项:

  1. 登录到你的自托管代理虚拟机。

  2. 通过以下链接下载 Visual Studio 构建工具:visualstudio.microsoft.com/thank-you-downloading-visual-studio/?sku=BuildTools&rel=16

    这将启动 Visual Studio 安装程序。

  3. 选择ASP.Net 和 Web 开发以及Azure 开发

  4. 点击修改。这将开始安装所需的框架和工具。

  5. 完成后,请下载并安装 .NET Core 2.2。你可以从这个链接下载:dotnet.microsoft.com/download/dotnet-core/thank-you/sdk-2.2.110-windows-x64-installer

    你可以在这里找到所有的 .NET 下载:dotnet.microsoft.com/download

  6. 通过在提升权限的 PowerShell 窗口中运行以下命令来安装 Azure PowerShell:

    [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
    Install-Module AzureRM -AllowClobber
    
  7. nodejs.org/download/release/v6.12.3下载 Node.js 版本 6.x。你可以下载名为node-v6.12.3-x64.msi的文件,并使用交互式安装程序进行安装。

你的主机现在已准备好构建PartsUnlimited解决方案。

运行 Azure 管道

在这个任务中,我们将运行管道作业,使用我们自己的自托管代理构建PartsUnlimited解决方案:

  1. 登录到Azure DevOps门户并浏览到PartsUnlimited项目。

  2. 浏览到Pipelines图 6.18 – Azure Pipelines

    图 6.18 – Azure Pipelines

  3. 打开名为PartsUnlimitedE2E的预创建管道。

  4. 点击编辑管道

  5. 在管道中,将代理池更改为您新创建的代理池:图 6.19 – 为管道选择代理池

    图 6.19 – 为管道选择代理池

  6. 保存管道。您还可以选择在保存后运行它,方法是选择保存并排队图 6.20 – 保存管道

    图 6.20 – 保存管道

  7. 现在,我们准备好执行管道。点击运行管道图 6.21 – 运行管道

    图 6.21 – 运行管道

  8. 代理池下,将池名称更改为您在前一部分配置的代理池名称,然后点击运行图 6.22 – 运行管道向导

    图 6.22 – 运行管道向导

  9. 这将开始在您的自托管代理上执行管道作业。完成此操作可能需要几分钟:图 6.23 – Azure 管道作业日志

    图 6.23 – Azure 管道作业日志

  10. 您可以点击作业名称以实时查看日志。

您现在已经完成了 Azure 管道的设置,该管道使用基于 VM 的自托管管道代理来运行作业。

使用容器作为自托管代理

Azure Pipelines 支持使用 Docker 容器作为运行管道作业的计算目标。您可以使用 Windows 容器(Windows Server Core/Nano Server)和 Linux 容器(Ubuntu)来托管您的代理。

为了将容器连接到您的 Azure DevOps 组织,您需要传递一些环境变量,例如代理池名称、个人访问令牌等。

设置 Windows 容器作为 Azure 管道代理

为了将 Windows 容器作为 Azure 管道代理使用,您需要先构建容器镜像,然后用 Azure DevOps 组织的环境变量运行它。让我们看看这个过程。

构建容器镜像

按照以下步骤构建容器镜像:

  1. 启动命令提示符并运行以下命令:

    mkdir C:\dockeragent
    cd C:\dockeragent
    
  2. 创建一个名为Dockerfile(无扩展名)的新文件,并用以下内容更新它。您可以使用记事本打开该文件:

    FROM mcr.microsoft.com/windows/servercore:ltsc2019
    WORKDIR /azp
    COPY start.ps1 .
    CMD powershell .\start.ps1
    
  3. 创建一个新的 PowerShell 文件,命名为start.ps1,并从此处复制内容:github.com/PacktPublishing/Learning-Azure-DevOps---B16392/blob/master/Chapter-6/start.ps1

  4. 运行以下命令以构建容器镜像:

    docker build -t dockeragent:latest.
    

您的容器镜像现在已准备好使用。您可以使用dockeragent作为镜像名称来引用此镜像。可选地,您也可以将此镜像保存在您的容器仓库中。

运行 Azure Pipelines 代理容器

现在,您已经准备好容器镜像,您可以通过运行该容器将其用作管道代理。

启动命令提示符窗口并运行以下命令。请确保更新 Azure DevOps 组织 URL、令牌和代理名称:

docker run -e AZP_URL=<Azure DevOps instance> -e AZP_TOKEN=<PAT token> -e AZP_AGENT_NAME=mydockeragent dockeragent:latest

现在,你的基于容器的 Azure 管道代理已经准备好使用。如果你希望每次只为一个作业使用容器并在作业执行完毕后重新创建容器,你可以使用 –-once 标志,使用一个容器运行一个作业,并使用容器编排工具(如 Kubernetes)在当前作业执行完毕后重新创建容器。

重要提示

请参考 Microsoft 文档 – docs.microsoft.com/en-us/virtualization/windowscontainers/about/ – 了解有关 Windows 容器的更多细节。

在接下来的部分中,我们将介绍如何将基于 Linux 的容器设置为 Azure Pipelines 代理。

设置 Linux 容器作为 Azure Pipelines 代理

为了将 Linux 容器用作 Azure 管道代理,你可以选择使用 Microsoft 在 Docker Hub 上发布的 Docker 镜像,或者自行构建 Docker 镜像。

Microsoft 的 Azure 管道代理镜像可以在此找到: hub.docker.com/_/microsoft-azure-pipelines-vsts-agent。你可以直接运行此镜像,并通过环境变量传入 Azure DevOps 组织的相关信息:

docker run \
  -e VSTS_ACCOUNT=<name> \
  -e VSTS_TOKEN=<pat> \
  -it mcr.microsoft.com/azure-pipelines/vsts-agent

或者,你也可以选择构建自己的 Docker 镜像来作为你的管道代理使用。该过程类似于为 Windows 容器构建镜像。请参考 Microsoft 文档:docs.microsoft.com/en-us/azure/devops/pipelines/agents/docker?view=azure-devops – 获取有关入口点脚本的参考。

使用 Azure 容器实例作为代理

Azure 容器实例 (ACI) 是一种托管服务,可以在 Azure 云中运行 Windows 和 Linux 容器。如果标准的 Microsoft 托管代理不符合你的需求(如要求、性能等),而且你没有足够的基础设施来在本地托管容器,你可以使用 ACI 来为 Azure DevOps 创建自托管代理。

你可以通过使用自定义镜像或重用 Microsoft 提供的镜像之一,在 ACI 上创建构建代理。

要在 ACI 上运行 Azure 管道代理,你需要 Azure DevOps 账户名、个人访问令牌和代理名称。获取所需的详细信息后,你可以通过在 Azure CLI 中执行以下命令来创建 ACI 上的代理(在连接到你的 Azure 订阅后):

az container create -g RESOURCE_GROUP_NAME -n CONTAINER_NAME --image mcr.microsoft.com/azure-pipelines/vsts-agent --cpu 1 --memory 7 --environment-variables VSTS_ACCOUNT=AZURE_DEVOPS_ACCOUNT_NAME VSTS_TOKEN=PERSONAL_ACCESS_TOKEN VSTS_AGENT=AGENT_NAME VSTS_POOL=Default

在这里,我们有以下内容:

  • RESOURCE_GROUP_NAME 是你希望在 Azure 中创建该资源的资源组名称。

  • CONTAINER_NAME 是 ACI 容器的名称。

  • AZURE_DEVOPS_ACCOUNT_NAME 是你的 Azure DevOps 账户名。

  • PERSONAL_ACCESS_TOKEN 是之前创建的个人访问令牌。

  • AGENT_NAME 是你希望创建的构建代理名称,并将在 Azure DevOps 中显示。

在此命令中,还有其他两个重要参数:

请记住,你可以使用 az container stopaz container start 命令来启动和停止 ACI 实例,这可以帮助你节省成本。

让我们来看看你可以与 Azure 管道代理容器一起使用的一些额外环境变量。

环境变量

运行在容器上的 Azure DevOps 管道代理可以通过使用额外的环境变量进一步自定义。环境变量及其目的如下所述:

  • AZP_URL:Azure DevOps 组织的 URL

  • AZP_TOKEN:个人访问令牌

  • AZP_AGENT_NAME:你的 Azure 管道代理名称

  • AZP_POOL:代理池名称(默认值为 Default

  • AZP_WORK:工作目录(默认值为 _work

在这一部分,我们了解了如何使用容器作为 Azure 管道代理来执行管道作业。

规划扩展 – Azure 虚拟机规模集作为 Azure 管道代理

Azure 虚拟机规模集是 Azure 服务,允许你创建和管理数百个相同的虚拟机,具备自动或手动扩展虚拟机数量的能力。Azure 虚拟机规模集可以作为 Azure 管道代理,适用于大规模项目,在这些项目中,你需要根据 Azure 管道作业执行负载的需求来动态扩展容量。

Azure 虚拟机规模集最多支持 1,000 个虚拟机。

规划扩展

基于 Azure 虚拟机规模集的代理可以根据 Azure Pipelines 作业需求自动扩展。规模集代理相比专用代理有几个优势:

  • 你在某个时刻需要更多的计算能力(CPU 和内存),而且这一需求会根据工作负载波动。

  • Microsoft 托管的代理无法满足你的管道需求。

  • 你的作业运行时间较长或需要较长时间才能完成。

  • 你希望连续使用相同的代理来执行多个作业,以便利用缓存等功能。

  • 你不想一直运行专用代理,因为这样会产生成本。

  • 你希望定期更新运行作业的虚拟机镜像。

Azure 虚拟机规模集可以根据 Azure Pipelines 当前的需求自动增加/减少可用的管道代理数量。这有助于节省成本,并支持你的扩展需求。

创建 Azure 虚拟机规模集

在本节中,我们将创建一个 Azure VM 扩展集,用作 Azure Pipeline 代理。请注意,Azure Pipelines 要求以特定配置创建扩展集,因此您可能无法使用现有的扩展集:

  1. 登录 Azure 门户并点击+ 创建资源

  2. 搜索 虚拟机扩展集图 6.24 – Azure 门户中的 VM 扩展集

    图 6.24 – Azure 门户中的 VM 扩展集

  3. 点击创建

  4. 按照此处描述的方式填写值:

    --订阅:选择您希望部署此扩展集的订阅。

    --资源组:选择现有的资源组或创建一个新组。

    --虚拟机扩展集名称:您选择的标识符。

    --区域:选择您选择的 Azure 区域;建议选择离您最近的区域。

    --可用性区域:建议选择所有三个区域以实现高可用性。

    --镜像:为 Azure Pipelines 代理选择一个支持的 Windows 或 Linux 镜像。

    --Azure Spot 实例:可以帮助降低成本。详情请参阅azure.microsoft.com/en-us/pricing/spot/

    --大小:为您的代理选择虚拟机大小。

    --身份验证:用户名/密码或 SSH 密钥:

    图 6.25 – 创建 VM 扩展集

    图 6.25 – 创建 VM 扩展集

  5. 点击下一步:磁盘 >

  6. 您可以自定义磁盘性能层和加密设置,并在需要时添加额外的磁盘。如果不确定,接受默认设置并点击下一步

  7. 在网络页面上,如果您的扩展集需要访问任何网络资源并确保安全连接,您可以选择将扩展集连接到现有的虚拟网络。请确保使用负载均衡器设置为,以用于 Azure Pipelines 扩展集。配置完成后,点击下一步图 6.26 – Azure VM 扩展集负载均衡设置

    图 6.26 – Azure VM 扩展集负载均衡设置

  8. 扩展部分,提供初始实例数量,并将扩展策略设置为手动。将其他设置保持为默认,点击下一步图 6.27 – 扩展集设置

    图 6.27 – 扩展集设置

  9. 管理部分,确保升级模式设置为手动。将其他设置保持为默认,点击下一步图 6.28 – 扩展集升级策略

    图 6.28 – 扩展集升级策略

  10. 健康和高级设置页面上,您可以选择更改任何希望自定义的环境设置。准备好创建扩展集时,点击审核并创建

  11. 验证成功后,点击创建以开始部署。

部署完成可能需要几分钟的时间。请耐心等待部署完成。虚拟机扩展集准备好后,我们将设置它作为 Azure Pipelines 代理使用。

使用虚拟机规模集设置 Azure 管道代理

在上一节中,我们创建了一个虚拟机规模集。现在,我们将其设置为 Azure 管道代理:

  1. 登录到你的 Azure DevOps 组织,进入 项目设置 > 代理池

  2. 点击 添加池

  3. 按照这里定义的值填写:

    --池类型:虚拟机规模集

    --服务连接的项目:选择你的 Azure DevOps 项目

    --Azure 订阅:选择你创建虚拟机规模集的 Azure 订阅:

    图 6.29 – 为规模集添加代理池

    ](https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/az-dop-expl/img/Figure_6.29_B16392.jpg)

    图 6.29 – 为规模集添加代理池

  4. 点击 授权,以启用对你 Azure 订阅的访问权限。你可能会被要求在此过程中登录到 Azure 帐户。

  5. 验证身份后,选择一个现有的虚拟机规模集,并按照这里描述的值填写:

    --你选择的代理池的名称和描述。

    --可选地,配置规模集在每次执行后删除虚拟机。

    --虚拟机的最大数量。

    --保留备用的代理数量。虽然这有助于更快地完成任务,但可能会增加你的 Azure 成本。

  6. 填写完所有值后,点击 创建:![图 6.30 – 创建基于规模集的代理池]

    ](https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/az-dop-expl/img/Figure_6.29_B16392.jpg)

    图 6.30 – 创建基于规模集的代理池

  7. 现在,代理池的创建将开始。请注意,代理池准备好接收任务可能需要大约 15 分钟。在完成时,你应该能看到代理池中的代理处于活动状态:

图 6.31 – 代理

](https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/az-dop-expl/img/Figure_6.31_B16392.jpg)

图 6.31 – 代理

一旦代理池准备就绪,你可以更新你的 Azure 管道,开始使用这个池来执行任务。

总结

在本章中,我们讨论了如何使用微软托管的代理和自托管代理来运行你的 Azure 管道任务。我们深入了解了设置自托管代理的过程,并更新了管道以使用自托管代理。

我们还讨论了如何使用 Docker 容器、Azure 容器实例和 Azure 虚拟机规模集作为你的 Azure 管道代理。通过本章内容,你应该能够为你的项目规划并实现适当的管道代理解决方案。

在下一章中,我们将学习 Azure DevOps 中的工件(Artifacts)。

第三部分:工件与部署

在本节中,我们将介绍如何在 Azure DevOps 中使用工件以及如何通过管道部署应用程序。

本节包含以下章节:

  • 第七章在 Azure DevOps 中使用工件

  • 第八章使用 Azure DevOps 部署应用程序

第七章:

第八章:在 Azure DevOps 中使用 Artifacts

在上一章中,我们讲解了如何在 Azure Pipelines 中托管构建代理。在本章中,我们将讲解如何在 Azure DevOps 中使用 Artifacts。我们将从解释什么是 Artifacts 开始。然后,我们将看看如何在 Azure DevOps 中创建它们,以及如何从构建管道中生成工件包。接下来,我们将讲解如何使用发布管道部署供稿。然后,我们将讲解如何设置供稿权限,以及如何在 Visual Studio 中消费包。最后,我们将讲解如何使用 WhiteSource Bolt 扫描包漏洞。

本章将涵盖以下主题:

  • 介绍 Azure Artifacts

  • 使用 Azure Artifacts 创建工件供稿

  • 使用构建管道生成包

  • 从构建管道将包发布到供稿中

  • 从供稿设置中配置供稿权限

  • 从 Artifacts 供稿中在 Visual Studio 中消费包

  • 使用 WhiteSource Bolt 扫描包漏洞

技术要求

要跟随本章内容,你需要有一个活跃的 Azure DevOps 组织。我们将在本章中使用的组织是PartsUnlimited组织,具体内容在第一章**,Azure DevOps 概述中创建。你还需要安装 Visual Studio 2019,可以从visualstudio.microsoft.com/downloads/下载。

我们示例应用程序的源代码可以从github.com/PacktPublishing/Learning-Azure-DevOps---B16392/tree/master/Chapter%207下载。

介绍 Azure Artifacts

每个开发者很可能都在代码中使用过第三方或开源包,以增加额外的功能并加快应用程序开发过程。使用社区已使用并测试过的流行的预构建组件,将帮助你更轻松地完成工作。

在你的组织中,由不同团队构建的功能、脚本和代码经常被其他团队和不同的软件开发项目重用。这些不同的工件可以被移动到一个库或包中,以便其他人也能从中受益。

有多种方式可以构建和托管这些包。例如,你可以使用 NuGet 托管和管理 Microsoft 开发平台的包,或使用 npm 托管 JavaScript 包,Maven 托管 Java 包等等。Azure Artifacts 提供了便捷的功能,使你可以轻松地共享和重用包。在 Azure Artifacts 中,包被存储在供稿中。供稿是一个容器,允许你将包进行分组,并控制谁可以访问它们。

你可以将包存储在你自己或其他团队创建的源中,但它也内置支持上游源。通过上游源,你可以创建一个单一源,用于存储组织生产的包以及从远程源消费的包,如 NuGet、npm、Maven、Chocolatey、RubyGems 等。

强烈建议将 Azure Artifacts 用作发布内部包和远程源的主要来源。原因在于,它能够让你全面了解组织和不同团队使用的所有包。源能够知道所有使用上游资源保存的包的来源,即使原始源宕机或包被删除,包也会被保存在源中。包是有版本管理的,通常你可以通过指定你想在应用程序中使用的包版本来引用一个包。

许多包允许无需登录即可访问。然而,也有一些包需要我们通过用户名和密码组合或访问令牌进行身份验证。对于后者,访问令牌可以设置为在指定的时间后过期。

在下一部分,我们将讨论如何在 Azure DevOps 中创建一个工件源

使用 Azure Artifacts 创建工件源

在这个演示中,我们将创建一个 Azure Artifacts 中的工件源。包存储在源中,这些源本质上是组织结构,用于将包分组并管理其权限。每种包类型(NuGet、npm、Maven、Python 和 Universal)都可以存储在一个源中。

在本次演示中,我们将再次使用我们的PartsUnlimited示例项目,并向项目中添加一个新的工件源。为此,请执行以下步骤:

  1. 打开一个浏览器并导航到 dev.azure.com/

  2. 使用你的 Microsoft 帐户登录,并从左侧菜单选择Artifacts。然后,点击+ 创建源按钮。

  3. 创建新源对话框中,添加以下值(确保上游源被禁用;我们在本章中不会使用远程源中的包):图 7.1 – 创建一个新源

    图 7.1 – 创建一个新源

  4. 点击创建按钮。

通过以上操作,我们已经创建了一个新的源,以便我们可以存储我们的包。在下一部分,我们将通过构建管道生成一个包。

通过构建管道生成包

现在我们已经创建了我们的源,接下来我们将创建一个构建流水线,在项目构建过程中自动创建一个包。在本例中,你可以使用本书 GitHub 代码库中提供的示例项目。这个示例项目包含了PartsUnlimited项目中的所有模型。我们将把所有模型添加到一个包中,并通过 Artifacts 进行分发。这样,你就可以在不同的项目之间轻松共享数据模型。

第一步是将 GitHub 代码库导入到 Azure DevOps 中的PartsUnlimited组织。

将示例项目添加到 PartsUnlimited 代码库

要将示例模型项目添加到 PartsUnlimited 代码库中,请执行以下步骤:

  1. 导航到 Azure DevOps 中的PartsUnlimited项目,并转到Repos > Files

  2. PartsUnlimited下拉菜单中选择导入代码库图 7.2 – 导入代码库

    图 7.2 – 导入代码库

  3. 将源代码库的 URL 输入到Clone URL框中,并为你的新 GitHub 代码库添加一个名称:图 7.3 – 指定代码库的 URL

    图 7.3 – 指定代码库的 URL

  4. 点击导入

  5. 一旦项目被导入,代码库将如下所示:图 7.4 – Azure DevOps 中的代码库

图 7.4 – Azure DevOps 中的代码库

现在我们已经将PartsUnlimited.Models项目导入到 Azure DevOps 代码库中,可以在构建流水线中使用它来创建 NuGet 包。

在接下来的部分中,我们将创建一个构建流水线,自动将我们的项目打包成一个 Artifact 包。

创建构建流水线

现在项目已经添加到代码库中,我们可以创建构建流水线。为此,请执行以下步骤:

  1. 再次导航到 Azure DevOps 并打开PartsUnlimited.Models项目。从左侧菜单中点击Pipelines

  2. 从右上角菜单中点击新建流水线,然后在向导的第一个屏幕中选择使用经典编辑器

  3. 在第二个屏幕上,设置如下截图所示的属性,然后点击继续图 7.5 – 选择源

    图 7.5 – 选择源

  4. 在向导的下一个屏幕中选择ASP.NET,然后点击应用。这样,构建流水线就会被创建。点击Agent job 1右侧的+号,并搜索NuGet

  5. 将 NuGet 任务添加到流水线:图 7.6 – 添加 NuGet 任务

    图 7.6 – 添加 NuGet 任务

  6. 重新排列任务,并将 NuGet 任务拖动到Build Solution任务之后。删除Test Assemblies方法,因为该项目中没有测试:图 7.7 – 重新排序任务

    图 7.7 – 重新排序任务

  7. 对新添加的任务的设置进行以下更改:

    --NuGet pack

    --pack

    --**/*.csproj

  8. 完成这些更改后,任务将如下所示:图 7.8 – 配置任务

    图 7.8 – 配置任务

  9. 接下来,让我们设置包的版本控制。推荐的包版本控制方法是使用 1

    --0

    --0

    --时区UTC

  10. 从顶部菜单中选择Save & queue,然后选择Save and run

构建管道现在将成功运行。在下一部分,我们将把在第一个演示中创建的PartsUnlimited.Models NuGet 包发布到我们的 feed。

从构建管道将包发布到 feed

现在我们已经构建了应用程序和包,并从构建管道中生成了包,我们可以将该包发布到我们在第一个演示中创建的 feed。

为此,我们需要在 feed 上设置所需的权限。构建将以其身份运行,该身份需要在 feed 上具有Contributor权限。一旦设置了这些权限,我们就可以扩展我们的管道,将包推送到 feed。

设置 feed 上的所需权限

要设置所需的权限,我们需要进入 feed 的设置:

  1. 使用您的 Microsoft 帐户登录,并从左侧菜单中选择Artifacts

  2. 转到 feed 的设置,通过点击右上角菜单中的Settings按钮:图 7.9 – 打开 feed 设置

    图 7.9 – 打开 feed 设置

  3. 然后,从顶部菜单中点击Permissions,点击+ Add users/groups图 7.10 – Feed 权限设置

    图 7.10 – Feed 权限设置

  4. 添加与项目同名的构建,在我的例子中是Parts.Unlimited Build Service身份:图 7.11 – 添加构建身份

    图 7.11 – 添加构建身份

  5. 点击Save

现在,构建管道的身份已在 feed 上拥有所需的权限,我们可以在构建过程中将包推送到该 feed。

发布包

我们现在准备扩展构建管道,并将包从构建管道推送到 feed。为此,我们需要执行以下步骤:

  1. 导航到 Azure DevOps,打开PartsUnlimited.Models项目。在左侧菜单中点击Pipelines

  2. 选择我们在上一步中创建的构建管道,然后点击右上角菜单中的Edit按钮。

  3. 再次点击Agent job 1旁边的+按钮,搜索 NuGet,并将任务添加到管道中。

  4. 将新添加的任务拖到我们在上一步中创建的 NuGet 任务下方。对任务的设置进行以下更改:

    --NuGet push

    --$(Build.ArtifactStagingDirectory)/**/*.nupkg;!$(Build.ArtifactStagingDirectory)/**/*.symbols.nupkg

    --目标 feed 位置此组织/集合

    --目标源PacktLearnDevOps

  5. 在进行这些更改后,任务将如下所示:图 7.12 – 添加 NuGet 推送任务

    图 7.12 – 添加 NuGet 推送任务

  6. 从顶部菜单选择保存并排队,然后选择保存并运行。等待构建管道成功完成。

  7. 最后,让我们检查一下包是否成功发布。点击左侧菜单中的Artifacts。你会看到包已成功推送到源中:

图 7.13 – 推送的包

图 7.13 – 推送的包

现在我们有了一个带有模型的包,我们可以在 Visual 项目中使用它。在接下来的部分,我们将创建一个应用程序并从 Azure DevOps 的源中消费该包。

从 Artifacts 源中消费包

现在,我们的PartsUnlimited.Models包已经推送到 Artifacts 中的源,我们可以从 Visual Studio 中消费这个包。在这一部分,我们将创建一个新的控制台应用程序,并从那里连接到源。

因此,我们需要执行以下步骤:

  1. 打开 Visual Studio 2019 并创建一个新的 .NET Core 控制台应用程序:图 7.14 – 创建新的控制台包

    图 7.14 – 创建新的控制台包

  2. 应用程序创建完成后,导航到 Azure DevOps,从左侧菜单选择Artifacts

  3. 从顶部菜单选择连接到源图 7.15 – 连接到源

    图 7.15 – 连接到源

  4. 在下一个屏幕中,从列表中选择Visual Studio。我们将使用这些设置在下一步中设置机器:图 7.16 – Visual Studio 机器设置

    图 7.16 – Visual Studio 机器设置

  5. 返回到 Visual Studio 中的控制台应用程序。然后,从顶部菜单选择工具 > NuGet 包管理器 > 管理解决方案的 NuGet 包图 7.17 – NuGet 包安装器

    图 7.17 – NuGet 包安装器

  6. 要将源添加到项目中,点击设置图标:图 7.18 – NuGet 设置

    图 7.18 – NuGet 设置

  7. 点击https://pkgs.dev.azure.com/PacktLearnDevOps/_packaging/PacktLearnDevOps/nuget/v3/index.json

    添加这些值后的结果如下所示:

    图 7.19 – 添加源的包源

    图 7.19 – 添加源的包源

  8. 点击更新,然后点击确定

  9. 现在,我们可以在应用程序中消费这个源。在 NuGet 包管理器中,选择我们刚刚添加的包源。确保勾选包括预发布版本,因为这个包尚未发布:图 7.20 – 选择包源

    图 7.20 – 选择包源

  10. 选择包并将其安装到项目中。

  11. 现在,我们可以在代码中引用该包并使用模型类。添加 using 语句,并通过以下代码替换 Program.cs 文件中的代码,创建一个新的 CarItem

    using System;
    using PartsUnlimited.Models;
    namespace AzureArtifacts
    {
        class Program
        {
            static void Main(string[] args)
            {
                Console.WriteLine("Hello World!");
                CartItem caritem = new CartItem()
                {
                    CartId = "1",
                    Count = 10,
                    DateCreated = DateTime.Now,
                    Product = new Product()
                    {
                        Title = "Product1"
                    },
                    ProductId = 21
                };
            }
        }
    }
    

在这个演示中,我们使用的是从 feed 自动构建和发布的包。在本章的下一部分也是最后一部分中,我们将探讨如何使用 WhiteSource Bolt 扫描包中的漏洞。

使用 WhiteSource Bolt 扫描包中的漏洞

WhiteSource Bolt 可直接从构建管道扫描包中的漏洞。它是一个开发者工具,用于扫描应用代码以及开源应用和包中的安全漏洞。它提供了可以通过 Azure DevOps 市场和 GitHub 安装的扩展。WhiteSource Bolt 可以免费下载,但此版本每天每个仓库的扫描次数限制为五次。

重要提示

关于 WhiteSource Bolt 的更多信息,您可以参考以下网站:bolt.whitesourcesoftware.com/

在本节中,我们将安装扩展到我们的 Azure DevOps 项目中,并将其自带的任务实施到现有的构建管道中。让我们开始吧:

  1. 打开浏览器并访问 marketplace.visualstudio.com/

  2. 在搜索框中搜索 WhiteSource Bolt 并选择 WhiteSource Bolt 扩展:图 7.21 – 安装 WhiteSource Bolt

    图 7.21 – 安装 WhiteSource Bolt

  3. 通过选择组织并点击 安装 按钮,在您的 DevOps 组织中安装扩展:图 7.22 – 在您的组织中安装扩展

    图 7.22 – 在您的组织中安装扩展

  4. 安装包后,返回到 Azure DevOps > Pipelines。您将看到 WhiteSource Bolt 已添加到菜单中。选择它:图 7.23 – WhiteSource Bolt 菜单项

    图 7.23 – WhiteSource Bolt 菜单项

  5. 设置 页面上,指定工作邮箱地址、公司名称和国家/地区。然后,点击 开始使用 按钮:图 7.24 – WhiteSource Bolt 设置

    图 7.24 – WhiteSource Bolt 设置

  6. 我们现在可以在管道中使用 WhiteSource Bolt 任务了。选择我们在 创建构建管道 部分中创建的构建管道。现在,编辑管道。

  7. 再次向管道中添加一个新任务,就像我们在 创建构建管道 部分中所做的那样,搜索 WhiteSource Bolt,并将该任务添加到管道中:图 7.25 – 添加 WhiteSource Bolt 任务

    图 7.25 – 添加 WhiteSource Bolt 任务

  8. 将任务拖动到构建解决方案任务的下方,因为我们希望在将包打包并推送到 Artifact feed 之前扫描解决方案。效果如下图所示:Figure 7.26 – 构建管道概述

    Figure 7.26 – 构建管道概述

  9. 您不必指定任何配置值;此任务将在没有它们的情况下运行。

  10. 从顶部菜单中,选择保存并排队,然后选择保存并运行。等到构建管道成功完成。

  11. 再次转到顶部菜单,选择WhiteSource Bolt Build Support。在那里,您将看到扫描的概述:Figure 7.27 – WhiteSource Bolt 漏洞报告

Figure 7.27 – WhiteSource Bolt 漏洞报告

通过此操作,我们已安装了 WhiteSource Bolt 扩展,并在将 NuGet 包打包并推送到 Azure Artifacts 的 feed 之前扫描了我们的解决方案中的漏洞。

这章就到这里了。

总结

在本章中,我们更深入地了解了 Azure Artifacts。首先,我们设置了一个 feed,并使用PartsUnlimited项目中的模型类创建了一个新的 NuGet 包。然后,我们创建了一个构建管道,在构建过程中自动打包并将包推送到 feed 中。最后,我们使用 Azure 市场上的 WhiteSource Bolt 扩展来扫描包中的漏洞。

在下一章中,我们将重点介绍如何使用发布管道在 Azure DevOps 中部署应用程序。

进一步阅读

查看以下链接以获取本章涵盖的更多信息:

第八章:

第九章:使用 Azure DevOps 部署应用程序

在前几章中,我们看到如何通过使用构建流水线自动化代码的开发过程。但软件生命周期中一个重要的部分是发布阶段。在本章中,我们将介绍发布流水线的概述;我们将学习如何使用 Azure DevOps 创建发布流水线,以及如何通过使用发布审批和多阶段流水线自动化和改进解决方案的部署。

本章将涵盖以下内容:

  • 发布流水线概述

  • 使用 Azure DevOps 创建发布流水线

  • 在发布流水线上配置持续部署

  • 创建多阶段发布流水线

  • 使用审批和门控控制你的发布过程

  • 使用环境和部署组

  • 使用基于 YAML 的流水线进行发布

技术要求

要跟随本章内容,你需要有一个有效的 Azure DevOps 组织。本章中使用的组织是我们在第一章中创建的PartsUnlimited组织,Azure DevOps 概述

发布流水线概述

发布流水线允许你实现软件生命周期中的持续交付阶段。通过发布流水线,你可以自动化测试过程,并将你的解决方案(提交的代码)交付到最终环境或直接交付到客户现场(持续交付和持续部署)。

通过持续交付,你将代码交付到某个环境进行测试或质量控制,而持续部署则是将代码发布到最终生产环境的阶段。

发布流水线可以手动触发(你决定何时部署代码),也可以根据事件触发,如主分支上的代码提交、阶段完成后(例如,生产测试阶段),或根据计划触发。

发布流水线通常连接到工件存储(应用程序的可部署组件和构建的输出)。工件存储包含一组构建的工件(不同版本的工件),而发布流水线则取这些工件并提供所需的基础设施和步骤来部署这些工件。

发布流水线(正如我们在第四章中所看到的,理解 Azure DevOps 流水线,针对构建流水线定义)由不同的阶段(可以独立运行的流水线部分)组成,每个阶段由作业任务组成。

发布流水线的架构如下:

图 8.1 – 发布流水线架构

正如你在上面的图示中看到的,发布流水线从工件(成功完成构建的输出)开始,然后在各个阶段之间移动,执行作业和任务。

在 Azure DevOps 中,发布管道按以下步骤执行:

  1. 当触发部署请求时,Azure Pipelines 会检查是否需要预部署审批阶段,并最终将审批通知发送给团队中相关人员。

  2. 经批准后,部署作业会排队并等待代理程序。

  3. 能够运行此部署作业的代理程序将获取该作业。

  4. 代理程序会下载发布管道定义中指定的工件。

  5. 代理程序运行部署作业中定义的任务,并为每个步骤创建日志。

  6. 当某个阶段的部署完成后,Azure Pipelines 会执行后部署审批(如果有的话)。

  7. 然后部署进入下一个阶段。

在发布管道中,工件被部署到环境(你的最终应用将运行的地方),这些环境可以是以下几种:

  • 你公司网络上的一台机器

  • 云中的一台虚拟机

  • 一个容器化环境,例如 Docker 或 Kubernetes

  • 一种托管服务,例如 Azure 应用服务

  • 无服务器环境,例如 Azure Functions

定义 Azure Pipelines 环境的一种方式是使用 YAML 文件,你可以在其中包含一个环境部分,指定你将部署工件的 Azure Pipelines 环境,或者使用经典的基于 UI 的编辑器

在接下来的部分,我们将详细了解如何使用 Azure DevOps UI 定义发布管道。

使用 Azure DevOps 创建发布管道

实现完整 CI/CD 流程的最终目标是自动化将软件部署到最终环境(例如,最终客户),为了实现这一目标,你需要创建一个发布管道

发布管道将构建产物(构建过程的结果)部署到一个或多个最终环境。

要创建我们的第一个发布管道,我们将使用之前在 Azure DevOps 上部署的PartsUnlimited Web 应用项目:

  1. 要在 Azure DevOps 中创建发布管道,请点击左侧菜单中的管道,选择发布,然后点击新建发布管道:图 8.2 – 创建新发布管道

    图 8.2 – 创建新发布管道

  2. 在右侧出现的选择模板列表中,你可以看到一组可用模板,用于创建适用于不同类型应用和平台的发布。对于我们的应用,选择Azure 应用服务部署,然后点击应用:图 8.3 – 发布管道模板选择

    图 8.3 – 发布管道模板选择

  3. 现在,为将包含发布任务的阶段提供一个名称。在这里,我将其命名为 Deploy to cloud:图 8.4 – 阶段名称

    图 8.4 – 阶段名称

  4. 阶段部分,点击1 个任务,1 个工作链接。在这里,你需要提供你的应用程序将要部署的 Azure Web 应用环境的设置,例如 Azure 订阅和应用服务实例(Web 应用),其中代码将被部署:

图 8.5 – 阶段设置

图 8.5 – 阶段设置

你现在已经定义了发布管道的阶段(单阶段)。在下一部分,我们将看到如何为发布管道指定工件。

定义发布管道的工件

工件是所有必须部署到最终环境中的项目(构建的输出),Azure Pipelines 可以部署来自不同工件源的工件:

  1. 要选择工件,在主发布管道屏幕上,点击添加工件图 8.6 – 向发布管道添加工件

    图 8.6 – 向发布管道添加工件

  2. 添加工件面板中,源类型默认设置为构建(这意味着你正在部署构建管道的输出)。在这里,你需要选择你想作为源的构建管道(发布工件的构建管道的名称或 ID;这里我使用的是PartsUnlimitedE2E构建管道)和默认版本(默认版本将在创建新发布时部署。对于手动创建的发布,版本可以在发布创建时更改):图 8.7 – 添加工件

    图 8.7 – 添加工件

  3. 点击添加按钮保存工件配置,然后点击右上角的保存按钮保存你的发布管道:

图 8.8 – 保存发布管道

图 8.8 – 保存发布管道

你的发布管道现在已经准备就绪。在下一部分,我们将看到如何创建 Azure DevOps 发布过程。

创建 Azure DevOps 发布

在定义了发布管道(阶段和工件)之后,我们需要创建一个发布。发布只是运行你的发布管道的一次执行:

  1. 要创建发布,在发布管道定义页面,点击右上角的创建发布按钮:图 8.9 – 创建发布

    图 8.9 – 创建发布

  2. 创建新发布页面,接受所有默认值(你需要有一个成功完成的构建,且已创建工件),然后点击创建图 8.10 – 创建发布

    图 8.10 – 创建发布

  3. 一个新的发布已创建,你会看到一个绿色的进度条,表示:图 8.11 – 发布已创建

    图 8.11 – 发布已创建

  4. 现在,你可以点击发布名称(这里是Release-1),你将被重定向到发布过程的详细信息:图 8.12 – 发布详情

    图 8.12 – 发布详情

  5. 如果你点击阶段,你可以看到每个步骤的详细信息:

图 8.13 – 阶段详细信息

图 8.13 – 阶段详细信息

你已经完成了第一个发布管道。在这里,我们手动触发了它。在下一部分,我们将看到如何在管道中使用变量。

在发布管道中使用变量

在发布管道中,你还可以使用变量和变量组来指定可以在管道任务中使用的变量参数。要为发布管道指定变量,选择变量选项卡并指定变量的名称和值:

图 8.14 – 发布管道变量

图 8.14 – 发布管道变量

然后,你可以通过使用$(VariableName)符号在管道任务中使用这些变量,如下图所示:

图 8.15 – 在发布管道任务中使用变量

图 8.15 – 在发布管道任务中使用变量

如果你的管道中有会变化的参数,建议使用变量。在下一部分,我们将看到如何为持续部署配置触发器。

配置持续部署的发布管道触发器

为了自动化你的应用程序的持续部署,你需要在发布管道定义中配置触发器:

  1. 要做到这一点,点击管道工件部分的持续部署触发器图标:图 8.16 – 持续部署触发器

    图 8.16 – 持续部署触发器

  2. 持续部署触发器面板中,启用它以在每次成功完成构建后自动创建新版本,并选择一个分支过滤器(例如,构建管道的默认分支):图 8.17 – 持续部署触发器配置

    图 8.17 – 持续部署触发器配置

  3. 现在,在阶段部分,选择部署前条件图标:图 8.18 – 部署前条件

    图 8.18 – 部署前条件

  4. 部署前条件面板中,检查此阶段的触发器是否设置为发布后(这意味着当从此管道创建新发布时,部署阶段将自动开始):

图 8.19 – 部署前条件定义

图 8.19 – 部署前条件定义

在此面板中,你还可以定义其他参数,例如选择触发新部署的工件条件(仅当所有工件条件匹配时,才会将发布部署到此阶段)、设置部署的时间表、允许基于拉取请求的发布部署到此阶段、选择可以批准或拒绝部署到此阶段的用户(预部署审批)、定义部署前需要评估的门控,并定义在多个发布排队等待部署时的行为。

你现在已经创建了一个发布管道,它将你的工件通过 Azure DevOps 部署到云,并应用了持续部署触发器和预部署条件检查。

在下一节中,我们将看到如何通过使用多个阶段来改进我们的发布管道。

创建一个多阶段发布管道

多阶段发布管道在你想通过多个步骤(例如开发、预发布和生产)发布应用程序时非常有用。一个非常常见的实际场景是,例如,首先将应用程序部署到测试环境。当测试完成后,应用程序会移动到质量验收阶段,然后如果客户接受发布,应用程序会移动到生产环境。

在这里,我们将做相同的事情:从之前创建的单阶段管道开始,我们将创建一个新的发布管道,包含三个阶段,分别为DEVQAProduction。每个阶段都是我们管道的部署目标:

  1. 在之前定义的管道中,作为第一步,我将部署到云阶段重命名为Production。这将是发布管道的最终阶段。

  2. 现在,点击克隆操作,将已定义的阶段克隆为一个新阶段:图 8.20 – 克隆一个阶段

    ](https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/az-dop-expl/img/Figure_8.20_B16392.jpg)

    图 8.20 – 克隆一个阶段

  3. 一个新的克隆阶段出现在之前创建的阶段后面。将此阶段的名称更改为QA图 8.21 – 克隆的阶段(QA)

    ](https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/az-dop-expl/img/Figure_8.21_B16392.jpg)

    图 8.21 – 克隆的阶段(QA)

  4. 现在,我们需要重新组织阶段,因为QA阶段必须在Production阶段之前执行。要重新组织这些阶段,请选择QA阶段并选择预部署条件。在预部署条件面板中,将触发器设置为After release(而不是After stage):图 8.22 – QA 阶段的预部署条件

    ](https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/az-dop-expl/img/Figure_8.22_B16392.jpg)

    图 8.22 – QA 阶段的预部署条件

  5. 如你所见,管道图现在发生了变化(你现在有QAProduction阶段并行执行)。现在,选择Production阶段的预部署条件属性;将触发器设置为After stage,并选择QA作为阶段:图 8.23 – Production 阶段的预部署条件

    ](https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/az-dop-expl/img/Figure_8.23_B16392.jpg)

    图 8.23 – Production 阶段的预部署条件

  6. 现在,阶段已按我们想要的顺序排列(QA 发生在 Production 之前)。

  7. 此时,我们有两个阶段将应用部署到相同的环境(QA 是作为 Production 的克隆创建的)。从 Tasks 下拉列表中选择 QA 阶段,并将 App service name 更改为一个新实例:Figure 8.24 – QA 阶段详情

    图 8.24 – QA 阶段详情

  8. 现在,我们需要重复相同的步骤来创建 DEV 阶段。从 QA 克隆它,设置其 Pre-deployment conditions 属性,将触发器设置为 After Release,并将 QA 的触发器更改为 After stage,选择 DEV 作为所选阶段。你的流水线现在将如下所示:

Figure 8.25 – 定义的多阶段发布流水线

现在,你已经创建了一个包含不同阶段(DevQAProduction)的发布流水线,用于控制代码的部署步骤。

在下一部分,我们将看到如何在阶段之间移动时添加审批。

使用审批和门控来管理部署

如前所述配置,我们的发布流水线只有在前一个阶段成功完成后才会移动到下一个阶段。这对于从 DEVQA 的过渡是可以的,因为在这个过渡中,我们的应用程序被部署到测试环境,但从 QAProduction 的过渡通常应该受到控制,因为应用程序发布到生产环境通常发生在审批之后。

创建审批

让我们按照以下步骤创建审批:

  1. 要创建审批步骤,从我们的流水线定义中,选择 Production 阶段的 Pre-deployment conditions 属性。然后,进入 Pre-deployment approvals 部分并启用它。接着,在 Approvers 部分,选择将负责审批的用户。请同时检查 The user requesting a release or deployment should not approve it 选项未被勾选:Figure 8.26 – 设置审批

    图 8.26 – 设置审批

  2. 点击 Save 保存你的流水线定义。

  3. 现在,创建一个新的发布以启动我们的流水线,并点击已创建发布的名称(这里叫做 Release-2):Figure 8.27 – 多阶段发布触发

    图 8.27 – 多阶段发布触发

  4. 发布流水线启动。DEVQA 阶段已完成,而在 Production 阶段,出现 Pending approval 状态:Figure 8.28 – 待批准

    图 8.28 – 待批准

  5. 发布流水线正在等待审批。你可以点击 Pending approval 图标,打开审批对话框。在这里,你可以插入评论,然后批准或拒绝发布:Figure 8.29 – 批准阶段

    图 8.29 – 批准一个阶段

  6. 如果需要,你还可以将该阶段推迟到特定日期,或将批准任务重新分配给其他用户。

  7. 如果你点击批准,该阶段将被批准,发布管道完成:图 8.30 – 完成的多阶段管道

    图 8.30 – 完成的多阶段管道

  8. 如果你现在点击由管道部署的 Azure 应用服务实例,你可以看到最终的代码(PartsUnlimited 网站)已部署到云端:

  9. 图 8.31 – 从发布管道部署的 Web 应用程序

图 8.31 – 从发布管道部署的 Web 应用程序

使用网关检查条件

在之前讲解的场景中,我们了解了如何为发布管道配置手动批准过程。有时,你需要避免手动过程,而是设定一个策略,只有在某些检查成功执行后,管道才可以继续。这就是网关发挥作用的地方。

在 Azure Pipelines 中,网关允许你自动检查来自 Azure DevOps 或外部服务的特定条件,然后仅在满足这些条件时才启用发布过程。你可以使用网关来检查项目的工作项和问题状态,并仅在没有开放漏洞时启用发布。你还可以查询测试结果,检查在发布前是否执行了对构件的安全扫描,监控基础设施健康状况等。

作为示例,在这里我们希望为之前创建的发布管道配置一个网关,以便检查 Azure Boards 上的开放漏洞。我们将通过以下步骤来完成此操作:

重要提示

如果有开放漏洞,发布管道无法继续执行。

  1. 要检查我们项目中的开放漏洞,我们需要为工作项定义一个查询。从我们的 Azure DevOps 项目中,选择Boards,点击查询,然后选择新查询图 8.32 – 为网关条件创建新查询

    图 8.32 – 为网关条件创建新查询

  2. 在这里,我定义了如下查询:图 8.33 – 查询定义

    图 8.33 – 查询定义

    此查询检查我们项目中的活动漏洞。

  3. 通过为查询命名(例如,ActiveBugs)并指定一个文件夹(这里我选择了共享查询文件夹)来保存查询:图 8.34 – 保存查询定义

    图 8.34 – 保存查询定义

  4. 现在我们准备定义网关。从我们之前创建的多阶段发布管道中,选择生产阶段,点击螺栓图标,然后启用网关,如下截图所示:图 8.35 – 启用网关

    图 8.35 – 启用网关

    在这里,你还可以指定评估门控前的延迟(在添加的门控第一次被评估之前的时间。如果没有添加门控,则部署将在指定的持续时间后再继续),我们还可以指定部署门控(添加评估健康参数的门控)。这些门控会并行定期评估,如果门控成功,部署将继续;否则,部署将被拒绝。

  5. 要指定我们的门控,点击添加,然后选择查询工作项(这将执行一个工作项查询并检查结果):图 8.36 – 门控定义(查询工作项)

    图 8.36 – 门控定义(查询工作项)

  6. 现在,选择 0(查询中匹配的工作项的最大数量),因为我们希望发布管道仅在没有活动错误时才完成:

图 8.37 – 指定门控条件

图 8.37 – 指定门控条件

在这里,你还可以定义评估选项,如 0 表示当所有门控在同一评估周期内成功时,部署将继续;门控失败后的超时(门控的最大评估周期;如果门控在达到超时之前未成功,部署将被拒绝)。

我们的门控现在已经定义并启用了。你还可以定义其他类型的门控,甚至可以有调用 Azure Functions 来评估发布条件的门控(如果你想将发布检查与外部系统的特定条件集成,这会非常有用)。

使用部署组

部署组是一组每台机器上都安装了部署代理的机器。每个部署组代表一个物理环境,并定义了一个并行部署的目标机器逻辑组。

你可以在 Azure DevOps 中定义一个部署组,通过进入管道部分并选择部署组

图 8.38 – 创建部署组

图 8.38 – 创建部署组

在这里,你可以添加已安装构建和发布代理的服务器。

每个创建的部署组都是部署池的一部分,并且此池也可以跨项目共享。部署组只能用于发布管道。

你可以通过进入发布管道编辑器,选择作业,并点击三点按钮来添加部署组作业。在这里,你可以看到添加部署组作业选项:

图 8.39 – 添加部署组作业

图 8.39 – 添加部署组作业

在写作时,YAML 管道尚不支持部署组作业。

YAML 发布管道与 Azure DevOps

Azure DevOps 最近新增的一个功能是通过使用 YAML 定义发布流水线的选项(之前这仅限于 CI 部分)。现在,通过使用多阶段流水线,你可以使用统一的 YAML 体验来配置 Azure DevOps 流水线,涵盖 CI、CD 和 CI/CD。

定义发布 YAML 流水线可以按照第四章中描述的方式进行,理解 Azure DevOps 流水线。然而,有一些概念需要理解,例如环境

环境是流水线所针对的一组资源——例如,Azure Web Apps、虚拟机或 Kubernetes 集群。你可以使用环境来按范围对资源进行分组——例如,你可以创建一个名为development的环境,用于存放开发资源,创建一个名为production的环境,用于存放生产资源。可以通过进入Pipelines下的Environments部分来创建环境:

图 8.40 – 创建环境

图 8.40 – 创建环境

以下是一个多阶段发布流水线的示例,用于将.NET Core 应用程序部署到 Azure Web Apps:

stages:
	- stage: Build_Source_# Build Source Code for Dotnet Core Web App
	  jobs:
	  - job: Build
	    pool: 'Hosted VS2017'
	    variables:
	      buildConfiguration: 'Release' 
	    continueOnError: false
	    steps:
	    - task: DotNetCoreCLI@2
	      inputs:
	        command: build
	        arguments: '--configuration $(buildConfiguration)'
	    - task: DotNetCoreCLI@2
	      inputs:
	        command: publish
	        arguments: '--configuration $(buildConfiguration) --output $(Build.ArtifactStagingDirectory)'
	        modifyOutputPath: true
	        zipAfterPublish: true
	    - task: PublishBuildArtifacts@1
	      inputs:
	        path: $(Build.ArtifactStagingDirectory)
	        artifact: drop
	- stage: Deploy_In_Dev # Deploy artifacts to the dev environment
	  jobs:
	  - deployment: azure_web_app_dev
	    pool: 'Hosted VS2017'
	    variables:
	      WebAppName: 'PartsUnlimited-dev'
	    environment: 'dev-environment'
	    strategy:
	      runOnce:
	        deploy:
	          steps:
	          - task: AzureRMWebAppDeployment@4
	            displayName: Azure App Service Deploy
	            inputs:
	              WebAppKind: webApp
	              ConnectedServiceName: 'pay-as-you-go'
	              WebAppName: $(WebAppName)
	              Package: $(System.WorkFolder)/**/*.zip
	- stage: Deploy_In_QA # Deploy artifacts to the qa environment
	  jobs:
	  - deployment: azure_web_app_qa
	    pool: 'Hosted VS2017'
	    variables:
	      WebAppName: 'PartsUnlimited-qa'
	    environment: 'qa-environment'
	    strategy:
	      runOnce:
	        deploy:
	          steps:
	          - task: AzureRMWebAppDeployment@4
	            displayName: Azure App Service Deploy
	            inputs:
	              WebAppKind: webApp
	              ConnectedServiceName: 'pay-as-you-go'
	              WebAppName: $(WebAppName)
	              Package: $(System.WorkFolder)/**/*.zip
	- stage: Deploy_In_Production # Deploy artifacts to the production environment
	  jobs:
	  - deployment: azure_web_app_prod
	    pool: 'Hosted VS2017'
	    variables:
	      WebAppName: 'PartsUnlimited'
	    environment: 'prod-environment'
	    strategy:
	      runOnce:
	        deploy:
	          steps:
	          - task: AzureRMWebAppDeployment@4
	            displayName: Azure App Service Deploy
	            inputs:
	              WebAppKind: webApp
	              ConnectedServiceName: 'pay-as-you-go'
	              WebAppName: $(WebAppName)
	              Package: $(System.WorkFolder)/**/*.zip

如前面的 YAML 文件所示,流水线定义了四个阶段:Build SourceDeploy in DevDeploy in QADeploy in Production。在每个阶段,应用程序都会在指定的环境中部署。

总结

在本章中,我们对如何在 Azure DevOps 中使用发布流水线进行了全面的概述。

我们为PartsUnlimited项目创建了一个基本的发布流水线,定义了工件,并通过添加持续部署条件创建了我们的第一个发布。

然后,我们通过使用多个阶段(DEVQAProduction)来改进我们的流水线定义,在本章的最后,我们展示了如何定义审批和控制点,以更受控的方式管理代码的发布,并介绍了基于 YAML 的发布流水线的相关概念。

在下一章,我们将看到如何将 Azure DevOps 与 GitHub 集成。

第四部分:Azure DevOps 的高级功能

在本部分,我们将把 Azure DevOps 与 GitHub 集成,并涵盖一些实际的示例。

本节包含以下章节:

  • 第九章将 Azure DevOps 与 GitHub 集成

  • 第十章使用测试计划与 Azure DevOps

  • 第十一章Azure DevOps 的实际 CI/CD 场景

第九章:

第十章:将 Azure DevOps 与 GitHub 集成

GitHub 是全球最受欢迎的开发平台之一,被开源开发者和企业广泛使用来存储代码。在本章中,你将学习如何在继续使用 GitHub 作为软件开发中心的同时,利用 Azure DevOps 的能力。

我们将涵盖以下主题:

  • Azure DevOps 和 GitHub 集成概述

  • 将 Azure Pipelines 与 GitHub 集成

  • 将 Azure Boards 与 GitHub 集成

  • GitHub Actions 概述

技术要求

为了跟随本章内容,你需要拥有一个有效的 Azure DevOps 组织和一个 GitHub 账户。你可以在此注册 GitHub 账户:github.com/join

让我们准备好本章的前提条件。本章要求你已经将Parts Unlimited GitHub 仓库克隆到你的 GitHub 账户中。你还需要一个 Azure DevOps 项目来跟随本章的示例。在继续到下一部分之前,请先完成以下步骤:

  1. 启动浏览器实例并访问 github.com/microsoft/PartsUnlimitedE2E

  2. 点击 Fork,如下图所示:图 9.1 – GitHub 仓库:Parts Unlimited

    图 9.1 – GitHub 仓库:Parts Unlimited

  3. 如果你尚未登录,GitHub 会提示你登录到你的账户。选择你希望将仓库克隆到的账户。

  4. 完成此操作需要几分钟的时间。完成后,你应该能在你的账户中看到该仓库。

  5. 本章我们将使用这个仓库来测试 GitHub 集成。

  6. 现在,登录到 Azure DevOps (dev.azure.com) 并创建一个新的空项目:

图 9.2 – 创建新项目

图 9.2 – 创建新项目

现在你已经准备好尝试本章中描述的示例。

Azure DevOps 和 GitHub 集成概述

GitHub 和 Azure DevOps 是互补的,它们为团队提供卓越的软件开发体验,使团队能够以更快的速度和更少的努力发布和交付软件。在许多场景中,GitHub 和 Azure DevOps 是竞争对手(例如,Azure Repos 与 GitHub 仓库),因此通常由你来选择适合自己需求的工具,并将它们集成在一起,构建一个完善的平台。

Azure DevOps 提供了多种 RBAC 级别、原生企业身份集成等功能,而 GitHub 则提供了跨身份的简单协作(在其企业版中包括 AD 集成)。

在持续集成/持续开发方面,Azure DevOps 相较于其竞争对手 GitHub Actions 处于领先地位,且已经成熟。因此,是否选择 Azure DevOps 和/或 GitHub 来处理你软件开发生命周期中的特定组件,取决于你的使用场景和需求。

GitHub 包含一个扩展市场,您可以在其中找到许多第三方应用程序,以将 GitHub 扩展到您使用的应用程序。Azure DevOps 集成可以通过 GitHub Marketplace 上的许多扩展来实现。让我们来看一些扩展。

GitHub 和 Azure DevOps 的集成通过 Azure Boards 和 Azure Pipelines 扩展来实现。让我们先看看在 GitHub Marketplace 中可以找到的 Azure DevOps 扩展:

  1. 启动浏览器并访问github.com/marketplace

  2. 在扩展市场中搜索Azure。您将找到许多可以将 Azure 解决方案与您的 GitHub 仓库集成的扩展。

  3. 在这里,我们关心两个特定的扩展:Azure Boards 和 Azure Pipelines。稍后我们会详细讲解:

    --Azure Boards:这个扩展允许您将 Azure Boards 工作项与 GitHub 对象(如提交、拉取请求和问题)关联:

图 9.3 – Azure Boards 扩展

图 9.3 – Azure Boards 扩展

--Azure Pipelines:这个扩展使您可以在 GitHub 仓库中存储和维护代码的同时,使用 Azure Pipelines 构建和发布软件:

图 9.4 – Azure Pipelines 扩展

图 9.4 – Azure Pipelines 扩展

您可以从 GitHub Marketplace 安装这些扩展,并从 GitHub 本身开始配置,但在本章中,我们将从 Azure DevOps 开始集成过程。GitHub 和 Azure DevOps 的集成也支持这两个产品的本地版本(GitHub 本地和 Azure DevOps Server)。

将 Azure Pipelines 与 GitHub 集成

将 Azure Pipelines 与 GitHub 集成使开发人员能够继续使用 GitHub 作为首选的源代码管理平台,同时利用 Azure Pipelines 的构建和发布功能。Azure Pipelines 为开源项目提供无限制的管道作业分钟数。

我们在本书前面详细介绍了 Azure Pipelines,所以在这一部分,我们将看看如何将 Azure Pipelines 配置和源代码存储在 GitHub 中,并利用 GitHub 和 Azure DevOps 构建 CI/CD 流程。

设置 Azure Pipelines 和 GitHub 集成

为了在 GitHub 上使用 Azure Pipelines,您必须授权 Azure Pipelines 访问您的 GitHub 仓库。让我们来看看如何进行授权:

  1. 登录您的 Azure DevOps 账户并选择我们在技术要求部分创建的项目。

  2. 点击Pipelines > 创建管道图 9.5 – 创建管道

    ](https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/az-dop-expl/img/Figure_9.05_B16392.jpg)

    图 9.5 – 创建管道

  3. 选择GitHub作为您的代码源位置:图 9.6 – Azure Pipelines 的 GitHub 源

    ](https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/az-dop-expl/img/Figure_9.06_B16392.jpg)

    图 9.6 – Azure Pipelines 的 GitHub 源

  4. 您需要从 Azure Pipelines 向您的 GitHub 账户授予权限:图 9.7 – 授权 Azure Pipelines(OAuth)

    ](https://github.com/OpenDocCN/freelearn-devops-pt4-zh/raw/master/docs/az-dop-expl/img/Figure_9.07_B16392.jpg)

    图 9.7 – 授权 Azure Pipelines(OAuth)

  5. 成功完成后,你将在 Azure DevOps 中看到你的 GitHub 仓库列表。选择新创建的PartsUnlimitedE2E仓库:图 9.8 – Parts Unlimited 仓库

    图 9.8 – Parts Unlimited 仓库

  6. 你现在会得到在 GitHub 帐户中安装 Azure Pipelines 应用程序的选项。你可以选择仅为特定仓库安装,或为所有仓库安装。做出选择后,点击批准并安装图 9.9 – 安装 Azure Pipelines 扩展

    图 9.9 – 安装 Azure Pipelines 扩展

  7. 由于Parts Unlimited是一个基于 ASP.NET 的应用程序,请选择ASP.NET作为你的管道配置模板:图 9.10 – Azure Pipelines 任务配置

    图 9.10 – Azure Pipelines 任务配置

  8. Azure DevOps 将自动生成一个管道 YAML 文件。你可以根据需求查看并修改它。vs2017-win2016继续:图 9.11 – Azure Pipelines 任务 YAML

    图 9.11 – Azure Pipelines 任务 YAML

  9. 点击保存并运行以保存管道。

  10. 你需要向仓库提交一次更改,以存储管道 YAML 文件。你可以提交到主分支,或者创建一个新分支来进行此操作:图 9.12 – 运行 Azure 管道

    图 9.12 – 运行 Azure 管道

  11. 点击保存并运行将创建管道并开始执行。构建任务完成可能需要几分钟:图 9.13 – 管道任务

    图 9.13 – 管道任务

  12. 在此过程中完成时,我们来看看你对 GitHub 仓库所做的更改。浏览到你的 GitHub 帐户并进入PartsUnlimitedE2E仓库。

  13. 你将看到一次提交以及一个新添加的azure-pipelines.yml文件,它存储着管道的配置:图 9.14 – GitHub 中的管道 YAML

    图 9.14 – GitHub 中的管道 YAML

  14. 如果你点击前面截图中显示的小黄色圆点,你将看到 GitHub 仓库页面上 Azure 管道的状态。在管道任务成功完成后,你应该能看到它在 GitHub 帐户上的状态更新:

图 9.15 – GitHub 中的任务日志

图 9.15 – GitHub 中的任务日志

这样,你就已经设置好了一个带有 GitHub 的 Azure 管道。

测试持续集成

在本节中,我们将尝试 GitHub 和 Azure Pipelines 的 CI 功能。我们将在 GitHub 中做出代码更改并提交拉取请求,这将自动触发 Azure Pipelines 任务。

让我们开始吧:

  1. 浏览到你的 GitHub 帐户并打开PartsUnlimited E2E仓库。

  2. 点击Readme.MD并点击编辑图 9.16 – Readme.MD

    图 9.16 – Readme.MD

  3. 更新文件,使其包含一些示例文本。选择创建新分支的选项并单击提出更改图 9.17 – 提出更改

    图 9.17 – 提出更改

  4. 单击创建拉取请求,如下图所示:图 9.18 – 创建拉取请求

    图 9.18 – 创建拉取请求

  5. 这将打开拉取请求页面。Azure Pipelines 作业将花费几分钟时间启动。一旦启动,您可以单击详细信息查看流水线作业的状态:图 9.19 – PR 自动化检查

    图 9.19 – 拉取请求自动化检查

  6. 这就完成了对 GitHub 和 Azure Pipelines 持续集成功能的测试。正如我们所看到的,Azure Pipelines 与 GitHub 集成得非常好,并提供了全新的 DevOps 体验。您可以合并拉取请求来完成此过程。

添加构建状态徽章

Azure Pipelines 提供了可以在 GitHub 仓库文档中使用的标记文本,以提供项目流水线作业的状态。这可以帮助开发人员随时了解流水线的状态,无需访问 Azure DevOps。

让我们学习如何设置 Azure Pipelines 状态徽章:

  1. 登录 Azure DevOps 并浏览到您的项目 > 流水线 > PartsUnlimited E2E

  2. 单击省略号(...),然后选择状态徽章图 9.20 – 状态徽章

    图 9.20 – 状态徽章

  3. 复制示例 markdown文本框的值。您还可以选择获取特定分支的 markdown。请将此 markdown 保存在临时位置:图 9.21 – 状态徽章 URL

    图 9.21 – 状态徽章 URL

  4. 现在,在我们可以在 GitHub 中使用它之前,我们必须允许对项目徽章的匿名访问。

  5. 单击项目设置 > 流水线 > 设置

  6. 关闭禁用匿名访问徽章设置。如果您发现该选项是灰色的,请首先在组织设置中关闭此选项:图 9.22 – 状态徽章访问

    图 9.22 – 状态徽章访问

  7. 现在,您可以在 GitHub 文档中使用此 markdown。建议您将其保留在您的仓库的 README 文件中,这样任何人都会首先看到它:图 9.23 – 状态徽章 markdown

    图 9.23 – 状态徽章 markdown

  8. 提交更改后,您应该会看到 Azure Pipelines 徽章:

图 9.24 – 状态徽章展示

图 9.24 – 状态徽章展示

这样,您就完成了 Azure Pipelines 与 GitHub 的集成。在接下来的部分,我们将看看如何将 Azure Boards 与 GitHub 集成。

将 Azure Boards 与 GitHub 集成

Azure Boards 是规划和跟踪工作项的最佳平台。将 Azure Boards 与 GitHub 集成,您可以在继续使用 GitHub 作为源代码管理平台的同时,继续使用 Azure Boards 作为您的规划和管理平台。

通过将 Azure Boards 与 GitHub 集成,您可以将 Azure Boards 中的对象链接到 GitHub。以下是几个示例:

  • 工作项和 Git 提交/问题/拉取请求链接意味着您可以将工作项链接到 GitHub 中相应的工作。

  • 您可以直接在 GitHub 上更新工作项的状态。

  • 总的来说,集成使我们可以轻松地跨两个平台跟踪和链接交付物。

现在,让我们设置 Azure Boards 集成。

设置 Azure Boards 和 GitHub 集成

Azure Boards 是 GitHub 市场中的另一个扩展。您可以从 Azure DevOps 和 GitHub 市场配置集成。

让我们通过以下步骤进行设置:

  1. 登录到 Azure DevOps,浏览到您的 Parts Unlimited 项目 > 项目设置 > Boards > GitHub 连接图 9.25 – 将 GitHub 连接到 Boards

    图 9.25 – 将 GitHub 连接到 Boards

  2. 点击 连接您的 GitHub 帐户。您需要授权 Azure Boards 访问您的 GitHub 帐户。成功链接后,您需要选择要连接的 GitHub 组织。

  3. Azure DevOps 会列出您的代码库。请为本项目选择PartsUnlimited E2E并点击保存图 9.26 – 选择 GitHub 代码库

    图 9.26 – 选择 GitHub 代码库

  4. 这将引导您回到 GitHub,安装 Azure Boards 应用程序。您可以选择为特定代码库或所有代码库安装该应用程序:图 9.27 – 批准 Azure Boards 扩展

    图 9.27 – 批准 Azure Boards 扩展

  5. 安装 Azure Boards 后,您应该会看到 GitHub 连接列出,并带有绿色勾选标志,表示连接成功:

图 9.28 – GitHub 连接状态

图 9.28 – GitHub 连接状态

完成后,您已经成功设置了 Azure Boards 和 GitHub 集成。

添加 Azure Boards 状态徽章

与 Azure Pipelines 状态徽章类似,Azure Boards 也提供状态徽章,显示 GitHub 仓库中工作项的统计信息。

在本节中,我们将通过以下步骤将 Azure Boards 的状态徽章添加到我们的 GitHub 仓库:

  1. 登录到 Azure DevOps,浏览到 Boards,并点击设置齿轮图标:图 9.29 – Azure Boards 工作项

    图 9.29 – Azure Boards 工作项

  2. 在设置页面中,浏览到状态徽章并设置以下选项:

    a) 勾选 允许匿名用户访问状态徽章 复选框。

    b) 您可以选择只显示“进行中”列,或包含所有列。

    您的屏幕应该如下所示:

    图 9.30 – Azure Boards 状态访问

    图 9.30 – Azure Boards 状态访问

  3. 复制示例 markdown 字段并保存设置。您可以在 GitHub 文档中使用此 markdown。

  4. 一旦您将 markdown 添加到 GitHub README 文件中,它应该显示 工作项 状态,如下截图所示:

图 9.31 – Azure Boards 状态展示

图 9.31 – Azure Boards 状态展示

接下来,我们将看看如何将 Azure Boards 对象链接到 GitHub 对象。

将 Azure Boards 工作项链接到 GitHub 对象

现在我们已经将 Azure Boards 与 GitHub 集成,让我们学习如何在这两个平台之间链接和跟踪项目。让我们开始吧:

  1. 在 Azure Boards 中,创建一个新的工作项。您可以使用我们之前完成的 Azure 看板状态徽章任务作为示例:

    图 9.32 – Azure Boards 工作项

  2. 您将看到,在 GitHub 中刷新后,您的状态徽章图标会立即更新,其中有一个项目处于 待办 状态。

  3. 由于此任务已完成,我们可以将其链接到相应的 GitHub 提交。打开新创建的任务并点击 添加链接图 9.33 – 添加链接

    图 9.33 – 添加链接

  4. 点击 链接类型 下拉菜单,选择 GitHub 提交。提供您的 GitHub 提交 URL 并点击 确定。请注意,您还可以选择链接到 GitHub 问题或拉取请求:图 9.34 – 添加链接窗口

    图 9.34 – 添加链接窗口

  5. 您现在会看到 GitHub 提交链接到工作项。将其 状态 更改为 已完成图 9.35 – 已添加 GitHub 链接

    图 9.35 – 已添加 GitHub 链接

  6. 通过这样做,您可以在 Azure Boards 中查看您的 GitHub 对象,并可以直接打开相应的提交链接到 GitHub:

图 9.36 – 已添加 GitHub 链接到 Azure Boards

图 9.36 – 已添加 GitHub 链接到 Azure Boards

接下来,我们将学习如何从 GitHub 更新工作项的状态。

从 GitHub 更新工作项

在本节中,我们将学习如何从 GitHub 本身更改 Azure Boards 中工作项的状态。这将帮助您将 GitHub 对象链接到 Azure Boards 的工作项,实现双向链接和跟踪系统。

让我们开始吧:

  1. 进入 Azure Boards > Boards > 新建项。创建一个您选择名称的测试工作项:图 9.37 – 更新工作项

    图 9.37 – 更新工作项

  2. 记下工作项的 ID(在此示例中为 347)。

  3. 现在,去您的 GitHub 仓库,对任何文件进行一些小的修改,并创建一个拉取请求。

  4. 在拉取请求信息框中,你可以通过使用 AB#347 来引用 Azure Boards 任务,其中 347 是你的工作项 ID:图 9.38 – 拉取请求信息框

    图 9.38 – 拉取请求信息框

  5. 一旦你完成拉取请求,你会看到提交信息现在已经超链接到 Azure Boards,并且该工作项在 Azure Boards 中的状态更新为 AB#<Work Item ID >。一旦你将工作项与 GitHub 链接,Azure Board 中的工作项也会更新,并附上指向相应 GitHub 对象的链接。

  6. 除了链接目标外,在本演示中,你还通过提交信息中的简单指令更新了工作项的状态。让我们来看一些你可以使用的示例消息:

图 9.40 – 示例消息

图 9.40 – 示例消息

本节内容介绍了如何与 Azure Boards 和 GitHub 集成。在本节中,我们探讨了如何通过将 Azure Boards 和 GitHub 一起使用来更好地管理任务。在接下来的章节中,我们将介绍 GitHub Actions。

GitHub Actions 概述

GitHub Actions 是 GitHub 提供的 CI/CD 服务,用于构建和发布在 GitHub 仓库中开发的应用程序。本质上,GitHub Actions 类似于 Azure Pipelines,你可以设置构建和发布管道来自动化整个软件开发生命周期。

GitHub Actions 于 2019 年初推出,提供了一个内置于 GitHub 中的简单 DevOps 体验。GitHub Actions 包括企业级功能,如支持任何语言,并为各种操作系统和容器镜像提供内置的自托管代理。

它包含了社区构建的各种预构建工作流模板,可以帮助你更轻松地构建 DevOps 管道。

详细讨论 GitHub Actions 超出了本书的范围,但你可以参考 github.com/features/actions 上的 GitHub Actions 文档来入门。

总结

在本章中,我们探讨了如何将 GitHub 和 Azure DevOps 一起使用,为我们的软件团队构建一个集成的软件开发平台。为此,我们学习了如何从 GitHub 设置和管理 Azure DevOps 管道,以及构建和集成 CI/CD 解决方案。

我们还了解了在 GitHub 上进行软件开发时,如何更好地规划和跟踪我们的工作。在这一点上,你应该能够将 GitHub 和 Azure DevOps 一起使用,提升整体的生产力和 DevOps 体验。你还应该能够设置这两项服务之间的集成,并在日常 DevOps 工作中使用它。

在下一章中,我们将通过 Azure DevOps 的帮助,看看一些真实世界中的 CI/CD 示例。

第十章:

第十一章:使用 Azure DevOps 测试计划

在上一章中,我们讨论了如何将 Azure DevOps 与 GitHub 集成。

本章将介绍如何在 Azure DevOps 中使用测试计划。全面的测试应该应用于每个软件开发项目,因为它能够为应用程序提供质量保障和出色的用户体验。我们将首先简要介绍 Azure 测试计划。接着,我们将探讨如何在 Azure DevOps 中管理测试计划、套件和用例。然后,我们将运行并分析一个测试。之后,我们将讨论探索性测试,并安装 Test & Feedback 扩展。

本章将涵盖以下主题:

  • Azure 测试计划简介

  • 探索性测试

  • 安装和使用 Test & Feedback 扩展

  • 计划性的手动测试

  • 测试计划、测试套件和测试用例

  • 管理测试计划、测试套件和测试用例

  • 运行和分析手动测试计划

技术要求

要跟随本章的内容,你需要有一个活跃的 Azure DevOps 组织。本章中使用的组织是我们在第一章**,Azure DevOps 概览中创建的Parts Unlimited组织。你还需要安装 Visual Studio 2019,可以从visualstudio.microsoft.com/downloads/下载。

用于运行和分析手动测试计划的测试计划可以从github.com/PacktPublishing/Learning-Azure-DevOps---B16392/tree/master/Chapter%2010下载。

Azure 测试计划简介

手动测试和探索性测试可以是确保应用程序质量和用户体验的重要测试技术。在现代软件开发过程中,质量是所有团队成员的责任,包括开发人员、经理、业务分析师和产品负责人。

为了推动质量,Azure DevOps 测试计划提供了强大的工具,团队中的每个人都可以使用。通过将测试计划嵌入 Azure DevOps,测试可以贯穿整个开发生命周期。

Azure DevOps 测试计划支持计划性的手动测试、用户验收测试、探索性测试和利益相关者反馈。接下来的章节将更详细地介绍这些内容。

我们将在接下来的章节中详细介绍这些内容。在下一节中,我们将讨论探索性测试。

探索性测试

在探索性测试中,测试人员探索应用程序以识别和记录潜在的缺陷。它侧重于发现,并依赖于个别测试人员的指导,发现那些通过其他类型的测试难以发现的缺陷。这种测试通常被称为临时测试。

大多数质量测试技术采用结构化方法,通过事先创建测试用例(就像我们在之前的演示中所做的那样)。探索性测试正好与之相反,主要用于需要了解产品或应用程序的场景。测试人员可以从用户的角度审查产品的质量并快速提供反馈。这还确保您不会错过可能导致关键质量故障的情况。这些临时测试的结果随后也可以转化为测试计划。

微软发布了测试与反馈扩展,用于探索性测试。所有参与软件开发项目的相关人员,如开发人员、产品经理、经理、UX 或 UI 工程师、营销团队和早期采用者,都可以在浏览器中安装并使用该扩展。该扩展可用于提交缺陷或提供反馈,从而提升软件的质量。

在接下来的演示中,我们将演示如何安装测试与反馈扩展。

安装和使用测试与反馈扩展

测试与反馈扩展可以从 Visual Studio 市场安装,目前支持 Chrome 和 Firefox(版本 50.0 及更高版本)。Chrome 扩展也可以安装在 Microsoft Edge 浏览器中,该浏览器基于 Chromium。

重要说明

要查看详细的浏览器和功能支持情况,请参考以下文章:docs.microsoft.com/en-us/azure/devops/test/reference-qa?view=azure-devops#browser-support

要安装测试与反馈扩展,请按照以下步骤操作:

  1. 访问 Visual Studio 市场:marketplace.visualstudio.com/

  2. 选择测试与反馈。从列表中选择测试与反馈扩展:Figure 10.1 – 选择测试与反馈扩展

    Figure 10.1 – 选择测试与反馈扩展

  3. 这将打开扩展的详细页面,您可以在这里进行安装。点击屏幕顶部的安装按钮:Figure 10.2 – 安装测试与反馈扩展

    Figure 10.2 – 安装测试与反馈扩展

  4. 接下来,您将被重定向到支持安装此扩展的浏览器页面。点击您当前浏览器下方的安装按钮进行安装。您将被重定向到当前浏览器的扩展页面,在那里您可以进行安装。

  5. 安装扩展后,图标将添加到地址栏的右侧。点击连接按钮:Figure 10.3 – 测试与反馈扩展配置

    Figure 10.3 – 测试与反馈扩展配置

  6. 你需要在这里指定 Azure DevOps 服务器 URL,以连接到你的 Azure DevOps 实例。URL 以 https://dev.azure.com/ 开头,以项目名称结尾。提供 URL 后,点击下一步。连接到项目后,你可以选择团队。选择Parts.Unlimited Team图 10.4 – 连接到 Azure DevOps

    图 10.4 – 连接到 Azure DevOps

  7. 点击保存

    现在扩展已经配置完成,我们可以开始使用它。你可以使用该扩展进行探索性测试或提供反馈:

  8. 我们将开始进行探索性测试会话。点击开始按钮:图 10.5 – 开始探索性测试

    图 10.5 – 开始探索性测试

  9. 这将激活菜单。一旦你打开了一个用于测试的 Web 应用,你可以找到存在 bug 的区域,截图、做笔记,或录制操作视频:图 10.6 – 扩展选项

    图 10.6 – 扩展选项

  10. 一旦你完成了探索、收集并注册信息,你可以创建一个 bug、任务或测试用例。点击创建 bug图 10.7 – 扩展选项

    图 10.7 – 扩展选项

  11. 你可以提供一个标题,并将你发现的信息也包含其中:图 10.8 – 创建 bug

    图 10.8 – 创建 bug

  12. 点击保存

  13. 你还可以查看来自扩展的所有活动列表。在那里,你也能看到 bug ID,这样你就可以在 Azure DevOps 中追踪它:

图 10.9 – 操作概览

图 10.9 – 操作概览

重要说明

若要了解如何在 Azure DevOps 中创建反馈项,请参考以下网站:docs.microsoft.com/en-us/azure/devops/test/request-stakeholder-feedback?view=azure-devops。若要使用Test & Feedback扩展响应这些反馈项,请访问 https://docs.microsoft.com/en-us/azure/devops/test/provide-stakeholder-feedback?view=azure-devops#provide。

在本次演示中,我们从 Visual Studio Marketplace 安装了Test & Feedback扩展,它可以用于探索性测试。

在下一部分,我们将探讨计划的手动测试。

计划的手动测试

多年来,手动测试与软件开发过程一同演变,变得更加敏捷。通过 Azure DevOps,手动测试被集成到支持的不同敏捷过程中,并且可以在 Azure DevOps 中进行配置。

重要说明

第二章中,更详细地介绍了在 Azure DevOps 中支持并集成的不同敏捷过程,标题为使用 Azure DevOps Boards 管理项目

软件开发团队可以直接从 Azure Boards 的看板开始手动测试。从看板上,你可以直接从卡片中监控测试的状态。这样,所有团队成员可以概览与工作项和故事相关的测试。团队还可以看到不同测试的状态。

在下图中,你可以看到在看板上显示的测试及其状态:

图 10.10 – 在工作中心显示的测试

图 10.10 – 在工作中心显示的测试

如果需要更先进的测试功能,Azure 测试计划也可以满足所有测试管理需求。测试中心可以通过左侧菜单中的测试计划访问,其中提供了完整测试生命周期所需的所有功能。

在下图中,你可以看到如何通过左侧菜单访问测试中心,以及不同的菜单选项:

图 10.11 – Azure DevOps 中的测试中心

图 10.11 – Azure DevOps 中的测试中心

这些功能包括测试计划、测试套件、测试用例、测试编写、测试应用和测试跟踪。测试计划、测试套件和测试用例将在下一节中详细讲解。

测试计划、测试套件和测试用例

在 Azure DevOps 测试计划中,你可以为软件开发项目中定义的冲刺或里程碑创建和管理测试计划和测试套件。测试计划提供了三种主要的测试管理构件:测试计划测试套件测试用例。这些构件作为特殊类型的工作项存储在工作仓库中,并可以导出并与不同的团队成员或跨团队共享。这也支持测试构件与项目中定义的所有 DevOps 任务的集成。

这三种构件具备以下功能:

  • 测试计划:测试计划将不同的测试套件、配置和单独的测试用例汇集在一起。通常,项目中的每个主要里程碑都应该有自己的测试计划。

  • 测试套件:测试套件可以将不同的测试用例组织成单独的测试场景,归入单个测试计划中。这样可以更容易地查看哪些场景已完成。

  • 测试用例:通过测试用例,你可以验证代码或应用部署的各个部分。它们可以被添加到测试计划和测试套件中。如果需要,它们也可以被添加到多个测试计划和套件中。这样,它们可以有效地重复使用,无需复制。测试用例旨在验证 Azure DevOps 中的工作项,如功能实现或错误修复。

在接下来的部分,我们将把这些理论付诸实践,看看如何在 Azure DevOps 中创建和管理测试计划。

管理测试计划、测试套件和测试用例

在本次演示中,我们将再次使用Parts Unlimited项目。该项目在 Azure DevOps 中也有一个测试计划,因此我们将首先查看它。接下来,我们需要遵循以下步骤:

  1. 打开一个网页浏览器并导航到dev.azure.com/

  2. 使用你的 Microsoft 账户登录,并选择Parts.Unlimited项目。然后,在左侧菜单中选择测试计划。这将让你导航到已经添加到项目中的测试计划。

  3. 从列表中选择Parts.Unlimited_TestPlan1以打开它。测试套件已被添加到该计划中。选择作为客户,我希望将我的信用卡信息安全地存储。这将打开已添加到该套件中的单个测试用例列表:图 10.12 – 打开测试套件项

    图 10.12 – 打开测试套件项

  4. 然后,右键点击列表中的第一个项:验证用户是否被允许保存其信用卡信息。在菜单中选择编辑测试用例图 10.13 – 编辑测试用例

    图 10.13 – 编辑测试用例

  5. 在该测试用例的编辑界面上,有四个步骤。你还可以从这里将测试用例链接到提交、拉取请求、分支或工作项。我们将把这个测试用例添加到现有的工作项中。在相关工作下,选择+ 添加链接,然后点击现有项图 10.14 – 将工作项添加到测试用例

    图 10.14 – 将工作项添加到测试用例

  6. credit card中。选择信用卡购买功能以将测试用例链接到:图 10.15 – 选择工作项

    图 10.15 – 选择工作项

  7. 点击确定以链接工作项。现在,父特性已与测试用例和测试套件关联。任何人都可以在它们之间导航并查看其关系。

  8. 在测试用例窗口中,点击保存并关闭

在某些情况下,测试用例应按特定顺序运行。为此,请点击顶部菜单中的定义,然后选择验证用户是否不允许保存无效的信用卡信息测试用例。接着将该测试用例拖动到列表中第一个测试用例的上方:

图 10.16 – 重新排序测试用例

图 10.16 – 重新排序测试用例

现在你将看到测试用例的顺序已发生变化。

你还可以为每个测试用例分配不同的配置。例如,你可以为不同的环境分配配置,如不同版本的 Windows 或浏览器、移动设备等:

  1. 要分配配置,请右键点击测试用例并选择分配配置图 10.17 – 分配配置

    图 10.17 – 分配配置

  2. 在配置概览列表中,你会看到这个测试用例已经选择了一个配置,即 Windows 10。如果没有,选择它并点击保存。然后关闭列表:

图 10.18 – 可用和已选择的配置

图 10.18 – 可用和已选择的配置

重要提示

添加和管理测试计划配置超出了本书的范围。不过,如果你想了解更多信息,可以参考以下文章:docs.microsoft.com/en-us/azure/devops/test/test-different-configurations?view=azure-devops

接下来,我们将创建一个新的测试套件。你可以创建三种不同类型的测试套件:静态,手动分配测试用例;基于需求,根据共同需求创建套件;以及基于查询,根据查询结果自动添加测试用例:

  1. 让我们添加一个新的基于需求的测试套件。为此,选择Parts.Unlimited_TestPlan1旁边的三个点 > 新建套件 > 基于需求的套件图 10.19 – 创建基于需求的测试套件

    图 10.19 – 创建基于需求的测试套件

  2. 在这里,你可以根据需求创建自己的查询来检索工作项。在这个演示中,我们将使用默认设置。点击运行查询,然后选择与运输相关的三个项目:图 10.20 – 选择与运输相关的工作项

    图 10.20 – 选择与运输相关的工作项

  3. 点击创建套件为每个项目创建一个测试套件。

  4. 我们将向这个测试套件添加一些测试用例。你可以一次添加一个,也可以使用网格布局快速添加多个测试用例。我们将在这里使用网格布局。选择一个已添加的测试套件,点击新建测试用例按钮旁边的箭头,然后点击使用网格添加测试用例图 10.21 – 使用网格添加测试用例

    图 10.21 – 使用网格添加测试用例

  5. 将以下测试用例添加到网格:

    a) 第一个测试用例:

    i) 标题订单摘要显示预期交货日期

    ii) 步骤操作访问“我的订单”

    iii) 步骤预期结果显示预期交货日期

    b) 第二个测试用例:

    i) 标题延迟订单被突出显示

    ii) 步骤操作访问延迟包裹的订单页面

    iii) 步骤预期结果延迟状态被突出显示

    c) 第三个测试用例:

    i) 标题包裹交付步骤

    ii) 步骤操作访问进行中的包裹订单页面

    iii) 步骤预期结果显示交付步骤和状态

    这将显示如下截图:

    图 10.22 – 定义测试用例

    图 10.22 – 定义测试用例

  6. 点击左侧的 保存测试用例 按钮,然后点击屏幕右侧的 关闭网格 按钮。

在本演示中,我们已经管理了一些测试用例并创建了一个新的基于需求的测试套件。在接下来的部分,我们将运行并分析一个手动测试计划。

运行和分析手动测试计划

在本演示中,我们将运行并分析一个手动测试计划。为此,我们将再次使用已经添加到 Azure DevOps 中的 Parts.Unlimited 项目的测试计划并导入一个测试套件。该测试套件可以从属于本章的 GitHub 仓库中下载。你可以在章节开头的 技术要求 部分获取 GitHub URL:

  1. 再次在 Azure DevOps 中打开 Parts.Unlimited 项目的测试计划。

  2. 首先,我们需要添加一个新的静态测试套件。为此,选择 端到端测试 旁边的三个点。

  3. 选择新创建的套件,并在顶部菜单中选择导入按钮以导入测试用例:图 10.23 – 导入测试用例

    图 10.23 – 导入测试用例

  4. 导入 GitHub 源代码中 第十章 文件夹中的测试计划。选择 CSV 文件并点击 导入 按钮:图 10.24 – 导入 CSV 文件

    图 10.24 – 导入 CSV 文件

  5. 导入文件后,双击测试用例并导航到参数部分。然后添加一些可以用于测试的参数,类似于以下截图:图 10.25 – 参数值

    图 10.25 – 参数值

  6. 点击顶部菜单中的 保存并关闭。现在我们已经准备好测试套件,可以开始测试了。点击顶部菜单中的 执行 选项卡,然后点击 测试用例,接着点击 运行,然后点击 使用选项运行图 10.26 – 运行测试

    图 10.26 – 运行测试

  7. 保持 使用选项运行 窗口中的默认设置,然后点击 运行图 10.27 – 使用选项运行

    图 10.27 – 使用选项运行

  8. 测试运行器现在会显示所有步骤:

图 10.28 – 测试运行器窗口

图 10.28 – 测试运行器窗口

现在我们可以开始实际的测试:

  1. 在 Visual Studio 中打开 Parts.Unlimited 项目。我们之前已经克隆了仓库。如果需要再次克隆项目,请参考 第五章**,在构建管道中运行质量测试

  2. 通过按 F5 键运行应用程序,并等待直到 Parts Unlimited 网站启动。现在将浏览器窗口放到测试运行器窗口旁边,并开始测试:图 10.29 – 开始测试 Web 应用程序

    图 10.29 – 开始测试 Web 应用程序

  3. 根据测试运行器的说明操作。每完成一个步骤,点击每个步骤右侧的通过测试图标。

  4. 如果你发现 Bug 或问题,可以直接在步骤上添加评论,或者在顶部创建一个单独的 Bug:图 10.30 – 添加评论或 Bug

    图 10.30 – 添加评论或 Bug

  5. 要完成测试,请点击测试运行器顶部菜单中的保存并关闭

  6. 现在返回到 Azure DevOps。在左侧菜单中,点击测试计划 > 运行

  7. 在最近的运行列表中,选择我们刚刚执行的运行:图 10.31 – 最近的测试运行

    图 10.31 – 最近的测试运行

  8. 在这里,你可以查看测试的所有细节和结果:

图 10.32 – 测试结果

图 10.32 – 测试结果

在本次演示中,我们创建了一个测试套件并导入了一个测试用例。然后我们运行了测试并测试了 Parts Unlimited 应用程序,并查看了 Azure DevOps 中的结果。

本章到此结束。

总结

在本章中,我们介绍了 Azure DevOps 测试计划。我们查看了不同的功能和能力,并管理了测试计划、测试套件和测试用例。然后,我们从 CSV 文件导入了一个测试用例,并测试了Parts Unlimited应用程序。接着,我们详细讲解了探索性测试,并使用 Test & Feedback 扩展来报告一个 Bug。

在下一章中,我们将重点介绍使用 Azure DevOps 的实际 CI/CD 场景。

进一步阅读

查看以下链接,获取更多有关本章内容的信息:

第十一章:

第十二章:使用 Azure DevOps 进行实际的 CI/CD 场景

在本章中,我们将展示一些示例项目,其中持续集成和持续交付CI/CD)过程通过使用 Azure DevOps 来处理。我们将以示例应用程序为基础,使用 Azure DevOps 设置 CI/CD 管道,以便管理软件开发、部署和升级生命周期。

本章将涵盖以下主题:

  • 为基于.NET 的应用程序设置 CI/CD 管道

  • 为基于容器的基础设施设置 CI/CD 管道

  • Azure 架构中心为 DevOps 提供支持

技术要求

要跟随本章学习,您需要有一个有效的 Azure DevOps 组织和一个 Azure 订阅。

您可以在dev.azure.com注册一个测试版 Azure DevOps 组织。如果您还没有 Azure 订阅,可以在azure.microsoft.com/en-in/free/获得一个试用版。

本章的代码可以在github.com/PacktPublishing/Learning-Azure-DevOps---B16392/tree/master/Chapter11找到。

为基于.NET 的应用程序设置 CI/CD 管道

典型的基于.NET 的应用程序包括使用 Microsoft 的.NET Framework 开发的应用程序,并在后端使用 SQL 数据库。应用程序可能有多个层次,例如前端、后端(也称为中间层或 API 层)和数据层(SQL Server)。

Azure Pipelines,作为 Azure DevOps 的一部分,提供了一个全面的解决方案来构建、部署和管理基于.NET 的基础设施部署。在本节中,我们将查看为示例基于.NET 的应用程序配置 CI/CD 的步骤。

我们将为应用程序创建两个环境,分别命名为暂存生产,并设置 CI/CD 管道。

示例应用程序简介

我们将使用一个简单的ToDo应用程序来进行这次演示。它是一个基于 Web 的应用程序,后端使用 SQL 数据库。

它是使用 Microsoft ASP.NET 构建的,针对的是.NET Framework 版本 4.62。您可以在这里访问源代码:github.com/Azure-Samples/dotnet-sqldb-tutorial/tree/master/DotNetAppSqlDb

建议您在开始构建 CI/CD 管道之前,快速浏览一下应用程序代码,以便熟悉它。

准备所需的 Azure 基础设施

在本节中,我们将创建所需的 Azure 基础设施来托管应用程序。我们将创建以下资源:

  1. Contoso-ToDo-Staging

    b) Contoso-ToDo-Production

  2. 应用程序组件:我们将为暂存环境和生产环境创建以下资源:

    a) 使用 Azure App Service 来托管 Web 应用程序

    b) 使用 Azure SQL 数据库来托管 SQL 数据库

在 Azure 中创建资源组

资源组是一个容器,用于在 Azure 云中存储资源。通常,资源组包括您希望作为一组管理的资源,或者生命周期相似的资源。我们将创建两个资源组:一个用于生产,另一个用于预发布。让我们在 Azure 中创建这些资源组:

  1. 使用您的 Azure 凭证登录到 Azure 门户,portal.azure.com

  2. 点击 资源组

    图 11.1 – Azure 门户中的资源组

  3. 在资源组页面上点击 创建

  4. 选择您的订阅,并输入资源组名称为 Contoso-ToDo-Staging

  5. 选择一个离您位置较近的区域:图 11.2 – 资源组创建

    图 11.2 – 资源组创建

  6. 点击 查看 + 创建,然后点击 创建 以开始部署。

  7. 重复步骤,为生产环境创建另一个资源组,命名为 Contoso-ToDo-Prod

您现在已经创建了资源组来托管 Azure 资源。

创建 Azure 应用服务

Azure 应用服务是 Microsoft Azure 提供的 平台即服务PaaS)Web 托管服务。您可以使用应用服务托管几乎任何语言构建的基于 Web 的应用程序。作为 PaaS 服务,应用服务允许您只需推送代码即可使应用程序上线,而无需担心底层的硬件、操作系统和平台组件。

在本示例中,我们将使用 Azure 应用服务来托管 ToDo 应用:

  1. 在 Azure 门户中,点击 + 创建资源,然后点击 Web 应用图 11.3 – 门户中的 Azure Web 应用

    图 11.3 – 门户中的 Azure Web 应用

  2. contosotodostagingXX 上,其中 XX 是您的首字母。

    d) 发布:选择代码

    e) 运行时堆栈:选择 ASP.NET V4.7

    f) 操作系统:选择 Windows

    g) 区域:选择一个离您位置较近的区域:

    图 11.4 – 创建 Azure 应用服务

    图 11.4 – 创建 Azure 应用服务

  3. 应用服务计划 下,选择以下选项:

    a) Windows 计划:输入一个新的应用服务计划名称

    b) SKU 和大小:您可以选择任何 SKU;建议使用 S0Basic,以避免由于测试目的而产生过高的 Azure 成本。在生产环境中,您应根据应用程序的资源需求选择适合的大小:

    图 11.5 – 应用服务 SKU

    图 11.5 – 应用服务 SKU

  4. 点击 查看 + 创建,然后点击 创建 以开始部署。

    完成后,您将收到一个通知,显示状态为完成。

  5. 重复此任务中的步骤,为生产环境创建另一个 Azure 应用服务。

在此任务中,我们为托管 ToDo Web 应用程序创建了一个 Azure 应用服务。

创建 Azure SQL 数据库

我们的示例 ToDo 应用使用 Microsoft SQL Server 存储所有的应用数据。在此任务中,我们将创建一个新的 Azure SQL 数据库,供 ToDo 应用存储所有持久化数据:

  1. 在 Azure 门户中,点击 + 创建资源,然后选择 SQL 数据库

    图 11.6 – Azure 中的 SQL 数据库

  2. 在 SQL 服务器 contosotodo-staging-db 上。

    d) contosotodo-staging-dbserver

    ii) 提供你选择的用户名和密码。

    iii) 位置:用于部署 Web 应用的 Azure 区域。

    e) 想使用 SQL 弹性池吗?

    f) 计算 + 存储:将 SKU 更改为 S0基础 以保持 Azure 成本在本测试项目期间较低。实际上,你需要根据应用需求选择合适的计算和存储组合:

    图 11.7 – 在 Azure 中创建 SQL 数据库

    图 11.7 – 在 Azure 中创建 SQL 数据库

  3. 点击 下一步:网络 >

  4. 对于 网络 配置,选择 公共端点 作为 连接方式,并选择 以允许 Azure 服务和资源访问此服务器。请注意,这仅用于本测试项目的部署;在生产环境中,建议仅允许来自特定应用服务器的访问。一旦选择,点击 查看 + 创建图 11.8 – 在 Azure 中审核 SQL 数据库创建

    图 11.8 – 在 Azure 中审核 SQL 数据库创建

  5. 点击 创建 以开始部署。完成后,你将在通知菜单中收到通知。

  6. 导航到新创建的 Azure SQL 数据库并复制连接字符串。这将在接下来的部分中使用。

  7. 重复这些步骤为生产环境创建另一个 Azure SQL 数据库。

在这个任务中,我们已经为我们的应用创建了 Azure SQL 数据库。

设置 Azure DevOps 项目

现在我们的 Azure 基础设施已准备好,接下来我们将设置一个 Azure DevOps 组织来构建 CI/CD 流水线。我们将使用 Azure Repos 作为我们的源代码管理系统:

  1. 使用你的 Azure DevOps 账号登录 dev.azure.com

  2. 在你的 DevOps 租户中创建一个名为 Contoso ToDo 的新项目:图 11.9 – 创建 DevOps 项目

    图 11.9 – 创建 DevOps 项目

  3. 我们将从导入 Azure Repos 中的应用代码开始。点击 Repos

  4. 导入仓库 下点击 导入图 11.10 – 导入一个仓库

    图 11.10 – 导入一个仓库

  5. 对于仓库 URL,输入 github.com/Azure-Samples/dotnet-sqldb-tutorial/,然后点击 导入

图 11.11 – 从 GitHub 导入仓库

图 11.11 – 从 GitHub 导入仓库

导入成功后,我们将看到项目文件现已在 Azure Repos 中可用。您可以浏览代码文件,查看 DotNetAppSQLDb 中包含的应用程序源文件:

图 11.12 – Azure 仓库中的文件

图 11.12 – Azure 仓库中的文件

我们现在将为应用程序设置构建管道。

为应用程序设置 CI

现在我们的应用程序代码已上传至 Azure Repos,接下来我们将创建一个构建管道,该管道将构建应用程序包,以便部署到 Azure 应用服务:

  1. 在 Azure DevOps 中,浏览到管道并点击创建管道图 11.13 – 创建管道

    图 11.13 – 创建管道

  2. 点击使用经典编辑器,通过 GUI 创建管道(这一步是可选的;如前面章节所述,您可以选择使用 YAML 文件配置管道):图 11.14 – 选择经典编辑器

    图 11.14 – 选择经典编辑器

  3. 选择您的 Azure 仓库和主分支,然后点击继续进入下一步:图 11.15 – 选择仓库

    图 11.15 – 选择仓库

  4. 选择ASP.NET作为管道模板:图 11.16 – 选择管道模板

    图 11.16 – 选择管道模板

  5. 查看管道配置。对于这个项目,默认配置已经能够完成工作。检查无误后,点击保存并排队图 11.17 – 管道构建任务

    图 11.17 – 管道构建任务

  6. 运行管道向导中,您可以添加评论并点击保存并运行以开始执行

  7. 一旦作业开始执行,您可以通过点击作业名称来查看状态:图 11.18 – 管道构建状态

    图 11.18 – 管道构建状态

  8. 现在,让我们在管道上启用 CI,以便在提交到分支时自动启动构建。编辑管道并浏览到触发器,启用 CI。如果您不是使用分支作为主要分支,您可以选择按分支进行过滤或切换到其他分支:

图 11.19 – 启用持续集成

图 11.19 – 启用持续集成

在这项任务中,我们创建了一个构建管道,并成功构建了我们的示例待办事项应用程序。在接下来的任务中,我们将执行部署。

为应用程序设置持续交付

现在我们的应用程序已准备好进行部署,我们将创建一个发布管道,将应用程序部署到 Azure。在这个管道中,我们将定义要将应用程序部署到哪些 Azure 资源,并添加额外的部署控制。

设置服务连接

Azure DevOps 需要访问 Azure 订阅,以便能够部署和更新 Azure 资源。Azure DevOps 中的服务连接允许你将 Azure DevOps 项目连接到外部服务。让我们为 Azure Pipelines 创建一个服务连接:

  1. 登录到 Azure DevOps 并浏览至 项目设置 | 服务连接

  2. 点击 创建服务连接

  3. 在连接列表中,选择 Azure 资源管理器Figure 11.20 – ARM 服务连接

    Figure 11.20 – ARM 服务连接

  4. 对于服务连接身份验证方法,选择 服务主体(自动)Figure 11.21 – ARM 服务连接服务主体

    Figure 11.21 – ARM 服务连接服务主体

  5. Azure DevOps 现在将要求你进行 Azure 身份验证。请使用至少拥有订阅所有者权限和全局管理员权限的帐户登录到 Azure Active Directory (AD) 租户。你可以选择将服务连接的作用域限制为某个资源组,或者允许整个订阅。选择你的 Azure 订阅并为其命名:

Figure 11.22 – 创建服务连接服务主体

Figure 11.22 – 创建服务连接服务主体

该服务连接现在可以在 Azure Pipelines 中使用。

创建发布流水线

发布流水线包括所有步骤和工作流,用于将应用程序部署到不同的环境中,例如开发、暂存、质量保证和生产。我们从为 ToDo 应用创建一个发布流水线开始:

  1. 登录到 Azure DevOps 并启动你的 Contoso ToDo 项目。

  2. 浏览至 Pipeline | Releases

  3. 点击 新建流水线Figure 11.23 – 新发布流水线

    Figure 11.23 – 新发布流水线

  4. 这将打开一个页面以选择模板。由于我们计划将 ToDo 应用部署到 App Service,请选择 Azure App Service 部署Figure 11.24 – Azure App Service 部署任务

    Figure 11.24 – Azure App Service 部署任务

  5. 阶段名称 输入 Staging Environment。你可以选择给出任何其他有意义的名称,最好能描述你环境中的场景:Figure 11.25 – Staging 阶段

    Figure 11.25 – Staging 阶段

  6. 现在你可以关闭 阶段 窗格。你的流水线应该如下所示:Figure 11.26 – 流水线快照

    Figure 11.26 – 流水线快照

  7. 为了部署应用程序,首先我们需要从构建流水线的输出中获取应用程序包。在 Artifacts 下,点击 + 添加Figure 11.27 – 发布流水线中的工件

    Figure 11.27 – 发布流水线中的工件

  8. 选择构建作为源类型,并选择在上一任务中创建的构建管道。你可以选择配置默认要部署的版本:图 11.28 – 发布管道中的工件源

    图 11.28 – 发布管道中的工件源

  9. 点击持续部署触发器按钮并启用持续部署。启用持续部署后,每当有新的构建版本可用时,都会触发发布(通常是在运行包含 CI 的构建管道之后)。如果启用拉取请求触发器,每次有新的构建版本时,都会创建一个发布,即使是有拉取请求的情况下。这对于纯开发管道可能是一个有用的场景:图 11.29 – 启用持续部署

    图 11.29 – 启用持续部署

  10. 阶段中,点击开发环境中的1 个任务,1 个工作图 11.30 – 管道阶段

    图 11.30 – 管道阶段

  11. 在任务视图中,选择你之前部署的 Azure 订阅服务连接和应用服务:图 11.31 – 应用服务部署任务

    图 11.31 – 应用服务部署任务

  12. 点击部署 Azure 应用服务并检查应用服务的部署信息。

  13. 点击+添加另一个任务来应用SQL 迁移脚本以使数据库准备就绪。搜索 SQL 并选择Azure SQL 数据库部署

  14. Azure SQL 任务中,修改以下设置:

    a) 显示名称:应用数据库迁移脚本。

    b) 选择你的 Azure 订阅并提供在创建 Azure SQL 数据库时捕获的数据库连接详情。

    c) 部署类型:内联 SQL 脚本

    d) 内联 SQL 脚本:提供以下脚本代码。这将会在 SQL 数据库中创建所需的表。请注意,这是一个用于创建所需架构的示例 SQL 脚本(也可以在github.com/PacktPublishing/Learning-Azure-DevOps---B16392/tree/master/Chapter11中找到);在生产环境中,您可以选择使用 Azure Pipelines 中的 SQL Server 数据工具项目来完成此操作。请参阅此文档了解更多关于 SQL 的 Azure DevOps 的内容:devblogs.microsoft.com/azure-sql/devops-for-azure-sql/

    /****** Object:  Table [dbo].[__MigrationHistory]    Script Date: 8/24/2020 12:35:05 PM ******/
    SET ANSI_NULLS ON
    SET QUOTED_IDENTIFIER ON
    IF NOT EXISTS
       (  SELECT [name]
          FROM sys.tables
          WHERE [name] = '__MigrationHistory'
       )
    BEGIN
        CREATE TABLE [dbo].__MigrationHistory NOT NULL,
            [ContextKey] nvarchar NOT NULL,
            [Model] varbinary NOT NULL,
            [ProductVersion] nvarchar NOT NULL,
        CONSTRAINT [PK_dbo.__MigrationHistory] PRIMARY KEY CLUSTERED 
        (
            [MigrationId] ASC,
            [ContextKey] ASC
        )WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
        ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
    
    END
    /****** Object:  Table [dbo].[Todoes]    Script Date: 8/24/2020 12:35:05 PM ******/
    SET ANSI_NULLS ON
    SET QUOTED_IDENTIFIER ON
    IF NOT EXISTS
       (  SELECT [name]
          FROM sys.tables
          WHERE [name] = 'Todoes'
       )
    BEGIN
        CREATE TABLE [dbo].Todoes NOT NULL,
            [Description] nvarchar NULL,
            [CreatedDate] [datetime] NOT NULL,
        CONSTRAINT [PK_dbo.Todoes] PRIMARY KEY CLUSTERED 
        (
            [ID] ASC
        )WITH (STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF) ON [PRIMARY]
        ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
    
    END
    
  15. 点击保存并点击+添加另一个任务。现在我们需要添加另一个任务,更新 Azure 应用服务连接设置中的数据库连接字符串。

  16. 在任务菜单中搜索Azure 应用服务设置图 11.32 – Azure 应用服务设置任务

    图 11.32 – Azure 应用服务设置任务

  17. Azure App Service 设置任务中,选择 Azure 订阅和用于暂存环境的应用服务连接详情。

  18. 连接设置中,提供以下格式的数据库连接字符串。在保存之前,请更新您的数据库连接详情。由于这是一个测试实验室,我们直接在管道任务中存储了安全信息。然而,在生产环境中,请使用变量和参数来存储任何连接字符串或其他信息。请参考此文档了解如何在 Azure 管道中安全地使用变量和参数:docs.microsoft.com/bs-cyrl-ba/azure/devops/pipelines/security/inputs?view=azure-devops

    [
      {
        'name': 'MyDbConnection',
        'value': 'Server=tcp:contosotodostagingdb.database.windows.NET,1433;Initial Catalog=ContoSoToDoStageDB;Persist Security Info=False;User ID=azadmin;Password=<YourPassword>;MultipleActiveResultSets=False;Encrypt=True;TrustServerCertificate=False;Connection Timeout=30;',
        'type': 'SQLAzure',
        'slotSetting': false
      }
    ]
    
  19. 一旦所有任务更新完成,点击保存。在提示时,可以将管道保存在根文件夹中。任务的顺序应如下:

    a) 应用数据库迁移脚本

    b) 应用 Azure App Service 设置

    c) 部署 Azure App Service

    图 11.33 – 保存发布管道

    图 11.33 – 保存发布管道

  20. 在管道中,点击+ 添加以添加另一个用于生产的阶段。您可以选择相同的 Azure App Service 部署,也可以克隆开发环境阶段。您可以在定位生产应用服务和 SQL 数据库实例时配置生产阶段。您的管道现在应如下所示:图 11.34 – 发布管道

    图 11.34 – 发布管道

  21. 通常,您不希望自动部署到生产环境。让我们修改流程,以便在生产部署之前进行手动审批。点击预部署条件图 11.35 – 发布管道触发控制

    图 11.35 – 发布管道触发控制

  22. 启用预部署审批,并选择至少一个用户进行审批,才能在部署到生产环境之前进行批准。

  23. 您可以添加一个额外的阶段,如测试用例、性能基准等,并准备好整体流程。完成检查管道后,点击保存

现在,部署应用程序的 Azure 发布管道已准备就绪。让我们创建一个发布,并查看我们是否能够通过 CI/CD 管道将应用程序启动并运行。

创建发布

让我们通过手动创建一个发布来测试发布管道:

  1. 在 Azure DevOps 中,浏览到发布并点击创建发布图 11.36 – 创建发布

    图 11.36 – 创建发布

  2. 审核发布详情并点击创建图 11.37 – 审核发布创建

    图 11.37 – 审核发布创建

  3. 点击创建将开始执行发布;您可以通过点击阶段上的日志来查看进度:图 11.38 – 发布状态

    Figure 11.38 – 发布状态

    一旦开发环境部署完成,你应该尝试启动应用服务,并查看ToDo应用程序是否正常工作:

    Figure 11.39 – ToDo 应用

    Figure 11.39 – ToDo 应用

  4. 你可以尝试添加待办事项并测试应用程序。一旦你准备好批准生产部署,点击批准开始生产部署:

Figure 11.40 – 批准生产部署

Figure 11.40 – 批准生产部署

你现在已经完成了发布,应用程序已经准备好使用。

尝试端到端 CI/CD 流程

现在你已经完成了端到端 CI/CD 流水线的设置,继续尝试以下操作,体验整个流程:

  1. 在 Azure Repos 中,修改主页的视图。前往 Repos | DotNetAppSQLDB | Views | Todos | index.cshtml,并将标签从Create new修改为Create New ToDo ItemFigure 11.41 – 修改应用程序代码

    Figure 11.41 – 修改应用程序代码

  2. 在新分支中提交更改,并完成拉取请求。你应该批准并完成拉取请求。

    这应该会启动自动构建流水线执行,并通过自动发布执行进行后续操作。

    最终,你应该在不需要任何手动步骤的情况下更新你的应用程序,唯一需要执行的任务是配置好的生产审批任务。

恭喜,你现在已经完成了端到端 CI/CD 流水线的设置和测试!在下一节中,我们将为 Kubernetes 基础的应用程序设置类似的流水线。

为基于容器的应用程序设置 CI/CD 流水线

在本例中,我们将采用一个基于容器的应用程序,并构建一个端到端的 CI/CD 流水线。为了演示,我们将使用一个基于 Python 和 Redis 的示例应用程序。

在本例中,我们将在整个解决方案架构中使用各种 Azure 资源。包括以下内容:

  • Azure DevOps:CI/CD 流水线

  • Azure Kubernetes 服务AKS):用于托管容器

  • Azure 容器注册表ACR):容器镜像存储和管理

示例应用介绍

在本节中,我们将使用一个名为Azure 投票应用的示例应用。它是一个标准的基于多容器的应用,使用以下组件:

  • Azure 投票应用后端:将在 Redis 上运行。

  • Azure 投票应用前端:使用 Python 构建的 Web 应用程序。

你可以在这里查看应用程序代码:github.com/Azure-Samples/azure-voting-app-redis

设置所需的基础设施

为了能够构建管道,首先需要设置所需的基础设施,包括 AKS 集群和 Azure 容器注册表。我们将为预发布和生产环境创建独立的资源作为标准最佳实践;然而,通过使用标签和 Kubernetes 命名空间的组合,也可以使用单一环境来同时处理生产和开发环境。

在本节中,我们将使用 Azure 命令行界面CLI)来执行所有基础设施部署任务。

创建 Azure 资源组

我们从创建一个 Azure 资源组开始,用于组织开发和生产环境的所有资源:

  1. 使用你的 Azure 凭据登录 Azure Cloud Shell(shell.azure.com)。

  2. 如果这是你第一次登录 Azure Cloud Shell,它会提示你创建一个 Azure 存储账户。选择你的订阅并点击创建存储

  3. 在 shell 类型选择中选择Bash

  4. 运行以下命令以列出所有订阅:

    az account list 
    
  5. 如果需要为资源提供指定订阅,请运行以下命令:

    az account set --subscription 'Your Subscription Name'
    
  6. 运行以下命令创建名为Contoso-Voting-Stage的资源。你可以选择上传一个自己选择区域的位置:

    az group create -l westus -n Contoso-Voting-Stage
    
  7. 重复资源组创建命令,创建另一个名为Contoso-Voting-Prod的资源组,用于生产环境。

你现在已经完成了所需的资源组创建。在接下来的步骤中,你将创建一个 Azure Kubernetes 集群。

创建 Azure Kubernetes 服务

AKS 是微软 Azure 提供的托管 Kubernetes 服务。在 Kubernetes 集群中有两种类型的主机——主节点(也称为控制平面)和节点。在 AKS 中,终端用户并不直接使用主节点。微软会创建并管理主节点,并将其隐藏在终端用户之外。作为用户,你只需在自己的订阅中部署 AKS 节点(Kubernetes 节点),而 Kubernetes 配置和微软托管的 Kubernetes 主节点的连接则在后台进行。使用 AKS 时,你只需为节点的基础设施费用付费;主节点由微软免费提供。

我们将使用 AKS 来托管我们的容器。

我们从创建一个 AKS 集群开始:

  1. 使用你的 Azure 凭据登录 Cloud Shell。

  2. 运行以下命令以创建一个具有默认配置和最新版本的 AKS 集群:

    az aks create: The syntax for creating an AKS cluster.    b) `--resource-group & --name`: The resource group's name and AKS cluster name.    c) `--node-count`: The number of AKS nodes you're creating.    d) `--enable-addons`: This specifies add-ons, such as monitoring and HTTP routing.    e) `--generate-ssh-keys`: This is a flag that lets `az cli` create SSH keys to be used for agent nodes.
    
  3. AKS 集群可能需要最多 10 分钟才能准备好。你可以通过运行以下命令来查看状态:

    az aks list
    
  4. 一旦你的集群准备就绪,你可以通过运行以下命令在 Cloud Shell 会话中获取 Kubernetes 认证配置:

    az aks get-credentials --resource-group Contoso-Voting-Stage --name Contoso-Stage-AKS
    
  5. 现在你可以尝试运行kubectl命令与 Kubernetes 进行交互。运行以下命令以获取所有 Kubernetes 节点的列表:

    kubectl get nodes
    

现在您的 Azure Kubernetes 集群已经准备好;请重复该过程为生产环境创建另一个 AKS 集群。

创建 Azure 容器注册表

ACR 是一个由 Microsoft Azure 托管和管理的私有 Docker 容器注册表。ACR 完全兼容 Docker,并且工作方式与 Docker 相同,唯一的区别是它由微软管理、托管并提供安全保障。我们将使用 ACR 来存储我们的容器镜像。

让我们为该项目创建一个容器注册表:

  1. 登录 Azure Cloud Shell 并运行以下命令来创建容器注册表:

    az acr create --resource-group Contoso-Voting-Stage --name ContosoStageACR --sku Basic 
    
  2. 一旦您的容器注册表准备好,您可以通过运行以下命令获取其状态和详细信息:

    az acr list
    

集成 ACR 与 AKS

AKS 需要有权限访问 ACR 中的容器镜像才能运行应用。让我们启用 AKS 与 ACR 进行交互的权限。

运行以下命令将 AKS 与我们的 ACR 集成:

az aks update -n Contoso-Stage-AKS -g Contoso-Voting-Stage --attach-acr ContosoStageACR

现在我们的基础设施已经准备好,我们将开始为应用设置代码仓库。

设置 Azure Repos 用于投票应用

在本节中,我们将创建一个新的 Azure DevOps 项目并导入 Azure Repos 中的投票应用源代码:

  1. 登录 Azure DevOps 并创建一个名为 Contoso Voting App 或您选择的其他名称的新项目。

  2. 导航到 Azure Repos 并点击导入 Git 仓库。请从以下链接导入 Azure 投票应用仓库:github.com/Azure-Samples/azure-voting-app-redis

图 11.42 – 导入仓库

图 11.42 – 导入仓库

现在我们的仓库已经准备好,接下来让我们从构建管道开始。

设置 CI 管道

构建管道将负责构建容器镜像并将其推送到 ACR。让我们开始吧:

  1. 登录 Azure DevOps 并打开Contoso Voting App 项目

  2. 导航到管道并点击创建管道

  3. 点击使用经典编辑器通过 UI 创建管道。

  4. 选择您在上一部分中创建的源 Azure 仓库作为管道的源。

  5. 对于模板,选择Docker 容器作为模板类型:图 11.43 – Docker 容器管道模板

    图 11.43 – Docker 容器管道模板

  6. root/azure-vote/Dockerfile 仓库中。

    f) 勾选包含最新标签

    图 11.44 – 推送镜像

    图 11.44 – 推送镜像

  7. 推送镜像任务中,重新选择 Azure 订阅和 ACR,并确保任务为推送镜像。请确保勾选包含最新标签

  8. 完成后,审查两个任务并点击保存并运行以开始管道作业执行。

  9. 审查作业日志以查看有关镜像构建和推送到 ACR 的详细信息。

  10. 完成后,导航到 Azure 门户并打开您之前创建的容器注册表。

  11. 导航到仓库;您应该能看到一个新镜像在那里被创建。让我们查看该镜像,找出我们在应用程序部署配置中需要更新的镜像名称:图 11.45 – ACR 中的容器镜像

    图 11.45 – ACR 中的容器镜像

  12. 记下镜像拉取连接字符串。我们将在下一个练习中使用它:图 11.46 – ACR 中的镜像语法

    图 11.46 – ACR 中的镜像语法

  13. 我们的管道现在已准备好并测试完成,所以让我们返回并在管道触发器配置中启用 CI:

图 11.47 – 启用 CI

图 11.47 – 启用 CI

现在我们的 CI 管道已经准备好,让我们从部署管道开始。

设置 CD 管道

在本节中,我们将设置部署管道,该管道将把应用程序代码部署到 AKS,并在需要时进行更新。Azure Pipelines 提供与托管在本地和云中的 Kubernetes 集群的本地集成。

更新 Kubernetes 部署清单文件

在 Kubernetes 的世界里,应用程序部署是通过编写 JSON 或 YAML 格式的清单文件来管理的。此示例应用程序的部署文件已经包含在 Azure 仓库中。您可以通过查看 Azure Repos 根目录中的azure-vote-all-in-one-redis.yaml文件来检查部署配置。

默认情况下,部署清单已配置为使用微软提供的容器镜像。我们需要更新它,开始使用我们自己的自定义镜像。让我们开始吧:

  1. 导航到azure-vote-all-in-one-redis.yaml文件。

  2. 在文件编辑器的右上角点击编辑

  3. 查找部署清单中的以下部分。这会将容器引擎重定向为使用微软提供的 Docker 镜像:

    image: microsoft/azure-vote-front:v1
    
  4. 用您自己的容器注册表和镜像名称替换该值。它应该像下面给出的示例一样。您应该指定最新的标签,以确保始终使用最新的镜像:

     image: contosostageacr.azurecr.io/contosovotingapp:latest
    
  5. 提交更改以保存部署清单文件。

现在,您的应用程序清单已经准备好进行部署。

设置发布管道

发布管道将在 Kubernetes 集群中应用部署清单,并执行镜像更新任务。让我们构建一个管道来自动化部署:

  1. 登录到Azure DevOps | 管道 | 发布

  2. 创建一个新的发布管道。选择Deploy to a Kubernetes cluster模板:图 11.48 – Deploy to a Kubernetes cluster 模板

    图 11.48 – Deploy to a Kubernetes cluster 模板

  3. 将阶段名称更新为Development Environment

  4. 让我们从添加工件开始。在工件中点击添加

  5. Artifact中,选择 Azure 仓库并选择我们导入的仓库。点击添加图 11.49 – 向管道中添加工件

    图 11.49 – 向管道中添加工件

  6. Deploy to Kubernetes中。

    b) azure-vote-all-in-one-redis.yaml)。浏览到您的默认目录并选择部署 YAML 文件。如果需要,我们可以定义其他选项,例如 Kubernetes 秘密和配置映射。验证所有配置有效后,点击保存

    图 11.51 – 选择部署 YAML

    图 11.51 – 选择部署 YAML

    e) 查看任务配置并点击保存以保存到目前为止的进度:

    图 11.52 – 任务配置

    图 11.52 – 任务配置

  7. 现在,我们将在管道中添加另一个步骤,以便在部署后更新 AKS 中的镜像。这将确保每次发布时,Kubernetes 都会拉取最新的镜像。点击+号,向管道中添加另一个kubectl任务。

  8. 配置任务,使其使用相同的 Kubernetes 连接。在参数中使用image deployments/azure-vote-front azure-vote-front=youracrname.azurecr.io/contosovotingapp:latest。在生产部署中,您可能不希望在管道中使用最新标签,而是应引用使用构建管道生成的版本标签。这样可以帮助您管理特定版本的部署,并且在需要时可以轻松回滚。

  9. 一旦准备就绪,保存管道并创建一个发布,以测试部署管道。

  10. 查看发布日志以了解部署步骤和流程。

  11. 一旦成功完成,返回编辑管道并启用持续部署:图 11.53 – 启用持续部署

    图 11.53 – 启用持续部署

    至此,我们的构建和发布配置已完成,具备了完整的 CI/CD 自动化。接下来查看 AKS 集群,确保我们的应用已正确部署并且可以访问(使用我们刚刚发布的版本):

  12. 使用 Azure shell 连接到您的 AKS 集群。

  13. 运行kubectl get podskubectl get services图 11.54 – kubectl 结果

    图 11.54 – kubectl 结果

  14. 记下azure-vote-front应用的公共 IP。您可以尝试访问该公共 IP,以检查应用是否按预期运行:

图 11.55 – 投票应用已启动

图 11.55 – 投票应用已启动

接下来,我们将为这个应用模拟一次端到端的 CI/CD 体验。

模拟端到端的 CI/CD 体验

在前面的部分中,我们设置了 CI/CD 管道。让我们尝试操作它,体验整体流程。首先,从Azure 投票应用更新应用标题为Contoso 投票应用

  1. 浏览到Azure Repos | 文件 | azure-vote | azure-vote | config_file.cfg并点击编辑

  2. 标题的值从Azure 投票应用更改为Contoso 投票应用图 11.56 – 更新应用名称

    图 11.56 – 更新应用名称

  3. 通过拉取请求流程提交更改。

  4. 一旦拉取请求完成,构建流水线将会触发,构建 Docker 镜像并推送到 ACR。

  5. 一旦构建流水线完成,它将触发发布流水线以启动另一个发布。最终,你应该能看到你的 Web 应用已更新标题。

本文到此结束,关于在 AKS 上托管的基于容器的基础设施的 CI/CD 流水线设置。

DevOps 的 Azure 架构中心

Azure 架构中心是一个集中式平台,提供关于在 Azure 上使用已建立的模式和实践来构建解决方案的指导。关于 DevOps,有多个示例架构可供参考。

你可以在这里访问 Azure 架构中心:docs.microsoft.com/en-us/azure/architecture/

请参考以下链接,了解更多关于在各种基础设施和应用场景中规划适当 DevOps 架构的内容:

总结

在本章中,我们分析了一个基于 .NET 和 SQL 的应用程序,并使用 Azure DevOps 为其设置了 CI/CD 管道。我们还探讨了如何通过审批工作流管理生产和预发布环境。

同样,我们还分析了一个基于容器的应用程序,并演示了如何使用 ACR 和 AKS 设置端到端的 CI/CD 管道。

最后,我们讨论了 Azure 架构中心,在规划 DevOps 架构时可以参考此资源。

这是最后一章,我们希望你喜欢阅读这本书!

posted @ 2025-06-27 17:07  绝不原创的飞龙  阅读(4)  评论(0)    收藏  举报