使用 Microsoft Azure DevOps 创建管道
本文将带领大家踏上使用 Azure DevOps 实现管道的旅程。
引言
本文旨在为通过 Microsoft Azure DevOps 实现持续集成和持续交付提供正确的指导。我们将尝试通过真实的案例研究来涵盖许多见解,因为案例研究有助于隐性地绘制我们的路线图。让我们开始吧!
案例研究
假设我们有一个大型解决方案。该解决方案包含以下 .NET Core 项目
- API 项目
- Web 项目 (MVC)
- 若干类库项目
- 单元测试项目 (类库)
- 集成测试项目 (类库)
- SPA 项目 (Angular 7)
解决方案依赖项
关于依赖项,我们需要特定版本的“.NET Core SDK”(在我们的案例中为 2.2.0)。当然,上述项目可能依赖于某些外部包。如果上述项目依赖于某些外部程序包怎么办?实际上,这没什么大不了的。但是,如果这些项目依赖于我们自己服务器上打包的其他一些程序包怎么办?这需要一些特殊的处理。
我们最终得到了以下依赖项
- .NET Core SDK 2.2.0
- 传统 NuGet 包
- 我们自己 TFS 服务器上打包的特殊包
注意:为保持流程的组织性,建议创建两个构建定义(后端、SPA)。
持续集成
以下是来自 Thought Works 的摘录
持续集成 (CI) 是一种开发实践,要求开发人员每天多次将代码集成到共享存储库中。然后,每次签入都会由自动化构建进行验证,从而使团队能够及早发现问题。通过定期集成,您可以快速检测错误,并更容易地定位它们。
创建构建定义(后端)
我们将通过 Web 浏览器访问 TFS,然后进入目标项目。在侧边栏菜单的“管道”部分选择“构建”,然后从“新建”中选择“新建构建管道”。
选择源
首先告知我们的构建定义源代码的位置是有意义的。在我们的案例中,源代码位于 TFS Git 中,因此我们将选择“使用经典编辑器”,然后选择“Azure Repos Git”。此外,我们还将识别其他必需的选项(团队项目、存储库、目标分支)。最后,我们将点击“继续”。
选择模板
TFS 可以提供许多现成的模板。实际上,这可以省去为构建定义创建每个任务的工作。但我更喜欢创建每个任务以获得尽可能多的知识。因此,我们将从一个空作业开始。
使用 NuGet 工具安装程序
可以使用“NuGet.exe”来安装程序包。通过添加“NuGet 工具安装程序”任务,我们可以使用 NuGet.exe 来安装 NuGet 程序包。使用哪个版本并不重要,因为我们启用了“始终下载最新匹配版本”。
还原 NuGet 包
添加 NuGet 工具安装程序任务后,我们可以想象我们正在编写适当的命令来针对 .sln 文件目录安装我们的程序包。在这里,想象就足够了,因为 NuGet 任务将处理其余的必要操作 :)。让我们添加 NuGet 任务以及以下配置
- 命令:restore
- 解决方案、packages.config 或 project.json 的路径:这可以是 .sln 文件的物理路径,也可以是表示任何 .sln 扩展名的表达式。我们将使用 **\*.sln 表达式。
- 要使用的源:正如我们所提到的,我们的部分程序包打包在 NuGet.org 上,而其他程序包打包在我们自己的 TFS 服务器上。为了处理这种情况,我们将把所有必需程序包的终结点包装在 NuGet.config 文件中,并让 NuGet 任务仅在还原过程中使用这些终结点。
注意:我们的存储库中必须有一个 NuGet.config 文件。
<configuration>
<config>
<add key="repositoryPath" value=".\packages" />
</config>
<packageSources>
<add key="nuget" value="https://api.nuget.org/v3/index.json" />
<add key="server1" value="http://server1.domain.com/nuget" />
</packageSources>
</configuration>
构建解决方案
现在,所有必需的依赖项都已准备好,我们的解决方案可以无缝构建。构建解决方案是一项必要任务,以确保所有依赖项都已正确加载。此外,在保证成功构建之前,我们无法执行任何进一步的任务(例如,单元测试)。所以,让我们添加一个 .NET Core 任务。
之后,我们必须指定以下配置
- 命令:build
- 项目路径:**\*.sln
- 参数:--configuration Release
执行单元测试
确保单元测试成功是强制性的。正如我们所提到的,我们有两个测试项目(单元测试、集成测试)。我们将添加一个“.NET Core”任务来执行包含在这两个项目中的所有测试用例。
配置将如下
- 命令:test
- 项目路径:
- **\*Project.UnitTest*.csproj
- **\* Project.IntegrationTest*.csproj
Publish (发布)
成功的单元测试是进行发布步骤的绿灯。我们将添加一个“.NET Core”任务来发布 API 和 MVC 项目。
配置将如下
- 命令:publish
- 项目路径:**/Project.Api.csproj
- 参数:
-c $(BuildConfiguration) -o $(Build.StagingDirectory) --no-build
MVC 项目的配置与此相同,只是项目路径不同,其值为 **/Project.MVC.csproj。
预定义变量
我们在 Arguments
配置项中注意到了 $(BuildConfiguration)
。这是一个预定义变量。这个变量是什么?使用它有什么好处?下面将给出这些问题的答案以及更多问题的正确答案。
存档发布结果
存档每个发布的文件,因为这些存档将用于为每个组件获取一个项目。我们将为 API 和 MVC 项目都添加两个存档文件任务。
MVC 项目的配置与此相同,只是要创建的存档文件不同,其值为 $(Build.ArtifactStagingDirectory)/Project.MVC.zip。
发布项目
后端构建定义即将完成。这一切都是关于持续集成的。下一步是将项目发送到正确的环境。因此,我们必须为每个存档的发布配置项目,以便发布定义可以访问它们并接管部署过程。我们将为 API 和 MVC 都添加一个“发布生成项目”类型的任务。
配置将如下
- 发布路径:$(Build.ArtifactStagingDirectory)/Project.Api.zip
- 项目名称:API
MVC 项目的配置与此相同,只是发布路径不同,其值为 $(Build.ArtifactStagingDirectory)/Project.MVC.zip。
构建定义(前端)
请记住,创建两个构建定义只是为了保持我们的流程组织性,这可能会根据每个解决方案拓扑而更改。
Angular 环境配置
每个应用程序都有配置,Angular 也不例外。实际上,Angular 以一种智能的方式处理每个环境的配置,它为每个环境引入一个 environment.ts 文件,并允许您在生成部署包时选择使用哪个环境。有关 Angular 环境设置的更多详细信息,请 在此 查找。
创建构建定义(前端)
我们将创建一个包含以下任务的构建定义
- 从 package.json 文件安装程序包(
npm install
)。 - 构建项目(
npm build
)以获取发布文件。 - 存档已发布的文件夹。
安装 Angular 包
要安装程序包,我们只需在包含 package.json 文件的目录中运行 npm install
命令。我们将添加“npm
”任务。
配置将如下
- 命令:custom
- 包含 package.json 的工作文件夹:Project.SPA
- 命令和参数:run testing-build
注意:testing-build
命令必须包含在 package.json 文件中,对于其他环境,例如生产环境,将添加一个新命令。
发布 Angular 项目
我们将为 Angular 项目添加一个发布生成项目类型的任务。
启用持续集成
我们需要添加一个额外的配置,以便在每次提交操作到我们的存储库后运行构建定义。这可以通过为所需分支在“触发器”选项卡中启用持续集成来完成。
持续交付
以下是来自 Wikipedia 的摘录
这是一种软件工程方法,在这种方法中,团队以短周期生产软件,确保软件可以随时可靠地发布,并在发布时手动进行。其目标是以更快的速度和更高的频率构建、测试和发布软件。通过允许对生产中的应用程序进行更多增量更新,该方法有助于降低交付更改的成本、时间和风险。一个直接且可重复的部署过程对于持续交付至关重要。
创建发布定义(后端)
执行构建定义会生成一个可部署的项目。我们的任务是创建一个发布定义并将其链接到构建定义。一旦构建定义完成,发布定义将自动运行,并将所有生成的项目部署到配置的环境中。要创建发布定义,我们将从 Web 浏览器打开 TFS,导航到侧边栏菜单中的“发布”,然后点击创建“新管道”。与构建定义类似,我们将从一个空作业开始。对于环境名称,我们将输入 API-Test。此外,我们还需要添加一个项目。这是为了确定我们将从哪个构建定义获取项目。因此,我们将点击“添加项目”,对于“源”(构建定义),我们将选择我们创建的后端构建定义,然后点击“添加”按钮。
现在,让我们配置 API-Test 任务。我们将从“任务”菜单中选择 API-Test。
解压项目
回到我们创建的构建定义,我们已经存档了已发布的项目。每个项目对应一个 .zip 文件。在发布定义中,我们只需解压存档文件,然后将文件复制到服务器上已部署网站的目标目录。此任务的配置将如下
- zip 文件路径:$(System.DefaultWorkingDirectory)/{BuildDefinitionName}/API/Project.Api.zip
- 文件夹路径:$(System.DefaultWorkingDirectory)/{BuildDefinitionName}/API/Project.Api
部署 API 项目
解压存档文件后,我们将这些文件复制到目标服务器上的目标目录。我们将添加一个“Windows 计算机文件复制”任务。此任务的配置将如下
- 源:$(System.DefaultWorkingDirectory)/{BuildDefinitionName}/API/Project.Api
- 计算机:服务器 IP
- 管理员登录:目标计算机的管理员登录信息。
- 密码:$(E) 管理员密码。建议从秘密变量访问。
- 目标文件夹:服务器上网站的目录。
创建秘密变量
我们将导航到变量菜单,然后添加一个新变量。为变量命名并添加值,然后将其类型更改为秘密变量。可以通过 $(variable) 模式访问任何变量。
创建环境 appsettings.json
毫无疑问,应用程序配置会因环境而异。例如,测试环境中的数据库连接字符串值与预生产环境和生产环境的值不同。这可以是任何其他配置(API 终结点、凭据……等等)。我们可以通过在 Visual Studio 中从“生成”->“配置管理器”添加新的解决方案配置来为每个环境创建 appsettings。我们将此配置命名为“Test”,然后右键单击 appsettings.json,然后选择“添加配置转换”。一个名为 appsettings.Testing.json 的新文件将在原始 appsettings.json 文件下创建。对于 web.config,我们将执行相同的操作。
现在,在拥有所需的配置文件后,我们必须配置我们的程序包,以便在运行时使用正确的 appsettings.json 文件(在本例中为 appsettings.Testing.json)。我们可以通过应用以下操作来实现
- 在 web.config 的
aspNetCore
部分中为“ASPNETCORE_ENVIRONMENT
”添加环境变量,值为“Testing
”。此步骤需要 在测试服务器上设置环境变量。 - 上一步将帮助“
ConfigureServices
”确定将使用哪个 appsettings 文件。
注意:您可能需要安装 Configuration Transform Visual Studio 扩展才能使用“添加配置转换”。此扩展可能会在生成配置文件后卸载项目。撤消对 .csproj 的更改并重新加载项目将解决此问题。
环境配置处理
我们最终得到了以下结果
- 我们有两个 appsettings.json 文件(appsettings.Testing.json、appsettings.json)。
- 我们有两个 web.config 文件(web.Testing.config、web.config)。
- 上述文件中的每个配置文件都对应一个服务器配置。我们的任务是编写一个 PowerShell 脚本来处理以下内容。我们可以通过添加“运行内联 PowerShell”任务来执行 PowerShell 脚本。
- 对于 appsetting.json 文件,我们将使用 appsettings.Testing.json 文件。这意味着不应包含其他文件。因此,我们只需删除所有其他 appsettings 文件。
- 对于 web.config 文件,我们必须使用 web.Testing.config 的配置。我们可以删除默认的 web.config 文件,并将 web.Testing.config 文件重命名为 web.config。
cd {website directory}
Remove-Item web.config
Remove-Item appsettings.json
Get-Item web.Testing.config | Rename-Item -NewName($_.Name -replace '\.Testing','')
对于 MVC 项目,将添加一个额外的任务链接到后端的构建定义,其功能将与 API 项目的任务类似。
创建发布定义(前端)
我们将遵循后端发布定义的相同方法,为前端创建另一个发布定义。当然,源别名会不同,因为它将链接到前端构建定义。此外,任务名称可以是前端。我们将导航到前端任务并添加必要的任务来处理生成项目的部署。我们只需要一个任务将项目复制到网站的目标目录。将添加一个“Windows 文件复制”任务,将前端项目复制到目标服务器上的目标目录。当然,这与我们在部署后端项目部分所做的类似,但有一些区别。这些区别在“Windows 计算机文件复制”任务中,它们如下
- 源:$(System.DefaultWorkingDirectory)/{BuildDefinitionName}/dist/Project.SPA
摘要
创建管道非常有趣。它让我们有机会体验许多技术方面——从多个服务器还原解决方案包、处理环境配置文件、编写 PowerShell 脚本、根据项目类型打包和部署网站、处理构建/发布定义任务以及许多其他方面。同时请记住,DevOps 包含许多概念,并且总是有人说“DevOps 需要真正的软件工程师”。
历史
- 2019年11月30日:初始版本