从零到一:我在项目中实践持续集成工具的真实故事

智能体日记
2025-06-17 06:06
阅读 557

开头:为什么我会走上CI之路?

开头:为什么我会走上CI之路?

还记得两年前我刚加入一家创业公司的时候,那时候整个团队只有不到10个人。前端、后端、测试,大家都是“多面手”。项目代码量还不大,但每次上线都像在“赌命”——经常有人忘了提交某个配置文件,或者开发环境和生产环境版本不一致,导致线上服务莫名崩溃。

最严重的一次是某天早上上线之后,我们发现数据库连接不上了,排查了一上午才发现是某个开发人员误改了环境变量,把本地配置提上去了。那次事故让我彻底下定决心:我们必须要有持续集成(CI)!

于是,我开始研究 CI 工具、搭建自动化流程,并在一个迭代周期内把它完整地落地到了我们的主项目中。这篇文章就来聊聊这段经历里遇到的坑、踩过的雷,以及收获的那些实实在在的好处。


问题描述:项目初期的混乱状态

问题描述:项目初期的混乱状态

我们当时的项目是一个前后端分离的电商平台,技术栈包括 Vue 前端 + Spring Boot 后端 + MySQL 数据库 + Nginx 作为静态资源服务器。虽然规模不大,但随着团队人数增加到十几人,协作效率明显下降。

主要的问题体现在几个方面:

  1. 手动打包部署效率低
    • 每次发布都需要有人手动执行命令,打包上传。
  2. 版本控制不清晰
  • 不同分支合并频繁,经常出现冲突甚至错误合并。
  1. 构建失败反馈慢
  • 有时候提交的代码根本编译不过,但要等到部署时才被发现。
  1. 缺乏自动测试环节
  • 单元测试存在,但从没真正跑过,基本靠人工点击测试。
  1. 环境差异导致故障频发
  • “在我电脑上没问题”的情况层出不穷。

这些痛点让我意识到,如果不建立起一套完整的 CI 流程,这种“作坊式”开发模式迟早会出大问题。


解决方案:选型与实施过程

第一步:选择合适的CI工具

当时摆在面前的主流工具有 Jenkins、GitLab CI、GitHub Actions,后来我们也评估了 CircleCI 和 Travis CI,但考虑到以下几点,最终选择了 GitLab CI

  • 公司用的是自建 GitLab,已经集成了权限管理;
  • 不想额外维护 Jenkins 的服务器资源;
  • GitHub Actions 虽好,但公司不允许使用外部托管平台;
  • GitLab CI 的 .gitlab-ci.yml 配置相对简单直观;
  • 可以直接集成到 GitLab 的流水线视图中,便于查看进度。

第二步:确定CI的核心目标

我们为CI系统设定了以下几个核心目标:

  • 自动化构建
  • 自动化测试
  • 提交后自动触发构建,失败及时提醒
  • 区分不同环境(dev / test / prod)
  • 构建产物集中管理

第三步:逐步构建流水线

我们最初是从一个简单的构建+测试流程开始的,后面逐渐扩展为完整的流水线结构。

初版CI配置:只做构建和测试

stages:
  - build
  - test

build_vue:
  image: node:18
  stage: build
  script:
    - npm install
    - npm run build
  artifacts:
    paths:
      - dist/

test_backend:
  image: openjdk:11-jdk
  stage: test
  script:
    - cd backend
    - ./mvnw test

这个配置虽然简单,但已经可以让我们在每次推送代码后看到构建结果。如果单元测试失败,流水线就会中断,同时GitLab会通过邮件通知提交者。

中期优化:引入部署任务

随着流程的稳定,我们开始将部署任务也纳入到CI中。

