React 在 GitLab 中自动化

header

React 在 GitLab 中自动化

背景

项目使用自建的 GitLab 进行托管,该项目为 React 前端项目,想用现有的条件下实现,自动化。包含构建,部署,版本升级

目标

  • 使用 GitLab CI/CD 实现自动化构建并部署到指定服务器(仅 dev 分支)
  • master 分支合并代码,实现自动升级版本号以及相关 release 产出跟 生成 CHANGELOG

说明

使用 GitLab 的自动化也就是 CI/CD 功能,主要是有个容器(GItLab Runner)去做相关的操作,使用 node 镜像去构建,并用 ssh 的连接服务器方式去 scp 或者 rsync,同步你的代码到目标服务器。

版本升级跟其他相关操作,这里使用了一个 npm 的第三方包 release-it

release-it

Release It! 🚀 Automate versioning and package publishing.
直译过来就是”自动化版本控制和包发布“。 我们可以用这个工具来进行版本发布。包括在发布时我们需要做的以下的事,都可以用这个包进行配置。

  • 升级版本 (修改 package.json 的 version 字段)
  • 打 tag 标签
  • 生成 changelog 日志
  • 产生 release 文件包
  • 发布到 npm
  • GitHub 或 GitLab CI/CD 的使用

操作步骤

环境介绍

  • 测试服务器: centos 7

部署 GitLab Runner

1. 使用 Docker 安装 GitLab Runner
1.1 安装 Docker,已有的可跳过
1
2
3
4
5
6
7
8
9
10
11
12
# 使用镜像地址安装
$ sudo yum install -y yum-utils
$ sudo yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo
$ sudo yum install docker-ce docker-ce-cli containerd.io
# 启动服务
$ sudo systemctl start docker
# 开机自启
$ systemctl enable docker
# 运行 hello-world 镜像
$ sudo docker run hello-world
1.2 安装 GitLab Runner 镜像
1
2
3
4
$ docker run -d --name gitlab-runner --restart always \
-v /srv/gitlab-runner/config:/etc/gitlab-runner \
-v /var/run/docker.sock:/var/run/docker.sock \
gitlab/gitlab-runner:latest
1.3 注册 runner
  • 需要在以下路径里面找到你的 runner 的 url 跟 token:

    • 找到需要绑定的项目
    • 在项目菜单的左侧 Settings –> CI/CD –> Runners
    • gitlab-runner
    • 拷贝其中的 url 跟 token 下面要用到
  • 运行下面的命令

    1
    $ docker run --rm -it -v /srv/gitlab-runner/config:/etc/gitlab-runner gitlab/gitlab-runner register
    • 输入你上面拷贝的地址 eg: http://gitlab.xxx.com.cn/
    • 输入 token eg: xxxxx
    • 输入描述 eg: dev_runner
    • 输入标签 eg: docker_node
    • 选择执行者选择 docker

release-it 配置

在项目的根目录创建文件 .release-it.json。用来配置 release-it 相关。示例文件如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
{
"git": {
"commit": true, # 开启 git
"tagName": "v${version}", # 打 tag 的名称模板
"commitMessage": "Release ${version}", # git 提交消息模板
"pushArgs": ["-o ci.skip", "--follow-tags"], # Git 提交 release 相关的时候不触发 ci 构建
"requireUpstream": false
},
"hooks": {
"before:init": "git fetch --prune --prune-tags origin" # 在之前拉一下最新的 tag
},
"npm": {
"publish": false # npm 部署关闭
},
"gitlab": {
"release": true, # GitLab 部署开启
"tokenHeader": "PRIVATE-TOKEN", # 调用 API 接口 header 中的 toekn 头
"origin": "http://gitlab.xxx.com", # GitLab 地址
"assets": ["dist/*.zip"] # 上传 release 页面的文件
},
"plugins": {
# 由于本项目使用 conventional 风格 git日志,该插件可以生成 changlog 文件
"@release-it/conventional-changelog": {
"infile": "CHANGELOG.md",
"preset": {
"name": "conventionalcommits",
"header": "# 📋 更新历史 \n\n",
"types": [
{ "type": "feat", "section": "✨ Features | 新功能" },
{ "type": "fix", "section": "🐛 Bug Fixes | Bug 修复" },
{ "type": "perf", "section": "⚡ Performance Improvements | 性能优化" },
{ "type": "revert", "section": "⏪ Reverts | 回退" },
{ "type": "chore", "section": "📦 Chores | 其他更新" },
{ "type": "docs", "section": "📝 Documentation | 文档" },
{ "type": "style", "section": "💄 Styles | 风格", "hidden": true },
{ "type": "refactor", "section": "♻ Code Refactoring | 代码重构" },
{ "type": "test", "section": "✅ Tests | 测试" },
{ "type": "build", "section": "👷‍ Build System | 构建" },
{ "type": "ci", "section": "🔧 Continuous Integration | CI 配置" }
]
}
}
}
}

