Azure-流水线实用指南-全-
Azure 流水线实用指南(全)
一、理解软件交付自动化的重要性
现代软件开发非常依赖敏捷性,它是项目或产品开发成功的关键因素。快速的技术发展和不断增长的商业趋势要求软件按时高质量地交付。如此快速的软件开发和交付阶段需要软件交付方面的自动化,以确保快速、频繁的部署和更高的产品质量。
从建立一个环境到将一个软件部署到该环境,软件开发应该尽可能地被编码和自动化,以避免人为错误并支持快速的发布节奏,同时将交付软件的质量保持在尽可能高的水平。自动化基础设施的建立以及软件的部署和测试方面大大降低了给定项目或产品的时间成本,因为它需要较少的人力资源干预。除此之外,自动化还进一步防止了人为错误,因为每个目标环境中使用的同一组脚本或任务实现了部署的一致性。
在这一章中,提供了软件交付过程自动化的快速介绍,这在软件项目/产品的应用生命周期管理(ALM)中是至关重要的。理解持续集成(CI)和持续部署(CD)的概念,以及讨论引入基础设施、配置、应用、组件部署自动化的重要性,并在部署后实现测试自动化,将为读者理解和利用本书的其余章节奠定基础。
第 1.01 课:DevOps
DevOps(软件开发开发和信息技术运营??)是你今天在软件开发行业听到的时髦词汇。它定义了软件开发组织的文化和实践。DevOps 的目标是建立一个环境,在这个环境中,定义、构建、测试和发布软件可以更快、更频繁地进行,并且具有更高的质量和可靠性。这需要一个组织采用一种协作文化,其中自动化是一个关键的信念。一家公司需要大量的基础架构更改或升级来支持新的开发运维实践。在 DevOps 文化中,开发人员和 IT 专业人员被鼓励更频繁地相互协作和交流,这强调了团队合作的概念。见图 1-1 。
图 1-1
DevOps 一瞥
微软的多诺万·布朗(Donovan Brown)为开发运维提供了一个更有意义的定义:“开发运维是人员、流程和产品的结合,能够为我们的最终用户持续交付价值。”这突出了这样一个事实,即人民是 DevOps 最重要的方面。人们需要调整实践和过程,以帮助他们协作并为团队的目标做出贡献,并创建一种文化,在这种文化中,自动化在向软件用户交付价值中扮演着重要的角色。
如前所述,软件交付的自动化对于交付高质量的软件和缩短上市时间至关重要。因此,将 Azure DevOps 中的部署自动化功能作为 DevOps 的综合工具套件是值得一试的。在本章接下来的几节中,让我们试着理解软件构建和部署的概念。
第 1.02 课:持续集成(CI)
在软件开发团队中,多个团队成员开发代码并参与创建软件功能。虽然许多人都在为一个代码库做贡献,但是保持代码库的完整性对于确保团队的任何成员都可以检索最新的代码库、在本地构建和运行代码库,并开始做出贡献是非常重要的。为了确保代码库的稳定性,可以使用两个因素。第一个是确保代码编译没有错误。第二个因素是确保所有单元测试都通过,最新的代码变更和单元测试的代码覆盖率非常高。可以定义一个构建来编译代码库的每个签入/提交,然后执行所有单元测试来验证代码库,以确保代码库的稳定性,这通常称为 CI 构建。根据所有单元测试的成功编译和通过,构建可以生成和发布输出,这些输出可以部署到目标环境中。参见图 1-2 。
除了单元测试之外,代码安全漏洞的验证可以集成到构建管道中,以提高项目/产品的安全性。进一步扫描代码质量也是可以在构建管道中验证的一个方面。从长远来看,使用这种左移方法及早检测安全漏洞和代码质量问题将会降低成本,因为在产品中检测到的漏洞修复起来成本很高。
图 1-2
连续累计
第 1.03 课:连续交付(CD)
在现代软件开发方法中,开发团队在短周期内生产软件。最大的挑战之一是确保在任何给定时间向目标环境发布软件的可靠性。直截了当且可重用的部署过程对于降低交付软件变更的成本、时间和风险是必不可少的。这些可能是生产中应用的增量更新。简而言之,CD 正在更频繁、更可靠地交付软件变更,DevOps 可以被认为是持续交付的产物。
第 1.04 课:持续部署
一方面,连续交付确保每个变更都可以部署到生产环境中,同时可以选择暂停生产部署,直到获得人工批准。另一方面,持续部署让每一个更改都可以自动部署到生产中。要实现连续部署,必须准备好连续交付,因为连续部署是通过自动化连续交付的批准步骤来创建的。参见图 1-3 。
图 1-3
持续交付与持续部署
第 1.05 课:发布/部署管道
发布管道描述了从从源代码控制中检索已完成的工作到将软件交付给最终用户的一系列操作。从版本控制中检索到的软件在到达发布管道中的生产环境之前,必须经过几个阶段的构建、测试和部署。基于所使用的软件开发实践,该过程涉及许多个人、团队、各种工具和组件。成功的部署管道应该为使用它的团队/个人提供部署流程的可见性、控制和灵活性。可以有多个关卡和批准级别,以增加通过管道发布的软件版本的可靠性。参见图 1-4 。
图 1-4
发布/部署渠道发布/部署渠道
第 1.06 课:基础设施即代码(IaC)
随着快速部署的高需求,设置新环境来手动部署软件可能是一项挑战,并且容易出错。因此,从头开始编写创建环境的脚本会使新环境运行得更快、更可靠。尤其是在以云平台为目标时,用代码设置新环境会产生更快、更可靠的结果。这种为建立基础设施而开发的代码被称为基础设施代码(IaC)。拥有 IaC 甚至允许版本控制给定项目中的目标环境设置,为我们如何设置环境增加了更多的可追溯性和可见性。有几种工具和技术可以用来实现 IaC,在本书中,我们将在后面的章节中更详细地讨论它们。
第 1.07 课:测试自动化集成
正如我们在持续集成中已经讨论过的,为验证应用代码而编写的单元测试应该在构建管道中执行。然而,还有其他测试,比如功能 UI 测试、API 测试、集成测试以及负载和性能测试,它们不能在构建管道中运行。不可能在构建管道中运行单元测试之外的测试的原因是,它们都需要在部署的目标环境中运行。因此,在将项目/产品部署到目标环境之后,除了单元测试之外,这些类型的测试应该集成到要执行的部署管道中。我们将在 Azure DevOps 系列的动手测试自动化一书中讨论更多关于测试自动化与管道的集成。
第 1.08 课:为什么我们需要自动化软件交付过程?
我们已经在本章前面的章节中讨论了软件交付过程自动化的几个方面。没有这样的软件过程自动化,更频繁地部署软件将是一项具有挑战性的任务。运营团队可能不得不花费大量时间来手动设置和部署新环境。设置过程中很有可能会遗漏一些步骤,导致新环境中出现意外问题,并导致部署的软件不可用或出现严重问题。所有这些都需要时间和金钱来解决。此外,每次设置和部署环境都需要为任务投入额外的人力资源,从而花费更多的钱。参见图 1-5 。
图 1-5
错误成本
考虑到执行完整测试所需的时间和人力资源,如果没有测试自动化来对部署的应用运行回归和冒烟测试,就不可能对每个交付执行完整的手动测试。这可能从两个方面影响应用。一种是跳过测试,因为测试成本可能会导致 bug 蔓延到产品中,这将花费更多的钱,甚至导致客户完全不满意。有时,这种不满会导致针对软件提供商的法律诉讼,这有时会损害整个企业及其声誉。另一个选择是试图一直手动地做所有的测试来确保质量,但是这将花费人力资源的金钱并且延迟交付,导致团队不能按时交付。这显示了尽可能自动化的迫切需要,以避免软件交付测试中的成本和问题。参见图 1-6 。
图 1-6
自动化测试与手动测试
为了避免所有这些成本,自动化部署和测试,结合使用左移方法识别软件中的安全性和其他漏洞,是至关重要的。尽可能早地检测这些漏洞(尽可能在流程流的左侧)将花费更少的钱来修复它们。
摘要
这一章已经向你介绍了软件交付自动化的概念。我们已经探索了 CI 和 CD 的概念,以及使用 IaC 和测试自动化来增强软件交付过程的需求和好处。有了对软件交付自动化概念的理解,我们就有足够的背景知识来探索本书的其余章节,这些章节将关注 Azure 管道来实现所讨论的概念。
在下一章中,我们将讨论 Azure Pipeline 特性的概述,这些特性将支持您理解其余章节,详细讨论每个特性及其用法。
二、Azure 管道概述
连续交付和部署已经成为从详细说明链接软件开发行业的重要方面。正如我们在第一章中所讨论的,持续集成和交付管道立即将您的软件开发过程带到一个高性能和可靠的水平。Azure DevOps 为我们提供了很好的特性,可以根据我们的项目需求创建 CI/CD 管道。本章将通过提供 Azure DevOps 管道特性的各个方面的基本介绍,帮助您了解 Azure DevOps 管道。
第 2.01 课:池和代理简介
正如您已经知道的,CI/CD 通过自动化构建和部署过程提高了您的交付速度。说到自动化,你需要一台机器在没有任何人类互动的情况下为你做这件事。Azure DevOps 提供代理为您做 CI/CD 工作。本课将帮助您了解这些代理以及在 Azure DevOps 中的何处可以找到它们。
在 Azure DevOps 中,您可以在项目设置下找到代理池部分。您将在“池”部分找到所有代理的详细信息。有两种类型的代理池:
Azure Pipelines:微软托管的代理池,包含所有平台的机器,Windows、Linux 和 MacOS,其中安装了许多软件工具。
私有/自托管代理池:有一个默认的私有池,您可以根据自己的需要创建更多的私有代理池。然后,您可以在这些专用池中注册机器,用作构建或部署机器。
转到“项目设置”,选择团队项目中“管道”部分下的代理池,以便查看代理池。见图 2-1 。
图 2-1
代理池
Azure DevOps 允许您基于项目可访问性类型(如私有或公共)使用大量托管代理管道。公共项目允许您在托管管道上一次使用十个并行执行,而私有项目(其中您的源代码或其他项目详细信息对公共访问是隐藏的)只允许您在给定时间使用一个构建或部署执行。参见图 2-2 。
图 2-2
Azure DevOps 代理
正如已经提到的,我们可以在私有池中配置我们自己的代理,这将在以后的章节中详细解释。配置自承载代理后,它将与该代理的所有信息一起添加到代理池中。例如,摘要将给出代理中安装的软件的详细信息以及这些版本。
Azure DevOps 以其多平台支持而闻名。一旦您检查托管代理池中的代理集合,您就能够体验 Azure DevOps 的这种多平台支持。以下是我们在本书中使用的版本中可用的不同托管代理。它支持 Mac、Ubuntu 和 Windows。参见图 2-3 。
图 2-3
托管代理池中可用的代理
此外,可以控制代理池权限以提供安全的访问。它有三个主要的权限级别。参见图 2-4 。
图 2-4
代理池安全性和权限
-
读者–只能查看代理池
-
用户–可以查看和使用池,但不能管理或创建代理池
-
管理员–可以管理、查看和使用代理池
即使是单个代理池,也可以应用与上面类似的单独权限集。
本课解释了什么是代理池以及可用的代理类型。此外,我们讨论了可以使用代理池功能部分来监控自托管代理的功能。最后,我们能够理解如何使用池的安全性部分中可用的权限级别来控制代理池的访问和管理功能。我们将在本书的后续章节中讨论关于代理的更多细节。
第 2.02 课:部署组
我们已经在本章的第一课中讨论了代理和池。正如我们已经知道的,代理是帮助执行构建或部署的专用机器。部署组也类似于代理池。部署组是一组安装了代理的计算机。部署组的特点是每台机器都是一个实际的部署目标,专用于每个部署环境,并有一个角色。例如,一个部署组可以拥有一台以 dev 为目标、以 webserver 为角色的机器,它们仅用于部署到 dev 环境的 web 应用。同样,一个部署组为每个部署目标和一个角色配备了一台专用机器。
转到 Azure DevOps 的组织设置。您将能够在 pipelines 部分找到部署池。在此部分,您可以创建和管理部署组。参见图 2-5 。
图 2-5
部署池
在配置部署组时,我们可以提供我们将要使用该组的项目。一旦我们创建了一个部署池,它就允许我们选择项目并定位我们需要使用的服务器平台。根据您的要求,Azure DevOps 提供了一个注册脚本,可用于配置部署组。参见图 2-6 。
图 2-6
部署组创建
在配置部署组时,使用注册脚本允许您为部署组的每个服务器添加标记,以表示机器的角色。例如,如果您创建一个标记为“Webserver”的服务器,那么您可以使用这个服务器来进行 web 应用部署。因此,在使用部署管道时,可以通过在代理阶段选择部署组来对部署任务进行分组,我们将在以后的课程中更详细地讨论这一点,这将有助于您更好地理解部署组的概念。
在本课中,我们对部署组及其用途有了基本的了解。您将能够在以后的章节中了解更多关于部署组的内容。
第 2.03 课:构建管道
在本课中,您将能够对如何构建管道有一个基本的了解。您还将了解什么是构建管道以及为什么使用它。
通过使用持续集成选项,Azure DevOps 构建管道可用于构建您的源代码,以尽早识别代码问题。您可以使用 Azure DevOps 构建管道来构建、测试和创建可部署的代码包。此外,构建可以用来为输出包分配版本号。
转到 Azure DevOps 项目,并从左侧窗格菜单中选择“管道”。您可以看到可以创建构建管道的管道部分。参见图 2-7 。
图 2-7
构建管道
Azure DevOps 支持两种类型的构建:即经典构建和 YAML 非标记语言(YAML)构建。经典编辑器允许您使用图形视图,并根据您的要求创建构建管道。但是当涉及到 YAML 构建时,您需要很好地理解 YAML 语法,以编写声明性脚本来将构建管道定义为代码。
构建管道的主要目的之一是从源代码创建可部署的包。但是,为了使用 Azure 版本,并不强制将代码保存在 Azure DevOps repos 中。Azure DevOps 允许你使用几个源代码控制系统。例如,如果您的源代码在 Bitbucket 中,您可以在 Azure DevOps 构建管道中构建 Bitbucket 代码。Azure Pipelines 支持广泛的存储库,如 Azure Repos、GitHub 和 GitHub Enterprise、Bitbucket、Subversion 和其他 Git repos。
在 classic editor 中,它允许您选择模板来创建构件或使用空作业,这适用于创建符合您需求的所有步骤。带有空作业的经典构建将如图 2-8 所示。
图 2-8
经典编辑器使用空作业构建管道
在构建管道中,有一些代理阶段,允许您在每个阶段下对代理的任务进行分组。Azure DevOps 有两个阶段:
代理阶段——与代理池中的代理连接,使用代理池代理执行任务。
无代理阶段–它无法连接代理池中的代理。此阶段下的所有任务都将在 Azure DevOps 服务器本身中执行。
构建管道的主要目的是构建代码、测试代码并生成输出包。当生成构建输出时,我们可以在服务器或文件共享上发布包。此外,我们可以生成包,并使用构建管道将这些包推送到 Azure DevOps 工件源。
Azure DevOps 管道中的另一个重要特性是触发器,它允许我们决定何时开始构建。触发器可用于决定新构建何时开始。此外,如果变更来自特定的分支,我们可以定义它,然后只触发一个构建。此外,我们可以使用文件夹路径作为过滤器来控制触发器,这样,如果某个东西被提交到给定的路径,就会触发一个构建。另一个选择是设置构建在给定的时间表上运行。我们将在后面的章节中讨论这些构建触发器。
安全性是任何类型工具的一个非常重要的特性。Azure DevOps 使用几种安全机制来保护整个部署过程。此外,它允许您通过限制每个用户或用户组的访问权限来单独保护每个构建管道。
正如本课中所讨论的,build 主要用于构建、测试和打包源代码作为可部署的输出。我们现在对 Azure DevOps 构建管道的能力有了一个简单的概念。我们将在以后的章节中讨论更多的细节。
第 2.04 课:释放管道
本课将介绍释放管道。发布管道,也称为部署管道,用于将版本部署到选定的部署平台。例如,Azure DevOps 发布了管道,可用于将 web 应用、功能应用、逻辑应用和各种类型的工件部署到 Azure 平台。
转到 Azure DevOps 项目并选择 pipelines 部分下的 releases。在此部分,您可以创建和管理所选项目的所有发布管道。参见图 2-9 。
图 2-9
释放管道
发布管道的主要目的是将创建的可部署包部署到目标宿主平台。
Azure DevOps 管道有一个工件部分和阶段部分。工件是发布管道的起点,可用于设置连续部署触发器。需要添加一种类型的工件来启用部署。工件部分允许您选择不同类型的工件,比如构建输出、来自工件提要的包以及像 Jenkins 这样的第三方工件。我们将在接下来的章节中探索 Azure 发布管道支持的所有工件类型。一旦启用了连续部署,就可以使用构建分支筛选器来控制这种连续部署。如果构建是由于给定分支中发生的变更而触发的,那么您可以说 deploy。此外,您可以启用拉请求触发器,允许您决定是否将从拉请求生成的工件部署到给定的目标分支。
在部署管道的各个阶段,您可以定义允许您控制部署的部署前和部署后条件。在预部署条件下,Azure DevOps 有三个主要触发器:手动触发器,在创建新版本后开始部署,如果管道的前几个阶段的部署成功,则触发给定阶段的部署。此外,部署前和部署后批准允许您基于手动批准控制部署流程。可以添加工件过滤器,允许您添加不同的条件。因此,只有满足这些条件,部署才会继续。此外,您还可以添加条件来控制拉式或基于请求的部署。Azure DevOps 具有 gates 特性,可以根据 gate 条件返回值的结果来控制部署。Gates 允许您基于 Azure 函数、REST API、工作项查询和其他几个 gates 来设置各种条件。此外,可以使用预部署条件来控制计划部署。
使用部署管道时,需要在几个阶段暂停部署。例如,一旦您部署到 QA 环境,如果自动化测试用例没有测试应用的合理区域作为覆盖,我们需要等待直到手工测试完成,以继续部署到生产。因此,我们可以在部署前和部署后步骤中设置手动批准。
与任何部署工具一样,Azure DevOps 也引入了几个选项来保护工具。对于部署管道,控制这些部署权限非常重要。否则,如果部署发生在错误的时间并且失去控制,就会给你带来很多麻烦。因此,我们可以通过仅向选定的用户或选定的用户组授予管理权限来单独保护每个部署管道,仅允许指定人员批准对重要目标(如生产)的部署。
本课对释放管道进行了基本介绍。您将在后续章节中了解发布管道的更多功能。
第 2.05 课:任务组
本课将向您介绍任务组。正如你已经知道的,我们可以为构建、执行单元测试和创建可部署的包创建 Azure DevOps 构建管道。要将应用的版本部署到目标平台,可以使用部署管道。每种类型的管道都使用任务/步骤来执行构建和部署步骤。有时,当我们在一个项目中工作时,我们会创建一个以上的管道,并且可能在两个管道中使用相同的步骤。如果我们必须创建一百个管道,我们需要创建一百次相同的管道。但是 Azure DevOps 为我们提供了一个任务组功能,我们可以创建一组可以在多个管道中使用的任务,并发送与每个管道相关的参数值。任务组有助于将可实现的、可重用的步骤作为多个管道中的单个块。
转到 Azure DevOps 项目并选择 Pipelines 部分下的任务组。参见图 2-10 。
图 2-10
任务组
Azure DevOps 任务组还通过引入安全机制来确保任务组的安全性,我们可以使用这些安全机制来控制项目用户的访问和管理功能。我们将在接下来的章节中讨论任务组的细节以及它们的使用示例。
在本课中,我们能够对什么是任务组有一个基本的概念。我们简要讨论了任务组的目的,这将有助于你继续准备本书的其余章节。
第 2.06 课:图书馆
这一课给你一个 Azure DevOps 库的基本介绍。该库可用于将管道的变量值保存为变量组,并将文件存储为安全文件。使用管道时,需要为管道任务定义变量。有时,多个管道之间会共享一些变量。当有这样的需要时,我们可以将共享变量保存在库下的一个变量组中。
转到 Azure DevOps 项目并选择管道下的库部分。您可以在这里添加变量组和管理共享变量。见图 2-11 。
图 2-11
图书馆
除了共享变量之外,Azure DevOps 库还允许你保存安全的文件,比如可以在管道中使用的证书和密钥。因此,您可以将所有受保护的文件保存在库部分。但是如果我们在这里保存受保护的文件,我们需要控制每个文件的访问权限。Azure DevOps 通过允许我们决定哪个管道可以使用受保护的文件以及哪个项目用户可以管理这些受保护的文件来确认这些文件的安全性。
在本课中,我们讨论了 Azure DevOps 库的基本用法。在以后的章节中,你会学到更多关于如何创建和使用变量组和安全文件的知识。
第 2.07 课:服务连接
服务连接是部署管道所需的最重要的功能之一。当我们进行部署时,我们需要在我们的 Azure DevOps 组织和外部资源之间创建连接,例如平台服务(如 Azure)、源代码控制提供者或其他外部服务(如 NuGet feeds)等。您甚至可能希望连接到第三方构建和部署平台,或者代码质量检查或代码安全性验证工具。几个例子是 Jenkins、章鱼或部署声纳云。简单的云部署目标也是通过服务连接连接到 Azure DevOps 组织的构建和部署的支持工具。
转到 Azure DevOps 项目设置,在管道部分,您可以导航到服务连接部分。参见图 2-12 。
图 2-12
服务连接
Azure DevOps 允许您连接许多工具和外部服务。您可以创建服务连接来连接像 Azure 这样的部署平台。此外,您可以使用服务连接来连接外部源代码控制工具,如 Bitbucket 和 GitHub。在某些情况下,我们尝试使用多种部署工具。因此,Azure DevOps 允许您与 Jenkins 和 Octopus 等服务器建立服务连接。使用服务连接可以连接许多工具。
添加服务连接后,它不应该被项目的所有用户控制。您可以使用权限级别来保护服务连接。对于一个服务连接,我们可以有两个用户权限:
用户–可以使用服务连接,但不能管理它
管理员–可以创建、管理和使用服务连接
本课简要介绍了什么是服务连接,以及它对 Azure DevOps 管道有多重要。此外,我们还了解了一些可以用 service connection 连接的外部工具和服务。我们将在以后的章节中讨论如何创建服务连接以及如何在管道中使用它们。
第 2.08 课:环境
Azure DevOps 部署/发布管道可用于各种部署。我们主要做 web app 部署,DB 部署,AKS 部署,功能 app 部署等。如果 Azure 是部署目标,则需要登录 Azure 门户来监控每个部署目标。Azure DevOps 引入了一个新功能,可用于从 Azure DevOps 服务器监控部署目标,而无需登录 Azure 门户。
Azure DevOps 环境部分在 pipelines 下提供。参见图 2-13 。
图 2-13
Azure DevOps 环境
Azure DevOps 环境代表了部署管道可以针对的资源集合。作为例子,我们可以使用 Azure Kubernetes 服务的名称空间,在撰写本书时,这些名称空间是 Azure DevOps 环境中的数据库。
Azure DevOps 环境提供了跟踪部署管道历史和部署资源细节的能力。此外,您可以跟踪每个部署环境中部署了哪些变更集,这对于识别部署了哪些特性或错误修复非常有帮助。此外,Azure DevOps 环境有一个非常重要的特性,它提供了部署资源的健康详细信息。因此,它允许用户跟踪部署的应用是否在期望的状态下运行,或者它是否需要更多的关注。
Azure DevOps 环境安全部分允许您使用三种不同的权限级别来控制环境管理功能:
创建者-可以管理、创建和经营环境
读者-可以看到环境
用户–可以创建环境
除了这些用户权限之外,环境只能与允许的管道一起使用。
正如我们在本课中所讨论的,环境可用于跟踪与部署管道相关的资源的性能,这对于跟踪部署到每个目标环境的所有更改非常有用。
第 2.09 课:并行管道和计费
正如我们所讨论的,Azure DevOps 有两种主要类型的代理:微软托管代理和自托管代理。但是,当我们使用多个管道进行部署时,我们需要并行部署的能力。否则影响项目的效率。
如果我们使用越来越多的自托管代理来进行并行部署,将会对项目预算产生巨大的负面影响。因此,Azure DevOps 服务器有几个可用选项。
在 Azure DevOps 中,转到项目或组织设置页面,并选择管道部分下的并行作业,以查看您的组织的并行作业功能。参见图 2-14 。
图 2-14
平行作业
当创建 Azure DevOps 项目时,有两个选项作为公共和私有项目。如果项目是作为公共项目创建的,它可以使用 Microsoft 托管的代理,这些代理支持十个并行作业。此外,如果您为一个公共项目创建一个自托管代理,它有无限的并行作业。因此,在不挂起或留在队列中的情况下进行部署非常重要。因此,Azure DevOps 为公共项目提供了多种并行作业执行能力。
如果项目是作为私人项目创建的,Microsoft 托管的代理每月提供 1,800 分钟。此外,它有一个并行作业,这意味着一次只能部署一个管道。对于自托管代理,它也有一个并行作业。但是,如果组织订阅了 Visual Studio Enterprise,则会向自承载代理添加一个并行作业。如果组织有越来越多的订阅,它会将更多的并行作业添加到管道中,作为每个订阅的一个附加并行作业。
当谈到 Azure DevOps 计费时,它免费提供了大多数功能。正如我们之前讨论的,它免费为 Microsoft 托管的代理提供一个并行作业,为自托管的代理提供一个并行作业。董事会和回购是免费的,最多五个用户。此外,它还免费提供高达 2GB 的工件存储空间。
测试在构建和部署周期中也扮演着更重要的角色。因此,Azure DevOps 为测试计划的创建提供了 30 天的免费试用。试用期过后,你就可以购买了。
转到 Azure DevOps 组织设置页面,并选择常规部分下的计费。参见图 2-15 。Azure DevOps 计费设置允许用户监控当前计费并为组织设置新的计费。
图 2-15
演员表
到目前为止,我们已经讨论了 Azure DevOps 计费和并行管道执行功能。在使用 Azure DevOps 时,这些类型的信息对于决策非常重要。在以后的章节中,您将了解到关于这些计费和并行作业的更多细节。
摘要
在本章中,我们讨论了与 Azure 管道相关的几个特性。我们确定了构建和部署管道、Azure DevOps 代理以及代理的使用。然后,我们简要讨论了任务组和库选项。此外,我们还了解了 Azure DevOps 的环境和计费。
在下一章,我们将讨论设置代理池;部署组和其中的代理,这将在本书的剩余部分继续帮助我们。
三、设置池、部署组和代理
在前两章中,我们讨论了持续集成和交付的概念,并简要探讨了 Azure Pipelines 的概念和特性。这为我们深入研究 Azure Pipelines 的每个特性提供了背景,这将使我们能够理解如何利用 Azure Pipelines 来自动化软件交付过程。
在这一章中,我们将看看 Azure Pipelines 中的代理。正如我们已经讨论过的,我们有两种类型的管道可以在 Azure DevOps 中使用。一个是 Azure Pipelines,它让 Windows、Linux 和 Mac 代理托管在微软服务器上,促进和构建许多类型的软件项目。下一种类型是自托管代理,可用于将您自己机器的虚拟或物理组件添加到您可以在 Azure DevOps 中创建的代理池中。
拥有一个自托管代理的主要优势是可以满足一些我们用 Azure 托管的管道无法满足的需求。其中一个需求是拥有自定义版本的软件需求来构建您的软件项目,例如,如果您需要一个特定的 SharePoint 版本,并且您的项目依赖于 SharePoint 库。Azure 托管的代理没有这种类型的特定需求,这是自托管代理派上用场的情况之一,因为你可以在你的机器上安装任何你想要的软件。
自托管(内部-甚至可以是云虚拟机)代理的另一个好用途是当您尝试部署到内部环境时,其中的计算机位于合作防火墙之后。在这种情况下,Azure 托管的代理看不到 cooperate 防火墙后面的机器。另一种你看不到 Azure 托管的管道的情况是当你使用 Azure App Service Environments(ASE)实现完全隔离和安全时。自托管代理的所有这些场景都有帮助,因为它们可以驻留在协作网络或 ASE 中,并使用所需目标的本地网络可访问性来执行 Azure 管道分配的部署作业。见图 3-1 。
图 3-1
视线
首先,让我们看看如何创建代理池并在其中设置权限。然后,通过几节课,让我们将代理添加到我们创建的池中,以了解如何在本章中使用它们。
第 3.01 课:设置池和权限
如前所述,我们可以将自托管、内部部署的机器、虚拟机或云虚拟机设置为代理。在设置代理之前,我们需要定义代理池以将代理作为一个组。一个代理池可以有多个分配了相同功能的代理,以使消费构建或发布管道能够在给定时间点利用可用代理的服务。
可以在两个级别上定义池。首先,您可以在 Azure DevOps 组织中定义一个池,并将其添加到所有现有的团队项目中。为此,请单击您的 Azure DevOps 组织中的组织设置,然后单击代理池➤添加池。您可以看到用于设置代理的名为 default 的默认自承载池(如果可用)。见图 3-2 。
图 3-2
添加池
将出现一个窗格,允许您为新池提供名称。通过授予权限,可以允许所有管道使用新池中的代理。如果希望以后从团队项目设置中将新池仅添加到所需的团队项目中,请取消选择使新池可用于所有团队项目的选项。见图 3-3 。
图 3-3
添加池
添加池后,您可以单击池名称导航到其作业页面,该页面显示代理池正在运行和排队的作业。您可以单击“设置”页面,在“设置”页面中,有一些选项允许将池应用于组织中创建的任何新团队项目。但是,此设置不会为任何现有项目提供已经创建的代理池。见图 3-4 。您只能在创建池时将池添加到现有项目中(参见图 3-3 ),或者通过转到单个团队项目并添加现有池来添加。您可以在设置页面中为池中的代理设置维护计划。见图 3-4 。
图 3-4
池设置
维护历史记录将显示为池中的代理执行的任何维护活动。“代理”选项卡允许您将代理添加到池中,在“详细信息”选项卡中,您可以查看详细信息,如池的描述和所有者。
在“安全”选项卡中,您可以为创建的代理池定义权限。如第二章所述,在代理池中有三种类型的权限可以分配。读者将被允许查看代理池。服务帐户权限将授予查看代理、创建会话和侦听池分配的作业的权限。管理员可以管理池,并查看和使用它。见图 3-5 。
图 3-5
代理池权限
转到团队项目,单击“项目设置➤代理池”导航到“项目设置代理池”页,将代理池添加到团队项目中。您可以添加没有为团队项目设置的现有池,也可以从“团队项目设置”页添加新池。从团队项目中添加池时,它只会被添加到当前团队项目中。如果希望将其添加到另一个团队项目中,可以通过将现有池添加到其他团队项目中来实现。见图 3-6 。
图 3-6
将代理池添加到团队项目中
在本课中,我们探索了向 Azure DevOps 组织和团队项目添加代理池的选项。自定义代理池对于设置自承载代理和使用不同的代理池非常有用,可让您将一组用于相同目的的代理组合成一个池。我们在本课开始时详细讨论了代理池的用处。
第 3.02 课:向池中添加代理
您可以将虚拟机或物理机设置为自托管代理。这些代理可以添加到名为 Default 的池中,这是默认的自承载代理池;或者如前一课所述,您可以向团队项目中添加自定义池。我们可以使用这些池来添加代理。要将代理添加到池中,您需要在添加代理的池中分配管理员角色。您可以在项目或组织的设置中进入该池。
有三种类型的计算机(Windows、Linux 和 Mac)可以设置为自托管代理池中的代理。设置每种类型的代理的说明可以在面板中找到,该面板通过单击“项目/组织设置”“➤代理库”,然后单击“代理库名称”“➤新建代理”按钮来加载。参见图 3-7 。
图 3-7
新代理
让我们从将 Windows 计算机作为代理添加到池开始。您只需按照加载的面板窗口选项卡中的说明进行操作。参见图 3-8 。
图 3-8
Windows 代理安装说明
您也可以点击图 3-8 所示的下载按钮,手动下载代理 zip 文件。然后将其提取到一个文件夹中。使用命令提示符或 PowerShell 窗口,运行 config.cmd 并按照提示进行操作。您必须提供 Azure DevOps 组织 url。然后你需要提供一个个人访问令牌(PAT ),我们已经在本系列的 Azure Boards 手册中讨论了如何创建一个。PAT 需要定义代理池管理和读取范围。您可以不使用 PAT,而是使用 negotiate 或 alt 作为身份验证选项,并提供用户名和密码来注册代理,或者使用集成身份验证类型来使用登录的 windows 凭据。您使用的凭据只需要设置代理,而不是用于维护代理与 Azure DevOps 的连接的凭据。因此,您不需要在设置代理后保持 PAT 或其他凭据处于活动状态,因为代理和 Azure DevOps 在设置代理时使用不同的机密令牌设置进行通信,这对您是不可见的。您可以从图 3-8 所示的详细说明链接中获得详细信息。您可以提供代理需要加入的代理池的名称。只要代理不需要执行任何交互活动,将代理作为服务运行是明智的。在您需要运行需要桌面交互的 UI 测试的场景中,您可以将其配置为具有自动登录选项的交互。见图 3-9 。
图 3-9
配置代理
或多或少,以类似的方式,您可以按照图 3-8 所示面板中选项卡中的说明,在 Mac 或 Linux 中设置代理。代理注册后,它将在代理池的“代理”选项卡中可用,并且可以执行由代理池分配的作业。可以启用或禁用代理,以便允许池向其分配作业。见图 3-10 。如果您在池中的给定代理上执行维护任务,例如应用安全补丁、安装软件,甚至应用 Windows 更新等,这将非常有用。
图 3-10
池中的代理
您可以单击代理来查看其作业和功能。“作业”选项卡将显示代理已执行和正在进行的作业。“功能”选项卡将显示代理的系统功能,您可以添加手动功能作为键和值,以便这些功能可用于构建和发布管道中的需求代理。这些需求如何工作将在第四章中讨论。见图 3-11 。
图 3-11
用户能力
关于向池中添加代理的课程到此结束,在该课程中,我们探索了在何处可以找到为所有平台在池中设置代理的说明。此外,我们以基于 Windows 的代理为例,讨论了设置代理的重要信息。此外,本课还解释了如何为自托管代理定义用户功能以及如何查看系统功能。
第 3.03 课:设置部署组
部署组可用于将部署目标保存在机器中。一个部署组可以注册多台机器,可以在这些机器上设置一个部署代理,标记不同的角色,如 webserver、dbserver 等。,表示该计算机在部署组中的用途。
在 Azure DevOps 组织级别,您可以在设置中找到部署池。部署池允许您与多个团队项目共享一个部署组。从“组织设置”中,您可以定义新的组织池。见图 3-12 。
图 3-12
创建新的部署池
如果需要,可以在创建部署池时将部署池设置为选定项目中的部署组。见图 3-13 。
图 3-13
新部署池
创建部署池后,您可以单击池名称,通过执行适用于 Windows 和 Linux 机器的脚本将机器添加到池中。下拉菜单允许您根据机器类型选择操作系统和可用的脚本更改。您可以单击 Use a personal access token 选项,将 PAT 嵌入到脚本中,这样它就可以在最少交互的情况下自动执行,将一台机器设置为部署组中的目标。您可以在 Azure DevOps 组织中的其他现有团队项目中设置部署组/池,甚至可以从当前设置的团队项目中移除部署组。见图 3-14 。
图 3-14
部署池详细信息
在“安全性”选项卡中,您可以定义部署工具的安全性。您可以定义四种类型的角色,并将用户或组添加到池权限中。管理员可以查看、管理和使用部署池。用户角色可以使用该池在团队项目中创建部署组并查看该池。服务帐户可以查看部署池中的代理/目标,并侦听池中的作业。读者只能查看池。参见图 3-15 。
图 3-15
部署池安全性
您可以展开 Azure Pipelines 左侧菜单,在那里您可以找到 deployment groups 子菜单,在这里您可以创建部署组或部署池中已经可用的配置作为部署组。见图 3-16 。
图 3-16
部署组
添加新部署组时,可以为其提供名称和描述。见图 3-17 。
图 3-17
从项目创建部署组
一旦在项目中创建了部署组,您就可以通过与其他团队项目共享它来在其他团队项目中提供它。参见图 3-18 。
图 3-18
共享部署组
在部署组中,您可以为角色读者设置安全性,读者只能查看该组;可以在管道中使用组的用户;以及可以管理和使用该组的管理员角色。与部署池窗口类似,团队项目中的部署组允许您复制并使用脚本在所需的操作系统、Windows 或 Linux 中创建目标。参见图 3-19 。在 targets 选项卡中,您将能够看到部署组的目标。
图 3-19
部署组详细信息
在项目中创建的部署组在组织设置中作为部署池提供,您可以在其中为项目、目标或设置安全性提供该部署组。见图 3-20
图 3-20
部署池
在团队项目中,可以使用组织的现有部署池来设置部署组。见图 3-21 。
图 3-21
将可用池作为一个组进行资源调配
在这一课中,我们学习了如何创建可在 Azure 管道中使用的部署组来完成部署。
第 3.04 课:向部署组添加目标
部署组中的目标是可以设置为参与部署的目标计算机、目的地或可以在 Azure 管道中使用的目标。您可以将 Windows 或 Linux 机器设置为部署目标,这在您的软件系统是本地的或者基础设施虚拟机设置在云平台上时非常有用。
若要添加部署目标,可以转到“组织设置”中的部署池或团队项目中的部署组。打开部署细节后,您可以找到可以在 Windows 或 Linux 机器上复制的脚本。选择个人访问令牌选项以在脚本中嵌入 PAT,以便它可以通过 Azure DevOps 进行身份验证来设置部署目标。通过复制上一课中所示的脚本,并使用管理权限在目标计算机 PowerShell 或终端 windows 中执行它,这将设置一个代理,并将目标计算机添加为部署组。见图 3-22
图 3-22
将目标计算机注册到部署组/池
与代理池代理类似,目标和部署组之间的通信是使用不同于您用来设置的 PAT 的令牌来维护的,因此不需要 PAT 处于活动状态来保持目标对部署组可用。
一旦将目标添加到池/组中,它将可用于使用相同池的部署组提供的项目。见图 3-23 。
图 3-23
部署池与目标一起添加
您可以向目标添加标记,以定义其在部署过程中的角色。见图 3-24 。
图 3-24
目标用 WebSrv 标记
但是,当您在多个项目中使用部署池来设置部署组时,可以在不同的团队项目部署组中为同一目标定义不同的标记。简单地说,这意味着同一台计算机可以作为目标位于同一部署池中,但可以作为不同的部署目标角色在不同的团队项目部署组中使用。见图 3-25 。
图 3-25
不同项目中的部署目标使用相同的部署池
在本课中,我们讨论了在部署组中设置目标的选项,这将有助于部署到您自己的内部或云基础架构的目标。
摘要
在这一章中,我们探讨了如何创建一个自托管的代理,它可以促进自定义构建管道的执行,并满足微软托管的 Azure Pipelines 代理的特殊软件需求。此外,如果您有备用机器或您自己的带有虚拟机的数据中心,您可能更愿意通过在您自己的代理池上注册它们来将它们用作构建代理。此外,我们还讨论了部署组和目标,以及如何设置它们来促进您自己的基础设施上的软件部署。
在下一章,我们将探索使用经典编辑器创建 Azure 构建管道的选项。
四、创建构建管道——经典——源代码管理、模板、作业和任务
构建管道允许您编译源代码,运行单元测试,并将您的代码发布为可部署的工件。在经典的构建管道中,您可以轻松地拖放步骤,并以非常直观的方式设置管道。您可以使用构建管道中的几个可用设置来确定其行为。在接下来的三章中,我们将详细探讨这些特性及其用法。
在本章中,我们将讨论 Azure DevOps 构建管道的几个部分。您将能够经历从选择源代码到构建和打包已构建的二进制文件以供发布的整个构建过程。
第 4.01 课:使用源代码管理提供程序
构建管道的主要目的是构建源代码、执行单元测试,以及将构建的源代码发布和打包为可部署的工件。我们需要从源代码控制库中选择源代码来构建。
构建管道创建的第一个重要特性是选择源代码报告。Azure DevOps 提供了两个内置的源代码管理提供程序。它们是被称为 team foundation 版本控制(TFVC)的集中式源代码控制 repo 和分布式源代码控制 repo Azure Git。因此,可以使用 Azure DevOps 将项目源代码作为 Git 源代码控件或 TFVC 来管理。但是当我们在 Azure DevOps 中创建构建管道时,它并不局限于它们自己的源代码控制仓库。您可以使用 Azure DevOps 构建管道连接外部源代码控制仓库,如 GitHub、Subversion、BitBucket 和其他 Git 仓库,并创建构建包。
转到 Azure DevOps 管道部分。开始创建新的构建管道。Azure DevOps 有两种类型的管道:YAML 构建管道(我们将在第八章讨论)和经典构建管道。选择 classic 编辑器,然后它会引导您到可以选择存储库的部分。见图 4-1 。
图 4-1
经典编辑器链接
经典编辑器是构建管道创建的更直观的版本。Azure DevOps 经典编辑器允许编码经验较少的用户轻松创建构建管道。在构建管道创建的开始,您可以选择您的源代码所在的存储库。见图 4-2 。
图 4-2
选择存储库
正如我们之前提到的,Azure DevOps 内置了两种类型的源代码控制:即 Azure Git Repo 和 Team Foundation 版本控制(TFVC)。这两个存储库都可以用来保存项目的源代码。
如果您选择 Azure Git repo 作为源,它将允许您从源选择页面中可用的下拉列表中选择团队项目、相关存储库和分支。选择相关值后,通过单击 continue 按钮继续构建创建过程。
选择空作业并创建构建管道。见图 4-3 。
图 4-3
选择空工单
创建构建管道后,您将能够看到“获取源代码”部分,该部分允许 Azure DevOps 用户更改源代码并更新所选源代码的值。
如果您继续使用 Azure Git repo,您也可以从这里选择 Azure DevOps 项目、存储库和分支。除了这三个值,它还允许我们为管道提供一些重要的配置值。参见图 4-4 。
图 4-4
Azure Git repo 作为源
图 4-5
源 Repo 构建标记和构建状态
-
Clean:通过将值选择为 true 来启用 clean,以便在运行构建之前清理代理中的构建工作区。
-
标记源代码:在每次构建或每次成功构建后,您都要在源代码中添加一个标记。如果您选择值为“成功时”或“总是”,它允许您决定标记格式。标记允许您跟踪由该版本生成的变更集/提交。此外,如果需要,您可以使用标签创建一个新的分支。在回购的“历史记录”标签中可以看到这些标签。参见图 4-5 。
图 4-6
显示构建状态
-
报告构建状态:显示源库中的构建状态为成功或失败,如图 4-6 所示。
-
签出子模块:如果选择了此选项,将允许构建管道从同一存储库或外部存储库中的子模块中签出文件。
-
从 LFS 签出文件:如果选中,此选项将在签出生成期间在生成代理中签出大文件,如音频和视频文件。
-
不同步源代码:这将不会在签出过程中同步源代码。
-
浅层获取:它允许您决定需要获取多少提交。
到目前为止,我们已经讨论了当我们选择 Azure Repos Git 作为源代码控制时,Azure DevOps 中可用的功能。
让我们讨论一下当我们选择 TFVC 作为源时可用的特性。参见图 4-7 。
图 4-7
TFVC 作为来源
一旦您选择 TFVC 作为源,它允许您决定工作空间映射。您可以决定使用这个构建来构建哪些源代码。
-
类型:有地图和斗篷两种。如果选择“映射”,它会将给定服务器路径中的选定文件夹映射到使用此生成管道进行的生成。如果您选择遮盖,它会排除选定文件夹的内容。
-
服务器路径:选择要在此版本中包含或排除的源代码。
-
$(build.sourcesDirectory)下的源路径:决定源中需要包含在构建中或从构建中排除的文件夹。
一旦您使用 TFVC 作为源创建了一个构建管道,它允许您随时更改工作区映射。除此之外,您可以在构建之前清理工作目录,并在构建成功完成时用构建号标记构建。
除了使用 Azure Git 和 TFVC 回购,Azure DevOps 允许您使用以下外部回购:
-
开源代码库
-
GitHub 企业服务器
-
破坏
-
云的碎片
-
其他 Git 休息
选择所需的外部回购并授权与其连接。之后,您可以使用 Azure DevOps 构建管道在外部 repo 中构建和打包源代码。
本课讨论了什么是源代码控制仓库,以便您可以连接 Azure DevOps 构建管道。此外,本课还解释了连接内部回购和外部回购的能力。
第 4.02 课:使用模板
随着新的开发工具和技术越来越频繁地引入到行业中,构建和部署工具也需要不断地改进,以便与那些新的开发工具和技术一起工作。Azure DevOps 有各种类型的构建模板,支持并使用多种技术设置构建管道。
当您创建 Azure DevOps 构建管道时,您可以使用空管道或模板来创建它。这一课将解释什么是模板,以及 Azure Pipelines 如何使用它们轻松设置。
我们已经知道,构建管道的目的是从链接的源 repo 中获取源代码,编译并构建源代码,测试源代码,发布代码,最后将发布的代码打包为可部署的包。Azure DevOps 中有各种可用的构建任务,我们可以使用它们来配置构建管道步骤。因此,我们必须一个接一个地添加每个相关的任务来建立一个构建管道。然而,使用 Azure DevOps 构建模板,您可以将特定技术构建设置的多个步骤添加到构建管道中,包括成功构建项目所需的通用配置值,这使得设置管道变得简单明了。
通常,Azure DevOps 构建模板是作为包创建的一组构建管道任务。模板可能包含恢复所需依赖项所需的所有任务,例如 NuGet 包、构建源代码、测试源代码、发布源代码,以及最终创建可部署的包。它还可能包含特定技术类型项目所需的一般配置。在添加了相关的构建模板之后,您可以通过对管道进行微小的更改来完成您的构建管道。因此,对于初学者来说,这使得构建管道配置过程更加容易。Azure DevOps 中有各种构建模板支持构建管道的设置,这些模板使用不同的开发工具和技术。让我们确定几个可用的构建模板。
ASP.NET 核心是一项众所周知的技术。因此,Azure DevOps 有一个我们可以使用的 ASP.NET 核心构建模板,如下所述。
当您创建一个新的管道时,它有一个您可以选择构建模板的步骤。参见图 4-8 。
图 4-8
构建模板
单击 apply 按钮后,它将被添加到构建管道中。参见图 4-9 。
图 4-9
ASP.NET 核心模板
一旦您将构建模板添加到构建管道中,它就会将所有必要的步骤添加到构建中。在 ASP.NET 核心模板中,我们可以确定以下添加的构建任务。
restore–如果项目源代码中使用了任何 NuGet 包或 Azure DevOps 工件提要,这将恢复所有引用包。
构建–这一步构建选定的项目,并验证源代码的编译状态。
测试——在构建项目源代码之后,接下来我们需要对源代码进行单元测试。此步骤可以配置为执行单元测试。
发布——这一步将准备好构建的二进制文件,以作为网站发布。
发布工件——这将发布可部署的工件。
正如您在上面看到的 ASP.NET 核心模板,所有必要的步骤都包含在模板中,它使构建管道配置对任何人来说都很容易,甚至对没有任何经验的用户来说也是如此。添加模板后,如果有必要,您可能需要做一些小的更改。因此,模板非常有用,它使构建配置过程变得高效。
如果你浏览一些其他的 Azure DevOps 模板,你将能够很好的了解这些模板是多么的有效和有用。如果我们考虑 docker,与直接部署 ASP.NET 核心相比,这是一种完全不同的部署。它需要从您实现的源代码中构建一个 docker 映像。因此,docker 构建管道应该能够连接到源代码,并使用构建步骤构建映像。docker 映像构建步骤需要执行更复杂的过程,如下载 docker hub 或源代码中包含的 docker 文件中引用的其他注册表中可用的 docker 映像。下载 docker 图像后,需要将其转换为 docker 容器。所有的构建过程都发生在这些 docker 容器中,最后它用您的应用创建一个 docker 容器,并将其转换为 docker 映像。Docker 映像是由 docker 构建创建的可部署包。在 docker 中,这些图像需要存储在特定的位置调用注册表中。
所以,在 Azure DevOps docker 模板中,它使用 docker 构建步骤创建一个 docker 映像;之后,使用另一个任务将创建的映像推送到注册表。参见图 4-10 。
图 4-10
Docker 模板
你已经看到了 Azure DevOps 模板如何支持两种完全不同的部署技术。即使您对这些技术完全陌生,您也能够使用这些模板轻松地创建一个构建管道。有很多模板可用于机器学习(ML)等最新技术。见图 4-11 。
图 4-11
机器学习构建模板
机器学习是一项最新的技术,我们大多数人都不知道如何为机器学习建立一个构建管道。但是 Azure DevOps 推出了一个机器学习模板,可以用来训练一个模型。训练模型时,需要在 Azure 中创建一个 ML 工作空间。为了创建工作区,我们通常使用 Azure CLI(命令行界面)命令。要使用机器学习,需要安装 Azure CLI ml 扩展。因此,在管道开始时,使用模板中的第一步,您可以准备代理来使用 Azure CLI ML 命令。基本上,机器学习是开发一种算法并训练数据,使其表现为所提供的算法。在训练模型之前,需要创建工作空间。创建工作区之后,您可以使用后续步骤来训练模型并部署它。所有这些步骤都可以通过为每个步骤提供相关数据,使用 Azure DevOps 机器学习模板来完成。
Azure DevOps 构建模板为用户创建支持各种技术的构建管道提供了很好的支持。此外,对于任何人来说,即使没有这些不同技术的经验,开始设置构建管道也是一个不错的选择。
第 4.03 课:使用多重职务
正如您已经知道的,CI 和 CD 是现代软件开发过程中非常重要的一部分。它将自动化复杂的软件构建和测试流程,如果您手动完成,这会给您带来很多麻烦。有时我们需要用不同版本的框架来构建代码,有时我们需要用不同的平台来构建代码。创建一个好的可部署包需要遵循很多场景。当您需要创建需要多个框架或平台支持的复杂构建管道时,Azure DevOps multiple jobs 提供了很好的帮助。
代理作业(也称为代理阶段)是您可以定义用于执行构建管道下的任务的构建代理的阶段。此外,代理作业/阶段可用于定义与该代理阶段下的所有任务相关的一些配置。
代理阶段允许您选择代理池和相关代理。正如我们在之前的课程中已经讨论过的,我们知道我们可以根据项目和计费要求创建托管代理和私有代理。在某些情况下,您可能需要使用托管代理中可用的某个特定框架版本来构建 agent 应用。因此,您可以为该代理阶段选择托管代理池。此外,可能会有一些情况,例如当您需要在代理中安装特定的框架版本时,如果代理中有相同框架的其他版本,则构建会失败。因此,在这种情况下,最好只使用特定的框架版本来创建私有代理。一个这样的例子是需要 SharePoint 版本,这在托管代理中是不可用的。因此,您可以使用代理阶段来决定是使用私有代理还是托管代理。
此外,项目需求代码必须使用特定版本的框架进行编译。例如,您需要一个具有。已安装. net framework 3.5。因此,您可以使用代理阶段的需求部分添加这些类型的需求。您可以设置具有特定框架版本的生成代理,并根据需要设置代理名称或特定功能。当 build 被触发时,它会搜索与代理阶段中定义的需求相匹配的代理。
如图 4-12 所示,您可以根据需要添加代理名称和代理版本。然后,当构建触发时,它将搜索满足需求中提到的所有需求的代理。与图 4-12 中提到的需求一样,它将在代理池中搜索名为“Agent01”且代理版本为“2.107.0”的代理,并使用该代理运行管道任务。
图 4-12
代理阶段需求
到目前为止,我们已经讨论了代理阶段的一些功能。现在让我们讨论一下在同一个构建管道中需要使用多个代理阶段的情况。在移动开发业务中,开发人员通常需要在 iOS 和 Android 平台上发布移动应用。此外,对于两个平台,有必要在相同的内部版本号下发布这些版本。我们可以通过使用相同的构建管道来构建 Android 和 iOS 应用,在同一构建中利用多个代理阶段,并将一个代理设置为 MacOS for iOS 应用,另一个根据 Android 应用的需要设置为 Windows 或其他平台。参见图 4-13 。
图 4-13
iOS 和 Android 的代理阶段
例如,我们可以创建一个包含三个阶段的构建管道,其中一个阶段可以用于通过运行单元测试来测试代码。对于代理阶段,您可以选择一个可以运行单元测试的代理。另外两个代理阶段可以使用两个不同的代理分别构建 Android 和 iOS 代码。iOS 使用 Mac OS 代理,Android 使用池中合适的 Windows 代理。通过使用多个代理阶段,您可以实现两个主要的构建需求。一个是你可以使用同一个构建管道,用同一个构建号为不同的平台构建一个移动应用。此外,您可以快速完成构建过程,因为代理阶段可以并行运行,而不会相互依赖。并行执行使构建过程更加高效并节省时间。参见图 4-14 。
图 4-14
代理阶段并行配置
我们已经讨论了代理阶段如何独立工作,如何并行构建而不相互依赖。可能存在代理阶段需要相互依赖的情况。考虑这样一种情况,您需要使用具有特定软件需求的代理来构建源,并且您需要决定是否继续使用具有单独软件需求的另一个代理来构建源,并且使用来自前一个代理阶段的构建输出。您可以轻松地开发一个构建管道,通过使用代理阶段和设置依赖关系来帮助这些类型的情况更容易地运行。参见图 4-15 。
图 4-15
代理阶段依赖性
此外,Azure DevOps 代理阶段具有并行化作业任务的能力。有时会有项目需求,需要使用各种配置(如调试和发布)来构建相同的代码。如果您需要使用不同的配置进行构建,代理阶段具有这种能力。此外,您可以决定并行执行需要使用多少代理,这允许我们为一个配置使用一个代理。如果组织中的代理数量有限,当您使用所有其他构建和发布的多个代理进行并行执行时,可能会遇到麻烦,这些代理需要在队列中等待,直到代理可用为止。因此,您可以定义代理阶段在给定的占用时间内使用的最大代理数量,并保持池中的其他代理可用。参见图 4-16 。
图 4-16
多个配置并行构建
构建源代码时,由于不同的原因,构建时间会有所不同。无论如何,为代理阶段定义一个超时值是有好处的。例如,有时您可能会遇到这样的情况:由于构建任务的问题,构建管道会持续运行更长的正常执行时间。在这种情况下,它可能会影响构建和部署过程的生产率。发生这种情况是因为队列中可能有其他生成在等待使用代理,并且长时间运行的生成会影响其他生成的队列等待时间。要控制此类问题,可以添加代理阶段超时,该超时将在指定的持续时间后导致构建失败。它可以减少队列中其他构建不必要的等待时间。除此之外,还可能存在需要更多时间来运行构建管道任务(如测试步骤)的情况。正如你所知道的,一些项目的自动化测试脚本运行在 4 到 5 个小时甚至更长时间,这需要更多的时间设置为代理阶段的超时值。参见图 4-17 。
图 4-17
代理超时
代理阶段还有一个有趣的特性,允许 Azure DevOps 用户在构建管道中使用 OAuth 令牌。例如,如果构建管道中使用的 PowerShell 脚本通过 Azure DevOps Rest API 调用来激活其功能,则需要对其进行身份验证才能执行对 Rest API 的调用。因此,您可以使用 PAT(个人访问令牌)作为一个选项来授权对 API 的访问,并将其作为一个参数提供。或者,如果您在管道中启用了“允许脚本访问 OAuth 令牌”,那么您就可以利用这个系统。出于相同目的在脚本中添加 Accesstoken。参见图 4-18 。
图 4-18
Auth token(验证令牌)
在本课中,我们讨论了代理作业/阶段和并行执行功能的一些功能和使用场景,以及阶段的依赖性和超时的使用,这将在您使用 Azure DevOps 设置构建管道时对您非常有用。
第 4.04 课:使用任务
由于其惊人的能力,Azure DevOps 构建管道可用于提高企业的生产力和效率。正如我们在前面的课程中讨论的那样,它有许多很好的模板。此外,它提供了代理阶段,允许用户创建更有用和更复杂的管道。在这些模板中,我们有可以使用的步骤。类似地,我们可以手动添加步骤/任务来构建管道,以便在代理作业中执行操作。让我们在本课中了解管道任务。
任务是代码段的一个包,创建它是为了在自动化管道中完成一些特定的工作。每项任务都需要几个输入,以便使用您在构建管道中设置为链接的源代码执行操作。此外,这些任务在几个版本中都可用,每个版本都有微小的改进。
正如我们已经知道的,构建管道可以使用构建模板来创建,也可以根据需求通过逐个添加任务来创建。Azure DevOps 中提供了各种任务,有助于执行不同的操作,如构建、测试、打包等。参见图 4-19 。
图 4-19
管道任务
使用不同的技术时,需要使用不同的构建任务。作为一个例子,我们使用 ASP 的 ASP.NET 核心构建任务。NET 核心源代码。当我们进行 Android 开发时,我们需要使用 Android 签名任务。同样,Azure DevOps 为不同的技术需求和目的提供了几个构建任务。
在某些情况下,我们需要执行命令来做一些事情。例如,在机器学习构建管道中,我们使用 PowerShell 任务执行 Azure CLI 命令来创建 ML 工作区。我们有 PowerShell、bash 和其他工具作为 Azure DevOps 任务。
我们已经讨论了 Azure DevOps 中可用的内置任务。如果可用的任务不符合您的需求,您可以从市场安装任务。marketplace 提供了各种免费任务,您可以将其安装到 Azure DevOps 组织中,并在管道中使用。然而,marketplace 是一个开放的平台,您可能会发现 marketplace 中的一些扩展任务有时并不可靠或有效。因此,建议使用来自可信提供者的任务,这些提供者具有良好的评论或良好的文档以及任务实现源代码的可用性,这允许您创建自己的版本——可能带有错误修复。最好以可控的方式将这些任务从市场安装到 Azure DevOps 实例中。出于控制目的,仅允许管理员用户安装市场工具。如果没有管理员权限的用户需要安装 marketplace 扩展,他们需要提出请求,以便管理员可以评估和批准此类请求,并安装所需的扩展。参见图 4-20 。
图 4-20
管理权限请求
发送请求 admin 后,获取包含所有必要信息的请求邮件。见图 4-21 。
图 4-21
市场扩展安装请求
收到这个请求后,管理员可以决定是否安装扩展。此外,如果没有符合您要求的任务,您可以创建自己的自定义任务,并在市场中发布它们,或者仅与您希望共享扩展的 Azure DevOps 组织共享它们。
Azure DevOps 构建管道中的任务具有几乎所有任务都可用的通用配置值,这允许您为任务决定一些控制选项。举个例子,当我们使用管道任务运行测试时,并不是所有的测试都能通过。因此,如果您想要继续构建管道,那么即使测试步骤失败也要运行它,并且您可以使用任务配置来这样做。使用管道时的另一个常见体验是,如果任务将会失败,那么它将花费太多时间来完成。在这种情况下,我们可以设置一个任务超时,在指定的超时时间后,服务器停止任务。参见图 4-22 。
图 4-22
任务的常见配置
在处理多个任务时,可能有必要在每个任务之间保持一些相关性。有时,您可以根据情况决定执行构建管道步骤,例如,如果管道不是基于拉请求(PR)触发的。在创建构建管道以构建 PR 请求的情况下,没有必要打包发布的代码,因为这是在将源代码合并到主分支之前完成的虚拟工作,以验证在将代码合并到目标分支之后,代码更改如何影响源代码。为此,您可以设置自定义控制条件,以便在步骤/任务不是由拉请求触发的构建并且所有先前步骤都成功的情况下执行该步骤/任务。参见图 4-23 。
图 4-23
NuGet 推送的自定义条件
在本课中,我们探讨了 Azure DevOps 任务用法和常见控制选项。此外,我们还讨论了 marketplace 扩展的用法以及在使用此类扩展时应该考虑的事项。
摘要
在本章中,我们已经开始探索经典的构建管道,详细介绍了连接各种源代码控制仓库的方法,以及使用模板来轻松完成构建管道的设置。此外,我们讨论了代理作业的目的和代理作业中的几个设置,它们有助于优化项目的构建执行需求。然后我们看了一下构建任务以及它们的公共控制选项和扩展的使用。
在下一章中,我们将进一步探索经典的构建管道,以了解如何使用变量,如何设置触发器和路径过滤器,格式化构建号以支持软件和软件包的版本控制,以及其他几个有用的构建管道特性和属性。
五、创建构建管道——经典——变量、触发器、过滤器、选项和保留
在前一章中,我们看了一些你可以在用经典编辑器设置 Azure 构建管道时使用的特性。这些包括使用不同源代码控制系统的能力、应用公共步骤模板来建立构建、在构建中使用多个作业,以及包括多配置构建的并行性。此外,您还探索了向构建管道添加任务或构建步骤的能力,甚至通过安装 marketplace 扩展获得额外的任务。然后你好好看看任务控制条件和自定义条件的使用,以满足各种场景。
有了这些知识,我们将在本章中逐步了解经典构建管道设置的更多功能,探索如何定义和使用变量,设置构建触发器,包括应用分支保护策略和路径过滤器构建。此外,我们将讨论格式化构建编号;启用、禁用和暂停将工作项链接到生成的生成。应用需求、超时和编辑经典构建的历史;以及保留选项。
第 5.01 课:使用变量
变量有助于将构建中使用的多个步骤的设置保存在一个公共位置。它们可以是路径、名称和密码等常用值,甚至是应用中使用的配置值。您可以在构建管道中使用两种类型的变量。Azure DevOps 提供的预定义变量可以在 https://docs.microsoft.com/en-us/azure/devops/pipelines/build/variables?view=azure-devops&tabs=classic
找到,你可以将 Azure 管道中的变量定义为自定义变量。让我们试着理解本课中每种类型的变量和用法。
通过使用$(variableName)语法,可以在任何管道任务中使用系统变量和自定义变量。要定义自定义变量,可以使用经典构建管道中的 variables 选项卡。单击 Add+将允许您向管道中添加新变量。预定义变量链接会将您带到有关预定义变量的 Microsoft 文档页面。
如果您的变量包含密码等敏感值,您可以通过输入值并单击挂锁图标将其锁定在每个变量中来隐藏该值。变量值一旦被锁定并保存,就不能再看到。如果您解锁它,该值将为空,您必须再次提供该值并锁定它。
在排队时启用设置的选项将允许您在新构建排队时更改变量的值。System.debug 是一个在排队时设置的有用变量,因为它允许您决定以调试模式运行正在排队的当前构建,在对构建进行排队时发出更多的诊断日志详细信息。这将有助于您识别损坏的构建管道中的问题并修复它们。见图 5-1 。
图 5-1
版本中的变量
在对构建进行排队时,您可以单击变量来查看排队时的可设置变量。见图 5-2 。
图 5-2
排队时可设置的变量
然后,您可以单击所需的变量来更新它。见图 5-3
图 5-3
运行管道前要更新的变量
点击变量时,可以更新变量的值。见图 5-4 。
图 5-4
排队时更新变量
变量可以定义为变量组,以便您可以在团队项目中的多个生成管道之间共享它们,甚至可以在生成管道和发布管道之间共享变量。若要在团队项目中定义变量组,可以使用管道➤库的“变量组”选项卡。单击+变量组以添加新的变量组。见图 5-5 。
图 5-5
添加新变量组
变量包含一个名称来标识它,您可以为它添加描述。对于变量组,您可以启用对管道的访问,使其可在 Azure 管道中使用。您可以克隆变量组,这对于为多个范围(如部署目标环境)创建相同的变量集非常有用。参见图 5-6 。
图 5-6
可变组
从 Azure Key Vault 链接机密允许您基于来自给定 Azure Key Vault 的选定变量设置变量组。由于这个功能,您将能够在 Azure Key Vault 中的一个公共安全库中存储您的所有秘密变量,并在所需的管道中使用它们。参见图 5-7 。
图 5-7
变量组中的 Azure 密钥库机密
在 Azure 构建管道中使用变量组有助于在多个构建管道中共享公共变量。在经典的构建定义中,可以在 Variables 选项卡中选择变量组,并将其添加到构建管道中,以便可以在管道中使用该组中的变量。与构建管道类似,您可以在 Azure 发布管道中使用变量组。您可以将变量组限定在给定的阶段,或者在 Azure 发布管道中发布它们。您可以使用克隆变量组的功能,将同一组变量创建到另一个具有不同值的组中,这有助于您将变量组中每个阶段的值保持在该阶段的范围内。参见图 5-8 。
图 5-8
在发布管道中使用变量组
我们已经讨论了变量的用法,如何将它们定义为管道变量,以及如何使用变量组跨管道共享变量。此外,我们还研究了使用 Azure Key Vault 机密作为变量的能力。
第 5.02 课:设置触发器和路径过滤器
构建管道可以手动触发。然而,为构建提供不同的触发选项是很重要的。例如,一旦代码被推送到存储库以验证代码编译状态并评估单元测试状态,您可能想要运行构建。或者它可能是您的回归测试验证的夜间时间表。
您可能有一个包含几个项目的大型代码库。想象一个场景,比如一个基于微服务的大型系统的实现。在这种微服务场景中,您可能只希望在为微服务推送的代码发生变化时构建相关的微服务,而不希望构建应用的其他部分。因此,对于触发器,它应该有一个过滤机制来确定哪些代码路径应该触发一个构建。
让我们探索构建的不同触发选项。
启用持续集成触发器将使构建在代码被推送到已定义的分支或者分支满足已定义的分支模式时被触发。推送到分支的每个提交都将被构建,您甚至可以在这样的构建中执行单元测试,以确保提交的代码在编译时没有任何问题,并且测试没有中断,从而证明代码的有效性。path filter 选项允许您过滤包含的路径,这样您就可以确保在给定的路径和给定的分支中是否发生了符合模式的代码更改,并在代码推送时进行构建。exclude 允许忽略该路径,以便仅推送到该路径不会触发构建管道。如果一个构建已经处于运行状态,batch changes 选项允许对一个分支的多个推送一起进行批处理,并在一个构建中执行,而不是每次推送都执行一个构建。参见图 5-9 。
图 5-9
持续集成触发器
调度触发器可用于设置一个触发器,该触发器在一周中所选日期的给定调度时间执行构建管道,并通过定义的分支模式使用所选的一个或多个分支。对于预定触发器,您也可以设置排除分支模式。此外,您可以选择将构建设置为仅在执行最后一个调度构建之后,在源代码或管道中发生更改时才触发。您可以将多个这样的计划作为触发器添加到一个版本中。这种构建调度允许您运行您的构建,比如说每晚运行,或者一天运行几次,根据漏洞扫描来评估您的代码库,并执行长时间运行的单元测试。参见图 5-10 。
图 5-10
预定触发器
还有另一种类型的构建触发器,允许您创建构建链。此选项允许您基于另一个构建管道的执行完成来触发给定的构建管道。也许您可以在一个时间表中使用一个构建,并在该构建完成后运行另一个构建,这可以让您执行一些相关的步骤或测试运行。或者您甚至可以将多个测试分成不同的构建,并在给定的先决条件构建完成后触发它们。您甚至可以添加 exclude include 分支过滤器模式,以考虑在给定的构建是针对满足所定义的分支模式的分支执行的情况下触发构建。见图 5-11
图 5-11
生成完成触发器
在本课中,我们已经了解了可以为构建管道设置的不同触发器,这有助于您基于不同的上下文执行。
第 5.03 课:格式化内部版本号
构建号可以用于将版本应用到作为构建管道的输出而生成的包/工件。此外,它允许您正确地版本化您的软件版本。您可以使用 Azure 构建管道来遵循和实现不同的构建号模式,我们将在本课中快速浏览一下。
格式化内部版本号的最简单方法是在给定的生成管道定义中的“选项”选项卡中设置内部版本号格式。您可以使用构件编号格式中的预定义变量来创建具有您偏好的编号格式的构件。参见图 5-12 。
图 5-12
内部版本号格式
\((Rev:r)或 revision 可用于向内部版本号添加修订格式,使每个内部版本号都是唯一的。对于任何内部版本号格式,它都将从 1 开始,并继续增加编号,直到基本格式发生变化。例如,如果您定义您的构建使用一个分支名称和修订,\)(Build。SourceBranchName)$(Rev:r)作为编译号格式,对于名为 master 的分支,编译号将是 master.1、master.2,并将继续。如果您构建的分支更改为 develop,它将从 develop.1 开始。$( Rev:RR)可以用来添加一个两位数的修订号,当修订号是一位数时,前面有一个零。例如,第一个版本的版本号是 01。
可以使用 PowerShell 之类的脚本来操作构建号,这些脚本可以作为构建管道步骤运行。在 PowerShell 中,您可以使用下面的语法来更新当前内部版本的内部版本号。
##vso[build.updatebuildnumber]buildnumber
例如,以下 PowerShell 语句将 PowerShell 变量$ BuildNumberToSet 的内容作为内部版本号应用于当前内部版本。
Write-Output "##vso[build.updatebuildnumber]$BuildNumberToSet"
使用 bash 脚本也可以做到这一点。
echo "##vso[build.updatebuildnumber]$BuildNumberToSet"
您可以使用您的脚本功能来操作您的源代码包版本号和您的内部版本号,以对您创建的包应用正确的版本控制。例如,在 C#项目中,您可以操作 AssmplyInfo.cs 文件、版本信息来更新程序集版本以及在版本中生成的 dll 或 exe 的程序集文件版本。或者在构建任务(比如创建 NuGet 包)中,您可以使用当前的构建号来应用 NuGet 包的版本。参见图 5-13 。
图 5-13
在 NuGet 包中使用内部版本号
使用预定义的变量$(Build ),可以在 Azure 管道中的任何脚本或任务中引用内部版本号。BuildNumber)。
在本课中,我们讨论了内部版本号的用法,以及使用内部版本选项或脚本来设置它。
第 5.04 课:启用、禁用和暂停生成
Azure DevOps 中的构建管道允许您保持启用、禁用或暂停它们。让我们看看每个设置的行为是什么,并讨论一下用法。
您可以在生成管道的“选项”选项卡中设置启用、禁用或暂停选项。参见图 5-14 。
图 5-14
启用、禁用或暂停生成管道
当具有所需功能的代理可用时,Enabled 选项允许构建排队并开始执行构建步骤。这是构建管道的正常预期情况,因为它应该根据其中设置的触发器来触发和执行。
生成管道的暂停选项允许生成排队,但在再次启用生成之前,生成不会开始执行。当您想要提交/推送对可能触发多个构建的源代码存储库的更改,但想要在您设置的构建暂停之前优先执行另一个构建时,此选项暂停很有用。
Disabled 选项在设置为 Paused 或 Enabled 之前不会让生成排队等待触发器。这在对管道进行维护或改进,同时对保存在管道定义中的内容进行中间更改时非常有用,因为这将阻止正在进行的构建管道步骤的执行。
在本课中,我们讨论了构建管道中定义构建管道排队和执行行为的三个可用选项,这使您可以在所描述的预期场景中有效地使用它们。
第 5.05 课:生成和工作项
工作条目被用来跟踪你在项目中所做的工作,我们已经在这个关于 Azure Boards 实践系列的第一本书中详细讨论了它们。这些工作项可以被集成到构建管道中,这样它们就可以在部署时被用来生成自动化的发布说明。此外,为了通知构建失败并确保有人对失败的构建负责,我们可以在失败的构建上创建一个工作项。在本课中,让我们看看如何将构建与工作项一起使用。
您可以在构建选项中定义,以便根据关联的工作项自动将工作项链接到与指定分支模式匹配的分支中的提交。一旦构建成功,将会创建与提交相关联的所有工作项的链接,这些工作项是在给定的构建中新构建的。稍后,这些工作项可以用于生成一个发布说明,同时基于先前部署的构建和当前部署的构建部署到一个给定的目标。参见图 5-15 。
图 5-15
将工作项与版本链接
为失败构建创建工作项允许您选择工作项类型,并使用首选值设置正在创建的工作项的字段值。这些值可以是构建中的变量或您定义的任何其他值。可以将工作项分配给请求者,以便在提交的情况下,将提交用户视为构建请求者,向其分配工作项。失败构建的责任可以分配给提交导致失败的代码的开发人员。这种能力使得失败的构建能够被及时处理,而不会被忽略。参见图 5-16 。
图 5-16
失败生成时创建工作项
在本课中,我们探讨了工作项和构建关联,以及创建工作项来分配构建失败责任。
第 5.06 课:构建状态徽章
“生成状态”标志是标识给定生成的当前生成状态的一种有用方式。它可以用于文档,如维基,或任何其他网页等。,您希望在其中报告构建的状态。
状态徽章在构建管道的选项页面中可用。它可以用作三种格式。一个图像 URL 将提供一个构建状态图像,可以在网页或 wiki 页面等中使用。您可以为一个特定的分支使用一个 Image URL,报告给定分支的构建状态。markdown 链接是一种 markdown 语法,因此您可以在任何 markdown 文档(如 wiki)中使用 build 徽章。参见图 5-17 。
图 5-17
构建状态徽章
在本课中,我们讨论了构建状态徽章,它可用于在文档中显示构建状态。
第 5.07 课:其他构建选项
还有几个构建选项值得关注,比如范围、超时和需求。
生成的授权范围可以设置为项目集合或当前项目。项目集合范围允许生成作业访问项目集合级别的信息(Azure DevOps 组织范围)。当前项目限制对当前项目的访问。一个示例场景是使用系统访问令牌和 Azure DevOps 的 REST API 来访问信息的 PowerShell 步骤,这些信息是基于 Azure DevOps 组织/项目集合或当前项目范围的授权范围设置的范围。生成作业超时指定在取消生成步骤之前,生成步骤在给定代理中可以执行的最大分钟数。如果对某个构建作业发出取消请求,如果取消未发生,该作业在服务器终止该作业之前等待的时间(以分钟为单位)由构建作业取消超时决定。
需求允许您定义如何根据代理在给定代理池中的能力来查找代理。您可以将其设置为检查功能是否存在,或者根据需求检查功能值。可以为一个构建作业设置多个需求。参见图 5-18 了解本课中讨论的选项。
图 5-18
范围、超时和需求
在本课中,我们探讨了一些其他选项,如授权范围、超时和构建作业的要求。
第 5.08 课:建立历史和保留
构建历史和保留是 Azure Pipelines 中另外两个有用的特性,值得一看以理解它们的用途和用法。
您对 Azure 构建管道所做的更改会被记录为历史。在对管道进行更改时,可以添加注释,以确保所做的更改易于识别。历史记录可用于比较两个历史记录之间对管道所做的更改。可以将管道恢复到给定的历史点,这在对构建管道进行维护或升级时非常有用。参见图 5-19 。
图 5-19
管道历史
构建管道的保留是精简的,可以作为项目设置使用。我们可以设置日期来保持构建的运行,拉请求构建,并在管道中附加工件。即使超过了保留构建的时间限制,“要保留的最近运行的次数”值将决定有多少构建的最后运行将保持可用或保留,而不考虑天数规格。参见图 5-20
图 5-20
建立保留
在本课中,我们讨论了构建管道历史记录、恢复到管道先前版本的能力以及构建运行的保留选项。
摘要
我们已经在本章中详细探讨了变量及其用法。详细讨论了构建的各种触发器和为正确的版本控制目的格式化构建号。此外,我们还研究了构建管道中的其他几个选项和功能,比如启用、禁用和暂停构建管道;失败时创建工作项并启用工作项的链接;构建状态徽章的使用;作业范围和超时;历史;正在还原生成管道;和保留选项。
在下一章中,我们将进一步了解经典构建管道的特性,例如队列、使用 PowerShell 脚本在构建中设置变量、访问脚本中的秘密变量值、使用系统访问令牌、任务组、无代理阶段、发布工件、导出和导入构建管道,以及将构建组织到文件夹中。
六、创建构建管道——经典——排队、调试、任务组、工件和导入/导出选项
在前两章中,我们已经讨论了 Azure 构建管道的许多有用特性。在这些文章中,我们讨论了如何使用构建任务、变量、构建作业选项、对构建使用不同的源代码控制系统、使用构建来保护分支,以及其他几个选项和功能来建立构建管道。
在这一章中,我们将探索更多的功能,例如使用 PowerShell 脚本中的变量对构建进行排队并在调试构建模式下启用诊断信息,OAuth 令牌的使用,为可重用性对任务进行分组,无代理阶段的使用,导入和导出构建,以及为可维护性将构建组织到文件夹结构中。
第 6.01 课:排队生成和启用调试模式以获取更多诊断信息
在使用构建管道时,我们需要学习如何快速修复构建失败。考虑这样一种情况,您正在发布一个关键的客户机版本,并且需要快速地将其推向生产,但是如果您的构建失败了呢?当这些类型的失败发生时,你们可能都经历过来自团队的压力。为了快速解决构建失败,有必要快速识别问题。构建失败后,我们需要阅读构建日志来了解失败的原因。但是有时提供的日志数据不足以确定失败的真正原因。让我们看一下同样的构建任务日志,调试状态为 false,调试状态为 true,看看我们在调试模式打开的情况下诊断问题时得到的好处。
以下 NuGet restore 任务已在调试模式设置为 false 的情况下执行。它有 178 条日志线。见图 6-1 。
图 6-1
带有调试错误状态的构建日志
如果我们在变量(system.debug 变量)中将 debug 设置为 true 来运行同一个构建,您可以看到两个日志之间的差异。它比前一个提供了更多的细节。如下图所示,相同的 NuGet 恢复步骤有 785 个日志行,这意味着它提供了比 debug false 更多的信息。见图 6-2 。
图 6-2
构建调试为真的日志
因此,在构建失败后,执行将调试值设置为 true 的构建,这提供了更多的细节,您可以使用这些细节轻松地确定构建失败的原因。
本课讨论了我们可以将 debug 变量值设置为 true,并获得有关失败的更多信息,通过这些信息,我们可以轻松地识别构建中的问题。
第 6.02 课:在 PowerShell 脚本中设置变量值
配置构建管道时,管道任务需要各种输入值。有时它可以是项目名称或文件夹路径,或者是基于您正在构建的项目类型的一组不同的值。我们都知道在构建步骤中使用参数化的值而不是硬编码的值是一个好的实践。因此,在管道中,我们在变量部分下声明变量。在管道的变量部分中定义的所有变量都可以在管道中的任何代理阶段使用。无需在管道变量部分声明变量,您也可以使用 PowerShell 脚本为代理阶段定义动态变量。这些动态变量只属于 PowerShell 脚本所属的代理阶段。
当您使用像 Octopus 这样的外部工具时,动态变量非常有用,Octopus 具有更强大的多维和限定范围变量管理功能。假设您已经定义了一个 Octopus 项目,它有一个带有一些值的变量集。您需要从 Octopus 变量集中读取值,并将这些值用于 Azure 构建管道的任务。您可以编写一个 PowerShell 脚本,使用 Octopus 中使用的相同变量名动态创建代理阶段变量,并应用从 Octopus 获得的值。见图 6-3 。
图 6-3
在 Azure DevOps 管道中使用 Octopus 变量
所有的魔法都是使用这段代码行完成的。
"##vso[task.setvariable variable=" + $octopusVariable.Name + "]" + $variableValue
它用给定的变量名创建一个变量,并给给定的变量值赋值。例如,一个变量可以在 Octopus 中被指定为环境,它可以有 develop 或 prod 等值。,它作为 Azure 管道中的一个新变量被应用。代理阶段中的任何任务都可以使用这些变量值。
本课讨论了一个非常有用的功能,该功能允许您通过动态使用 PowerShell 脚本来创建构建管道变量。
第 6.03 课:在 PowerShell 中访问秘密变量值
正如在前面的课程中所讨论的,有各种类型的生成任务可用于为各种要求配置生成管道。在大多数情况下,我们需要使用 PowerShell 脚本来自动化一些管道任务。因此,了解 PowerShell 脚本如何在管道中使用变量是很有好处的。见图 6-4 。
图 6-4
PowerShell 任务
在处理项目时,我们需要处理不同类型的值。有些可以公开分享,有些需要保密。因此,由于这些秘密值需要不同的保护级别,因此需要区别对待。
代理通过在代理内部创建环境变量来使用生成管道中定义的变量值。但是对于秘密值,它不会在代理环境变量中添加任何值。因此,在 PowerShell 脚本中,我们只能通过对非机密变量使用\(env:variablename 或\)(variablename)来访问变量。但是对于秘密变量,由于代理不在其中创建环境变量,所以我们不能使用\(env:variable 格式访问秘密变量。在 PowerShell 中访问秘密变量的唯一可能的方法是使用\)(variablename)格式。
我们能够了解在 PowerShell 脚本中如何处理秘密变量,以及这些秘密变量在管道中的行为。此外,在本课中,我们讨论了生成管道中秘密变量行为的原因。
第 6.04 课:在构建中使用身份验证令牌
正如我们在本书之前的课程中已经讨论过的,在 Azure DevOps 构建管道代理阶段有很多可用的配置选项。这些配置值可用于提高构建过程的效率和效果。在本课中,我们将讨论代理阶段的 OAuth 配置。
在使用 Azure DevOps 时,有时需要使用 Azure REST API 端点来创建、删除、更新和检索 Azure DevOps 服务资源。因此,大多数 PowerShell 任务用于在构建管道中执行 REST API 调用。正如我们已经知道的,在执行任何 REST API 调用之前,有必要使用认证机制来允许 API 执行授权的操作。在 Azure DevOps 中,个人访问令牌(PAT)是提供身份验证的最常见方式。但是代理阶段的 OAuth 配置允许我们在不使用 PAT 作为认证参数的情况下执行 API 调用。
Azure DevOps 构建管道中的启用 OAuth 令牌配置使任务启动的脚本和其他流程能够通过系统访问 OAuth 令牌。ACCESS.TOKEN 变量。启用对系统访问令牌的访问时,可以在构建管道作业中执行的任务脚本中使用$env:SYSTEM_ACCESSTOKEN 环境变量。见图 6-5 。
图 6-5
启用 OAuth 令牌
下面的代码示例显示了如何使用 API 脚本列出构建。它在任务脚本中使用\(env:SYSTEM_ACCESSTOKEN 变量进行身份验证。如果未启用构建管道 OAuth 配置,脚本将无法运行,因为\)env:SYSTEM_ACCESSTOKEN 无法获取值,因为只有在启用了构建管道 OAuth 配置时才允许获取值。
$url = $env:SYSTEM_TEAMFOUNDATIONCOLLECTIONURI + $env:SYSTEM_TEAMPROJECTID + "/_apis/build/builds?api-version=5.1"
Write-Host "URL: $url"
$pipeline = Invoke-RestMethod -Uri $url -Headers @{
Authorization = "Bearer $env:SYSTEM_ACCESSTOKEN"
}
Write-Host "Pipeline = $($pipeline | ConvertTo-Json -Depth 100)"
在本课中,我们讨论了如何在构建管道中使用 OAuth 配置,以及这种配置的重要性。
第 6.05 课:创建和使用任务组
管道的一个重要特征是管道任务。当我们配置构建管道时,有时我们需要在多个构建管道中使用同一组任务。假设一个用微服务架构开发的项目。假设 Azure 函数已经用于开发微服务架构,我们需要为每个函数配置一个单独的构建管道。在这种情况下,我们在每个函数构建管道中使用相同的步骤。它有一个构建任务来构建代码,一个 NuGet pack 任务来打包构建的输出,一个 NuGet push 任务来将打包的内容推送到 Azure DevOps 工件提要。如果项目中有 100 个函数,我们需要创建 100 个管道来构建它们。但是,我们可以创建任务组来减少配置管道的工作量,而不是重复同样的工作 100 次。
任务组将一组重复的任务进行分组,并将其作为多个管道的共享组件进行维护。如果我们考虑这样一种情况,即项目中有多个使用相同任务集的构建管道,我们可以使用重复任务创建一个任务组,并使用每个构建管道向它传递参数,以便它构建和打包不同的项目。
让我们看看如何利用一组现有的构建步骤轻松地创建一个任务组。创建一个包含所有必要任务的完整管道。之后,如果每个任务有任何输入值,就将这些值参数化。现在选择要添加到任务组的任务,并创建一个任务组。见图 6-6 。
图 6-6
创建任务组
添加任务组后,它将在 Azure DevOps 任务组部分下可用。现在,我们可以使用任务组来创建构建管道。见图 6-7 。
图 6-7
添加要构建的任务组
如果我们创建一个任务组,我们也可以与其他项目共享。您可以将任务组从一个项目导出到同一组织或外部组织中的另一个项目。任务组是非常有用和高效的组件,我们可以在 Azure DevOps 中进行配置。例如,如果要在另一个项目或另一个组织中的项目的生成管道中配置相同的生成任务,可以导出任务组。当您点击 task group export 按钮时,它将下载 json 文件。您可以在另一个团队项目中导入此文件,它会自动为您创建一个任务组。
本课解释了任务组的用途和重要性。我们能够了解如何创建一个任务组及其目的。此外,我们讨论了它的功能和可重用性,允许我们导出和导入到同一个组织中的项目和外部组织中的项目。
第 6.06 课:使用无代理阶段
自动化构建使用一台或多台机器为我们做一些工作,而不需要任何人工交互。我们称这些机器为代理,当涉及到自动化管道时,它们扮演着任务执行者的重要角色。但是,在某些情况下,您需要执行一些不需要机器来执行的活动,例如等待批准。对于这些等待类型的目的,您可以在构建管道中使用无代理阶段。在本课中,我们将讨论无代理阶段功能。
无代理阶段包含无需代理计算机帮助即可执行的任务。大多数任务都是依赖于从外部查询或 API 检索的数据的手动干预任务或操作。正如您已经知道的,一个构建管道可以有多个代理阶段。类似地,如果需要,您可以向构建管道添加多个无代理阶段。见图 6-7 。您可以对代理阶段或无代理作业进行排序,并根据需要建立执行顺序或启用并行执行。见图 6-8 。
图 6-8
添加无代理阶段
当进入无代理阶段时,它可以执行不需要代理计算机参与的任务。例如,在某些情况下,我们可能需要在构建管道中的两个任务之间留出一个时间间隔。假设我们执行一个脚本,将更改应用到 Azure 中的现有资源,或者想要提供一个新资源。将这些更改应用到 Azure 中的资源需要一些时间。可能需要等到更改完全应用后,才能在下一个任务中继续执行构建管道,因为这取决于您对 Azure 资源所做更改的可用性。因此,我们可以使用无代理任务来等待所需的时间段,以将更改应用到 Azure 资源,并继续下一个任务的另一个代理阶段,这取决于 Azure 资源的更改。参见图 6-9 。
图 6-9
无代理阶段的延迟任务
无代理阶段的另一个有用任务是查询工作项任务。考虑这样一种情况,当且仅当所有的工作项在 sprint 中被标记为完成时,您才需要打包工件。因此,您需要做的是编写一个查询来获得特定 sprint 中处于 to-do 或 in-progress 状态的工作项的计数。如果在 sprint 中有任何未完成的工作项,您应该停止构建管道而不创建工件。参见图 6-10
图 6-10
无代理阶段的查询工作项任务
另一个有用的任务是手动干预任务,它可以等待用户批准或拒绝流水线的进一步执行。这种类型的手动干预有助于在进一步执行流水线之前对所执行的步骤进行任何所需的手动验证。
除了这些任务,市场上还有一些其他无代理任务。
学习完本课程后,您能够了解 Azure DevOps 构建管道中可用的无代理阶段。此外,我们还讨论了一些特定于无代理阶段的任务,以及这些任务在一些实际场景中的用法。
第 6.07 课:发布工件
Azure DevOps 构建管道用于从 repo 获取源代码,构建代码,测试代码,发布构建的二进制文件,并将其打包为可部署的工件。发布的工件是大多数构建管道的结果。Azure DevOps 使用不同的方法来保存构建工件。一种方法是将发布的工件保存在同一个构建管道中。此外,您可以将工件作为 NuGet 包发布到 Azure DevOps NuGet 提要或外部 NuGet 提要。他们保存工件的方式是将它们保存在一个共享的文件位置。
保存工件的最著名、最简单的方法是使用发布工件任务将发布的工件保存到管道本身。在完成构建之后,如果您将工件放置作为同一个构建,那么您将能够找到附加到构建管道的工件。见图 6-11 。
图 6-11
附加到管道的已发布项目
附加到构建管道的工件具有较短的生命周期,因为它们将依赖于构建保留时间。
使用相同的发布构建输出任务,可以将工件发布到给定文件的共享路径中。当您关注安全性,并希望使用它作为本地代理将您的构建工件发布到您的网络的共享文件夹中时,保留一个文件共享是值得的,因为您的公司网络之外的人不能访问它。
在本课中,我们简要讨论了构建工件。在第七章中,我们将讨论这些不同的工件发布选项,更详细的讨论,以及使用场景。
第 6.08 课:导出和导入生成定义
正如我们所知,有时我们需要为多个项目建立构建管道,主要是为了相似类型的构建需求。在这种情况下,花费更多时间从零开始手动设置每个构建管道是不值得的。Azure DevOps 具有导出和导入构建管道的能力,当我们在多个项目中需要类似的构建时,这允许我们轻松地设置构建管道。
如果您必须在单个项目中设置多个相似的构建管道,您可以轻松地克隆构建管道并根据需求进行更新。或者,您可以导出现有的生成,然后导入以在同一个团队项目中创建新的生成管道。转到您需要导出的构建管道,并单击 export options。见图 6-12 。
图 6-12
导出生成管道
它将下载 json 文件。为了导入管道,您可以将 json 文件导入 Azure DevOps 项目,它将创建一个构建管道。见图 6-13
图 6-13
导入构建管道的 json
但是,如果您想要导出管道,并将其导入到相同或不同 Azure DevOps 组织中的不同团队项目,这并不像上面解释的导入到相同团队项目那样简单。
在我们将构建管道 json 导入到另一个项目之前,需要对导出的 json 文件做一个小的更改。Azure DevOps 项目对每个团队项目都有唯一的 id。当您导出构建管道时,它包含 json 文件中源团队项目的项目 id。此项目 id 需要替换为目标团队项目 id 的项目 id。否则,由于 json 中项目 id 的差异,在尝试导入目标团队项目的构建并保存它时,它会给出一个错误。因此,首先您必须使用下面的 REST API 调用找到目标和源项目 id。您可以通过更改相关的组织名称和项目名称来查找项目 id,从而运行下面的 REST API 调用。见图 6-14
图 6-14
项目 id
https://dev.azure.com/yourorgname/_apis/projects/teamprojectname?api-version=5.0
找到目标项目 id 和源项目 id 后,用目标项目 id 替换导出的 json 文件和源项目 id。然后,您可以将它导入到目标团队项目中,并保存它以创建一个生成管道。
本课讨论了 Azure DevOps 中可用的构建管道导出和导入功能及其用途。此外,我们能够学习在团队项目和 Azure DevOps 组织之间导出和导入构建管道的技术。
第 6.09 课:将构建组织到文件夹中
根据项目体系结构的不同,一个团队项目中可以有多个生成管道。例如,如果团队使用微服务架构开发系统,就需要为每个微服务组件建立单独的构建管道。以一种更易于管理的方式组织构建管道以增加其可维护性将是一件好事。
本课讨论如何在团队项目中创建文件夹结构,并以更易于管理的方式组织生成管道。见图 6-15
图 6-15
构建文件夹结构
让我们考虑一个使用 Azure 函数作为后端微服务组件的移动开发项目。函数构建可以放在名为 Functions 的文件夹下。移动构建可以组织在名为 mobile 的文件夹下。此外,如果基础架构是使用脚本调配的,则这些基础架构构建可以放在基础架构文件夹中。同样,所有构建管道都应该使用有意义的文件夹结构进行分类。它将帮助用户轻松访问相关的构建管道,而无需滚动浏览所有的构建定义。
本课讨论了拥有一个良好的、有组织的文件夹结构来保存构建定义的重要性,这有助于用户轻松识别和维护构建管道。
摘要
在本章中,我们讨论了 Azure DevOps 版本中更有用的配置和功能。正如我们所解释的,构建的调试模式对于检查构建失败日志和识别失败原因非常重要。此外,在使用 PowerShell 脚本时,我们还讨论了 Azure DevOps 管道中一些有用的功能。此外,我们讨论了任务组和构建工件的使用,这是 Azure DevOps 构建管道的一个非常重要的部分。此外,我们能够了解如何在同一组织或外部组织中的团队项目之间导入和导出构建管道,这在需要在项目之间复制相似的构建管道时非常有用。最后,我们讨论了拥有一个组织良好的文件夹结构来保持构建管道的重要性。
在下一章中,我们将详细讨论构建工件,以确定我们可以使用的不同选项来发布带有使用场景的工件。
七、使用工件
构建的工件或输出包含二进制文件和将软件部署到目标环境所需的支持文件。根据正在构建的项目类型,以及部署和测试需求,工件的内容可能会有所不同。它们可能包含部署规范,如脚本或模板,如 YAML 文件、测试数据、测试执行脚本等。
有几种方法可以在构建中发布工件,比如使它在构建中可用,将工件放在共享路径中,或者将其创建为一个包并上传到一个提要中。让我们在本章中详细探讨这些选项。此外,让我们看看如何使用从另一个构建以及在开发工具中上传到提要的包。
第 7.01 课:发布构建工件
正如我们之前简单提到的,有几种方法可以发布构建生成的工件。您可以使用发布管道中每个已发布方法中可用的工件来将软件部署到预期的目标。让我们讨论每种类型的发布机制。
第一种方法是将一个构建的输出发布为同一个构建中的工件。这使得构建管道的实现变得简单。构建中的步骤将生成部署所需的内容。生成的内容通常存放在构建工件存放目录中。然后工件暂存目录将被发布到构建中。见图 7-1 。
图 7-1
在构建中创建一个放置并发布工件
第二种选择是使用共享路径。该选项主要在使用文件服务器时有用。您可以使文件服务器路径对本地代理方案可用,在这种情况下,代理可以访问网络中的共享路径。
第三个选项是使用 FTP 上载任务,您可以在团队项目中设置 FTP 服务器的服务终结点。为此,您可以使用通用服务连接类型,在该类型中,您可以向 FTP 服务器提供 FTP 服务器 URL 和凭据。见图 7-2 。
图 7-2
通用服务连接
下一个选项是将您的构建工件打包成一个 NuGet 包,并将其上传到一个 NuGet 提要。为此,您可以使用团队项目中可用的工件提要,我们将在本章的下几课中详细讨论。
在本课中,我们讨论了可用于从构建中发布工件的不同选项。
第 7.02 课:将工件打包并发布为 NuGet
发布构建工件的一个选择是使用 NuGet 包。与其他方法相比,使用 feed 来保存构建包有一个很大的好处。主要是它允许你保持发布的包,不管版本是否由于为版本设置的保留限制而从 Azure DevOps 中删除。
当您使用 NuGet 包任务时,您可以将内部版本号作为版本控制应用于包,或者您可以使用另一种首选版本机制。NuGet 包支持语义版本化,这是版本化软件版本的首选和可靠的方式。此外,它允许您使用外部部署管道,比如使用 NuGet 包部署的 Octopus。此外,您可以通过构建和打包成 NuGet 包来共享解决方案的公共代码组件。
要将构建输出的内容打包为 NuGet 包,可以使用一个名为 nuspec 的文件。nuspec 文件包含创建 NuGet 包的规范,例如包的名称、版本(版本可以在 NuGet pack 任务中被覆盖)、作者详细信息,甚至包含文件或指定路径模式中的文件的规范。你可以在 https://docs.microsoft.com/en-us/nuget/reference/nuspec
这里参考 nuspec 参考,了解更多关于 nuspec 文件的信息。如果您正在复制所有的构建内容,以便在构建任务中构建一个工件暂存目录,那么您可以将它们打包成一个 NuGet 包,使用一个基本的 nuspec 文件,该文件没有包含在包中的文件规范。它将在基本路径中添加指定文件夹中的所有内容。见图 7-3 。
图 7-3
纽吉特包
您可以使用 NuGet push 任务将打包的 NuGet 包推送到 NuGet 提要。它可以是在团队项目中创建的工件源。或者您可以使用自己的公共或私有 NuGet 提要,或者第三方包提要,比如 Octopus 服务器/cloud NuGet 提要,允许 Octopus 部署用作部署管道。如果您使用外部 NuGet 提要,您必须使用提要的 URL 和访问键(如 API 键)建立到外部提要的服务连接。见图 7-4 。
图 7-4
获取服务连接
工件源可以在团队项目中创建。现在,通过将提要的团队项目公开,可以公开创建这些提要。这样的提要允许你公开分享你的包。见图 7-5 。
图 7-5
创建订阅源
正如我们在本课中所讨论的,NuGet 包是将软件作为包发布的一种有用而可靠的方式。此外,它们可以用来与您的开发团队共享公共代码。
第 7.03 课:在构建中使用 NuGet 包
您可以在您的构建管道中使用您自己创建的 NuGet 包或公开可用的 NuGet 包。为此,您可以使用 NuGet 恢复任务。但是建议使用 NuGet restore 任务设置要使用的 NuGet 版本,以确保在您的构建中使用正确版本的 NuGet exe 进行恢复操作。参见图 7-6 。
图 7-6
设置 NuGet 版本
然后,您可以使用 NuGet restore 任务,并指定要从中读取的提要(如果它是来自团队项目的内部提要)。参见图 7-7 。
图 7-7
获取订阅源
或者选择使用 NuGet.cong 文件,它可以指定外部提要引用。链接 https://docs.microsoft.com/en-us/nuget/reference/nuget-config-file
提供了关于 NuGet.config 文件的详细参考信息。
即使是 dotnet restore 任务也支持指定内部提要、公共 NuGet gallery 或 NuGet.config 文件来定位在构建中下载包的提要。
在本课中,我们讨论了如何在构建中利用 NuGet 包。
摘要
在这一章中,我们看了使用 Azure 构建管道发布工件的用法和功能。我们还查看了工件的不同发布选项,并详细讨论了作为 NuGet 包的工件,包括在构建管道中重用 NuGet 包。
在下一章中,我们将重点关注创建基于 YAML 的构建管道,这将允许我们将管道版本作为代码进行控制。
八、创建和使用 YAML 生成管道
我们在前几章讨论了 Azure DevOps 经典构建管道。现在,您应该对经典构建的特性和构建管道的使用有了很好的理解。Azure DevOps 提供了两种类型的管道:经典的构建和发布管道以及 YAML 管道。在这一章中,让我们讨论 YAML 构建管道,它使我们能够将管道作为代码。
第 8.01 课:YAML 管道入门
YAML 管道是使用 YAML 脚本创建的 Azure DevOps 管道,该脚本提供了所有的触发器、管道任务等。,作为代码。因此,整个构建管道作为一个脚本来管理,而不使用任何 UI。您在前面关于经典构建管道的章节中获得的知识将使您更容易学习和使用 YAML 管道。然而,与经典的构建管道相比,您需要更多的脚本知识来实现 YAML 构建管道。
当创建 Azure DevOps YAML 管道时,它为您提供了一个源代码仓库列表,供您选择代码可能存在的位置。见图 8-1 。
图 8-1
选择源代码管理
在下一步中,它允许您选择存储库。例如,如果您选择 Azure Git 作为源 repo,项目中的所有 Azure Git Repos 将在第二步中列出以供选择。参见图 8-2 。
图 8-2
选择存储库
下一步允许用户选择管道将要配置的技术。例如,如果您需要配置一个. NET 核心应用,您需要选择。列表中的. NET 核心框架。参见图 8-3 。
图 8-3
选择要配置管道的框架
在过程结束时,它将根据创建管道时选择的值创建一个 YAML 管道。您可以修改此 YAML 脚本来添加或删除任务、变量、触发器和池。参见图 8-4 。
图 8-4
YAML 脚本
您可以从头开始编写自己的 YAML 脚本,并将它们保存在源 repo 中,而不是使用上面解释的管道创建过程。通过创建经典构建管道,这些 YAML 脚本可以转换为 YAML 构建管道。在经典的构建管道中,有一个模板将管道配置为代码。参见图 8-5 。
图 8-5
经典版本中的 YAML 模板
选择该模板,并使用您自己的 YAML 构建管道创建一个构建管道。
到目前为止,我们已经讨论了如何在 Azure DevOps 中创建 YAML 构建管道。让我们看看 YAML 是如何使用建造管道的。与使用 UI 组件创建的经典构建管道相比,YAML 管道是使用脚本创建的。因此,很容易使用一个脚本文件来更新管道。通过使用 YAML 管道,我们得到的最重要的好处是,用户可以对构建进行版本控制,这有助于跟踪对管道所做的更改。例如,您需要将声纳分析任务集成到管道中。如果使用 YAML 管道,可以从回购的稳定分支中创建一个特征分支作为特征分支,并更新特征分支中的 YAML 文件。然后,您可以测试管道,并将其合并到稳定分支,就像您对普通源代码所做的那样。
在本课中,我们学习了 Azure DevOps YAML 管道入门的基本步骤。
第 8.02 课:设置管道触发器和过滤器
正如我们在前面章节中所讨论的,一旦您将代码变更推送到 repo,就可以设置一个自动管道来自动触发。如前几章所述,您能够使用可视化工具为经典构件设置自动化触发器和过滤器。本课讨论了可以用编码方式实现的 YAML 管道触发器和过滤器。
在 Azure DevOps pipeline 中启用持续集成时,可以选择添加过滤器和指定触发器。例如,假设在 Azure DevOps 项目中有四种类型的分支,名为功能分支、版本分支、开发分支和主分支。但是,当且仅当代码变更被推送到一个特性分支时,您才需要触发一个构建。您可以启用与分支过滤器的持续集成来达到这一要求。
此外,在 Azure DevOps 的分支过滤器中,它允许用户向代码路径添加更多过滤器,这有助于以自定义方式指定自动化触发器。举个例子,假设一个 Azure DevOps 分支触发器已经被设置为在代码更改被推送到功能分支时触发。此外,还有一个要求,当且仅当对特定文件夹中的代码进行了更改时,才应该触发构建。因此,您可以通过使用 Azure DevOps YAML 管道中可用的路径过滤功能来实现这一要求。
让我们试着用另一个例子来说明触发器的用法。当您使用微服务架构开发解决方案时,应用的每个组件都应该能够单独部署。假设在开发一个基于微服务的应用时,已经实现了多个 Azure function apps。因此,需要为每个功能应用单独创建一个构建和发布管道。如果您在构建管道中启用了持续集成,并且只添加了一个分支过滤器,则每次对所选分支进行推送时,都会触发此构建。它为构建代理带来了不必要的流量,因为它构建了所有的微服务构建,即使只有一个被更改,这也是对资源时间的浪费。通过添加路径过滤器,您可以解决这个问题。因此,您可以为给定的微服务构建指定一个触发器,以便在仅将代码更改推送到相关微服务代码文件夹路径时进行构建。
遵循 YAML 示例脚本将帮助您学习如何设置触发器。一旦主分支或开发分支或任何版本分支或任何特性分支发生变更,它就会触发构建。如果您想要为一个特定的分支触发一个构建,您可以给这个分支一个带有“include”关键字的名称,如下所示。如果您不想为一个给定的分支触发一个构建,您可以在 YAML 脚本中为该分支指定一个带有“exclude”关键字的名称。此外,下面 YAML 中的 path filter 的含义是在将代码更改推送到 Functions 文件夹中的 UserRegistration 文件夹时触发构建。
trigger:
branches:
include:
- master
- develop
- version/*
- feature/*
paths:
include:
- Functions/UserRegistration
variables:
BuildConfiguration: 'Release'
FunctionPath: 'Functions/ UserRegistration'
NuspecName: 'TestPro.Services.UserRegistration.nuspec'
pool:
vmImage: 'windows-latest'
name: $(Build.SourceBranchName).$(Build.BuildId)
steps:
- template: ../Templates/BuildNumber.yml
- template: ../Templates/CoreFunctionBuild.yml
parameters:
BuildConfiguration: $(BuildConfiguration)
FunctionPath: $(FunctionPath)
NuspecName: $(NuspecName)
除了使用分支和路径过滤器设置触发器之外,您甚至可以使用标记过滤器。标记过滤器允许您基于应用于 Git 提交的标记来触发管道。您也可以将其设置为排除标签。有一个选项可以将 batch 设置为 true 或 false,以便在管道活动运行时批处理和执行更改。请参见下面的示例。
trigger:
batch: true
与代码推送触发器类似,您可以使用分支和路径过滤器在 YAML 管道中设置拉请求触发器。下面显示了一个示例实现,它类似于持续集成触发器。拉请求触发器还可以包括和排除分支和路径。
pr:
branches:
include:
- master
- develop
- version/*
- feature/*
paths:
include:
- Functions/UserRegistration
要禁用拉请求触发器,可以使用下面的语法;但是,这不会影响持续集成触发器。
pr: none
有一个默认为真的自动取消布尔选项,如果有更多的更改被推送到同一个拉请求,它将自动取消正在进行的拉请求构建。
pr:
autoCancel: false
此外,您还能够在 YAML 管道中使用过滤器设置预定的触发器。Cron 语法用于以 UTC 时间设置触发器。如下面的示例所示,您可以设置多个计划。将 always 布尔值设置为 true 允许您设置是否应该运行计划的生成,即使在最后一次运行后没有对代码进行任何更改。always 布尔值的默认值为 false。
schedules:
- cron: "0 0 * * *"
displayName: Daily midnight build
branches:
include:
- master
- version/*
exclude:
- releases/ancient/*
- cron: "0 12 * * 0"
displayName: Weekly Sunday build
branches:
include:
- version/*
always: true
本课解释了 Azure DevOps 管道触发器的使用和过滤器的使用。此外,我们能够通过实现示例来识别过滤器和触发器的用法。
第 8.03 课:在 YAML 中使用变量
设置构建管道时,需要提供各种类型的值来构建管道任务。我们已经在前面的章节中讨论了 Azure DevOps 变量组和变量的使用,以及在使用经典版本时如何使用变量。本课将讨论如何在 YAML 构建管道中使用变量值。
在 YAML 脚本中,可以用“variables”关键字定义变量。在变量部分,提供变量名和值。之后,这些值可以在管道任务中使用。因为变量只在一个地方定义,所以很容易改变脚本的变量。参见图 8-6 。
图 8-6
任务中使用的 YAML 变量
当您将您的构建维护为 YAML 时,您可能需要定义具有不同访问级别的变量。一个 YAML 脚本可以用三种类型的变量来编写。您可以定义可在多个作业和阶段中使用的全局变量。此外,您可以定义可以在指定作业中使用的变量。例如,如果您希望用调试配置生成一个代理作业,用发布配置生成另一个代理作业,您可以定义作业级变量。还有另一种类型的变量,不仅可以在作业中使用,还可以用作代理变量。有时我们需要访问环境变量来执行管道中的各种操作。
你可以使用两种语法来定义变量。第一种语法如图 8-6 所示。在第二种语法中,您可以在两行中定义变量的名称和值,如下例所示。
variables:
- name: MY_VARIABLE
value: some value
- name: MY_VARIABLE2
value: some value2
在前面的课程中,我们学习了变量组以及如何使用它们。正如您已经知道的,变量组允许用户保存在更多管道之间共享的变量值。可以使用下面显示的语法在 YAML 管道中引用变量组。
variables:
- name: MY_VARIABLE
value: some value
- group: my-variable-group-1
- group: my-variable-group-2
您可以在管道任务中使用变量组中的变量,有两种语法:宏样式和运行时表达式样式。假设您在变量组中指定了一个 myvar 变量,它的用法如下所示。
variables:
- group: my-variable-group
steps:
- script: echo $(myvar) # uses macro syntax
- script: echo $[variables.myvar] # runtime expression
你可能有的另一个问题是,如何在使用 YAML 管道时保持秘密值。正如你已经知道的,YAML 变量是在脚本中定义的,我们不能在 YAML 脚本中提供加密值。因此,如果您想要使用任何秘密值,需要使用 web UI 将其定义为管道变量,而不是定义为 YAML 变量,或者您可以将它保存在变量组中。
在本课中,我们讨论了在 YAML 管道中使用变量的用法和语法。
第 8.04 课:管道中的作业和阶段
作业用于定义管道执行阶段。可以用执行所需操作的步骤/任务来定义作业。
当您有一个包含单个作业的管道时,您不必指定 job 关键字,但是您必须指定管道的步骤,如下所示。
pool:
vmImage: 'ubuntu-16.04'
steps:
- bash: echo "Hello world"
与传统的构建管道类似,如果需要,您可以在一个管道中定义多个作业。
jobs:
- job: A
steps:
- bash: echo "A"
- job: B
steps:
- bash: echo "B"
在作业中,您可以定义要使用的代理,如下所示。
jobs:
- job: myJob
timeoutInMinutes: 10
pool:
vmImage: 'ubuntu-16.04'
steps:
- bash: echo "Hello world"
您可以在您的管道中定义类似于发布管道中的阶段,我们将在第 9 和 10 章中讨论传统的发布管道。在每个阶段,如果需要,可以使用多个作业。
stages:
- stage: MyBuild
jobs:
- job: BuildJob
steps:
- script: echo My Build steps!
- stage: MyTest
jobs:
- job: TestingOnWindows
steps:
- script: echo Testing on Windows!
- job: TestingOnLinux
steps:
- script: echo Testing on Linux!
- stage: MyDeploy
jobs:
- job: DeployJob
steps:
- script: echo Deploying the code!
定义作业时,可以定义管道中其他作业的条件和相关性。
jobs:
- job: FirstJob
steps:
- script: exit 1
- job: SecondJob
dependsOn: FirstJob
condition: failed()
steps:
- script: echo this will run when FirstJob fails
- job: THirdJob
dependsOn:
- FirstJob
- SecondJob
condition: succeeded('SecondJob')
steps:
- script: echo this will run when SecondJob runs and succeeds
作业可以作为在池的代理上运行的代理池作业运行;或者运行在 Azure DevOps 服务器或容器作业上的服务器作业。代理池作业可以要求代理功能,如操作系统。
pool:
name: myPrivateAgents
demands:
- agent.os -equals Windows_NT
- anotherCapability -equals capabilityvalue
对于服务器作业,您可以将池指定为服务器。
jobs:
- job: myserverjob
pool: server
容器作业将在托管代理上运行。例如,下面的 YAML 管道从 DockerHub 获得版本为 16.04 的 Ubuntu 容器映像,并在托管的 Linux VM 代理上运行它,这些步骤在用容器映像创建的容器实例中执行。
pool:
vmImage: 'ubuntu-16.04'
container: ubuntu:16.04
steps:
- script: printenv
您可以定义作业设置为签出为无的 YAML 管道,以防止代码签出,从而便于实现部署管道。下面的语法被定义为执行部署作业,而不签出 repo,也不从指定的构建管道(例如,本例中 ID 为 15 的构建管道)下载最新的工件。
- job: Deploy
pool:
vmImage: 'ubuntu-16.04'
steps:
- checkout: none
- task: DownloadPipelineArtifact@2
inputs:
source: 'specific'
project: 'mysampleproj'
pipeline: 15
runVersion: 'latest'
在部署作业中,可以使用代理池来定位您的部署计算机。此外,可以将环境用作虚拟机或 Kubernetes 来进行部署。
jobs:
- deployment: VMDeploy
displayName: web
environment:
name: VMenv
resourceType: VirtualMachine
tags: web1
正如我们在本课中所讨论的,YAML 管道作业甚至可以用于管道的多个阶段,它们可以用于实现构建管道和部署管道。
第 8.05 课:工作中的步骤和任务
在作业中,您可以使用任务定义步骤,以定义要执行的操作。有多种类型的步骤可以定义为 YAML 管道中的步骤。
命令行任务可以在管道中定义为脚本。
steps:
- script: echo Hello world!
displayName: hellosample
可以在执行 bash 命令的步骤中定义 Shell 脚本任务。pwsh 允许您定义可以在 Windows、macOS 或 Linux 中执行的 PowerShell 核心任务。但是,如果在一个步骤中使用 PowerShell 作为任务,那么它只能在 Windows 平台上运行。
steps:
- powershell: echo Hello $(name)
displayName: Say hello name
name: chaminda
对于所有这些步骤任务,您可以使用 failOnStderr 布尔值来定义执行是否应该在脚本或命令行执行失败时使管道失败。
steps:
- pwsh: echo Hello $(name)
displayName: Say hello name
name: chaminda
workingDirectory: $(build.sourcesDirectory)
failOnStderr: true
签出是您可以定义的另一个步骤操作,以允许签出源代码管理仓库。如前一课所述,将此项设置为“无”会阻止签出操作。签出设置为 self 将签出当前 YAML 管道代码所在的回购。但是,如果需要,您可以在 pipeline 步骤中使用签出任务来定义其他 repos 并将其签出。在下面的 checkout 示例中,可以看到 GitHub repo 和 Azure Git repo 的用法。
resources:
repositories:
- repository: MyRepoNameToUseInChekoutStep
type: github
endpoint: MyGitHubServiceConnection
name: Chamindac/myrepo
trigger:
- master
pool:
vmImage: 'ubuntu-latest'
steps:
- checkout: self
- checkout: MyRepoNameToUseInChekoutStep
- checkout: git://MyTeamProject/myazuregitrepo
任务是可用于管道的任务目录,我们在经典构建中讨论过。您可以在链接 https://docs.microsoft.com/en-us/azure/devops/pipelines/tasks/?view=azure-devops
中找到所有可用任务的列表,并找到每个任务的 YAML 片段。所有的任务都是预定义的,非常有用,因此您可以快速实现您的管道。诸如查询工作项和调用 HTTP REST API 之类的任务可以使用服务器作业(无代理)来实现基于 YAML 的部署管道的门控,我们将在第 9 和 10 章的经典发布管道的使用课程中对此进行描述。
在本课中,我们探讨了管道中的几个可用任务,这些任务以各自的名称指定,如 script 和 pwsh,以及默认情况下可用于实现管道需求的任务目录。
第 8.06 课:使用模板
在第六章中,我们讨论了使用任务组来实现通用步骤。类似地,使用 YAML 管道,您可以通过使用模板将步骤共享给多个管道来达到相同的目的。
在 Azure YAML 管道中有四种模板可用。阶段、作业、步骤和变量是这些模板类型,它们对您来说更有意义,因为您已经在本章的前几课中学习了这些类型。
下面是一个阶段模板的用法,名为 name 的参数定义为空字符串,默认值为空字符串。
# File: stages/mystagetemplate.yml
parameters:
name: ''
stages:
- stage: Print_${{ parameters.name }}
jobs:
- job: ${{ parameters.name }}_Windows
pool:
vmImage: vs2017-win2016
steps:
- script: echo hello ${{ parameters.name }}
- job: ${{ parameters.name }}_Mac
pool:
vmImage: macos-10.14
steps:
- script: echo hello ${{ parameters.name }}
上述阶段模板可以在管道中使用,如下所示。请注意参数值是如何传递的。
stages:
- template: stages/mystagetemplate.yml
parameters:
name: Chaminda
- template: stages/mystagetemplate.yml
parameters:
name: Pushpa
同样,您也可以定义作业和步骤模板,并在管道中使用它们。
工作模板如下。
# File: jobs/myjobtemplate.yml
parameters:
name: ''
pool: ''
sign: false
jobs:
- job: ${{ parameters.name }}
pool: ${{ parameters.pool }}
steps:
- script: echo hello
作业模板可以如下所示使用。
jobs:
- template: jobs/myjobtemplate.yml
parameters:
name: macOS
pool:
vmImage: 'macOS-10.14'
- template: jobs/myjobtemplate.yml
parameters:
name: Linux
pool:
vmImage: 'ubuntu-16.04'
Step 也将具有类似的语法,唯一的区别不是作业内容,而是步骤内容和参数化以匹配步骤需求。
可以定义变量模板来保持变量共享。变量名和值可以在模板中定义,如下所示。
# File: variables/mybuildvartemplate.yml
variables:
- name: vmImage
value: vs2017-win2016
- name: buildplatform
value: x64
- name: buildconfiguration
value: release
然后,变量模板可以使用以下语法在管道中使用。
variables:
- template: variables/mybuildvartemplate.yml
pool:
vmImage: ${{ variables.vmImage }}
steps:
- script: build x ${{ variables.buildplatform }} ${{ variables.buildconfiguration }}
在本课中,我们探讨了如何使用模板将阶段、作业、步骤和变量作为模板进行共享,以及如何在 YAML 管道中使用模板。
摘要
在这一章中,我们重点了解了 YAML 管道实现,以支持管道作为代码,这使我们能够轻松地对我们实现的管道进行版本控制和跟踪源代码的更改。本章探讨了定义基于 YAML 的管道以支持构建、测试和部署需求的各种选项。有了这些知识,您将能够用您的应用代码并排编写您的管道并对它们进行版本控制。
在下一章中,我们将讨论经典的发布管道实现选项和特性。一旦您发现了经典发布管道中的可用功能,您可以使用这些知识来尝试和实现经典管道以及 YAML 管道所满足的相同需求,因为您现在已经对 YAML 管道语法有了坚实的理解。
九、Azure 发布管道——服务连接、模板、工件、阶段和环境
在前几章中,我们讨论了设置构建管道的特性和选项。构建管道允许您构建源代码并使用构建的二进制文件创建可部署的包,使用代码分析工具检查源代码中的漏洞,以及运行单元测试。此外,您可以在构建管道中运行部署操作,尤其是在涉及 YAML 管道时,部署的实现也是通过 YAML 构建管道设置的。
Azure DevOps 中的发布管道具有各种功能,使您能够部署到几乎所有可用的目标和平台。在本章中,我们将探索 Azure DevOps 中与部署管道相关的一些可用功能,以便您能够理解这些功能的使用,从而实现自动化软件交付,甚至是生产目标。
第 9.01 课:服务连接
通常,在给定的软件中,不同的平台上可能有不同的部署目标。既可以有云目标,也可以有本地目标。此外,目标可以是云平台资源或云上的基础设施。为了支持部署到如此多样的平台,需要连接到这样的资源。换句话说,应该对给定资源中的端点进行身份验证,并且应该从 Azure DevOps 以服务连接的形式连接到端点,以便允许管道与资源进行交互。
例如,我们可以考虑 Azure 订阅或资源组。Azure 中的服务原则允许访问 Azure 资源。使用服务原则,您可以在 Azure DevOps 中建立 Azure 服务连接。见图 9-1 。
图 9-1
Azure 服务连接
您可以从 Azure DevOps 建立各种各样的服务连接。它们涉及诸如 Azure、AWS 之类的云服务目标,诸如 Bitbucket 和 GitHub 之类的代码回购,不同类型的部署工具 chefs、Octopus 以及许多其他连接代码质量工具的目标。
到 GitHub 和 Bitbucket 等源代码控制仓库的服务连接允许您将不同的源代码控制仓库连接到 Azure 管道。您可以通过将它们与服务连接联系起来,在这样的 repos 中构建可用的代码。
Azure DevOps 的 marketplace 扩展安装了一些服务连接类型。例如,要链接 sonar cube 服务器,您需要安装 sonar cube 扩展。一旦添加了扩展,就可以设置管道来触发源代码控制库中源代码的代码分析。另一个例子是面向 Amazon Web Services (AWS)的服务连接,允许部署到 AWS。参见图 9-2 。
图 9-2
不同类型的服务连接
在本课中,我们探讨了服务连接及其使用,以促进与 Azure DevOps 的外部资源连接。
第 9.02 课:使用模板
模板被预先创建为一组组合在一起的管道任务,用于给定的目的。这些模板还设置了常用的变量,以便快速部署到所需的目标。见图 9-3 。
图 9-3
发布模板
例如,如果您应用 Azure 机器学习模型部署模板作为您的管道模板,它将创建部署机器学习模式所需的两个步骤。您可以选择创建为服务连接的 Azure 订阅,并使用此模板快速开始机器学习模型部署。参见图 9-4 。
图 9-4
ML 模型部署模板
模板的主要用途是让您开始使用给定类型的应用,并快速完成目标部署。如果您是设置发布管道的初学者,这些模板将帮助您在更短的时间内熟悉发布管道,最大限度地减少学习工作量。您可以通过从 Visual Studio 市场设置扩展来安装附加模板。
我们在本课中讨论了模板的使用,这将帮助您快速开始使用发布管道。
第 9.03 课:发布的工件
正如我们在本书第七章中讨论的,构建管道应该生成可部署的二进制包,称为工件。这些工件可以在发布管道中使用,将它们的内容下载到目标上,并根据需要进行部署。
Azure 发布管道支持许多工件类型。参见图 9-5 。
图 9-5
工件类型
如果您已经在构建本身中将您的工件发布为发布的放置文件夹,那么您可以将该构建用作您的构建的工件类型。一旦构建完成,如果您想要设置发布的连续触发,那么将构建设置为通过其他方式发布构件的构件类型甚至是有用的,例如发布中的构件提要。
Azure repos 可以用作另一种工件类型。在发布步骤中可以使用代码或其他文件,如 YAML 部署支持文件。有时,甚至机器学习所需的基于 Python 的部署和部署后测试代码文件也可以存储在 Azure repos 中,并在发布管道中使用,以执行部署和测试步骤。通过使用 GitHub 和 Team Foundation 版本控制 repos 作为发布管道中的工件,可以达到类似的目的。
如第七章所解释的,Azure 工件可以用来在工件提要中存储生成的工件,比如 NuGet 包。工件提要可以在发布中使用,包可以下载并在部署代理中使用,以部署到所需的目标。
Azure container repositories 和 docker hub 作为工件,允许您使用它们中可用的 docker 映像,以便在发布管道中使用。此外,Jenkins 管道可以集成为一个工件源,这样您就可以在发布管道中使用 Jenkins 管道的输出。
一旦添加了工件,您就可以基于新工件的可用性为管道设置一个触发器,这允许连续的部署。使用生成时,可以为触发器添加额外的排除或包含分支筛选器。当使用 repo 时,它可以基于 pull 请求设置一个触发器,带有一个目标分支过滤器,您可以使用分支过滤器来触发提交。参见图 9-6 。
图 9-6
回购工件触发器
在本课中,我们讨论了可以在发布管道中使用的不同类型的工件,这使您能够基于新工件的可用性来触发发布管道。
第 9.04 课:发布阶段
发布阶段可用于控制发布管道的流量。您可以将它们视为管道中的部署环境表示。管道中的阶段为您提供了定义您想要的软件交付工作流的灵活性。在这一课中,让我们探索发布阶段的功能和用法,以管理软件项目向期望目标的交付。参见图 9-7 。
图 9-7
释放管道流量
可以用三种类型触发器设置阶段。手动触发要求您在从发布管道创建发布后,通过单击手动部署来手动触发阶段。“后阶段”允许您定义前面的阶段,以便仅当所有前面的阶段完成时才触发当前阶段。一旦为管道创建了发布,发布后将触发一个阶段,通过手动创建或在连接的工件上设置连续部署触发器。参见图 9-8 。此外,您可以为给定的阶段设置预定的发布。工件过滤器允许您过滤分支,排除或包含模式,或者设置其他工件条件。启用拉取请求部署将允许将基于拉取请求的发布部署到给定阶段;但是,建议在生产阶段禁用此功能。
图 9-8
阶段触发器
可以设置一个具有预部署批准的阶段。作为审批者,您可以添加个人或组,并设置审批超时。设置批准将在触发阶段时向批准人发送提醒电子邮件。批准者可以批准或拒绝部署到给定阶段。但是,如果需要,可以安排延迟时间来批准部署。这种预部署批准可以有效地用于保护所需的环境,如生产或演示环境。此外,当应用的一个版本正在被测试时,它可以被用来防止到诸如质量保证阶段的任何部署,以便它防止在质量保证阶段的应用的组件被意外地覆盖,直到 QA 团队决定接受新的版本进行测试。部署前审批设置见图 9-9 。部署后批准也可以像部署前批准一样进行设置,以表明如果某个已部署的应用通过了给定应用的必需的强制工作条件,则该应用将得到验证和考虑。见图 9-9 。
图 9-9
部署前批准
另一个可以应用于 stage 的预部署设置是 Azure pipelines 中的 gates。Gates 允许您调用第三方调用,并在继续某个特定阶段之前等待期望的结果。换句话说,gates 用于在部署给定阶段之前执行看门人的工作。例如,在允许发布部署 QA 阶段之外的任何阶段之前,查询工作项门可以评估是否有任何关键错误处于未解决的状态。参见图 9-10 。
图 9-10
盖茨
某个阶段的部署队列设置允许您定义多个发布在给定阶段排队时的行为。您可以定义在给定的阶段是否允许并行部署,但是这是一个极不可能的场景。当部署排队的多个版本时,可以使用一个序列中的所有版本。或者,您可以将设置为仅部署最新版本,并放弃其他以前的部署请求。参见图 9-11 。
图 9-11
部署队列设置
在部署后阶段,如本课前面所讨论的,可以设置批准以表示应用在该阶段工作正常,在部署到该阶段后,让它触发任何后续阶段。此外,您还可以向部署后阶段添加关卡。此外,您可以选择在部署阶段失败时设置重新部署触发器,以便它将当前阶段以前成功的部署再次部署到该阶段。参见图 9-12 。
图 9-12
重新部署触发器
您可以克隆一个阶段来创建另一个阶段,这使您可以轻松地创建发布工作流。在一个阶段中,您可以添加代理阶段、部署组阶段和无代理阶段,这些将在第十章中详细介绍。与构建管道类似,您可以将任务添加到发布阶段,以定义作为部署和自动化测试操作执行的步骤。见图 9-13 。
图 9-13
阶段
在本课中,我们讨论了前阶段和后阶段中可用于简化发布工作流的几个功能。
第 9.05 课:环境
可以用作部署目标的资源集合可以设置为 Azure DevOps 中的环境。一个环境可能包含一个 Kubernetes 集群、一组虚拟机或资源,例如 Azure web app 或 functions apps。
您可以创建一个有虚拟机、Kubernetes 或没有资源的环境。创建无资源环境时,可以在以后向环境中添加资源。参见图 9-14
图 9-14
环境
对于环境,您可以基于读者、用户和管理员的角色设置权限,其中管理员可以管理环境,用户可以使用管道中的环境,而读者只能查看。
环境可以添加检查,有点类似于 gates。检查甚至还包括工件的批准者评估。参见图 9-15 。
图 9-15
环境检查
YAML 管道可以使用环境作为部署行动的目标。参见图 9-16
图 9-16
YAML 的使用环境
环境促进了 YAML 管道基于批准的工作流实施,类似于传统发布管道中可用的阶段。
在本课中,我们已经确定了在 YAML 管道环境中的用法和可用选项。
摘要
本章给出了发布管道的初步介绍,强调了服务连接的功能和模板的使用,以便轻松地开始使用发布管道。然后我们讨论了工件在发布管道中的使用,以及设置基于工件的触发器来支持连续部署。还详细讨论了实现发布工作流的发布阶段功能,解释了每个可用选项的用法。此外,我们探索了允许为 YAML 管道设置部署目标的环境,类似于经典发布管道中的阶段。
在下一章中,我们将讨论发布管道阶段的可用阶段,以便您获得成功实施发布工作流所需的知识。此外,我们将探索其他选项和特性,例如变量、发布定义历史的使用,以及发布管道的导出和导入选项。
十、Azure 发布管道——作业、部署组、变量和其他选项
在前一章中,我们讨论了一些与发布管道相关的重要特性。描述了允许发布管理的各种部署目标的服务连接。此外,我们探索了可用于发布管道实现的模板的使用,发布管道中实现发布工作流的阶段,以及设置触发器、批准和关口的方法。还讨论了新的功能环境,以了解其用法。
作为上一章的延续,我们将探讨代理作业、部署组作业和无代理作业阶段及其用法。然后,我们简要地讨论变量及其在发布管道中的使用,这或多或少类似于变量在构建管道中的使用。
第 10.01 课:代理作业
代理作业需要安装 Azure DevOps 代理来执行作业。根据我们在本课中讨论的部署目标,代理计算机可以是托管代理计算机或本地计算机。
根据执行情况,代理的步骤技术要求会有所延迟。代理的需求可以作为代理阶段的需求。例如,如果您的部署步骤涉及 Azure CLI,要部署到 Azure 目标,您的代理计算机需要有可用的 Azure CLI。代理阶段的需求用于这些类型的技术需求。见图 10-1 。
图 10-1
代理需求
如果您正在部署到云目标,如 Azure 或 AWS,您可以使用 Microsoft 托管代理来执行部署操作。但是,如果您要部署到内部部署目标或更安全的 Azure 目标(如 Azure App Service Environment ),您可能需要设置自己的部署代理机器。大多数情况下,内部部署环境位于企业防火墙之后,托管代理无法看到针对此类目标执行的部署。与此类似,在 Azure App Service Environment (ASE)中,对平台服务的访问只能在 Azure ASE 中定义的虚拟网络中进行。因此,您需要在 Azure ASE 虚拟网络中设置一个配置为 Azure DevOps 代理的虚拟机,它可以访问 Azure ASE 中的平台服务。
有类似于构建管道的并行选项,允许您在单个代理或 multipliers 中指定的多个配置中运行作业步骤。当在多个配置上运行时,您可以指定代理数量限制。您可以在多个代理中运行同一组任务,也可以使用多代理选项。见图 10-2 。如果您希望部署到不同的目标,这些选项会很有用,因为指定的配置可能会启用调试配置上的部署,以诊断一些问题,同时还有一个发布配置目标。
图 10-2
平行
您可以在代理步骤中有选择地设置下载或跳过下载工件。见图 10-3 。例如,如果您有一个单独的代理作业来运行自动化测试,那么除了需要执行的自动化测试脚本之外,您可能不需要下载工件。因此,您可以跳过部署文件,只下载与测试执行相关的工件。
图 10-3
史前古器物
您可以设置允许脚本在代理阶段访问 OAuth 令牌,以便代理作业中的任何脚本任务都可以使用系统访问令牌来访问 Azure DevOps 的 REST API。
代理作业有两种超时设置。超时定义了作业可以在代理中执行的时间。作业取消超时定义在服务器终止作业之前,当发出取消请求时,给作业多少时间来完成。
执行选项允许您定义作业开始的条件。见图 10-4 。如果部署失败,您可能需要设置回滚过程,这在前面的代理作业中已定义。在这种情况下,您可以将其设置为在当前代理作业中的上一个作业失败时执行,并定义回滚任务。如果您希望在成功部署作业后执行自动化测试,您可以设置一个代理作业,以便在成功执行该作业后执行部署,从而在后续作业上执行功能测试,前提是前一个作业成功。但是,与生成代理作业不同,执行是在发布代理作业中按定义的顺序进行的,并且没有像在生成代理作业中那样定义依赖项的选项,因为执行是按发布管道中设置的作业顺序进行的,所以不需要依赖项。
图 10-4
OAuth 令牌和作业运行条件
您可以使用 Azure DevOps 中默认可用的许多任务,以及通过代理作业中的市场扩展添加的任务来执行所需的部署步骤。这些部署步骤可能涉及设置给定环境目标的基础设施,部署您的应用,甚至执行功能和集成测试。在 Azure DevOps 的市场中,你可以找到支持各种平台的任务和几乎所有你需要做的动作。如果找不到任务,你可以自己实现它们,我们将在第十一章详细讨论。您可以将您的任务分组为任务组,以便在多个代理作业中重用它们,我们在第二章中讨论了任务组。
在本课中,我们讨论了在发布管道中使用代理作业。
第 10.02 课:部署组作业
部署组作业意味着在定义的部署组上执行。我们已经在本书的第二章中讨论了部署组和部署池,以及如何将它们添加到具有角色的目标机器中。
在发布管道中,可以在部署组作业中使用团队项目中定义的部署组。您可以使用部署组目标中定义的角色作为给定部署组阶段的必需标记。例如,可以使用部署组作业中的标记将角色设置为 webSvr 的任何机器标识为 Web 服务器,这需要使用应用的 Web 服务器部署步骤进行部署。见图 10-5 。
图 10-5
部署组标记
与代理作业类似,部署组作业也有超时和作业取消超时设置,您可以使用这两个设置来分别确定作业在超时前可以执行的时间,以及在终止前发出取消请求后允许完成作业的时间。
要并行部署的目标设置根据部署组的目标中选定的标记和定义的角色,定义当部署组中有多个目标可用时,部署操作并行执行的目标数量。这使您能够在负载平衡的情况下部署多个 web 服务器,等等。,并行。超时 0 表示无限超时,超时以分钟为单位定义。见图 10-6 。
图 10-6
目标并行设置和超时
与部署组中的代理作业类似,您还可以定义在给定的作业中下载哪些工件。OAuth 令牌访问和基于条件的作业执行也可以像代理作业一样进行设置。这些功能可用于定义部署组的回滚和测试执行场景,正如我们在上一课中对代理作业所做的解释。当使用测试执行时,这种机器中的角色可以是基于标签(如 test client)的测试客户端角色。
这些任务可以在类似于代理作业的部署组阶段中使用,以根据其目标角色实现部署。即使在市场任务中,也可以根据需要利用任务组。
在本课中,我们探索了部署组作业中的可用选项,以在 Azure DevOps 中设置发布管道。
第 10.03 课:无代理作业
无代理作业对于执行不需要计算机来执行正在执行的步骤非常有用。无代理作业可执行的步骤数量有限。见图 10-7 。
图 10-7
无代理作业步骤
使用无代理阶段,您可以使用延迟步骤在给定代理或部署组作业后等待给定时间。延迟时间过后,可以执行下一个代理或部署组作业。这种类型的延迟在诸如在云平台目标上配置基础架构的场景中非常有用。一旦在这样的云平台上执行基础设施命令来提供所需的平台资源,可能会有时间要求。因此,延迟任务可以用来等待这样一个所需的时间。
类似于在管道阶段之间应用的门控,在部署前和部署后阶段,您可以利用无代理阶段来实现代理或部署组作业之间的门控,或者通过使用诸如调用 Azure 函数、调用 REST API、查询 Azure Monitor 警报和查询工作项任务等任务来实现。有关门控的更多信息,请参阅第九章。
手动干预任务可用于在代理或部署组作业之间实施批准、拒绝步骤。在执行管道的下一步之前,如果您希望手动执行某个操作,这些批准可能会很有用。
在无代理作业中,与代理或部署组作业相比,设置最少。参见图 10-8 。无代理作业可以针对乘数中指定的多种配置执行。可以指定超时来执行无代理阶段。运行条件允许您根据上一步成功或失败来定义是否应执行无代理阶段;或者使用自定义条件,帮助您确定是否需要根据管道执行流执行无代理作业。
图 10-8
无代理作业设置
在本课中,我们讨论了无代理阶段以及发布管道中无代理步骤的用法。
第 10.04 课:变量
类似于构建管道的发布管道包含变量。在发布管道的“变量”选项卡中,您可以定义键和值对。变量中包含的敏感信息可以定义为机密,这样的变量值一旦标记为敏感就不可见。参见图 10-9 。
图 10-9
敏感变量
如图 10-9 所示,发布管道中的变量的范围可以是发布或阶段。同一变量在每个阶段可以包含不同的值。对于发布管道中的每个变量,您可以在发布时将其设置为可设置的,这允许在创建发布时设置这些变量的值。参见图 10-10 。
图 10-10
发布时可设置
如第二章所述,变量组可用于为多个发布管道保存共享变量,甚至与构建管道共享变量。这样的变量组可以在具有发布范围或阶段范围的发布管道中使用。见图 10-11 。
图 10-11
发布管道中的变量组
当变量自动解析时,可以在另一个变量中使用$(variablename)来重用变量。这有助于在多个变量中重复值,并确保变量包含唯一的值,只需更改一个位置就可以更改变量值。
在本课中,我们讨论了变量及其在发布管道中的用法。
第 10.05 课:其他有用的功能
发布管道还有一些其他有用的功能:在“保留”选项卡、“选项”选项卡、“历史记录”选项卡中,以及在“导入”、“导出选项”等发布菜单中。
在“保留”选项卡中,您可以设置版本保留设置。有一个链接可以设置项目默认值以及留成。无论保留日期设置如何,您都可以设置保留版本的天数以及应保留的最小版本数。保留天数指定版本将保留的天数。无论天数是多少,在“要保留的最小发布次数”中指定的发布次数都将被保留。参见图 10-12 。
图 10-12
保留
您可以设置版本号格式,并向版本定义添加描述。发布号可以与带有修订版的内部版本号一起使用,以赋予完整发布号更多的含义。参见图 10-13 。
图 10-13
发布号
options 选项卡提供了发布管道的集成选项,可以与存储库、板和外部服务吉拉集成。参见图 10-14 。
图 10-14
集成
发布管道的历史记录提供了发布管道中的修订信息,您可以在其中进行版本比较,并在需要时恢复到给定版本。
在本课中,我们讨论了发布管道的一些有用选项。
摘要
在本章中,我们详细探讨了代理作业、部署组作业和无代理作业及其用法。此外,我们还研究了其他一些特性,如变量、选项、集成、保留设置、发布管道的历史及其使用。
在下一章,我们将探索 REST API 和命令行界面的特性以及它们的用法。
十一、REST API、命令行和扩展开发
在前几章,我们讨论了 Azure DevOps 中的构建和发布管道。我们已经研究了经典和 YAML 管道。对于我们讨论的管道功能,REST API 支持我们以编程方式处理许多操作。此外,Azure DevOps 的命令行界面(CLI)提供了几个命令,可用于构建和发布的编程管理。
对构建和发布管道的编程访问对于生成报告、操纵管道行为,甚至实现管道的可扩展性都很有用。在这一章中,让我们看看如何利用 REST API 和 CLI,以及先决条件是什么。接下来,我们讨论如何使用对构建和发布管道的编程访问来构建扩展。
第 11.01 课:使用构建和发布 REST APIs
Azure DevOps build 的 REST API 提供了几个 API。您可以使用 REST API 执行诸如运行构建、更新构建定义、获取关于构建的细节、标记构建等操作。
REST API 请求/响应对可以用下面列出的五个组件来标识。
-
请求 URI
VERB https://{instance}[/{team-project}]/_apis[/{area}]/{resource}?api-version={version}
其中
instance
将 Azure DevOps 组织或 Azure DevOps 服务器分别定义为dev.azure.com/{organization}
或{server:port}/tfs/{collection}
。资源路径应该是
_apis/{area}/{resource}
的形式,例如_apis/build/builds
。API 版本应定义为表示 REST API 的版本,以{major}.{minor}[-{stage}[.{resource-version}]]
的格式使用,例如api-version=5.0
或api-version=5.0-preview
或api-version=5.0-preview.1
-
HTTPS 请求报头
强制请求头/动词/操作,如 GET、POST、PUT、PATCH 或 HEAD。您可以选择提供一个授权头作为载体令牌。
-
消息请求正文
为了支持 POST、PUT 操作,您可以为 JSON 这样的主体提供指定为 application/json 的内容类型。
-
响应报文头
HTTP 响应代码,2xx 表示成功,4xxx、5xx 表示错误。可选的响应头,如 Content-type,以支持请求/响应。
-
响应消息正文
JSON 或 XML 响应体。
每个请求都应该提供访问 REST API 的授权头。您可以在所需的访问范围内使用 Azure DevOps 中生成的个人访问令牌(PAT )(我们已经在 Azure Boards 手册中更详细地描述了 PAT)。
要在 PowerShell 中创建所需的授权头,可以使用下面的代码段。
$AzureDevOpsPAT = "yourazuredevopsPAT"
$User="";
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $User,$AzureDevOpsPAT)));
$header = @{Authorization=("Basic {0}" -f $base64AuthInfo)};
然后,您可以在调用请求中使用这个头,如下所示。
$Url = 'https://dev.azure.com/'+ $OrganizationName + '/' + $teamProjectName +
'/_apis/git/policy/configurations?repositoryId=' + $repository.id + '&refName=refs/heads/' + $fromBranch + '&api-version=5.1-preview.1';
$policies = Invoke-RestMethod -Uri $Url -Method Get -ContentType application/json -Headers $header
使用 REST API 来实现功能,这在 Azure DevOps 中是不可用的,是值得讨论的事情。例如,假设您使用构建策略来保护您的版本(发布)分支。如果您想将一个版本分支中的分支保护构建策略复制到另一个版本,没有现成的方法可以做到这一点。您必须在新分支中手动创建分支保护构建策略。但是,您可以使用 REST API,通过获取一个分支的策略并将其应用到另一个分支来实现 PowerShell 脚本。
另一个例子是,在向给定目标发布时,您可能想要从您的构建的相关变更和工作项中生成一个发布说明。给定目标的发布必须考虑之前对目标所做的发布,然后检查从上一个发布到目标的所有中间发布和构建,以识别当前发布中的所有变更。在这种情况下,REST API 将派上用场,您可以在 PowerShell 中实现所需的功能,并在发布管道中执行它来生成发布说明。
让我们快速看一下如何使用 REST API 对构建进行排队,以理解它是如何工作的。
POST https://dev.azure.com/{organization}/{project}/_apis/build/builds?api-version=5.1
您必须为 REST API 的 post 请求提供主体。作为最低要求,所提供的 json 主体应该包含构建定义 id。此外,您可以提供更多信息,如源分支。注意,构建定义 id 48 在下面是硬编码的,它可以被参数化。
{
"definition": {
"id": 48
},
"sourceBranch": "master"}
此类请求的示例脚本如下所示。
$AzureDevOpsPAT = "yourPAT"
$OrganizationName = "yourAzureDevOpsOrgname"
$teamProjectName = 'yourteamprojectname'
$User="";
$base64AuthInfo = [Convert]::ToBase64String([Text.Encoding]::ASCII.GetBytes(("{0}:{1}" -f $User,$AzureDevOpsPAT)));
$header = @{Authorization=("Basic {0}" -f $base64AuthInfo)};
$Url = 'https://dev.azure.com/'+ $OrganizationName + '/' + $teamProjectName + '/_apis/build/builds?api-version=5.1'
$body = '{
"definition": {
"id": 48
},
"sourceBranch": "master",
}';
$BuildQResponse = Invoke-RestMethod -Uri $Url -Method Post -ContentType application/json -Headers $header -Body $body
$BuildQResponse
在本课中,我们讨论了使用 REST API 执行构建和发布操作的可能性。此外,几个有用的场景解释了 REST API 可以在哪里使用,我们还看了一个示例来了解它如何与 PowerShell 一起工作。
第 11.02 课:使用 Azure 管道 CLI
与 REST API 类似,我们可以使用 Azure DevOps CLI 进行编程访问,并在 Azure 管道上执行操作。Azure DevOps CLI 是 Azure CLI 的扩展。作为先决条件,您需要安装 Azure CLI。
您可以通过在 PowerShell 窗口或命令提示符中执行az --version
来检查当前安装的 Azure CLI 扩展。见图 11-1 。
图 11-1
已安装的 az 扩展
要设置 az devops 扩展,您可以在 PowerShell、命令提示符或终端窗口中执行az extension add --name azure-devops
。见图 11-2 。
图 11-2
安装 az devops 扩展
要了解 az devops 扩展中可用的命令,请执行az devops --help
。您可以看到有几个可用的命令。除此之外,让我们关注管道命令。见图 11-3 。
图 11-3
az devops 命令
您必须执行az devops login
--org orgname
,然后在提示获得 Azure DevOps 组织的 CLI 认证时提供 PAT 作为令牌。您也可以使用 Windows 中的$env:AZURE_DEVOPS_EXT_PAT = 'yourPAT'
和 Linux 或 macOS 中的export AZURE_DEVOPS_EXT_PAT=yourPAT
设置环境变量,然后登录。见图 11-4 。
图 11-4
使用 CLI 登录 Azure DevOps
让我们以 REST APPI 为例,尝试对一个构建进行排队,看看如何使用 CLI 来完成。为了理解 build queue 命令,您可以运行一个az pipelines build queue –help,
,它会给出所有的帮助信息。要对一个构建进行排队,您可以运行一个命令,例如,az pipelines build queue -p 'Project X' --definition-id 48
,这个构建就会被排队。见图 11-5 。
图 11-5
使用 CLI 构建队列
您可以在 PowerShell 脚本或批处理脚本中使用 CLI,然后将它们用作管道中的步骤或用于其他目的。
在本课中,我们讨论了如何使用 Azure DevOps CLI 对 Azure 管道进行编程访问。
第 11.03 课:开发和分发扩展
如果市场上现有的现成功能或可用的扩展不能满足您对管道的要求,您可以为 Azure 管道开发扩展。
您可以选择使用基于 typescript 或基于 PowerShell 的管道扩展来设置管道扩展。但是,只有 windows 代理能够运行基于 PowerShell 的任务。如果您打算在所有代理平台上运行管道扩展,建议使用 typescript 来开发管道扩展。
您需要在 PowerShell 的文件夹中或终端窗口中运行一个npm init
来为扩展完成 npm 初始化。出现提示时提供所需的信息,初始 package.json 将在该文件夹中创建。见图 11-6 。
图 11-6
npm 初始化以创建 package.json
然后可以运行 NPM install azure-pipelines-task-lib-save 添加任务库来创建管道任务。见图 11-7 。这会将所需的节点模块安装到您的扩展文件夹中。
图 11-7
添加管道任务库
然后,您需要通过执行以下命令来添加 typescript 类型。
npm install @types/node --save-dev
npm install @types/q --save-dev
运行tsc –init
以确保在构建扩展时 typescripts 被编译成 javascripts。如果您的机器中还没有安装 typescript,您需要使用npm install -g typescript
命令全局安装它。
有了这个所有需要开发的结构,你的扩展就创建在文件夹中了。接下来,您需要将任务 json 添加到扩展任务文件夹中。您可以使用下面显示的模板,并用所需的值替换{{placeholder}}。Microsoft 文档中提供了该模板,建议从文档中复制最新的模板。以下文件内容中的输入是为示例任务设计的,您可能需要根据您的任务需求使用输入。
{
"$schema": "https://raw.githubusercontent.com/Microsoft/azure-pipelines-task-lib/master/tasks.schema.json",
"id": "{{taskguid}}",
"name": "{{taskname}}",
"friendlyName": "{{taskfriendlyname}}",
"description": "{{taskdescription}}",
"helpMarkDown": "",
"category": "Utility",
"author": "{{taskauthor}}",
"version": {
"Major": 0,
"Minor": 1,
"Patch": 0
},
"instanceNameFormat": "Echo $(samplestring)",
"inputs": [
{
"name": "samplestring",
"type": "string",
"label": "Sample String",
"defaultValue": "",
"required": true,
"helpMarkDown": "A sample string"
}
],
"execution": {
"Node10": {
"target": "index.js"
}
}
}
上述任务 json 文件中的可替换值可以像下面这样更新。
"id": "bdf70ab0-8600-45fd-98d4-834e22030ff6",
"name": "chamindacdemotask",
"friendlyName": "My Demo Task",
"description": "Demo Task",
"helpMarkDown": "",
"category": "Utility",
"author": "chamindac",
然后,我们可以使用下面的内容创建一个 intex.ts (typescript 文件)来启用演示/示例任务的功能。
import tl = require('azure-pipelines-task-lib/task');
async function run() {
try {
const inputString: string | undefined = tl.getInput('samplestring', true);
if (inputString == 'bad') {
tl.setResult(tl.TaskResult.Failed, 'Bad input was given');
return;
}
console.log('Hello', inputString);
}
catch (err) {
tl.setResult(tl.TaskResult.Failed, err.message);
}
}
run();
然后可以从扩展文件夹中执行tsc
,将 typescript 编译成 javascript。现在,如果您运行node index.js,
,它将在本地测试扩展;但是,由于没有提供输入,它将失败。见图 11-8 。
图 11-8
测试扩展任务
您可以提供一个带有$env:INPUT_SAMPLESTRING="Chaminda"
的输入字符串,并测试它来检查是否成功执行。见图 11-9 。
图 11-9
提供输入参数值的测试函数
要部署扩展,您需要打包它。但是在打包之前,您需要为它创建一个清单文件。对于我们使用的示例,您可以创建一个名为 vss-extension.json 的文件,并添加下面的内容。
{
"manifestVersion": 1,
"id": "build-release-task",
"name": "Chamidac Build and Release Tools",
"version": "0.0.1",
"publisher": "chamindac",
"targets": [
{
"id": "Microsoft.VisualStudio.Services"
}
],
"description": "Tools for building/releasing with chamindac. Includes one build/release task.",
"categories": [
"Azure Pipelines"
],
"icons": {
"default": "img/extension-icon.png"
},
"files": [
{
"path": "buildAndReleaseTask"
}
],
"contributions": [
{
"id": "custom-build-release-task",
"type": "ms.vss-distributed-task.task",
"targets": [
"ms.vss-distributed-task.tasks"
],
"properties": {
"name": "buildAndReleaseTask"
}
}
]
}
要打包您的扩展,您需要有 tfx CLI,它可以用npm i -g tfx-cli
命令安装。您必须在扩展文件夹中创建一个名为buildAndReleaseTask
的文件夹,并移动除了vss-extension.json
文件之外的所有文件和文件夹。您可以在扩展中添加更多文件夹,并添加更多任务来创建包含多个任务的扩展。然后从扩展文件夹中,run tfx extension create --manifest-globs vss-extension.json
命令将扩展打包。
要创建发布者,您必须登录 https://marketplace.visualstudio.com/manage
并设置您的发布者档案。然后,您可以使用tfx extension publish --manifest-globs vss-extension.json --share-with
https://dev.azure.com/yourorgname
命令将您的扩展发布、共享到您的组织。
发布后,您的扩展模块可以共享给其他组织或公开共享。参见图 11-10 。
图 11-10
扩展ˌ扩张
在本课中,我们讨论了如何为 Azure pipelines 构建扩展。
摘要
在本章中,我们讨论了使用 REST API 和命令行界面对 Azure 管道的编程访问。此外,我们已经讨论了构建管道扩展所需的基本步骤。
在下一章中,我们将看看测试自动化与 Azure 管道的集成选项。
十二、将测试集成到管道中
测试是软件交付过程中非常重要的一个方面。为了保证交付的软件项目或产品的质量,一些测试类型可以很容易地自动化,并与构建和发布管道相集成。
在这一章中,我们将会看到可以自动化的测试类型,以及我们可以用来有效运行管道自动化测试的特性和组件。
第 12.01 课:使用管道运行单元测试
用单元测试验证应用的代码以确保代码按预期运行是很重要的。实现单元测试是为了测试开发人员使用测试驱动开发方法(TDD)和行为驱动开发(BDD)编写的代码。
构建管道可以用来执行用许多类型的单元测试工具编写的单元测试。通常的做法是构建代码,然后执行单元测试,并将代码打包成可部署的二进制文件。要使用构建管道执行测试,您可以找到几个可用的任务。见图 12-1 。
图 12-1
测试任务
使用 Visual Studio 测试任务,您可以执行使用测试框架(如 MSTest、xUnit、NUnit 等)开发的多种类型的测试。该任务允许您在代理作业中使用多代理配置的同时,将测试分布在多个代理中,以便高效地运行它们。
还有其他任务,如 dotnet 命令行任务,允许您运行 dotnet 测试来执行使用开发的测试。NET 核心。命令行任务可用于执行机器学习代码单元测试运行等任务。见图 12-2 。
图 12-2
运行 Python 测试
当从 VS 测试任务或 dotnet 测试运行测试时,测试运行的结果会自动发布到管道。但是,如果您使用命令行执行测试,例如 Python 测试,则可能需要将测试结果的输出发布到管道,以便结果显示在已执行构建的 test 选项卡中。若要发布测试结果,可以使用“发布测试结果”任务,并指定测试执行的结果输出文件和测试结果的格式,以便将其发布到管道。见图 12-3 。
图 12-3
发布测试结果
在本课中,我们讨论了如何利用可用于管道的任务,通过构建管道来设置单元测试执行。
第 12.02 课:使用管道运行功能测试
集成和功能测试用于测试部署的应用。它们可能被实现为使用不同测试框架的 API 级测试或用户界面测试。Selenium 是广泛使用的主要测试框架之一。Net 等语言。还有其他的测试框架,比如 Cypress,它也在促进基于场景的功能 UI 测试实现。
测试应用的自动化功能测试应该在部署到给定目标后执行,以确保目标应用按预期运行。自动化和使用部署管道运行自动化的功能测试使团队能够为每个版本运行他们的大部分测试,从而在交付的应用中实现更高的质量。
基于 Selenium 的功能测试要求您以交互模式运行代理来执行测试。我们在本书第三章中讨论了如何设置代理。然而,Cypress 框架 UI 测试也可以用非交互式代理来执行。
要执行基于 Selenium 的测试,您可以利用虚拟机或物理机中的代理设置作为交互式代理。这样的代理应该为 Visual Studio 测试平台安装程序任务的测试执行做好准备。见图 12-4 。
图 12-4
VS 测试平台安装程序
然后,您可以使用 VS 测试任务来执行使用 C#用 Selenium 编写的测试。如果您已经用 Java 开发了测试,那么您可以使用 Maven 任务来执行发布管道中的测试。
测试执行可能需要您使用虚拟机作为测试客户端,尤其是当您需要运行交互式代理时。您可能需要设置多台测试客户机来有效地分发和运行您的功能测试。然而,保持这些虚拟机在诸如 Azure 的云平台中持续运行将是昂贵的。为了最小化成本,您可以在测试执行之前设置机器的按需启动;一旦测试执行完成,关闭测试客户端,这样云平台上的费用将被最小化。见图 12-5 。
图 12-5
测试客户端按需启动和停止
在本课中,我们讨论了使用发布管道来执行功能测试。
摘要
在这一章中,我们讨论了使用单元测试和功能测试来确保所交付的应用的质量。
在本书中,我们讨论了关于 Azure pipelines 的几个重要事实。在介绍性章节中,我们已经讨论了为什么我们需要实现持续集成和交付。然后,我们探讨了代理池和代理,甚至部署设置。接下来,我们将在接下来的几章中详细讨论经典的构建管道。还讨论了 YAML 管道,使您能够理解管道作为代码的用法。除此之外,我们还讨论了发布管道的使用,以及在发布和构建管道中测试执行的实现和使用。总的来说,这本书让你对实现和使用 Azure pipelines 有了基本的了解,使你能够快速部署软件应用,同时不影响所交付的应用的质量。