1.0 前言

上节,我们介绍了 Koa 项目的部署,大家可以发现我们是手动执行各种命令来控制整个流程的,在实际开发过程中,每次都要去各种服务器上操作这些是很麻烦的,而且还容易出错,所以就有了持续集成,把这个流程工程化,这个流程就叫 CI/CD

CI(Continuous Integration) 简称持续交付,意思是新增代码后自动校验代码格式,打包,构建,跑单测,单测覆盖率,对应我们前端常见的就是 ESLint,Webpack 打包,各种脚本。

CD(Continuous Delivery)简称 持续部署,意思是 经过 CI 后,代码自动部署,对应前端的常见的是 打包后,自动发布到 oss,刷新cdn。

常用的 有 Jenkins,Gitlab CI/CD,Github Action,一般公司中都会用用到 Gitlab CI/CD,然后结合它提供的持续集成功能,接下来我们就讲讲 基于 Gitlab 的持续集成。

2.0 Gitlab CI/CD 简介

2.0.1 简单介绍

GitLab 中默认开启了 CI/CD 的支持,且使用 YAML ,通过根目录的 .gitlab-ci.yml 来描述管理项目构建配置,我们只需要在 .gitlab-ci.yml 配置文件中定义流水线的各个阶段,以及各个阶段中的若干任务就可以了。

比如下面这个最简单的配置:

  1. image: node:latest
  2. stages:
  3. - test
  4. test
  5. stage: test
  6. script:
  7. - echo 'hello,world!'

这样 代码 push 到 Gitlab 后,会自动执行这个任务,我把这个 Demo 放到 Gitlab 公网上了,大家可以看下实际效果
打开 gitlab 项目的地址,点击 左侧的 CI/CD下就能看到构建信息。

image.png

点击详情可以看到:
image.png
这里面就有我们刚才 echo ‘hello,world!’ ,那我们 echo 换成 npm install, npm run build,就换成了我们执行的执行的 npm 命令,这样不把我们的项目串联起来了么。

2.0.2 .gitlab-ci.yml 一些常用属性

.gitlab-ci.yml 包含了很多配置文件,接下来我们讲讲一些常用的配置,我们根据一个常用的配置来介绍。

  1. # image 标记 使用的 docker 镜像,这里我们使用 nodejs 镜像
  2. image: node:latest
  3. # variables 是定义环境变量,可以在直接获取
  4. variables:
  5. HCNAME: "hucheng"
  6. cache:
  7. paths:
  8. - node_modules/
  9. # stages 定义 执行步骤,包含了需要执行的job,类似第一步干嘛,第二步干嘛,接着干嘛
  10. stages:
  11. - install_deps
  12. - build
  13. - deploy
  14. # install_deps 就是job,job下面的 stage 字段和上面一一对应起来
  15. install_deps:
  16. stage: install_deps
  17. only: # 这里的 only 标记 在下面3个分支下面,push代码后,执行当前job,,only 支持 branch,tag,change,正则
  18. - develop
  19. - preview
  20. - master
  21. script: # script 就是你要执行的脚本了
  22. - echo $HCNAME && npm install
  23. build:
  24. stage: build
  25. only:
  26. - develop
  27. - preview
  28. - master
  29. artifacts: # artifacts 标记,当前job 执行完成后,在 gitalb 网页可以下载的文件,会出现个下载按钮,可以下载这个目录
  30. paths:
  31. - ./dist
  32. script:
  33. - npm run build
  34. deploy:
  35. stage: deploy
  36. only:
  37. - develop
  38. - preview
  39. - master
  40. script:
  41. - npm run publish

stages

例子中 stages 值为一个数组(p.s. 用 - 代表数组和 markdown 类似)。包含了三个 job,test, build, deployr 分别实现自动测试,打包项目和部署。下方的 stage 必须在全局定义的 stages 内。

variables