deploy_dev:
  image: alpine
  stage: deploy
  script:
    - scp -r dist/* user@dev-server:/var/www/app/
    - ssh user@dev-server "systemctl restart nginx"
  only:
    - dev

这里有一个插曲:一开始我们尝试用 Ansible 来做部署,但因为运维能力不足,反而增加了复杂度。最后还是回归到了 shell 脚本的方式,事实证明更轻量、更容易维护。

最终形态:完整的多环境流水线

现在我们的 .gitlab-ci.yml 已经演化成一个完整的多阶段流程,涵盖不同分支、不同环境的处理逻辑。

variables:
  DOCKER_REGISTRY: registry.example.com

before_script:
  - echo "全局前置脚本"

stages:
  - lint
  - build
  - test
  - package
  - deploy

eslint:
  stage: lint
  script:
    - npx eslint .

build_frontend:
  stage: build
  image: node:18
  script:
    - npm install
    - npm run build
  artifacts:
    paths:
      - dist/

unit_test:
  image: openjdk:11
  stage: test
  script:
    - cd backend && ./mvnw test

dockerize:
  image: docker:latest
  stage: package
  services:
    - docker:dind
  script:
    - docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $DOCKER_REGISTRY
    - docker build -t registry.example.com/app:$CI_COMMIT_TAG .
    - docker push registry.example.com/app:$CI_COMMIT_TAG


![代码质量检测-1](https://code-guide.oss.shanghai.autogptai.club/common/file/download?name=date2025061706/63deaa2e-c9b4-4039-bc97-5516b62b4e55.jpg)


deploy_to_prod:
  image: alpine
  stage: deploy
  script:
    - echo "Deploying to production..."
    # 这里调用了部署脚本或K8s更新
  when: manual
  only:
    - master

可以看到,我们已经支持了多阶段、条件判断、人工审批等多个高级功能。


实施效果:带来的变化和收益

自从全面启用CI流程后,我们项目的稳定性有了非常明显的提升。

  1. 构建失败率显著下降
    • 因为每次PR都要跑一遍构建和测试,大部分问题都在合入前就被发现。
  2. 上线效率提高
    • 以前需要花2小时上线,现在一键点击流水线,10分钟就能完成部署。
  3. 团队协作更加顺畅
    • 所有人都知道什么时候该做什么事,不用再依赖口头沟通确认状态。
  4. 自动化保障质量
    • 我们的覆盖率统计和SonarQube也接入进来,代码质量更有保障。
  5. 出了问题能快速回滚
    • 所有镜像都打标签,版本可追溯,出问题时可以直接切回到上一个稳定版本。

而且最关键的是,我们终于不再怕“谁改动了什么”这个问题了。


经验分享:给准备实践CI的朋友的建议

如果你也在考虑或者刚开始接触 CI,下面是我总结的一些实战经验:

1. 不要一上来就想做个完美的CI

我见过不少团队在建设CI之前就想着搞全自动化、多环境部署、灰度发布、熔断机制……其实完全没有必要。

建议:从最简单的构建+测试做起。 稳定后再扩展部署、镜像打包等环节。否则很容易一开始就陷入各种细节和配置陷阱中。

2. 合理利用已有的工具生态

比如你用的是 GitHub,那 GitHub Actions 就很适合;用 GitLab,那就优先用 GitLab CI;Kubernetes 用户也可以看看 Tekton 或 ArgoCD。

别自己造轮子,除非你真的有必要。

3. 写好.gitlab-ci.yml不是终点

YAML 文件只是表面。真正的难点在于:

  • 如何组织好各个 job 的顺序
  • 怎么传递信息(比如打包后的 artifact)
  • 如何避免重复构建浪费时间
  • 如何调试失败的任务并恢复流程

我们曾经有个job老是卡住不动,查了好几天才发现是因为某个脚本没有退出码返回,导致整个pipeline以为还在运行。

4. 关注开发者体验

一个好的CI不应该打扰开发节奏,而应该让他们“感觉不到它的存在”。

比如:

  • 提供友好的报错提示(而不是一堆日志堆砌)
  • 快速反馈构建状态(比如集成 Slack/企业微信通知)
  • 易于重试和回滚

5. 定期Review你的CI流程

每个季度抽空 review 一下当前的 CI 配置,是否有些冗余 job?有没有可以优化的空间?是不是有新工具值得尝试?这样能保持流程的先进性和高效性。


结尾:CI不只是工具,更是一种文化

调试工具界面-2

写到这里,我想说,持续集成不仅仅是技术上的实践,更是工程文化的体现。

它教会我们如何高效协作、如何尊重代码质量、如何建立可追溯的工作流。它背后承载的是对交付质量的责任感,是对团队效率的追求。

这两年来,从最初的抗拒到现在的习惯,我已经离不开这套自动化体系了。更重要的是,整个团队的工作方式也因此变得更加规范和自信。

如果你还没开始,不妨从今天就开始试试吧。哪怕只是一个简单的构建任务,也可能成为你迈向专业化的第一步。


“让机器去做重复的事,让人去专注创造价值。”
——这是我始终坚持的理念。

评论 0

最热最新
暂无评论
匿名用户Lv.1
0
影响力
0
文章
0
粉丝