从零到一:前端CI/CD工作流搭建实践

引言:一个实习生的工程化觉醒

2024年7月8日,我开始了在前端开发领域的实习生涯。加入了一家致力于云产品服务创新的开发公司,很快发现公司在工程化方面存在诸多不完善之处------项目缺乏统一的CI/CD工作流,团队协作时各种奇怪问题频发,代码规范执行也不够严格。这成为了我接触前端工程化的契机,也是我职业生涯中第一次系统性地搭建CI/CD流水线。

起初,这个任务对我来说既陌生又枯燥。和大多数刚入行的开发者一样,我的关注点一直局限在业务代码开发上,对工程化知之甚少。但当Leader给出"一周内完成所有配置"的要求时,我不得不快速进入状态,啃 了两天的GitLab CI/CD pipeline 熟悉了配置相关的文档,包括每一个配置对象的作用以及使用都理解了一遍。同时通过博客也做了很多了解。开启了这段充满挑战的研究之路。

一、CI/CD基础认知

1.1 什么是CI/CD?

CI(持续集成,Continuous Integration)是指开发人员频繁地将代码变更合并到共享主干(通常每天多次),每次合并都会触发自动化构建和测试流程。

CD 持续交付(Continuous Delivery)和持续部署(Continuous Deployment),前者确保代码可以随时安全地部署到生产环境,后者则自动将变更部署到生产环境。

1.2 为什么需要CI/CD?

在传统开发模式中,我常遇到以下问题:

  • "在我机器上是好的"------环境差异导致的问题
  • 代码合并冲突频发
  • 质量问题到项目后期才暴露
  • 手动部署容易出错

CI/CD通过自动化解决了这些问题,带来了以下优势:

  • 快速反馈:代码提交后立即获得构建和测试结果
  • 质量保障:通过自动化测试和代码检查保证代码质量
  • 降低风险:小批量频繁集成减少大规模冲突风险
  • 提高效率:自动化流程解放开发者生产力

二、GitLab CI/CD核心概念

2.1 Pipeline基础结构

GitLab CI/CD的核心是.gitlab-ci.yml配置文件,它定义了整个流水线的结构和行为。一个典型的Pipeline包含:

yaml 复制代码
stages:
  - verify # 前置检查阶段
  - package # 构建阶段
  - release # 部署阶段

job1:
  stage: verify
  script:
    - echo "运行前置检查"
  
job2:
  stage: package
  script:
    - echo "运行构建"

2.2 Runner与执行环境

Runner是执行Pipeline作业的代理,支持多种执行环境:

  • Shell Runner:直接在主机上执行
  • Docker Runner:在容器中执行(推荐)
  • Kubernetes Runner:在K8s集群中执行(适合大规模部署)

我们选择了Kubernetes Runner(腾讯云Serverless集群),因为它提供了良好的隔离性和可扩展性。

三、代码提交阶段的规范化

3.1 Git Hook与Husky

Git Hook是Git在特定事件(如提交、推送)发生时自动运行的脚本。我们使用Husky来更便捷地管理Git Hook。

配置步骤:

  1. 安装Husky:
css 复制代码
npm install --save-dev husky
  1. 在package.json中添加prepare脚本:
json 复制代码
{
  "scripts": {
    "prepare": "husky install"
  }
}

3.2 预提交检查(Pre-commit)

我们在.husky目录下创建pre-commit钩子,确保每次提交前都通过代码检查和测试:

bash 复制代码
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npm run lint  # 代码风格检查
npm run test  # 单元测试

3.3 提交信息规范(Commitlint)

统一的提交信息格式让项目历史更清晰,也为自动化处理提供基础。我们使用commitlint来强制执行规范:

  1. 安装依赖:
scss 复制代码
npm install --save-dev @commitlint/config-conventional @commitlint/cli
  1. 配置commitlint.config.js:
java 复制代码
module.exports = {
  extends: ['@commitlint/config-conventional'],
  rules: {
    'type-enum': [
      2,
      'always',
      ['feat', 'fix', 'docs', 'style', 'refactor', 'test', 'revert', 'build', 'chore', 'ci', 'perf'],
    ],
    'type-case': [2, 'always', 'lowerCase'],
    'type-empty': [2, 'never'],
    'subject-full-stop': [2, 'never', '.'],
  },
};
  1. 创建commit-msg钩子:
