CI/CD原理、yaml语法、.gitlab-ci.yml配置、runner流程等文章也许你已经看了不少,但是还没实际操作过的同学相信也很多。下面带你实际操作一把CI/CD,串一串学过的知识点。
什么是CI/CD
通俗来说就是启动一个服务,能够监听代码变化,然后自动执行打包,发布等流程;
拿最简单的静态页项目部署流程举例:首先需要手动npm run build
后,再将dist
文件夹通过工具上传到服务器的某个目录下,再启动配置好的nginx
等服务器程序;有时为了调试,不得不频繁发布测试......
"懒是促进技术进步的原动力"
如果我们修改代码后,能够自动完成后续的那一堆任务那该多好,CI/CD的概念发展了起来。
可见要实现自动化,我们最起码需要两个关键步骤:
-
监听代码变化;
-
执行后续的各种任务;
而gitlab为我们提供了现成的工具gitlab-runner
,能够帮助我们实现上面所述的步骤;我们只需要按照官方说明,在自己的服务器上 安装gitlab-runner
,并在项目仓库里注册其相应的信息即可。
gitlab-runner的主要作用
-
监听来自gitlab的各种消息(如:代码
push
); -
执行
.gitlab-ci.yml
文件(GitLab CI/CD的配置文件)中的任务;
如何自动化构建、自动化测试、自动化部署?那都是.gitlab-ci.yml
中的Job
,后面会介绍。
也就是说,自动化流程都可以通过.gitlab-ci.yml
中的Job
的Shell
指令来实现。下面进入正题,我们先来搭建CI/CD所需的环境。
搭建gitlab CI/CD
1. 创建gitlab仓库
首先创建一个gitlab仓库(本示例里叫做testCI,是用vue-cli
创建的一个朴实无华的项目)。进入项目后看到界面如下:
打开左侧菜单Settings > CI/CD
项,可以看到Runners
项,点击右侧按钮Expand
:
gitlab CI/CD需要我们自己的服务端 启动
gitlab-runner
,而gitlab-runner
启动后得到的服务进程就叫做Runner
;每个gitlab项目都可以绑定多个Runner
。
下面创建Runner
的索引,用来关联当前项目仓库与后面的 **Runner**
进程
2. 创建Runner索引
这里我们点击New project runner
按钮去新建一个Runner
索引,界面入下:
然后按照以下步骤操作:
-
选择
Runner
服务器的操作系统 -
创建
Runner
的tags
,也可以勾选Run unstagged jobs
(用途后面讲解); -
点击创建按钮
Create runner
进入Runner注册指令页面:
到这里,需要在gitlab完成的操作已经结束,下面开始服务器端的配置流程。
对于只想试试看的同学可以在自己电脑上进行下面的操作,也就是把自己的电脑作为服务器。
3. 创建Runner服务
正如开头我们介绍过,我们的服务器要监听gitlab的push
消息就需要安装gitlab-runner
软件,启动后就创建了Runner
服务。
可根据上图所示的官方链接,查看安装指令;下面是macOs
系统的安装步骤。
- 按照上图所示的指令安装
gitlab-runner
;含义如下所示:
bash
# 1. 打开终端应用程序,并使用管理员权限(sudo)运行以下命令,将GitLab Runner的二进制文件下载到/usr/local/bin/gitlab-runner
sudo curl --output /usr/local/bin/gitlab-runner https://gitlab-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-runner-darwin-amd64
# 2. 给二进制文件执行权限,以允许它运行
sudo chmod +x /usr/local/bin/gitlab-runner
# 3. 切换到将运行Runner的用户的主目录。例如,使用以下命令切换到当前用户的主目录
cd ~
# 4. 运行以下命令来安装GitLab Runner:
gitlab-runner install
# 5. 启动Runner
gitlab-runner start
当这5步执行完毕后,终端输入gitlab-runner status
查看gitlab-runner
运行状况:
Runner
服务启动成功。
- 执行
Step1
指令进行注册:
arduino
gitlab-runner register --url https://gitlab.com --token glrt-jDV81_Ex5pRFxxQhyqi9
该指令用于将当前的
Runner
注册到gitlab并与我们的前面创建的Runner
索引信息绑定在一起。
输入该指令后会有3步交互式输入:
a. 设置gitlab地址;直接点击回车即可。
b. 设置Runner
的名字;随便写,这里是test-ci
c. 设置Runner
的执行器类型;这里选择shell
类型。
最终效果如下图所示,这就完成了Step2
:
- 执行
Step3
指令:gitlab-runner run
,可以看到终端显示如下:
到这里,gitlab CI所需的环境算是搭建完成了!
回到gitlab开始的CI/CD页面,就可以看到新建的Runner
服务可以使用了。
4. 编写.gitlab-ci.yml文件(后续补一篇配置项解析文章)
Runner
会读取项目根目录下的.gitlab-ci.yml
文件,执行其中的任务,我们在项目根目录下添加.gitlab-ci.yml
文件:
内容如下:
bash
stages:
- dev
- test
测试dev:
stage: dev
tags:
- test
script:
- npm i
- npm run dev
测试test:
stage: test
tags:
- test
script:
- echo "Running test..."
这里规定了两个任务阶段:dev
与test
,同时创建了两个Job
:测试dev
与测试test
,并将测试dev
挂载在了dev
阶段,将测试test
挂载在了test
阶段;
这两个Job要注意tags需要与gitlab上创建的Runner索引的tags相同,不然不会执行!
5. push代码试一下
将代码修改push
到git仓库,就能看到Runner
终端有反馈了!同时可以看一下gitlab仓库的Pipelines
页面:
可以看到dev
阶段正在执行中(上图所示的"状态图标"为"进行中")。
如果任务一直处于等待状态,可能是gitlab访问不到本地Runner服务的IP地址,或者网络有问题,如图:
可以点击"状态图标"看下日志页面:
发现npm run dev
熟悉的输出,可以在服务端(这里是本地开发环境)打开该链接看一下:
最终,我们成功利用gitlab CI
的能力,运行了本地的npm run dev
命令......
总结
到这里,其实主要目的已经达到了:
-
我们成功搭建了gitlab CI/CD所需的环境;
-
实现了服务端监听git的
push
行为; -
服务端
Runner
执行了.gitlab-ci.yml
文件上的Job
。
若要实现更复杂的流程,只需要完善.gitlab-ci.yml
文件中的配置。
后续改进
上面我们搭建了gitlab CI/CD所需的环境,并成功执行了本地的npm run dev
。由于npm run dev
指令是持续性的任务,导致测试dev
是无法完成的Job
,进而导致dev
阶段一直处于运行状态,而test
阶段无法开始;我们修改下配置(npm run dev
-> npm run build
):
bash
stages:
- dev
- test
测试dev:
stage: dev
tags:
- test
script:
- npm i
- npm run build # 这里换成build
- pwd # 打印当前路径
- ls # 打印当前目录下的文件列表
测试test:
stage: test
tags:
- test
script:
- echo "Running test..."
最终运行结果如图:
全部Job
顺利执行完毕:
这样我们就完成了基本的CI/CD流程的创建,如果还需要deploy、test等后续功能,只需要继续完善.gitlab-ci.yml
文件,例如:通过shell
命令将dist
移动到想要的位置,启动nginx
等;或者通过执行*.sh
文件来完成更复杂的操作。
结束
gitlab CI/CD大致的工作流程:
-
我们将修改的代码
push
到gitlab仓库; -
gitlab将
push
消息发送到我们的服务器,服务器Runner
接收到消息; -
服务器
Runner
将仓库代码pull
下来,按照.gitlab-ci.yml
文件执行Job
; -
服务器
Runner
将构建信息(例如测试报告,终端输出等)上传到 GitLab 。 -
GitLab 服务器根据
Runner
执行结果,更新项目的 CI/CD 状态和日志,并通知相关的用户或团队。
6.如果.gitlab-ci.yml
文件不增加其他配置(如:artifacts
字段等),Runner
将在执行完Job
后清理构建产物(如dist
文件夹);
通过上面的演示,我们完成了一个前端项目最基本的gitlab CI/CD流程,功能很简单,但是相信没上手实践过的同学对其基本原理与流程能有一定的了解,今后在看相关文章时也能有一个基本的概念。