您当前的位置:首页 > 电脑百科 > 程序开发 > 编程百科

使用 GitHub Actions 重构和优化发布流程的实用技巧

时间:2023-09-08 11:46:46  来源:51CTO  作者:

译者 | 刘汪洋

审校 | 重楼

概括:这篇文章分享了作者在使用 Github Actions 作为 CI/CD 工具时遇到的一些问题和解决方案,包括如何避免重复代码、如何管理环境变量、如何使用缓存和工件、如何利用复用工作流等。

开始构建发布流水线

GreptimeDB 自开源伊始,就采用 GitHub Actions 实现了自动化软件构建过程,从而诞生了首个发布流水线。

对于开源项目,构建一个稳定且一致的发布流水线具有以下关键价值:

  1. 供应随时可用的软件构件:身为软件供应链的上游生产者,我们必须为不同的下游用户提供安全、可信赖、随时可用的软件构件,如二进制文件、镜像等。
  2. 优化开发者体验:用户可无需繁琐配置或从零开始设置和编译,即可获取适合各自平台的即时可执行的软件构件。
  3. 实现发布工作流的自动化测试:结合不同类型的回归测试(例如性能、稳定性、集成测试等)和自动发布流程,以提高软件的整体质量。

虽有其他替代方案,如 Circle CI、Travis CI、GitLab CI,或自托管的开源项目如 Tekton 和 Argo Workflow, 但选择 GitHub Actions 的理由显而易见:它与 GitHub 生态系统融合,为用户提供了便捷的操作界面和丰富的软件市场访问权限。

然而,用户友好并不意味着维护轻松。相反,GitHub Actions 的维护可能变得复杂。GreptimeDB 的最初开源版本中的 release.yml 仅包含了精炼的183行代码。但随着许多贡献者的修改,这份文件逐渐演变并整合了:

  • 构建多样化平台上的构件;
  • 构建激活软件构件的不同功能开关;
  • 在实际构建之前执行集成测试;
  • 将软件构件推送到不同仓库(如 DockerHub、ACR、S3等);
  • 控制不同的发布条件(如手动触发、错误容限等);
  • 等等。

还有,由于一些特殊需求(如调试发布、每日构建等),在不同的内部仓库中产生了许多只有微小差异的相似流水线分支,这增加了维护的压力。

随着构建要求的复杂性不断提高,release.yml 文件迅速变得庞大,充满了冗余配置,维护难度增大。如果不及时进行重构,发布流水线将面临迅速甚至彻底的失效风险。

发布流水线退化问题分析

随着构建要求的复杂性不断提高,release.yml 文件迅速变得庞大,充满了冗余配置,维护难度增大。如果不及时进行重构,发布流水线将面临迅速甚至彻底的失效风险。

发布流水线退化问题分析

审查release.yml文件后,我们需要识别一些促使它迅速退化的因素。只有深入了解问题的根源,我们才能制定合适的重构方案。

  1. 语言局限性:GitHub Actions 的基于 YAML 的领域特定语言(DSL)与通用编程语言相比表现力不足,从而可能产生冗余和难以维护的代码。
  2. 调试难度高:GitHub Actions 因难以调试而闻名,特别是项目使用的 Rust 语言编译成本较高,进一步加长了调试周期。尽管如 act 等工具可以在本地执行 GitHub Actions,但实际运行操作仍然必须进行,因此无法有效缩短编写-运行-调试的周期。
  3. 动作解耦不足:GitHub Actions 通过 Composite 组合不同动作。我们由于缺乏经验,未将逻辑分解为独立动作,而是将所有内容集中到一个 YAML 文件中,因此维护起来较为困难。
  4. 重复构建问题:由于 GitHub 缺乏支持 ARM64 的虚拟机实例,为了优化编译性能,我们选择在 GitHub 的 x86_64 虚拟机实例上进行 AMD64 和 ARM64 软件构件的跨平台编译。虽然可以使用 Docker Buildx 激活 QEMU 进行 ARM64 平台模拟构建,但性能不佳。由于我们依赖于 GitHub Runner 主机环境而非 Dockerfile,实现一致的可重复构建颇具挑战性。

能够在首次尝试时就成功执行 GitHub Actions 的人非常罕见。

我们在重构过程的开始阶段,应该首先注重可维护性优于性能(构建速度)。发布的流水线将随项目的增长不断演化,因此可维护性至关重要。如果忽视了可维护性,可能会逐渐陷入困境,最终导致研发效率的降低。只有保障了可维护性,我们才能着手提高性能。在编译/构建场景中,合理利用各种缓存机制和优质的构建机器通常能够提升性能。

重构计划

