在持续集成与持续部署(CI/CD)领域,GitHub Actions 曾是众多开发者的热门选择,但如今,其弊端逐渐显现,让不少人在使用前不得不深思熟虑。
团队由大约 15 名工程师组成,采用基于主干的开发方式,每天多次向主分支推送代码。团队代码存储在按模块划分的单一代码库(monorepo)中,结构如下:
monorepo/
├─ api1/
├─ api2/
├─ web-app1/
├─ web-app2/
每个文件夹都相互独立,可单独进行测试、构建和部署,各自拥有独立的流水线。团队原本期望利用 GitHub Actions 的路径触发功能,仅在对应文件夹代码变更时启动相应流水线,以提高效率。
在实际操作中,却遭遇了严重问题。按照良好的开发实践,通常只有在所有检查通过后才允许合并拉取请求。但在上述 monorepo 架构下,这一常规操作变得异常艰难。在 GitHub 中,虽可指定 "必需检查",如设置 "web-app1 - 单元测试" 必须通过才能合并拉取请求,但问题在于,该检查仅在 "web-app1" 文件夹有代码变动时才会运行。这就导致如果拉取请求仅修改了 "api1" 文件夹的代码,即便其他所有相关检查都已通过,也无法合并请求。为解决此问题,团队不得不运行额外的流水线来确定拉取请求是否可合并,这种方式不仅操作繁琐(类似 "hack" 手段),而且维护困难、成本高昂。令人遗憾的是,此问题提出近 3 年,GitHub 却未采取有效措施改进。理想情况下,GitHub 不应依赖特定名称的必需检查,而应规定所有由拉取请求触发的检查都通过后才能合并,这样才能从根本上解决问题。
随着项目发展,流水线日益复杂,GitHub Actions 的管理难度也急剧上升。以一个示例工作流为例:
name: CD - api1
on:
push:
paths:
- 'api1/**'
branches:
- master
workflow_dispatch:
inputs:
target_environment:
type: environment
default: 'staging'
required: true
workflow_call:
inputs:
target_environment:
type: string
required: true
jobs:
deploy-api1:
environment:
name: ${
{ github.event_name == 'push' && 'production' || inputs.target_environment }}
smoke-tests:
if: ${
{ github.event_name == 'push' || inputs.target_environment == 'production' }}
name: Smoke Tests
uses:./.github/workflows/smoke-tests.yml
with:
target_environment: 'production'
secrets: inherit
在这个工作流中,为了实现不同的触发条件和逻辑判断,不得不添加大量类似if: ${ { github.event_name == 'push' || inputs.target_environment == 'production' }}
的语句。虽然可以将其拆分为多个具有不同触发条件的工作流,但这样会导致需要维护的文件数量大幅增加。原本工作流的复用应简洁高效,但实际情况却是需要编写更多代码行,且存在大量重复语句,如工作流名称、secrets: inherit
等。目前团队的.github
文件夹中已经包含 30 多个文件,管理负担日益沉重。
此外,needs
子句也常常引发问题。在进行代码重构和删除某些任务时,很容易忘记更新needs
子句以及后续相关步骤。虽然有一些代码检查工具(linters)可用,但它们并不完美,无法完全避免此类错误。最糟糕的是,往往只有在推送工作流之后才能发现错误,这使得问题的发现和修复变得滞后,增加了开发成本和风险。
另一个严重的缺陷是 GitHub Actions 缺乏本地开发支持。虽然有 act 工具可尝试在本地模拟运行,但在实际使用中,其效果并不理想,无法满足开发者在本地快速验证和调试工作流的需求。这使得开发者在开发过程中遇到问题时,难以迅速定位和解决,严重影响了开发效率。
在所有这些问题中,最令人失望的是 GitHub 对这些问题的态度。尽管用户反馈强烈,一些问题的讨论帖已经开放多年,但 GitHub 却未采取实质性行动来修复这些问题或改进产品。近期,GitHub 甚至关闭了许多相关问题的讨论,这引发了社区的强烈不满。从其公开的路线图来看,也没有迹象表明这些关键问题将得到妥善解决,这让用户对 GitHub Actions 的未来发展充满担忧。
鉴于以上诸多问题,以及 GitHub 缺乏改进的动力,在选择 CI/CD 工具时,确实需要重新审视 GitHub Actions 的适用性。目前,CI/CD 市场提供了众多替代方案,如 Gitlab、Jenkins、TeamCity 等。笔者团队在实际使用中发现,这些工具在某些方面能够提供更优质的服务,性价比更高。此外,像 Dagger 这样的新兴工具也值得关注和评估,它们为 CI/CD 领域带来了新的思路和功能,可能更适合一些特定的项目需求。
总之,在技术选型过程中,我们不能盲目跟风,而应根据项目的实际需求、团队的技术能力和工具的实际表现进行综合考虑。对于 GitHub Actions,虽然它在某些场景下仍有一定的应用价值,但在使用前务必充分了解其局限性,并结合自身情况谨慎决策。希望通过本文的分享,能够帮助开发者在 CI/CD 工具的选择上做出更明智的选择,提高项目的开发效率和质量。
你在使用 GitHub Actions 或其他 CI/CD 工具时,是否也遇到过类似的问题呢?欢迎在评论区留言分享你的经验和看法,让我们一起共同探讨如何优化 CI/CD 流程,提升项目开发的效率和质量。
科技脉搏,每日跳动。
与敖行客 Allthinker一起,创造属于开发者的多彩世界。
- 智慧链接 思想协作 -