使用Jenkins对前端进行持续集成

onaug6th

背景

目前公司测试环境前端项目部署,是由测试人员负责手动操作。当需要更新测试环境版本时,测试同事需要手动操作以下过程。

  1. 连接打包服务器
  2. 打开svn管理工具,找到目标svn版本号并拉取项目
  3. 拉取项目后,打开命令行,下载依赖。
  4. 等待依赖下载结束后。敲下打包命令
  5. 等待构建结束,并将资源文件压缩成压缩包复制到桌面
  6. 链接部署服务器
  7. 找到需要部署的站点文件夹
  8. 粘贴至目标文件夹并解压

在项目多的时候,重复操作极大的浪费时间。如果遇到同一时间不同项目组打包项目,打包和部署服务器就要排队使用,测试人员只能在等待中浪费时间。为了解决这些问题,选择寻找合适的持续集成方案。来自动化完成重复的步骤。

我尝试过轻量的自动部署方案(walle,spug)。但由于两者对于Windows系统和svn支持太低。最后还是选择了老牌稳健的Jenkins。

我们利用Jenkins来自动化处理上述问题。(拉取代码,打包构建,将资源送往目标服务器)。让测试同事不再需要关心打包环节,并从这一繁琐的过程中解放出来,回到本应专注的测试程序工作环节上。

下载docker与Jenkins镜像

借助docker这个搭环境的神器来搭建Jenkins,首先安装docker

# 安装docker
yum install docker
# 启动docker
systemctl start docker
# 设置镜像源,加速下载镜像
vim etc/docker/daemon.json

{"registry-mirrors": ["http://hub-mirror.c.163.com"]}

# 服务重启
systemctl restart docker.service
# 安装docker Jenkins
docker pull jenkins/jenkins

# 建立Jenkins数据存储文件夹
mkdir /usr/jenkins

# 设置权限
chown -R 1000:1000 /usr/jenkins

# 启动Jenkins,映射到 9527 端口
docker run -itd --name jenkins -p 50000:50000 -p 9527:8080   --privileged=true -v   /usr/jenkins:/var/jenkins jenkins/jenkins

Jenkins初始化

成功启动容器后,访问Jenkins服务器IP地址加端口号,进行Jenkins初始化,初始化的管理员密码从日志中可以获取。

#查看容器ID
docker ps -a

#查看容器日志
docker logs 容器ID

选择推荐安装,等待安装后即可。

安装Jenkins插件

初始化完后。使用刚刚创建的账号登录Jenkins进入界面,需要安装几个插件来支持我们的业务。

在系统管理——插件管理中,安装以下三个插件。

  1. Subversion Plug-in(svn支持)
  2. Publish Over SSH(远程连接)
  3. NodeJS Plugin(前端资源构建)

插件配置

插件安装完后,需要对插件进行配置。

ssh插件配置

在系统管理——系统设置中,找到 publish over SSH。点击新增按钮,添加需要发布的远程机配置。

比如需要发布到开发环境的远程机,添加以下信息。

部署机器操作系统为windows,需要给部署机器安装ssh并开启服务,以支持ssh链接。

windows安装ssh

部分机器可能设置了防火墙,需要在防火墙给22端口添加出站入站规则。允许ssh连接。

node.js插件配置

在系统管理-全局工具配置中,找到 NodeJS

需要注意的是Node.js版本避免过高,选择开发稳定版本,能避免不少版本过高导致部署过程出现一些奇怪的问题。

插件配置完毕后,就能够新建构建任务了。

新建构建任务

任务类型选择自由风格软件项目。

任务信息

添加参数化构建过程,用于处理不同情况处理的构建。这边需要关注两个参数 env, svnUrl,对应着:构建及发布环境、构建的svn版本号。

env 在前端项目构建时,会当作变量传入。用于动态修改构建的项目环境类型。

svnUrl 为每次项目构建时,拉取代码的SVN地址。

svn仓库配置

由于是代码版本控制工具是SVN,需要选择 Subversion 选项,在 Repository URL 中填入变量 $svnUrl。代表构建时使用传入的地址参数。

同时还需要提供一个svn账号凭证,用于拉取SVN代码。

配置node.js打包前端项目

选择node.js进行构建。

在构建中,能够借助命令行给node.js环境来安装某些源工具,比如yarn、cnpm、nrm。后续可将安装源工具的命令去掉,直接执行安装依赖命令。

此处的命令负责打印常见信息,并执行构建命令。在构建结束后将 dist 文件夹的内容压缩成压缩包:"dist.tar.gz"

配置构建后操作

在前端资源打包完成后,我们需要将文件送到目标服务器。此处添加送往的目标服务器。

点击Add Server添加构建后需要将文件传送的目标服务器,并指定传送的文件名称dist.tar.gz,并编写传送后需要执行的命令。

Exec command 中的命令在不同的操作系统中是不一样的,当系统为unix系统时,执行的为unix命令。当为windows系统时,执行的为批处理命令。