重构 YAML 文件不同于常规编程项目,它更多地是一次对配置流程的全面审查,虽然这听起来并不完全符合逻辑,却存在较高的偶发复杂性。在此过程中容易陷入难以察觉的问题,进而可能面临解决的艰难挑战。以下总结了针对正在经历此类重构的一些实用建议。

  1. 采用 Dockerfile 实现构建标准化:虽然基于 Dockerfile 的构建可能影响性能,但这样的方式增强了可维护性,统一了跨平台构建流程,确保了构建的可重复性。
  2. 统一构建命令接口:基于上述考虑,需将各类构建命令精简为单一 make 命令。将编译的复杂性限制在 yaml 文件之外,避免发布阶段隐藏过多细节,且在开发阶段的 Makefile 或脚本中展现出来。通过 Makefile,用户可以体验到与发布阶段一致的构建过程,从而提升开发效率。
  3. 采用 AWS EC2:鉴于 GitHub Actions 目前缺乏 ARM64 VM 实例,需要采用交叉编译。使用 AWS EC2 ARM64 实例来构建 ARM64 平台的软件,以实现所有平台构建过程的标准化。
  4. 模块化解耦合:将 release.yml 拆分,使其成为一组明了的任务集合。每个位于 actions 目录下的 action.yml 文件都应保持简洁明了,以便根据相同操作自定义各种流程,提高整个过程的灵活性和效率。由于 GitHub Actions 内无组任务机制,此法是最佳方案。
  5. 简化任务执行:每个任务需专注于单一、特定的任务,增强其幂等性。这样在出错时,重试工作将更容易。此外,有助于更有效地提取顶层控制变量,允许更精确的手动触发控制。
  6. 避免在 Actions 中过度加载 Shell 命令:不要在单个 GitHub Actions 步骤中打包过多 Shell 命令,以利于维护。如果命令较多,可考虑转换为外部脚本并精简输入参数,确保脚本的独立执行和验证。
  7. 引入 Pre Job 分配 Runners:Allocate Runners 是首要任务,用于为后续工作分配 Runners 并创建全局版本标签。例如,使用 EC2 时,Allocate Runners 将通过 EC2 API(由 ec2-github-runner Action 实现)分配相应平台的 EC2 实例。未来计划引入更精确的选择算法以优化 Runner 分配成本。
  8. 实现全球统一流程:避免创建功能相似的 GitHub Actions 分支,以减少维护负担。为促进透明的开源开发,所有内部使用的构建流程已合并至主要的 GreptimeDB 存储库。代码若为开源,则软件产品和构建过程也应同样开放。
  9. 在 GitHub 存储库中合理使用变量和秘密:不应把大部分外部参数当作机密处理。一些非机密的外部参数应配置为 GitHub 变量,以便未来可以方便修改。应避免在 YAML 中硬编码将需要频繁修改的变量。

展望

