适用于开源项目的终极(免费)CI/CD
我把很多空闲时间都花在了 GitHub 上开发开源软件 (OSS) 上,主要是为了好玩和学习新东西。但有一件事我可以告诉你,那就是浪费时间寻找无法复现的 bug……或者和那些本该帮你的工具(比如你的持续集成 (CI) 系统)斗争,这可一点也不好玩。
您是否想过应该在哪个 CI/CD 解决方案上投入时间?您来对地方了!
强制披露:我现在在微软工作,但早在跳槽之前我就开始考虑CI迁移,而且我并没有被任何方式强迫这么做。我参与开源软件项目的经验可以追溯到我现在的工作之前,因此我试图在本文中以开源软件维护者的身份提供我的真实反馈。
TL;DR
- 如果你打算长期维护一个开源项目,你必须做的就是自动化
- 浪费时间最糟糕的方式是当你的自动构建没有按预期工作时:不稳定、不可靠的构建和跨平台问题可能会让你发疯
- 实用主义应该是你的主要动力,力求用最少的时间完成工作
基于此,我发现Azure Pipelines目前提供了我认为最佳的时间投入/收益比。
GitHub Actions CI/CD解决方案面向所有人开放后(计划于 11 月 13 日上线),这种情况或许会有所改变。但在此之前,我会坚持使用久经考验的解决方案,这样我就能有更多时间陪伴家人,而不是纠结于构建问题 🍸
您将在这里学到什么?
- 如何为托管在 GitHub 上的开源项目设置Azure Pipelines (本例中为 Node.js,但它适用于任何堆栈)
- 为什么它可以帮助您节省一些有限的 OSS 工作时间
如果您不关心背景故事,您可以直接采取行动。
完整的故事
几年来,我一直在 GitHub 上维护多个开源项目,这些年来我得出了这样的结论:
- 🔥 成为一名维护者很难(不是开玩笑!)
- ⏲ 它会占用你大量的空闲时间(有时你可能更愿意与家人和朋友一起度过)
- 😭 短期内偷工减料以节省时间几乎总是会导致长期浪费大量时间(就像任何软件项目一样)
玩笑归玩笑,最后一点很容易被忽视,而且我因为没有添加适当的测试或 CI 而陷入了太多次,例如:
“我这样做主要是为了我自己,但我会分享它,以防它对其他人有用”
哎呀,没想到这一点😱
大错特错。一旦问题和 PR 出现,就太晚了。
审查、测试和部署贡献者提供的修复和新功能,就变成了浪费时间的黑洞。
不过,在完成了几个项目之后,你很可能不会再犯这个错误,并且会像我一样建立一个最小的 CI 管道 😎
然后就好了。不知怎么的。
几年前,如果你想为开源项目寻找免费的托管 CI 解决方案,选择并不多。我很高兴有一些解决方案存在,因为它们是免费的。
因此,我最终使用了Travis CI、AppVeyor和CircleCI等最流行的解决方案。每个方案都能满足特定的需求,但遗憾的是,它们并非完美无缺。
服务 | OSS层 | |
---|---|---|
特拉维斯·CI | 在 GitHub 上开始使用 CI 的最简单、最常见的方法。 | 所有存储库 Linux + Mac 构建之间共享 5 个并发作业 |
AppVeyor | 长期以来,它是唯一为 Windows 构建提供免费层的 CI 平台。 | 1 个并发作业 Windows + Linux 构建。 |
CircleCI | 这是这三种解决方案中最灵活的一种,因为你可以使用自己的容器,但设置起来也是最复杂的 | 1 个并发作业 1000 次构建 分钟/月 仅限 Linux 构建 |
红色构建和问题
对于大多数简单的项目来说,使用这些解决方案中的任何一个可能就足够了。但随着时间的推移,我遇到了很多问题,而且问题也随着项目的复杂性而增长。
构建矩阵
首先是环境问题:我在 Mac OS 上开发,CI 在 Linux 上运行……而 Windows 上却出现了问题。因此,我最终像许多项目一样,使用了 Travis CI + AppVeyor 的组合。
然后是与多个平台版本兼容的问题。例如,一个支持 Node.js 的项目>= 8
最好在所有 LTS 版本以及最新的稳定版本上进行测试:这意味着目前8.x
、10.x
和12.x
。
几乎所有 CI 服务都支持这些用例的构建矩阵定义,所以这很好。
但是,当你开始拥有多个项目,并且每个项目都有多个构建时,总构建时间就开始成为一个问题:我已经不得不等待好几天(!)才能合并一些 PR,因为许多 PR 是同时来自不同项目的(并且所有 PR 都共享相同的工作线程限制)。当你的流程已经很长(比如一个 PR 构建需要 1 小时)时,它很快就会出现问题。
不确定性不受欢迎
最后,还有一个最可怕的问题,它浪费了我生命中无数的时间:不稳定的构建😱。
有时,您的一次或多次构建会莫名其妙地失败。您(或您的贡献者)浪费了大量时间调查问题,最终发现问题出在持续集成服务上,而不是代码上。
如果只是偶尔出现这种情况,并且你对此有所怀疑,那么只需重新启动构建即可。但有时却不行,你需要花费宝贵的时间来尝试修复 CI,因为:
- 推送了一个不幸的更新(错误)(糟糕的事情发生了,但它曾经存在了数周)
- 构建容器镜像已进行调整(并且你的 CI 也变得💥)
- “我们目前遇到了技术困难”
- 没有理由...😞
随着时间的推移,这会让你对自己的 CI 产生警惕,这不是一件好事。
我知道我可能要求过高,而且大多数开源项目使用这些解决方案都很好。而且平心而论,考虑到所有这些服务都是免费提供的,也没什么可抱怨的。
了解 Azure Pipelines
前段时间,我发现JHipster已将其所有 CI 迁移到Azure Pipelines。我很早就了解这个项目了,它的 CI 复杂性简直令人发指,包含大量的组合路径和漫长的构建时间。这引起了我的兴趣,并尝试迁移一些我自己的项目来测试它。
好吧,我很惊讶地发现,与其他解决方案相比,Azure Pipelines 为您提供了很多免费功能:
- 它可以针对任何操作系统(Windows/Mac/Linux)
- 速度很快(OSS 层每个组织有 10 个并行工作者)
- 它似乎更可靠(根据我自己的经验以及与 JHipster 维护者的讨论)
- 设置和运行起来相当容易(虽然比 Travis 稍微复杂一些,但灵活性更高)
我首先迁移了一个简单的 Node.js项目的测试。现有的 Travis/AppVeyor 组合被替换为单个 Azure Pipeline,以便在 Windows/Mac/Linux 上进行测试,就像这个 PR中所做的那样。为了在 Windows 上顺利运行Prettier ,我不得不禁用 gitautocrlf
选项,但除此之外,迁移过程非常简单。
首次成功之后,我继续迁移更为复杂且要求更高的generator-ngx-rocket CI ,结果如下。
前 | 后 | |
---|---|---|
服务 | Travis + AppVeyor + Circle CI 与自定义 Docker 镜像 | Azure Pipelines |
组合 | Travis 上有 40 个构建(Linux * 2 Node 版本), AppVeyor 上有 20 个构建(Windows), CircleCI 上有 1 个构建(Android) |
83 个版本(Linux/Windows * 2 个 Node 版本 + Mac/Android) |
构建时间 | PR 大约需要 1 小时(Travis 大约需要 50 分钟,AppVeyor 大约需要 1 小时,CircleCI 大约需要 5 分钟) | PR 大约需要 1 小时(如果仅限于之前的 Travis 场景,则大约需要 30 分钟) |
这次迁移并不简单,因为我必须使用模板来生成组合矩阵,但结果很棒:
- 只需管理一个配置(无需为 Android 构建额外的 Docker 镜像)
- 在同一时间测试更多组合
- 一些额外福利,例如将 Android 构建的 APK 直接发布为构建工件
经过这次经历,我可以说我现在完全支持 Azure Pipeline,并且我将继续迁移我的其他存储库👍
我向你保证它看起来很棒,尤其是 OSS 层 😍
一旦它在 11 月 13 日向所有人开放,它可能会成为最好的解决方案(在这种情况下,本文将会更新😉)。
不过,Azure Pipelines 仍需考虑以下两点:
- 如果您未被邀请成为 Beta 测试人员,您暂时无法使用 GitHub Actions。但与此同时,您可能需要一个可用的 CI 解决方案!
- GitHub Actions for CI/CD 基于 Azure Pipelines 堆栈的部分内容,因此如果您已经在使用后者,那么迁移应该会轻而易举
我们开始做吧!
此刻,你可能想亲自尝试一下。我们将逐步介绍如何为你的 Node.js 项目部署 Azure Pipeline CI(如果你使用其他技术栈,也别放弃,其实区别不大,我会提供一些建议😉)。
您可以在此存储库中看到示例结果。
要求:
- 一个Azure DevOps 帐户(您可以使用您的 GitHub 帐户登录)
- GitHub 存储库,其中包含一些您想要自动化的测试
1. 准备你的存储库
首先,您必须为 CI 准备测试脚本。
对于 Node.js 项目,通常通过在文件test
中添加脚本来完成package.json
:
{
"scripts": {
"test": "jest"
}
}
在这个例子中,Jest将用于运行单元测试。
您可以通过运行来测试您的脚本npm test
,以确保一切正常。
2.创建 Azure DevOps 项目
在您的 Azure DevOps 帐户中,创建一个新项目并为其命名:
3. 设置管道
之后,转到左侧的管道部分:
然后单击New pipeline
开始设置过程:
选择GitHub (YAML)
,然后按照流程将您的帐户与 Azure DevOps 关联:
选择您的存储库,然后在 GitHub 上授权该应用程序。
之后,选择第一个Node.js
选项(或任何其他与您的技术栈相关的选项):
对于其他技术栈和语言,例如 C#、Java、Go、Python 等,您应该查看文档生态系统部分中的相应页面。您将获得关于如何使用您喜欢的技术进行构建的具体提示。
您可以在此存储库中找到许多示例 YAML 文件。
4. 自定义 YAML
然后,您将在编辑器中看到此 YAML 文件:
# Node.js
# Build a general Node.js project with npm.
# Add steps that analyze code, save build artifacts, deploy, and more:
# https://docs.microsoft.com/azure/devops/pipelines/languages/javascript
trigger:
- master
pool:
vmImage: 'ubuntu-latest'
steps:
- task: NodeTool@0
inputs:
versionSpec: '10.x'
displayName: 'Install Node.js'
- script: |
npm install
npm run build
displayName: 'npm install and build'
现在,您只需更改最后一部分来运行命令,npm test
而不是npm run build
:
- script: |
npm install
npm test
displayName: 'npm install and test'
单击Save and run
,然后选择直接提交master
还是使用 PR 创建新分支。
我建议您在此阶段创建一个带有 PR 的新分支,以便您可以在将其合并到存储库之前试验构建配置。
之后Save and run
再次单击,然后检查一切是否运行正常。
5. 添加构建矩阵
现在您已经有一个可以运行的 CI,但使用 Azure Pipelines 的好处之一是您可以轻松添加跨平台构建,所以让我们这样做吧。
在菜单中选择Edit pipeline
返回 YAML 编辑器:
首先在文件顶部添加此矩阵:
strategy:
matrix:
linux-node-10:
imageName: 'ubuntu-latest'
nodeVersion: '10.x'
linux-node-latest:
imageName: 'ubuntu-latest'
nodeVersion: '>=12.x'
mac-node-10:
imageName: 'macos-latest'
nodeVersion: '10.x'
mac-node-latest:
imageName: 'macos-latest'
nodeVersion: '>=12.x'
windows-node-10:
imageName: 'windows-latest'
nodeVersion: '10.x'
windows-node-latest:
imageName: 'windows-latest'
nodeVersion: '>=12.x'
这将允许您的测试每次使用 2 个不同的 Node.js 版本在 Windows、Linux 和 Mac OS 上运行,总共 6 个版本。
然后更新该pool
部分以使用当前构建的图像名称:
pool:
vmImage: $(imageName)
最后更新node
任务以对 Node.js 版本执行相同的操作:
- task: NodeTool@0
inputs:
versionSpec: $(nodeVersion)
displayName: 'Install Node.js'
单击Save
,然后Run
测试更新后的管道,就完成了。
如果您在第一次保存管道配置时创建了一个带有 PR 的分支,那么您还需要先在 GitHub 上合并此 PR,以激活管道以进行新的提交和 PR。
不要忘记查看完整的文档,以了解所有可用的任务和功能。
6. 添加状态徽章(可选)
我强烈建议您在 GitHub 存储库上添加状态徽章,以便人们对您的项目产生积极的信号:
- 它得到维护,你关心它的质量
- 贡献者可以自信地推动 PR
为此,请返回管道构建并单击Status badge
菜单:
然后使用按钮复制 markdown 代码,并将其粘贴到readme.md
存储库根目录的文件顶部:
一旦提交到master
分支,它将在项目的 GitHub 文档中可见。徽章状态将根据上次推送的提交自动更新master
。
想与其他徽章一起完善此状态徽章吗?请访问https://shields.io。
你甚至可以创建自己的徽章:
7. 享受你的夜晚
就是这样!
一旦新的提交或 PR 被推送到您的存储库,CI 就会处理它并直接在 GitHub 上显示结果:
现在您可以放松并再次享受您的空闲时间🍻。
为了更加放心,我建议您使用新的 CI 启用所需的状态检查,以便只有通过所选检查的 PR 才允许合并。
不要忘记在评论中分享您的反馈和经验!
进一步
当然,作为维护者,你还可以做很多事情来简化你的工作,我会在以后的文章中分享。但我认为 CI 是任何项目都应该首先实施的措施之一。
您还可以使用 Azure Pipelines 做更多的事情(我是否在某处提到过 CD?)但我们稍后再讨论这个。
在Twitter上关注我,我很乐意讨论并接受您的建议!
鏂囩珷鏉ユ簮锛�https://dev.to/itnext/the-ultimate-free-ci-cd-for-your-open-source-projects-3bkd