Exec command 中的 superDeploy.bat 为目标服务器预留的批处理文件,负责将文件解压缩,送往部署目录的处理。

完成以上配置后,保存此任务。

在远程机器添加批处理文件

当配置的目标机器为windows系统时,文件会被送到配置远程链接的账户所属用户文件夹下。在传输完毕后,预留的 superDeploy.bat 文件会被执行。

superDeploy.bat 接收两个参数,当前构建的环境,和构建后文件传送的路径。

批处理文件负责复制压缩包到目标文件夹,在目标文件夹解压缩等操作。

这里通过命令行来调用 7z 的解压缩功能,需要给部署机安装 7z解压软件。也能更换为其他解压缩软件。

7z官方中文站

开始第一次构建

完成配置后,点击 Build with Parameters 开始构建,构建前需要填写构建参数。

此时会按照SVN项目地址拉取代码,构建前端资源时,会执行npm run build:${传入的环境参数} 命令。对应的为前端项目 package.json 中各环境的打包命令。

{
    "scripts": {
        "build:dev": "vue-cli-service build --mode=dev",
        "build:test": "vue-cli-service build --mode=test",
        "build:prod": "vue-cli-service build --mode=prod"
    }
}

此处利用了 vue-cli3.0 提供的构建命令和环境变量文件,来提供各环境的打包命令。前端项目需要配置多种打包命令,来支持Jenkins的动态环境构建。

前端项目添加多环境打包命令

一切就绪,点击开始构建。Jenkins就会按照SVN地址拉取代码,并且执行构建命令,在构建完成后将dist文件夹压缩成压缩包,送到目标服务器并且执行预留在目标服务器的批处理文件。批处理文件将压缩包移动到执行的目标目录,处理解压缩的动作。一个自动构建和部署的过程就完成了。

实际构建时间需要40秒~70秒,但对于手工操作来说要强太多了。

踩过的坑

  1. 文件传送的用户目录名称不一样

在某些电脑上出现,登录的用户名为 user,但实际传输到目标的文件夹为 user.iZjenfhextasd 这样的文件夹。需要注意脚本的正确存放位置。

  1. cnpm安装依赖偶尔超时

需要修改Jenkins镜像中安装的cnpm源码文件的超时时间配置。

docker cp jenkins:/var/jenkins_home/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/Node_JS_12.18.4/lib/node_modules/cnpm/node_modules/urllib/lib/urllib.js /usr/jenkins/

#修改文件中的内容

docker cp /usr/jenkins/urllib.js jenkins:/tmp/

docker exec -u root -it jenkins /bin/bash

mv /tmp/urllib.js /var/jenkins_home/tools/jenkins.plugins.nodejs.tools.NodeJSInstallation/Node_JS_12.18.4/lib/node_modules/cnpm/node_modules/urllib/lib/urllib.js

或者能更换为其他依赖下载命令,比如yarn。

  1. 部署机网络或性能问题,偶尔无法连接

保证部署机能够正常运行,不爆满内存与CPU使用。

  1. ssh连接失败

检查openSSH服务是否启用,或者防火墙是否禁用了22端口的出入。

  1. 依赖更新问题

Jenkins首次安装依赖会根据项目中锁定版本号的文件进行依赖版本安装(package-lock.json,yarn-lock),安装过后 node_modules 文件夹会存留。如需要更新特定依赖版本,需要手动修改 package.json 中的版本号并重新提交构建,或者选择任务中的 “清空工作区选项”。

写在最后的碎碎念

在公司没有运维的情况下。一开始只是抱着尝试的心理来探索持续集成的方案,在尝试了 walle/spug 这样的轻量部署方案均失败后曾打算放弃。但听到测试同事的一句吐槽:“自动部署说了三年了,都没有做出来”。于是下定决心一定要将这个目标完成。

我始终坚信着,如果某件事情迟迟完成不了,那它应该是在等待某个人来完成。我就要尝试来成为这个人。

于是开始不断收集资料,查阅文档,从零开始搭建。windows与svn总有大量奇奇怪怪的问题,在搭建的过程频频受阻。好不容易搭建好了,依赖却安装不了了,障碍一个接一个。

在连续失败了95次之后,第96次终于成功将所有的流程走通。成功的喜悦无以言表,差点就激动得在座位上跳了起来。

就这样,测试同事的生产力得到了解放。不再需要为打包的事情苦恼,一切都变得这么简单。

感谢TL一直的信任和支持,在我提出有这样的想法时,不断的帮我争取借用到各个生产服务器环境的权限。也让我领悟到,只有不断跳出固定领域。不断挑战自己不熟悉的内容,自身的能力才有更大的提升。

希望这篇文章能够帮到你,have a nice day :)

阅读 2k
61 声望
4 粉丝
0 条评论
你知道吗?

61 声望
4 粉丝
宣传栏