GreptimeDB 对发布流水线的重构只是其走向成熟旅程中的一个环节。我们正朝着构建更高质量、更强大的 CI 努力发展:

  1. 拓展平台生态系统: 我们 windows 系统软件产品即将发布,届时欢迎来测试和体验。
  2. 增加自动化测试种类:在未来的计划中,我们将在 CI 流程中融合各类测试方式,例如混沌测试和性能测试,以持续提高软件的质量。
  3. 优化 CI 使用成本:通过精确分配各类 Runners,满足不同用例的需求,我们计划使整个 CI 运行更为经济和高效。
  4. 提升构建效能:虽然重构发布流水线在一定程度上对构建性能造成影响(#2113),但我们计划通过采用更智能的构建缓存技术,进一步加速构建过程。
  5. 强化软件供应链的安全性:在现代软件制品管理中,软件供应链安全日渐重要。作为一个开源项目,我们将确保软件产品的安全性、可信性和透明度。我们计划在发布流程中加入基本安全措施,如 SBOM 管理、软件签名和验证等。

虽然充分利用 GitHub Actions 存在挑战,我们仍将坚持不懈地改进。如你对此感兴趣并想要深入了解,欢迎加入我们在 Slack 上的社区进行讨论!你的建议对我们下一阶段的改进很可能会起到关键作用。

译者介绍

刘汪洋,51CTO社区编辑,昵称:明明如月,一个拥有 5 年开发经验的某大厂高级 JAVA 工程师,拥有多个主流技术博客平台博客专家称号。

标题:Practical Tips for Refactoring Release CI using GitHub Actions,作者:Greptime



Tags:GitHub Actions   点击:()  评论:()
声明:本站部分内容及图片来自互联网,转载是出于传递更多信息之目的,内容观点仅代表作者本人,不构成投资建议。投资者据此操作,风险自担。如有任何标注错误或版权侵犯请与我们联系,我们将及时更正、删除。
▌相关推荐
使用 GitHub Actions 重构和优化发布流程的实用技巧
译者 | 刘汪洋审校 | 重楼概括:这篇文章分享了作者在使用 GitHub Actions 作为 CI/CD 工具时遇到的一些问题和解决方案,包括如何避免重复代码、如何管理环境变量、如何使用缓...【详细内容】
2023-09-08  Search: GitHub Actions  点击:(279)  评论:(0)  加入收藏
▌简易百科推荐
即将过时的 5 种软件开发技能!
作者 | Eran Yahav编译 | 言征出品 | 51CTO技术栈(微信号:blog51cto) 时至今日,AI编码工具已经进化到足够强大了吗?这未必好回答,但从2023 年 Stack Overflow 上的调查数据来看,44%...【详细内容】
2024-04-03    51CTO  Tags:软件开发   点击:(5)  评论:(0)  加入收藏
跳转链接代码怎么写?
在网页开发中,跳转链接是一项常见的功能。然而,对于非技术人员来说,编写跳转链接代码可能会显得有些困难。不用担心!我们可以借助外链平台来简化操作,即使没有编程经验,也能轻松实...【详细内容】
2024-03-27  蓝色天纪    Tags:跳转链接   点击:(12)  评论:(0)  加入收藏
中台亡了,问题到底出在哪里?
曾几何时,中台一度被当做“变革灵药”,嫁接在“前台作战单元”和“后台资源部门”之间,实现企业各业务线的“打通”和全域业务能力集成,提高开发和服务效率。但在中台如火如荼之...【详细内容】
2024-03-27  dbaplus社群    Tags:中台   点击:(8)  评论:(0)  加入收藏
员工写了个比删库更可怕的Bug!
想必大家都听说过删库跑路吧,我之前一直把它当一个段子来看。可万万没想到,就在昨天,我们公司的某位员工,竟然写了一个比删库更可怕的 Bug!给大家分享一下(不是公开处刑),希望朋友们...【详细内容】
2024-03-26  dbaplus社群    Tags:Bug   点击:(5)  评论:(0)  加入收藏
我们一起聊聊什么是正向代理和反向代理
从字面意思上看,代理就是代替处理的意思,一个对象有能力代替另一个对象处理某一件事。代理,这个词在我们的日常生活中也不陌生,比如在购物、旅游等场景中,我们经常会委托别人代替...【详细内容】
2024-03-26  萤火架构  微信公众号  Tags:正向代理   点击:(10)  评论:(0)  加入收藏
看一遍就理解:IO模型详解
前言大家好,我是程序员田螺。今天我们一起来学习IO模型。在本文开始前呢,先问问大家几个问题哈~什么是IO呢?什么是阻塞非阻塞IO?什么是同步异步IO?什么是IO多路复用?select/epoll...【详细内容】
2024-03-26  捡田螺的小男孩  微信公众号  Tags:IO模型   点击:(8)  评论:(0)  加入收藏
为什么都说 HashMap 是线程不安全的?
做Java开发的人,应该都用过 HashMap 这种集合。今天就和大家来聊聊,为什么 HashMap 是线程不安全的。1.HashMap 数据结构简单来说,HashMap 基于哈希表实现。它使用键的哈希码来...【详细内容】
2024-03-22  Java技术指北  微信公众号  Tags:HashMap   点击:(11)  评论:(0)  加入收藏
如何从头开始编写LoRA代码,这有一份教程
选自 lightning.ai作者:Sebastian Raschka机器之心编译编辑:陈萍作者表示:在各种有效的 LLM 微调方法中,LoRA 仍然是他的首选。LoRA(Low-Rank Adaptation)作为一种用于微调 LLM(大...【详细内容】
2024-03-21  机器之心Pro    Tags:LoRA   点击:(12)  评论:(0)  加入收藏
这样搭建日志中心,传统的ELK就扔了吧!
最近客户有个新需求,就是想查看网站的访问情况。由于网站没有做google的统计和百度的统计,所以访问情况,只能通过日志查看,通过脚本的形式给客户导出也不太实际,给客户写个简单的...【详细内容】
2024-03-20  dbaplus社群    Tags:日志   点击:(4)  评论:(0)  加入收藏
Kubernetes 究竟有没有 LTS?
从一个有趣的问题引出很多人都在关注的 Kubernetes LTS 的问题。有趣的问题2019 年,一个名为 apiserver LoopbackClient Server cert expired after 1 year[1] 的 issue 中提...【详细内容】
2024-03-15  云原生散修  微信公众号  Tags:Kubernetes   点击:(6)  评论:(0)  加入收藏
相关文章
    无相关信息
站内最新
站内热门
站内头条