目前我所在的团队规模不大,人员不多,研发流程并没有像之前在大厂时那么规范,也没有成熟的基建来给到我们提供辅助,所以上线发布流程就是一个任性,直接在本地打完包手动上传到OSS就完事,简单高效,但问题也很多,急切需要用自动化手段来解决一些手工劳动。
因为我们用了 gitlab 来管理代码,所以直接上方案:gitlab CI/CD runner
gitlab CI/CD runner
本质上,Gitlab Runner 就是一个可以执行脚本的环境,它会根据你 gitlab 仓库中的配置文件,来执行一连串的任务。而 Gitlab Runner 可以被安装在服务器,虚拟机,甚至是Docker容器中。
准备工作
- 已部署好的 gitlab 服务
- gitlab 服务域名的https证书
- 用于安装 Gitlab Runner 的服务器
tip: 可以用这个命令获取https证书
openssl s_client -showcerts -connect gitlab.example.com:443 -servername gitlab.example.com < /dev/null 2>/dev/null | openssl x509 -outform PEM > /srv/gitlab-runner/certs/gitlab.example.com.crt
安装GitLab Runner
我们选择使用 Docker 来安装 Gitlab Runner(详细的安装说明),将配置目录 /etc/gitlab-runner/ 映射到外部
docker run -d --name gitlab-runner --restart always \ -v /srv/gitlab-runner/config:/etc/gitlab-runner \ -v /srv/gitlab-runner/certs:/etc/gitlab-runner/certs \ -v /var/run/docker.sock:/var/run/docker.sock \ -v /etc/localtime:/etc/localtime gitlab/gitlab-runner:latest
注册 Runner
docker run --rm \ -v /srv/gitlab-runner/config:/etc/gitlab-runner \ -v /srv/gitlab-runner/certs:/etc/gitlab-runner/certs \ -v /var/run/docker.sock:/var/run/docker.sock \ -v /etc/localtime:/etc/localtime gitlab/gitlab-runner register \ --non-interactive \ --executor "docker" \ --docker-image alpine:latest \ --url "https://gitlab.example.com/" \ --registration-token "xxxxxxxxxxxxxx" \ --description "docker-runner" \ --tls-ca-file /etc/gitlab-runner/certs/gitlab.example.com.crt \ --tag-list "fe"
registration-token,可以从 gitlab CI/CD 的 runner 中获取
稍微解释下 register 的参数
--non-interactive // 非交互模式注册 Runner --executor "docker" // 提供 Runner 执行器。对于大多数用例来说,输入 docker --docker-image alpine:latest // 如果您输入 docker 作为执行器。对于在 .gitlab-ci.yml 中没有定义镜像的项目,系统会要求您使用默认镜像 --url "https://gitlab.example.com/" // 您的 GitLab 实例 URL --registration-token "xxxxxxxxxxxxxx" // 注册 Runner 时获取的令牌 --description "docker-runner" // Runner 描述 --tag-list "fe" // 以逗号隔开的与 Runner 有关的标签 --tls-ca-file /etc/gitlab-runner/certs/gitlab.example.com.crt // https证书文件路径
注册完成后,在 gitlab CI/CD 的 runner 中查看 runner 的状态,如果是绿色就能正常使用了
配置 .gitlab-ci.yml 文件
一个基本的 .gitlab-ci.yml 文件内容如下
# 定义三个stage stages: - test - build - deploy test-job: # 注明该任务在test阶段执行 stage: test script: - npm install --registry=https://registry.npmmirror.com - npm run test build-job: # 注明该任务在build阶段执行 stage: build script: - npm run build only: - main artifacts: paths: - build/ expire_in: 1 hour # 可选,设置 artifacts 的过期时间 deploy-job: # 注明该任务在deploy阶段执行 stage: deploy script: - npm deploy only: - main
stages 用来定义流水线的各个阶段,使得任务串行运行,test-job / build-job / deploy-job 是自定义的任务,任务里面的 stage 表明当前任务属于某个阶段,script 是用于执行的脚本列表,only 是限定提交分支包含在分支列表里才执行,artifacts 是 GitLab CI/CD 用于在不同作业之间共享文件的机制,更多定义和用法可以查看官网链接。
针对我们的实际情况,我设计一种根据分支名规则来触发不同脚本执行任务的方案
- 当分支名是 dev/publish 时,触发开发环境的构建和发布
- 当分支名是 prod/**/publish 时,触发正式环境的构建和发布
- 构建完成的产物,通过阿里云 ossutil 上传到 OSS
- 发布完成后,通过企业微信机器人通知团队成员
大概的配置如下
variables: NPM_CONFIG_REGISTRY: https://registry.npmmirror.com/ image: node:18-alpine stages: - deploy before_script: - export NODE_OPTIONS="--max-old-space-size=4096" # 使用阿里云的源来加速 apk 安装 - sed -i 's/dl-cdn.alpinelinux.org/mirrors.aliyun.com/g' /etc/apk/repositories - apk add git curl deploy-dev: stage: deploy only: refs: - dev/publish tags: - fe script: - | echo "安装pnpm" npm install -g pnpm --registry=$NPM_CONFIG_REGISTRY pnpm install --registry=$NPM_CONFIG_REGISTRY - | echo "构建项目" pnpm build - | echo "上传到OSS" wget http://gosspublic.alicdn.com/ossutil/1.7.18/ossutil64 -O /usr/bin/ossutil64 chmod 755 /usr/bin/ossutil64 ossutil64 config -e $OSS_END_POINT -i $OSS_ACCESS_KEY_ID -k $OSS_ACCESS_KEY_SECRET ossutil64 cp -r -f ./dist oss://xxxxxxxxxxxxxx/ - | echo "通知企业微信" VERSION=$(node -pe "require('./package.json').version") curl \ -H "Content-type: application/json" \ -d "{\"msgtype\":\"text\", \"text\": {\"content\":\"dev 发布成功,版本号: $VERSION\"}}" \ "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxxxxxxxxxxxxx"
以上还只是比较简单的实现,能够满足常规的发布需求,还可以继续深入的完善一下,比如,只发布到指定的环境,版本回滚等功能。
更新:
在 gitlab-runner 的配置文件 config.toml 中,在 [runners.docker] 下添加一行
pull_policy = "if-not-present"
运行 CI 时会先在本地检查是否有指定的镜像,没有的话再从 Docker Hub 拉取
《在小团队中如何做前端自动化部署》留言数:0