一个完整的生产环境的 CI/CD 流程,往往会包括以下这些阶段:
编码 → 提交 → 构建 → 测试 → 交付 → 部署
这里只是演示,就省略了测试相关阶段,只包含提交、构建、发布、部署,一个简单的流程如下:
vue 应用构建依赖于 Nodejs,需要在 Jenkins 上安装 Nodejs 插件,并且进行一些配置。
点击系统管理,进入插件管理页面
点击可选插件,搜索 nodejs 进行安装
安装完成之后,进入全局工具配置页面,对 nodejs 插件进行配置,选择你需要的版本并配置别名:
发布到远程服务,需要用到 publish over ssh
插件,也需要先安装并且进行配置。和上面一样在插件管理搜索安装,之后需要系统配置中进行配置。
这里需要新增 SSH Server,就像平常通过 ssh 连接远程服务器一样,需要填写名称、远程机器 ip,远程机器登录账号,其中的远程机器目录可以填写,这个路径必须在远程机器中已存在,不存在不会自动创建,填写之后后面传输文件时,文件的路径就相对于这个路径,否则就相对于账号的家目录。
之后,通过高级选项配置登录密码或者密钥:
这里填入密码,或者填写 ssh 连接生成的密钥,就和平常通过 ssh 免密登录远程机器一样。填写完成之后,在最下面可以进行连接测试,连接测试成功这个配置就是可用的了。
Jenkins 自动化流程构建可以用多种形式,这里演示最基本的两种,分别是自由风格项目和流水线模式。
在工作台页面点击新建任务
新建一个自由风格项目
点击确定之后,进入任务配置。
(1)scm 配置
在源码管理这里,选择 Git,填写 Git 仓库地址。如果出现以下提示,是 Git 插件存在问题,查看一下全局配置,在机器上安装 Git,之后对 Git 插件进行一下配置即可。
这里是我在前面文章中搭建起来的 GitLab 上创建的一个仓库
将 Git 仓库地址填入,就像平常拉取 GitLab 中的代码一样需要登录凭证,这里也需要创建登录信息
创建一个 Git 登录凭证,并选择使用,Git 仓库不再有错误提示即已连接成功。下方的分支更改为 publish 分支,这是为了通过分支的合并触发自动构建。
(2)触发机制
在构建触发器这里,选择轮询,H/15 * * * * 表示每15分钟轮询一次,轮询会监测 Git 仓库相应分支的 Head,如果对比上次有变化,就会触发构建。可以点击问号,查看相应选项的帮助文档。
(3)构建
由于这里是构建 vue 应用,之前也提前安装了 nodejs 插件,在构建环境中,选中 node 和 npm,并且选择配置好的 nodejs 版本。
之后,在构建中选择构建步骤,选择执行 shell
在输入框中输入构建集成发布的脚本
node -v
npm -v
cd ./hello-world
npm install
npm run build
zip -r $WORKSPACE/publish.zip ./dist
脚本比较简单,就是前端应用发布的基本脚本。
要注意的一点是,如果使用了私服 npm 包,使用 npm install --registry="指定包源"
进行依赖包还原
$WORKSPACE
是 Jenkins 中的环境变量,指向当前构建的根目录,即当前git仓库的更目录。可用的环境变量可以通过构建配置页面中的链接进行查看。
(4)远程发布
如过需要进行远程发布,即把构建发布好的应用传输到其他服务器上,就要使用 publish over ssh
插件了,前面我已经配置好了远程服务器,这里在上一步的脚本构建之后再增加一个构建步骤
填写好相应的文件路径配置,注意各个路径都是相对路径,及各自所相关的路径是哪一个,这里若弄不清楚,可以各种情况尝试一下看下结果,自然就清晰了。
之后,编写文件传输后在远程服务器上执行的脚本,文件传输到远程服务器之后,往往还有很多操作,如解压、备份等,这里需要一定的 shell 基础。
#! /bin/sh
datename=$(date +%Y%m%d%H%M%S)
echo "开始备份"
if [ -d "/home/website/publish/" ];then
zip -r "/home/website/backup/publish-$datename.zip" /home/website/publish
rm -rf /home/website/publish
fi
echo "备份结束"
echo "开始部署"
if [ -d "/home/temp/publish/" ];then
rm -rf /home/temp/dist
fi
cd /home/temp
unzip ./publish.zip
mv /home/temp/dist /home/website/publish
rm -rf /home/temp/dist
echo "部署结束"
可以在上方的高级设置中设置一下跟踪远程脚本,这样就可以看到我们的脚本在远程服务的执行情况,方便发现部署过程中的错误
也可以设置一下远程连接超时时间,避免脚本执行较久时 ssh 连接断开,导致部署失败。默认时120000毫秒,设置为0即不限时间。
配置完成之后,返回项目,点击开始构建
之后点击下方的构建记录,在控制台输出可以看到构建过程
登录远程服务器,可以看到发布之后的文件
之后通过 nginx 反向代理到 publish 文件夹,前端就可以正常访问了,后续的开发代码提交之后,只要合并到 publish 分支,Jenkins 会根据设置的轮询间隔监测分支的变动,自动进行构建发布备份等操作。当然你也可以设置监测 master 分支,根据 post-commit 触发构建,这样每次有代码提交,都会触发构建。
Pipeline 是 Jenkins 的一套插件,有特定的语法,比起自由风格项目,更能将软件发布的各个阶段规范化,更加清晰地定义构建发布的各个阶段。更加详细的介绍可参考官方文档:管道 (jenkins.io)
Pipeline 的定义写在一个 Jenkinsfile 文件,这个文件可以直接在 Jenkins 项目配置页面中编写,也可以包含在项目代码库中,官方更加推荐写在项目代码库,加入到版本控制中。
下面将刚才的自由风格项目改造为 pipeline 流水线项目:
新建一个项目,这次选择 pipeline 类型
一样配置构建触发器
之后在下方的流水线配置中进行构造 jenkinsfile 编写
pipeline {
agent any
environment {
def BUILDVERSION = sh(script: "echo `date +%Y%m%d%H%M%S`", returnStdout: true).trim()
}
stages {
stage('环境验证') {
steps {
nodejs('nodejs-14.16.1') {
sh 'node -v'
sh 'npm -v'
}
}
}
stage('拉取源码') {
steps {
echo '开始拉取代码'
git branch: 'publish', credentialsId: '260b288d-5229-4ee9-b2eb-73f1cde84c77', url: 'http://xxx.xxx.xxx.xxxx:8929/gitlab-instance-08a71c21/vue-test.git'
echo '拉取代码完成'
}
}
stage('还原项目') {
steps {
dir('./hello-world') {
echo '开始还原项目'
nodejs('nodejs-14.16.1') {
sh 'npm install'
}
echo '还原项目结束'
}
}
}
stage('生成项目') {
steps{
dir('./hello-world') {
echo '删除上次生成结果文件夹'
sh 'rm -rf ./dist'
echo '开始生成项目'
nodejs('nodejs-14.16.1') {
sh 'npm run build'
}
echo '生成项目结束'
}
}
}
stage('部署项目') {
steps{
dir('./hello-world') {
echo '开始部署'
sh 'pwd'
sh "zip -r $WORKSPACE/publish-${BUILDVERSION}.zip ./dist"
sshPublisher(
publishers: [
sshPublisherDesc(
configName: 'test',
transfers: [
sshTransfer(
cleanRemote: false,
excludes: '',
execCommand: """
#! /bin/sh
echo "开始备份"
if [ -d "/home/website/publish/" ];then
zip -r "/home/website/backup/publish-${BUILDVERSION}.zip" /home/website/publish
rm -rf /home/website/publish
fi
echo "备份结束"
echo "开始部署"
if [ -d "/home/temp/publish/" ];then
rm -rf /home/temp/dist
fi
cd /home/temp
unzip ./publish.zip
mv /home/temp/dist /home/website/publish
rm -rf /home/temp/dist
echo "部署结束"
""",
execTimeout: 0,
verbose: true,
flatten: false,
makeEmptyDirs: false,
noDefaultExcludes: false,
patternSeparator: '[, ]+',
remoteDirectory: "/temp",
remoteDirectorySDF: false,
removePrefix: "",
sourceFiles: "publish.zip"
)
],
usePromotionTimestamp: false,
useWorkspaceInPromotion: false,
verbose: true
)
]
)
echo '部署结束'
}
}
}
}
}
这里的 pipeline 表示一个工作空间,jenkins 根据这个关键字分配一个工作空间进行构建工作的执行。一个 stage 代表一个构建阶段,各个构建阶段相互是独立的,可以通过定义全局变量等进行一些全局配置,如这里的 BUILDVERSION
环境变量。
这里就不具体介绍 pipeline 语法了,详细的可以参考官方文档:使用 Jenkinsfile
也可以通过配置页面的流水线语法链接,调整到 Jenkins 的帮助文档,里面有一个代码片段生成器,可以帮助生成一些基本操作的代码,这里生成的代码一般不要更改,包括换行,直接拷到 jenkinsfile 中使用即可。
当然,这里的片段生成器不是万能的,很多插件的代码这里也生成不了,对于插件只要用到哪个了解哪个即可,jenkins 的插件很多,我们也没办法每个都了解。
配置完成之后,点击立即构建,可以看见每次构建的流水线管道,包括每一个阶段的执行情况
点击每一次的构建记录,通过控制台输出一样可以看到具体的构建过程输出
在远程服务器上,通过备份记录,也可以看到直接部署成功了
这里通过一个前端工程简单地介绍了以下 Jenkins 自动化流水线构建是怎么实现的,也是工作中实际应用的一个简化版本。下一篇将介绍以下怎么基于 Jenkins 搭建 .net core 应用的自动化构建流程。
上一篇:DevOps— CI/CD 工具 Jenkins
下一篇:DevOps—基于Jenkins构建.Net Core应用自动化流程