Windows on Arm 的持续集成





5.00/5 (2投票s)
本文将介绍为 Windows on Arm (WoA) 平台启用持续集成和持续交付 (CI/CD) 的最佳实践。
在介绍一些通用概念后,我们将呈现 WoA 的 CI/CD 的现状,并深入探讨如何在当今最常用的平台上具体设置。最后,我们将介绍我们在 Linaro 的 Windows on Arm 团队中用于跟踪和支持我们工作的基础设施。
关于 CI
CI 在现代软件开发时代的发展,提高了我们工作的质量和健壮性,并缩短了发布周期。然而,这也给团队带来了很多复杂性,有时甚至让他们无法理解自己的 CI 以及如何在本地运行它。如果您对此主题感兴趣,Martin Fowler 的两本书 - 《持续集成》和《持续交付》 - 尽管有些年头了,但绝对是很好的参考资料。
在这里,我们将重点关注您自己的 CI 基础设施应具备的良好属性,以使其可靠且高效。
可重现性
这一点怎么强调都不为过,您的 CI 环境应该是可重现的。一台干净的机器应该能够通过单个命令,以完全自动化的方式进行安装和配置。开发人员应该能够毫不费力地在本地使用它。 Docker 和容器化技术在通用性方面是极好的工具。可惜的是,它尚未适用于 Windows on Arm,主要原因是 WoA 尚不支持基于 Windows 的镜像。
但不要灰心,您始终可以脚本化您的机器安装过程,使其易于在多台机器上重现。这是我们团队选择的方法,也是我们目前推荐的方法。重要的是要有自动化的东西。
软件是一门易于重现的学科,所以请充分利用这一点!
隔离性
CI 中的作业运行不应影响后续运行。通常,这通过按需提供云提供商的虚拟机或使用容器化来实现。目前,WoA 在此方面还没有解决方案。是的,WoA 虚拟机 在 Azure 上可用,但目前没有现有的 CI 系统能够按需提供它们。
可扩展性
您的 CI 基础设施应该能够按需扩展和缩减。与隔离性一样,这一点目前还无法实现,但应该会在未来某个时候可用。目前,您必须部署足够的机器来支持您的工作负载。
易用性
最后,与其撰写关于如何构建、测试和交付程序的冗长文档,不如只编写简单的构建、测试和交付脚本(Python 可能是一个不错的选择),并确保它们在您的可重现环境中正常运行,无需任何手动设置。
除了让任何开发人员都能轻松修改您的项目之外,您的 CI 配置也会非常简单,并且您可以无缝地更换您的 CI 提供商。
Windows on Arm 的 CI 生态系统现状
目前,没有 CI 提供商提供自己的 Windows on Arm 运行器,这意味着您将不得不部署和维护自己的机器。这就是所谓的“自托管运行器”。
自带设备 (BYOD)
物理机
- 任何 Windows on Arm 笔记本/平板电脑(例如, Microsoft Surface Pro X、联想 Thinkpad X13s、HP Elite Folio、三星 Galaxy Book Go)。
- 现已上市:Windows Dev Kit 2023。一台很棒的开发人员机器。
- 树莓派 4:小巧但便宜且使用灵活。这是 如何在上面安装 Windows。
Apple Silicon Mac:您可以使用 UTM 轻松免费运行 Windows on Arm 机器。价格昂贵,但如果您还需要支持该平台,可能值得。
云
自 2022 年 4 月起,可以在 Azure 上运行 Windows on Arm。
软件
操作系统
我们建议运行 Windows 11,因为它将允许您通过模拟运行任何 x64 软件。
工具链
从 Visual Studio 2022 17.4 开始,VS 和 Microsoft Visual C++ (MSVC) 原生支持 Arm64,与以前的模拟版本相比,速度大大提高。
clang-cl 是 MSVC 编译器和链接器的直接替代品。它仍然使用 MSVC 的头文件和库,因此与 MSVC 在 ABI 上兼容。
如果您依赖 GCC 和 Mingw,这些工具目前还不能用于 WoA。这是正在进行中的工作,感谢 Zac Walker,他已经将补丁向上游推送到 GNU Binutils。
llvm-mingw,现已可用,是 GCC 的替代品,针对 MinGW(因此与 MSVC ABI 不兼容),它是 Martin Storsjö 和其他人的辛勤工作的结果。它甚至可以用来从 Linux 交叉编译 WoA 二进制文件,就像 VideoLAN (VLC) 所做的那样!
运行 Windows on Arm 的 CI
所有现有的 CI 提供商都允许您添加自托管运行器/代理。多亏了这一点,任何新的架构都可以得到支持,只要它能够执行运行器程序。在本节中,我们将介绍如何在每个平台上部署您自己的运行器,以及如何使用它。
Azure Pipelines
请遵循这些说明来创建和配置新的代理。它应该会自动注册为服务并在您的机器上启动。
然后,您可以在管道 yaml 描述中通过选择新代理来使用它。
trigger:
- master
pool:
name: Default
demands:
- agent.name -equals <AGENT-NAME-HERE>
steps:
- script: cmd /c "echo Hello World"
displayName: 'Say Hi'
GitHub
使用 GitHub 设置运行器非常简单。只需遵循本指南。
它将提供您需要复制粘贴以下载、注册和启动运行器的所有命令。有原生的 Arm64 版本可用。
然后,只需使用 runs-on: self-hosted
来使用此运行器。
name: hello-world
on: push
jobs:
my-job:
runs-on: self-hosted
steps:
- name: say-hi
run: echo "Hello World!"
GitLab
在 GitLab 上,此过程需要更多步骤。首先,获取一个令牌以将您的运行器注册到项目或子组。然后下载gitlab-runner.exe(如果您运行的是 Windows 10,则为 32 位)。最后,注册它(使用 shell 执行器)。
您应该为该运行器或运行器组分配一个特定的标签名称,以便在您的管道中轻松引用它,例如 win-arm64
。
最后,在您的管道中使用 tags
条目来使用此运行器。
build:
stage: build
tags:
- win-arm64
script:
- echo "Hello World"
Jenkins
尽管 Jenkins 有些年头了,但它在许多公司仍然被使用。它的原理与其他平台相同:注册代理,然后在您的作业/管道中引用它。
请遵循这些说明来为 Jenkins 注册新代理。您需要在机器上安装 openjdk(有原生的 ARM64 版本可用)。
您的代理将被指定一个或多个标签。然后,您可以在作业配置(通过 Web 界面)或 管道配置中引用这些标签。
Linaro 的 WoA CI
我们团队的目标是帮助开源项目原生支持 Windows on Arm。在对 Python 进行了一些工作之后,我们开始深入研究 LLVM、Dart/Flutter、MySQL、Node.JS、Perl 等。
最终目标是将我们所有的工作都合并到上游,但补丁的接受需要时间,有时,缺乏托管的 CI 运行器可能是一个阻碍。
为了主动跟踪我们合作的项目,我们需要自己的 CI 系统。
选择 CI 提供商
首先,我们必须选择一个系统来托管我们的 git 仓库,并在其中运行 CI。由于它们是最常用的,我们选择了 GitLab 和 GitHub。
GitLab 有一个非常好的功能:您可以创建项目子组,这有助于组织您的仓库。在 Github 中,一切都在一个组织下。因此,我们加入了官方的 Linaro Gitlab 工作空间并启动了我们自己的子组。
运行器
最初,我们想为此工作使用 Azure VM。Azure DevOps 可以使用 Azure 虚拟机规模集,但部署时间很长,并且提供的机器在每次管道运行后不会被销毁,因此无法提供真正的作业隔离,只能提供可扩展性。其他提供商提供基于容器化的预配,但这尚未适用于 Windows on Arm。
因此,唯一可能的选择是让虚拟机全程运行。考虑到成本,我们选择了使用 Linaro 实验室中的自己的机器。它托管在剑桥,主要用于在各种不同的主板上验证 Linux 内核和引导加载程序。现在,它也帮助我们的团队支持 Windows on Arm 开发!
起初,我们使用了几台 Surface Pro X,然后使用了Windows Dev Kit 2023 设备,这使我们的 CI 时间缩短了 25% 到 30%。考虑到$600 8 核 / 32GB 的价格,这确实是今天能获得的最佳性价比。
可重现性
为了使我们的 CI 可重现,由于 docker 尚未适用于 Windows on Arm,我们开发了自己的解决方案来安装所有我们需要的程序。Windows 上现有的包管理器(chocolatey, vcpkg, nuget, winget, …)的问题在于它们不完整,因为整个系统不是用它们构建的,就像 Linux 发行版一样。 MSYS2 是一个很好的尝试,但它只能与开源软件一起使用,并且由于该平台缺乏 GCC,因此尚不支持 WoA。
我们的解决方案,wenv,试图填补这一空白。为了简单起见,我们有一组固定的依赖项(我们使用的那些),该工具不旨在取代通用的包管理系统。为了简化部署和升级,需要一个简单的 powershell 命令(类似于 chocolatey install)来下载/升级 wenv,并且可以复制粘贴。
为了确保此脚本的健壮性,它以 bash 编写,并带有严格的“set -euo pipefail”选项。是的,我们使用 Bash 安装 Windows 程序,是不是很有趣(而且有利可图)?Powershell 和 batch 应该考虑添加一个等效项。
运行 wenv 后,会生成一个名为 activate.bat 的脚本,用于设置 PATH 以便所有依赖项(如 Python venv)都可用。
为了在 wenv 下运行 gitlab-runner.exe,我们使用了一个简单的批处理文件。
cmd /c "C:\wenv\arm64\activate.bat" gitlab-runner.exe run-single ^
--output-limit 100000 ^
--url https://gitlab.com/ ^
--token SECRET_TOKEN ^
--name RUNNER_NAME ^
--executor shell ^
--shell powershell ^
--builds-dir C:/ci
最后,为了在启动时运行它,我们使用 nssm 将其声明为一个服务(教程)。因此,我们所有的作业都直接在此可重现的环境中执行。
易用性
对于我们处理的所有项目,我们都会创建一个专用的构建配方。这些配方在此处列出。所有繁重的工作都包含在一个脚本中,该脚本用任何语言(batch, powershell, python, bash)编写,并且该脚本在可重现的 wenv 环境中进行测试和开发。
为了代码和 CI 配置的复用,我们编写了 packagetools。因此,一个新的配方只需要实现一个特定的 python 接口,其余的都默认完成。甚至可以将二进制包上传到我们的 Azure 存储。
因此,任何人都可以轻松添加新包,或克隆和重现现有包。
最后,我们设置了一个夜间 CI 作业,用于跟踪我们关注的项目的外部更改,使我们能够尽早发现回归。此作业定义在其自己的存储库中,因此可以轻松查看我们跟踪的内容,而不是将此配置分散到不同的地方。
除了帮助我们开发补丁之外,该系统还发现了过去项目的几项回归,成为支持 Windows on Arm 的宝贵盟友。
结论
我们希望本文能帮助您了解如何为新的 Windows on Arm 平台启用 CI/CD。此外,我们还提供了一些关于如何设计 CI 系统的一般性想法。如有疑问,请遵循KISS 原则,并始终将可重现性作为首要目标。
未来,我们预计现有的 CI 提供商将开始在其自身的基础设施中积极支持 Windows on Arm 运行器,从而允许任何人开始为这个令人兴奋的新平台构建和交付。