GitLab CI 配置

2. 准备工作
2.1 ssh 秘钥串

在需要部署的服务器上,使用如下命令打印秘钥:

1
2
3
4
# 打印公钥
$ cat ~/.ssh/id_rsa.pub
# 打印私钥
$ cat ~/.ssh/id_rsa

如果提示没有该文件,则需要手动生成一份。执行以下命令,一直回车,直到结束。再重复上步骤,将公司要里的内容复制到本地备忘录中,下面要用。

1
2
# 生成秘钥对
$ ssh-keygen -t rsa

2.2 GlitLab Token

这个是 release-it 在部署提交 git 的时候需要用到的权限。

  • 在 GitLab 中,右上角选择自己头像,选择 preferences。
  • Access Tokens 下,名字随意,Scopes 全选,点击 Create personal access token
    • gitlab-token.png
  • 将生成好的 token 复制出,备用
    • gitlab-token-2.png
      2.3 将私钥放到到 GitLab 中
      为了下载代码,可将私钥放到 GItLab 中,操作方法如下:
  • 打开 GItLab 地址
  • 点击右上角头像,选择 Preferences
  • 点击左侧 SSH Keys,将 2.1中生成的公钥填到框里,点击 Add
  • gitlab-ssh
3. CI 配置
3.1 配置 CI 变量

在 CI 运行的时候有些变量,处于安全考虑,不会明文显示,这里可以把相关变量放到 CI 的 Variables 中,CI 运行的时候,可以直接读取。

  • 打开项目的 GitLab 地址,Settings –> CI/CD –> Variables
    • 添加 GITLAB_TOKENSSH_PRIVATE_KEY两个变量。 其中 GITLAB_TOKEN 是 2.1 中生成的 token; SSH_PRIVATE_KEY 则是 2.1 中的私钥.
    • gitlab-ci-variable
      3.2
      在需要构建的项目根目录中创建 .gitlab-ci.yml 文件。文件示例如下:
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      variables:
      SOURCE_PATH: 'dist/notice' # 替换成自己的,需要拷贝的文件夹地址
      REMOTE_ADDRESS: 'root@172.177.217.117:/root/webapp/' # 替换成自己的,拷贝目标的远程的地址


      stages:
      - build
      - deploy
      - release

      before_script:
      - apt-get update
      - apt-get install -y zip unzip git openssh-client
      - eval `ssh-agent -s`
      - echo "${SSH_PRIVATE_KEY}" | tr -d '\r' | ssh-add - > /dev/null
      - mkdir -p ~/.ssh
      - chmod 700 ~/.ssh
      - '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
      - git checkout $CI_BUILD_REF_NAME
      - git remote set-url origin "git@gitlab.xxx.com:$CI_PROJECT_PATH.git" # 替换成自己的 GitLab 地址
      - git config --global user.name "${CI_USERNAME}"
      - git config --global user.email "${CI_EMAIL}"
      - git pull origin $CI_BUILD_REF_NAME
      - yarn install


      build:
      stage: build
      tags:
      - docker_node
      script:
      - echo "Start building App"
      - yarn config list
      - yarn install
      - yarn build
      - echo "Build successfully!"
      - zip -q -r ./dist/notice.zip ./dist/notice


      cache:
      paths:
      - node_modules/
      - dist/

      deploy_development:
      stage: deploy
      tags:
      - docker_node
      script:
      - echo "Deploying to dev server"
      - scp -r $SOURCE_PATH $REMOTE_ADDRESS
      - echo "Deployed"
      environment:
      name: production
      only:
      - dev

      release:
      stage: release
      only:
      refs:
      - master
      tags:
      - docker_node
      script:
      - DEBUG="release-it:*" GITLAB_TOKEN="$GITLAB_TOKEN" yarn run release --ci --verbose

产出

  1. package.json 版本变化
  2. Tags 打标签
  3. Releases 打包后的二进制文件
  4. CHANGELOG.md 生成的变化日志

总结

其中的每个点来说都不难,但是整合跟调试的过程中,有很多错误,刚开始只有个简单的报错,根本不知道为什么会这样,这里学会了使用 DBUG 日志,能够帮助你来定位错误,同时有的文档里面没有描写的,看源码的调用使用也能够解决 一部分问题。在 issues 中看别人提的问题,也能解决一些问题,最重要的是看官方给的文档,能够解决更多的问题。

总而言之,遇到问题,想办法去解决,但是需要精准的定位问题,才可以。

参考文章

Install Docker Engine on CentOS
Registering runners
push 时跳过 ci 执行
Automate versioning and changelog with release-it on GitLab CI/CD
Run GitLab Runner in a container

-------------------本文结束 感谢您的阅读-------------------
坚持原创技术分享,您的支持将鼓励我继续创作!