值为键值对象,为了后续的流程,此处定义了开发项目和部署项目的 namespace 和 repo_name。同 shell 类似,后续使用其值需要加上 $ 符号。定义的变量也有对应的作用域,定义在顶层就可以作为全局变量供所有 job 使用,如果是一些 job 特有的变量,就定义在 job 内部。gitlab 默认提供了很多全局变量给我们使用,常用有:

  1. name: CI_PROJECT_NAME,
  2. namespace: CI_PROJECT_NAMESPACE,
  3. path: CI_PROJECT_PATH,
  4. url: CI_PROJECT_URL,
  5. repo: CI_REPOSITORY_URL,
  6. tag: CI_COMMIT_TAG,

before_script

值为数组,每一个元素其实就是一个 linux 命令,写的时候装作自己在写 shell 就好。该部分主要生成了后续构建需要的镜像标签,切换当前目录等。为了 debug 方便,这些变量最好打印。类似的,如果在 job 完成后有一些时候操作,可以定义 after_script。需要注意的是如果定义在顶层,内部的命令会在每个 job 运行之前执行,如果某些 job 需要特别的预操作,可以在 job 内部再配置一个 before_script 对象,它会复写外部的全局预操作。

test_stage

名为 testjob 的具体配置,一般是个复合对象。

stage

job 对应的 stage,如果有多个 job 对应同一个 stage,在执行时会并行执行这些 job

script

这个 job 执行的命令,此处是进入的项目仓库目录,并且执行了一个 shell 脚本,这个脚本定义了执行项目的所有单元测试。一般建议如果要执行的命令过多,就把这些命令写成脚本放在项目内。CICD 流程直接执行这个脚本。

only

only 指明了 job 的执行场景,可以是分支名。

3.0 Koa 结合 .gitlab-ci.yml

.gitlab-ci.yml 配置文件如下:

  1. image: node:latest
  2. cache:
  3. paths:
  4. - node_modules/
  5. stages:
  6. - install_deps
  7. - deploy
  8. install_deps:
  9. stage: install_deps
  10. script:
  11. - npm install
  12. deploy:
  13. stage: deploy
  14. only:
  15. - tags
  16. script:
  17. - sh ./deploy

这里我们分为 2 个步骤,当在 Gitlab 上 打完 tag 后 触发构建,先执行 npm install 获取依赖,接着执行 deploy 的 shell 脚本,我们看看 shell 脚本里面具体内容。

  1. domain_name=koa-test
  2. app_dir=/data/app
  3. app_name=koa-test
  4. ip=xxx.xxx.xxx.xxx
  5. ssh work@$ip "mkdir -p ${app_dir}/${domain_name}/releases/${CI_COMMIT_TAG}"
  6. rsync -az ./ --exclude .git --exclude .gitignore work@$ip:${app_dir}/${domain_name}/releases/${CI_COMMIT_TAG}
  7. ssh work@$ip "ln -snf ${app_dir}/${domain_name}/releases/${CI_COMMIT_TAG} ${app_dir}/${domain_name}/current"
  8. ssh work@$ip "cd ${app_dir}/${domain_name}/current && npm run start:prd"

npm run start:prd 对应 package.json 是:

  1. "scripts": {
  2. "dev": "cross-env NODE_ENV=dev nodemon bin/www",
  3. "start:prod": "cross-env NODE_ENV=dev && pm2 delete koa-test || true && pm2 start ./bin/www --watch --name koa-test",
  4. "lint": "lint-staged"
  5. },

上面的 ip 表示我们的 ECS 服务器的IP,根据 tag ,把构建好的文件通过 ssh 把文件放到对应的目录下,然后 通过 pm2 启动这个项目。

这样通过 Gitlab CI/CD 我就完成了,当前项目的构建,部署。整个流程打完 tag 后自动触发,不需要人为参与,完成了整个流程。

4.0 小结

这节我们学习了 Gitlab CI/CD 的介绍,结合 Koa 项目的基本使用,大家可能本地没有这些环境,但是可以理解下,在实际工作中用的非常频繁,可以参照 Demo 看看,Demo 链接