CI/CD 持续集成部署实践

持续集成与持续部署 (CI/CD) 是 DevOps 的主要内核,如实施得当,能极大地提高代码质量,加快开发速度,帮助团队更高效地开发。

在这篇文章中,我们会分享 RightCapital 在这方面的最佳实践,团队文化,希望能对你有所启发。

此文主要介绍我们后端项目的 CI/CD,用到的技术栈大概如下:

  • PHP
  • GitLab CI
  • Kubernetes
  • Helm + Helmfile + Helm Secret

持续集成 Continuous Integration

什么是 CI

开发者每次通过 push 或者 merge 导致的代码变更,会触发一系列的自动化工具执行代码检测。这些检测会帮助我们发现代码中的错误和可能的隐患,让问题在极早期暴露出来,而不用等到代码部署到 production 环境等用户反馈才意识到问题。

我们的 CI Pipeline

我来简单介绍一下我们在 CI 中具体做了些什么?

  • Prepare 阶段:做一系列初始化工作,比如安装项目依赖
  • Lint 阶段:代码风格的检查
    • PHP CS Fixer:确保所有人的代码风格一致
    • Yaml Lint:确保项目中的 yaml 文件格式正确,且风格一致
  • Test 阶段:测试
    • PHPUnit:执行的单元测试和集成测试
    • PHPStan:代码静态分析检查,比如查找未定义变量,类型错误使用等问题
  • Post 阶段:收尾工作
    • Sentry:将代码 commits 和 Sentry 关联起来,在 Sentry 收集到报错之后能快速定位到代码变更和提交人
    • Trigger Deploy:会触发部署的 pipeline,我们在下一章节细说

由于我们公司循序使用 GitFlow,所有代码变更皆产生自 feature, bugfix, hotfix 分支,且我们禁止了 develop, release, master 分支上的直接代码变更,所有变更皆需通过 PR 的方式才能被 merge 到这几个主干分支;而如果某个 PR 的任何一个检查中失败了,都是不允许被 merge。也就是说,我们通过以上 CI 流程,确定了我们能接受的代码质量底线。

什么是持续部署 Continuous Deployment

当持续集成完成之后,及时的进行自动部署,以确保每个时刻我们的代码都是可交付的。

  • Pre-deploy 阶段:做一些准备工作,比如下载 CI Pipline 的一些 artifacts
  • Publish:
    • Quay Cloud:build docker 镜像,并推送到 quey.io 上(quay.io 是一个企业级的 Docker Registry)
    • TS Schema Generator:这是我们内部的一个工具,会分析我们的 PHP 代码中 model,自动提取 API schema 并生成给前端用的 TypeScript 代码,并打包发布。里面包含了我们 API model 的属性名词、类型等源信息。
  • Deploy:
    • 这一步我们会将代码部署自动部署到分支对应的环境,并执行一系列的操作
      • 比如 master 部署到 production 环境,release 分支部署到 staging 和 uat 环境,develop 分支部署到 development 环境
      • 这里一系列操作包括:
        • 使用 helm + helmfile 将我们前面打包好的 docker 镜像部署的 K8S
        • 使用 helm secret 将我们的 env 部署到 K8S 成 secrets,我们在之前的《使用 SOPS 管理 Secret》中有介绍
        • 自动执行 migration,我们会在程序自动部署后,自动备份数据库,然后运行 migration 执行数据库变更
        • 缓存清理等工作……

代码任何时刻皆是可交付的,而这对于一个在高效持续改进产品的团队来说非常重要。而使用自动的方式规范了流程,避免了人工失误的可能,在任何数据库变更之前我们都会先自动先备份数据库,确保了数据安全。

Review Branch

这是什么?这是我们非常自豪的一套最佳开发环境部署实践,来看一下这些场景:

  • 由于我们的功能都在 feature 分支上开发,而 feature 分支在没有通过 CI 和代码评审之前是无法被 merge 到 develop 分支的,也就是说代码无法部署到 development 环境,可在开发期间经常有前后端联调的需求那我们怎么解决?
  • 在代码 review 过程中,虽然 CI 通过了,可评审员有时还希望将代码运行起来,手动测试一下,如何才能方便高效?

解决方案:我们可以为每个 branch 自动部署一个临时的环境用于测试和联调,这个环境在 PR 被 merge 后即被自动销毁。然后我们在前端页面底部做了一个 DevBar,可以看到当前有哪些环境和分支,且能随时切换 API 到任意环境开始测试,还能看到当前环境的 commit 相关的一些信息。

如果前后端需要联调怎么办? 后端只需要告诉前端一个信息,分支名是什么,Done!代码评审测试测试怎么办? 在前端选择当前分支名的环境即可开始测试。

这套方案极大的简化了我们的开发环境管理成本,而且让其他流程运转也都更高效了。

这套方案的实现基于了以下技术,我们后续会有文章细说实现:

1. GitLab CI Review Apps
2. K8S + helm
3. Cert manager

结语

也许有人会质疑这套流程过于苛刻,以至于影响开发效率。对于没有任何制约的代码推送,我们的流程自然会慢,而这正是我们希望发生的事情。

因为我们坚持代码质量重于开发速度,并且依靠流程的高度自动化,也能保持足够的高效,鱼和熊掌是可以兼得的。如果你也认可我们的理念,不妨投个简历加入我们。

这篇文章是一个我们 CI/CD 的一个总览,如果对我们的具体实现感兴趣,请关注订阅我们的账号/公众号获取后续更新。

本文作者:NauxLiu, DevOps Manager, RightCapital

本作品采用《CC 协议》,转载必须注明作者和本文链接
欢迎关注我们的微信公众号「RightCapital」
RightCapital
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 1

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!