我的团队以前简直是在疲于应付 CI 的维护。我们花了差不多两年的时间,去伺候一个臃肿的 Jenkins 实例,每次一有插件更新它必崩;后来我们又短暂且痛苦地折腾了一阵 GitLab Runner,它们不是经常闲置,就是偏偏在最要命的时候把额度跑光。我花在写 Groovy 流水线和调试基础设施上的时间,竟然比真正 Review 代码的时间还要多。我太需要一套不用我自己去管构建服务器的 CI 系统了。
这就是我找到 Harness Continuous Integration 的原因。我之前听说过他们托管的构建基础设施——Harness Cloud,光是“再也不用自己去管虚拟机或容器了”这个承诺,就足以让我注册试用了。接下来,我会分享我是如何跑通第一个构建的,中间踩了什么坑,以及我学到了什么。
设置流水线
登录 Harness 账号后,你首先会注意到左上角的模块选择器。我点进了 Continuous Integration 模块。
接下来,创建流水线非常简单:
- 点击左侧导航栏的 Pipelines。
- 点击 + Create a Pipeline。
- 起个名字(我起的是
node-api-build),然后点击 Start。
接着就会打开可视化的流水线编辑器。跟死盯着一堆 Groovy 代码的 Jenkinsfile 不同,Harness 用的是可视化的画布。我一开始对可视化编辑器是持怀疑态度的——它们通常这也不让干那也不让干——但我还是决定公平地试它一把。
添加构建阶段
流水线建好后,我需要添加一个阶段。我点击了 Add Stage,选择 Build 作为阶段类型,并命名为 build_and_test。
这里需要关联你的代码。Harness 会让你选择 Git 托管平台。如果你用的是 GitHub、GitLab、Bitbucket 或者他们自家的 Harness Code Repository,你需要设置一个连接器。
我踩的第一个坑: 我在配置连接器时太心急了。我选了 GitHub,点击“Create New Connector”,直接把我的个人访问令牌(PAT)贴了进去,却没有正确设置代码库的权限范围。连接测试悄无声息地失败了——它提示“成功”,但当我试图在下拉菜单里选择我的代码库时却怎么也找不到。
我只好返回去,删掉那个连接器,重新建了一个。这一次,我确保我的 GitHub PAT 勾选了 repo 权限范围,并且明确把 API URL 设置成了 https://api.github.com(而不是企业版 URL,有些模板里默认是那个)。搞定之后,连接测试通过了,我也顺利从下拉菜单里选中了我的 node-api 代码库。我点击了 Set up Stage。
选择基础设施
这是我当初最感兴趣的部分。在我的新 CI 阶段里,我点击了 Infrastructure 标签页。
Harness 在这里给了几个选项:你可以把自己的本地虚拟机、Kubernetes 集群,或者 Harness Cloud 作为运行构建的环境。我选择了 Cloud。
Harness Cloud 使用的是 Harness 托管的基础设施,随需启动,构建完就自动释放。我保留了操作系统和架构的默认选项,然后点击了 Continue。
整个基础设施的设置大概只点了三下鼠标。相比我以前花在配置 GitLab Runner 或者给 Jenkins Agent 分配 EC2 实例上的那些时间,这简直简单得让人不敢相信。
配置执行步骤
现在到了干正事的时候:告诉流水线该干嘛。我点击了阶段里的 Execution 标签页。
Harness 有一个步骤库,里面有很多常用操作的预置步骤——比如 Docker 构建、推送镜像、运行测试等。但我想先从简单的开始,所以我点击加号添加了一个步骤,并从步骤库中选择了 Run。Run 步骤可以让你执行任意的 Shell 命令。
我给这个步骤起名叫 install_and_test。在构建命令框里,我输入了:
npm ci
npm run test
我踩的第二个坑: 我没有配置 Shell 类型。Run 步骤默认在 Shell 中执行命令,但我没意识到 Harness 使用的默认容器镜像里可能根本没装 Node.js。运行流水线时,它立刻就报错了:npm: command not found。
为了解决这个问题,我回到 Run 步骤的设置里,找到了 Container Registry 和 Image 字段。我把镜像设置成了 node:18-alpine。这等于告诉 Harness 要在一个 Node.js 容器里运行我的命令。
我还注意到 Run 步骤里有个 Optional Configuration 区域。展开后我看到了资源限制的设置。我的测试比较轻量,所以内存我保留了默认值(500Mi),只是以防万一稍微调高了一点 CPU 限制。
运行构建与查看结果
我点击了 Save,然后点击 Run。
流水线跑起来了,页面也跳转到了执行视图。在这里我可以实时观看构建过程。Harness Cloud 大约花了 15 到 20 秒就配好了构建基础设施——这比我对冷启动 Jenkins Agent 习以为常的 2 到 3 分钟快了太多。
npm ci 命令下载了依赖,npm run test 执行了我的测试套件。整条流水线大概在 1 分 45 秒内就跑完了。
执行视图会清晰地显示每个步骤的通过或失败状态,你可以点进任何步骤查看完整的控制台输出。界面干净易读,再也不用在一大堆日志文本里扒拉那唯一关键的一行报错了。
我希望早点知道的事
在跑通基础构建后,我又花时间摸索了一些功能,要是早点用上它们,我最初的设置会更顺畅:
测试智能: 这是 Harness 最亮眼的特性。它会分析你的代码变更,只运行受这些变更影响的测试,而不是跑整个测试套件。在大型项目上,这能把测试执行时间缩短多达 80%。虽然我的小项目还没配置这个,但我能想象,对于一个包含成千上万个测试的单体仓库来说,这绝对是颠覆性的。
缓存: 我发现我的 npm ci 步骤每次运行都在从头下载依赖。Harness 支持智能缓存。你可以在 Run 步骤前配置一个 Cache 步骤,在构建之间保存和恢复你的 node_modules 目录(或者 Maven 的 .m2、pip 缓存等)。设置好之后,我的构建时间从 1 分 45 秒直接降到了大约 45 秒。
YAML 模式: 虽然可视化编辑器很适合入门,但你可以随时通过流水线编辑器右上角的 YAML/Visual 切换开关转到 YAML 模式。对于将流水线配置和代码一起进行版本控制来说,这至关重要。我现在所有的修改都在 YAML 里完成,然后直接提交到代码库里。
实话实说的局限性
没有工具是完美的,Harness CI 也有它的取舍:
连接器的学习曲线: 给 GitHub、Docker 镜像仓库和云厂商设置连接器,需要处理大量的权限范围和身份验证方法。它并不比其他 CI 工具更难,但也绝对不轻松。第一次上手的话,给自己留出一个小时专门来搞连接器配置吧。
Harness Cloud 的可用性: 虽然按需提供的基础设施非常棒,但并不是所有地区都支持。如果你有严格的数据驻留要求,可能就需要在自己的基础设施上运行构建,这就又回到了你原本想避开的管理开销上。
定价的复杂性: Harness Cloud 上的构建使用的是基于额度的计费系统。试用期的额度很充裕,但在正式决定购买前,你需要仔细评估预期的构建量,特别是如果你的团队每天要在多个分支上跑几十次构建的话。
社区内容较少: 与 Jenkins 或 GitHub Actions 相比,Harness 目前由社区编写的插件或可复用的流水线代码片段要少得多。内置的步骤库能覆盖大多数需求,但如果你的构建流程中用到了非常冷门的工具,你可能得自己写自定义的 Run 步骤,而不是直接套用一个现成的 Action。
最后的想法
在 Harness 里搞出一条能用的 CI 流水线大概花了我 30 分钟,这还包括了我排查连接器和容器镜像错误的时间。不用再去分配、维护构建基础设施,也不用再为闲置的资源付费,这种体验真的是一种解脱。
如果你已经厌倦了伺候 CI 服务器,或者不想看着团队的生产力耗费在调试 YAML 上,Harness CI 绝对值得你认真看看。建议你先在 Harness Cloud 上用一个简单的 Run 步骤跑通测试,然后再去探索缓存和测试智能功能——那才是真正帮你省时省力的杀手锏。