bash 复制代码
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

npx commitlint --edit "$1"
  1. 设置执行权限:
bash 复制代码
chmod 755 .husky/commit-msg

这样配置后,不符合规范的提交信息会被拒绝,例如:

bash 复制代码
⧗   input: chore123: test
✖   type must be one of [feat, fix, docs, style, refactor, test, revert, build, ci, perf] [type-enum]

规范提交:

sql 复制代码
git commit -m "feat: 添加提交信息"

四、代码合并阶段的自动化检查

4.1 代码质量报告集成

GitLab支持基于Code Climate规范的代码质量报告。我们配置了ESLint和Stylelint生成符合规范的报告:

  1. 在package.json中添加脚本:
css 复制代码
{
  "scripts": {
    "lint:script:ci": "eslint --ext .tsx,.ts --format gitlab ./src",
    "lint:style:ci": "stylelint src/*.{css,less} src/**/*.{css,less} --custom-formatter=node_modules/stylelint-formatter-gitlab"
  },
  "devDependencies": {
    "eslint-formatter-gitlab": "3.0.0",
    "stylelint-formatter-gitlab": "1.0.1"
  }
}
  1. 配置.gitlab-ci.yml:
yaml 复制代码
stages:
  - verify
  - package
  - release

lint-job:
  stage: verify
  allow_failure: false
  image: XXX
  variables:
    ESLINT_CODE_QUALITY_REPORT: gl-codequality-script.json
    STYLELINT_CODE_QUALITY_REPORT: gl-codequality-style.json
  script:
    - npm i
    - npm run lint:script:ci & lint:style:ci
    - npx deepmerge-cli gl-codequality-script.json gl-codequality-style.json > gl-codequality.json
  artifacts:
    name: "$CI_JOB_NAME-$CI_JOB_STAGE-$CI_COMMIT_SHORT_SHA-$CI_COMMIT_TIMESTAMP"
    when: always
    reports:
      codequality: gl-codequality.json
  only:
    - merge_requests
    - main
    - tags
  tags:
    - k8s

sonarqube-check:
  stage: verify
  allow_failure: false
  image:
    name: XXX
    entrypoint: [""]
  variables:
    SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar"
    GIT_DEPTH: "0"
  cache:
    key: "${CI_JOB_NAME}"
    paths:
      - .sonar/cache
  script:
    - sonar-scanner
  only:
    - merge_requests
    - main
    - tags
  tags:
    - k8s

关键点说明

  • verify是特殊阶段,会在其他阶段前运行
  • 同时运行了检查任务和合并报告任务
  • artifacts:reports:codequality将报告上传到GitLab,在MR界面进行展示

4.2 单元测试与覆盖率

配置了Jest测试框架,并生成测试报告和覆盖率数据:

  1. 安装依赖:
css 复制代码
npm install jest-junit --save-dev
  1. 配置测试脚本:
less 复制代码
{
  "scripts": {
    "test:ci": "tsdx test --ci --reporters=default --reporters=jest-junit --coverage --coverage-reporters=cobertura --coverage-reporters=text --coverage-reporters=text-summary"
  }
}
  1. 配置 .gitlab-ci.yml:
yaml 复制代码
unit-test-job:
  script:
    - npm run test:ci
  artifacts:
    reports:
      junit: junit.xml
      coverage_report:
        coverage_format: cobertura
        path: coverage/cobertura-coverage.xml
  coverage: /Statements\s*:\s*(\d+.?\d*)%.*/

4.3 安全扫描

GitLab提供了内置的安全扫描功能,我们启用了以下检查:

yaml 复制代码
sast-job:
  stage: test
  script:
    - echo "运行SAST扫描..."
  artifacts:
    reports:
      sast: gl-sast-report.json

secret-detection-job:
  stage: test
  script:
    - echo "运行泄密检测..."
  artifacts:
    reports:
      secret_detection: gl-secret-detection-report.json

五、构建与部署自动化

5.1 多环境构建策略

为不同环境配置了不同的构建策略:

bash 复制代码
build-job:
  stage: package
  allow_failure: false
  image: XXX
  script:
    - npm i
    - npm run build
    - echo $IMAGE_NAME:$IMAGE_TAG
    - docker -v
    - docker build --rm --no-cache -t $IMAGE_NAME:$IMAGE_TAG `pwd`
    - docker push $IMAGE_NAME:$IMAGE_TAG
  only:
    - tags
  tags:
    - k8s

5.2 自动化部署

部署配置根据环境有所不同:

yaml 复制代码
deploy-job:
  stage: release
  allow_failure: false
  image: XXX
  script:
    - sed -i "s/xxx/${IMAGE_TAG}/g" .kube/serverless.yml
    - export KUBECONFIG=`pwd`/.kube/config
    - kubectl delete -f .kube/serverless.yml || true
    - kubectl apply -f .kube/serverless.yml
  only:
    - tags
  tags:
    - k8s
  environment:
    name: dev
    url: $APP_DOMAIN

六、经验总结与最佳实践

6.1 实施过程中的挑战

  1. 基础分支问题:当目标分支(如master)没有运行过代码质量检查时,MR会比较失败。解决方案是确保主分支至少运行一次完整的Pipeline。
  2. 缓存问题:在K8s环境中,缓存路径必须使用相对路径,否则不同Runner实例间无法共享缓存。
  3. 并行任务协调 :使用&wait实现并行任务时,需要注意任务间的资源竞争。

6.2 推荐的最佳实践

  1. 渐进式采用:从最基本的lint和test开始,逐步添加更复杂的检查。
  2. 失败快速:将最重要的检查放在前面,尽早发现问题。
  3. 可视化反馈:充分利用GitLab的报告功能,让问题一目了然。
  4. 文档化:记录此次的CI/CD搭建指南,降低后续的学习成本。

七、未来规划

  1. 研究自动化回滚,当监控发现问题时自动回滚到上一个稳定版本。
  2. 探索cicd 配置如何集成可复用的工具,避免每个项目需要自动化测试时都做重复的配置。

结语

从对CI/CD一无所知到最后完整的搭建了工作流,现在回头看,这段经历真的让我成长不少,既艰难又充满成就感。深刻认识到工程化对团队开发效率的重要性。一个好的CI/CD系统就像交通信号灯,虽然建设时需要投入,但一旦运行起来,就能让整个开发流程有序且高效。

好了,我的分享就到这里啦! 目前加入了新公司,带我的导师一直鼓励我多总结,将自己的产出留痕,以便于感知自己的收获,并且通过发布文章,分享自己的经历也能和更多人交流学习,开发之路永远需要保持开放的心态。

所以今天就把之前搭建CI/CD的过程整理一下,既是对自己的复盘,也希望本文能帮到在探索前端工程化或者有同样需求的小伙伴噢~

相关推荐
故作春风5 小时前
从零开始学 GitHub Actions:用自动化提升开发效率
ci/cd·自动化运维
seth12 小时前
coding 要停服了, 把所有 CI 迁移到 Github 上 (服务器无需翻墙)
ci/cd·docker·github
mCell2 天前
Webhook:连接、自动化与系统集成的新范式
ci/cd·go·github
Gold Steps.2 天前
基于 Gitlab、Jenkins与Jenkins分布式、SonarQube 、Nexus 的 CiCd 全流程打造
运维·ci/cd·gitlab·jenkins
LCG元3 天前
基于MCP的CI/CD流水线:自动化部署到云平台的实践
运维·ci/cd·自动化
鼠鼠我捏,要死了捏3 天前
生产环境CI/CD流水线构建与优化实践指南
ci/cd·devops·流水线
mapengpeng1999@163.c3 天前
持续集成持续发布CICD
ci/cd
老马啸西风5 天前
maven 发布到中央仓库之 Ignore Licence-04
java·ci/cd·maven
hwj运维之路7 天前
GitOps实践指南:GitLab CI/CD + ArgoCD 实现 Kubernetes 自动化部署
ci/cd·gitlab·argocd
qinyia7 天前
利用Wisdom SSH高效搭建CI/CD工作流
运维·ci/cd·ssh