点击关注我的Telegram群组和微信公众号

MENU

构建 Azure Pipelines 自托管代理

2023 年 04 月 30 日 • 阅读: 601 • 技术,云服务

前言

使用 Azure Pipelines 为 C# .NET MSIX 应用构建 CI/CD 管道文中,我介绍了为开源项目创建 Azure Pipelines CI/CD管道的方法。这一方法使用的是 Azure 的云端虚拟机映像环境,每次编译时都需要重新构建环境后再进行编译;而桌面端应用通常又需要很长的编译时间故效率并不高。因此,我最近在自己的 Homelab 中开了一个虚拟机,专门用于编译管道,通过固定的运行环境和更高的性能来减少管道运行时间。

作为参照,由微软托管的云端虚拟机的硬件配置是:2x CPU, 7GB RAM, 14GB SSD, Windows Server 2022 10.0.20348

构建环境

编译环境

在微软提供的虚拟机映像中,不同的映像都提前配置了常见的软件环境,包括常见编程语言的运行时和编程工具,而我们在安装好自托管系统后需要手动安装这些环境。对于 Snap Hutao 项目而言,这包括了Visual Studio 2022.NET Framework 7Windows SDK

代理池权限设置

回到 Azure DevOps 网站,在组织设置里进入 Pipelines Agent pools 设置。进入 Default 代理池,并选择 Security,将CI/CD 管理员的帐号添加进用户权限。如果该帐号已经是组织管理员,则无需设置。

添加主机进 Azure Pipelines

在 Azure DevOps网站中,在登录的状态下点击右上角个人设置里的 Personal Access Token。点击 New Token 来创建一个新的密钥,为其设置一个名称,将组织选择为即将添加主机需要服务的组织,在权限范围内将 Agent Pools设置为 Read & manage。创建成功后,将获得的 Token 保留备用。
权限控制

再次进入组织设置的 Default 代理池页面,点击右上角的 New agent,我们将会获得创建 Azure Pipelines 代理主机的软件和命令。按照页面的指示,在代理主机上下载管理程序并执行 PowerShell 命令。在这里,我选择的是64位 Windows 并且执行 .config.cmd以将代理软件以服务运行于主机上。

config.cmd脚本中,你会被要求输入刚刚创建的 Token 并为当前主机代理命名,其余要求的设置我建议完全默认,因为这会和Azure Pipelines 云端映像环境保持一致,这有助于在未来遇到环境时更容易地找到通用的解决方案。
cmd脚本

当你看到服务已启用的提示后,说明管道代理程序已经在运行,你可以关掉 PowerShell 命令行了。而在 Azure DevOps 组织代理池设置中,你也可以看到刚刚创建的主机了。
代理上线

修改 CI/CD 配置

最基本的设置

  1. 我们需要将配置文件里的代理池指定为刚刚创建的主机上;因为不再使用云端映像,所以 vmImage: 'windows-2022' 也可以删除了

    pool:
      name: Default
      demands: agent.name -equals Hutao-Server
  2. 修正环境目录。对于云端映像而言,使用环境变量目录是更安全的解决方案。但是在前文中我们说过 Azure Pipelines 对于 .NET 7 的兼容性有问题,所以在配置文件中我使用了很多绝对路径。在迁移到新的系统环境中后,我们需要更新这些路径。比如说云端映像中的 Windows SDK 版本为 10.0.22000.0 而我本地版本为 10.0.22621.0。因此,我需要将 MSIX 构建的命令修改为
- task: CmdLine@2
  displayName: Build MSIX
  inputs:
    script: '"C:\Program Files (x86)\Windows Kits\10\bin\10.0.22621.0\x64\makeappx.exe" pack /d $(Build.SourcesDirectory)\src\Snap.Hutao\Snap.Hutao\bin\x64\Release\net7.0-windows10.0.19041.0\win10-x64 /p $(Build.ArtifactStagingDirectory)/Snap.Hutao.Alpha-$(build_date).$(rev_number).msix'

可选的更改

将机密文件持久化存储在代理主机上

在胡桃项目的管道配置中,我将输出的文件用 Rclone 上传到云端用于分发。在使用云端代理时,我们需要将 rclone 配置文件作为机密文件储存并在管道运行时由 Azure 以加密的形式发送到主机上。现在我们可以将配置文件添加到主机的代理目录里,然后将 configPath里从机密文件指向该文件

- task: rclone@1
  displayName: Upload CI via Rclone
  condition: and(succeeded(), eq(variables['Build.SourceBranch'], 'refs/heads/main'))
  inputs:
    arguments: 'copy $(Build.ArtifactStagingDirectory)/Snap.Hutao.Alpha-$(build_date).$(rev_number).msix downloadDGPCN:/releases/Alpha/'
    configPath: 'C:\agent\_work\_tasks\rclone.conf'

插件目录

自定义插件

在胡桃项目的流水线作业中,我使用了 MagicChunks 插件来实现对包信息的更改。但是这个插件有一个 warning 提示使用了过时的 PowerShell 指令,原作者因不再积极维护该插件而没有合并 PR。 对于这种情况,我们可以直接将修正分支打包下后自行编译,然后将插件文件覆盖于 C:\agent\_work\_tasks\ 目录中。这种做法并不会消除警告(因为插件元信息是由云端储存的),但能在实际上解决插件的问题。

运行速度对比

根据下面的对比,我们可以看到使用自托管的主机后,我们规避了大量的环境安装流程;得益于更高的虚拟机性能,编译和打包阶段所费时间也大大减少。流水线运行单次总时间由原本的5分钟左右,降低到现在稳定的2分30秒左右。
时间对比

返回文章列表 文章二维码 打赏
本页链接的二维码
打赏二维码