使用 Jenkins 优化团队开发流程

个人简介

hustlzp

个人博客: hustlzp.com

GitHub: github.com/hustlzp

概要

真实的需求

曾经加入一个学生创业公司,主要做 Python Web 开发,使用 Git 管理代码。

反复遇到过的问题

人总是会失误的,如何尽量避免这种人为失误?

真实的需求

思考:能否将测试/部署等 「容易遗漏的、重复性的、枯燥的」 过程,交给机器自动完成?

这样做的好处:

Jenkins 简介

市场占有率最高(70%)的自动化持续集成工具。

Jenkins 安装和启动

针对 Windows、Ubuntu、CentOS 等数 10 种操作系统都提供了原生安装包。

CentOS 6.5

yum install jenkins
service jenkins start

使用 Docker

docker run -d -p 8080:8080 -t zaiste/jenkins

启动后,Jenkins 会运行在 8080 端口,可通过浏览器访问。

案例:使用 Jenkins 优化 Python Web 项目的开发、测试、部署流程

后台技术栈

部署在阿里云上的 2 台服务器

Jenkins Job 规划

Job: Jenkins 中的核心概念,表示一种抽象的任务。

根据我们的项目需要,设计如下三个job:

基于 Jenkins 的工作流简介

  1. 开发新功能时,需新建特性分支,开发完毕后合并到 master,并自动触发 tm_test 任务
  2. tm_test 若运行通过,则自动触发 tm_staging_deploy 任务,否则发送邮件报警
  3. 人工登陆运行在 staging 服务器上的网站,检查是否达到预期效果
  4. 若达到预期效果,手动触发 tm_production_deploy 任务
  5. 人工登陆运行在 production 服务器上的网站,检查是否达到预期效果

tm_test

流程图:

tm_test / 设置触发条件

需要达到的效果:每当开发成员向 master push 代码时,自动触发 tm_test 任务。

如何实现:

结合上述 2 点,因此只需要在 Git 服务器上配置好 Webhook 即可:

tm_test / 准备测试环境(示例)

在 tm_test 中添加 Execute shell 项,输入:

# 创建隔离的 Python 运行环境
if [ ! -d "venv" ]; then
  virtualenv -p /usr/bin/python2.7 venv
fi

# 安装项目依赖的第三方库
. venv/bin/activate
pip install -r requirements.txt

tm_test / 执行单元测试

在 tm_test 中添加 Execute shell 项,输入:

nosetests --with-xunit --with-coverage --cover-package=tm && coverage xml

tm_test / 代码质量检测

使用 Pylint 检测 Python 代码质量:

pylint tm2 > pylint.xml || exit 0

使用 JSHint 检测 JavaScript 代码质量:

jshint --reporter=jslint $WORKSPACE/tm2/static/js/ > jslint.xml || exit 0

等等...

tm_test / 检测 TODO 等特殊标记

一些人的习惯:写代码的时候,如果某个功能有待日后完善/重构,可以加一个 TODO 注释进行标记:

# TODO: need to filter the recommend teachers
recommend_teachers = Teacher.query.limit(10)

可以借助 Task Scanner Plugin 插件,实现对特殊标记的检测:

tm_test / 测试覆盖率报告

使用 Cobertura Plugin 插件来生成测试覆盖率报告:

单个文件的详细报告:

tm_test / 代码质量检测报告

使用 Violations 插件来生成代码质量报告。

支持 pylint、jshint、csslint、cpplint 等诸多代码质量检测工具。

tm_test / 邮件告警

Jenkins 支持构建失败时发送邮件进行告警,下面为 SMTP 配置界面:

Tips:将 qq 邮箱绑定到手机(13588888888@qq.com),即可实现短信报警通知。

tm_test / 触发下游 job

使用 Parameterized Trigger Plugin 插件触发其他 job。

上面的配置表示:当 tm_test 构建成功时,自动触发 tm_staging_deploy 任务。

tm_staging_deploy

流程图:

需要 SSH plugin 插件实现远程登录。

tm_staging_deploy / 部署代码示例

cd /var/www/tm
export MODE=PRODUCTION           # 设置环境变量
git reset --hard HEAD
git pull -f                      # 更新代码
source venv/bin/activate
pip install -r requirements.txt  # 安装依赖项
python manage.py db upgrade      # 执行数据库upgrade
supervisorctl restart tm         # 重启app

tm_production_deploy

流程图:

Jenkins 配置文件备份

Jenkins 的配置是一项较为费时的过程。

需要对 Jenkins 的配置文件(xml)进行备份,以便出现意外后恢复。

使用 ThinBackup 插件实现备份。

Jenkins 配置变更记录

为什么要记录 Jenkins 配置的变更?

举例:某天 A 对 Jenkins 配置进行了更新。第二天 Jenkins 服务器出现错误,A 着手解决,但是他忘记了到底对配置做了哪些更改,找了很久都没有发现错误所在。

思考:如果能够知道 Jenkins 配置文件的变更历史,对于 debug 有非常大的帮助。

→ 使用 SCM Sync configuration plugin 插件记录 Jenkins 配置文件的变更历史。

原理:每次更新 Jenkins 配置,都会 push 一个 commit 到单独的 Git 仓库。

结语

对于互联网团队来说,不仅要关注用户体验(对外),也要关注工作体验(对内)。

不仅保证业务的交付(结果),也要注重开发流程的持续改进(过程)。

不断优化开发流程 = 不断提升产品的交付速度和质量 + 不断提升员工的工作体验。

→ 程序员和公司的一种 双赢

使用到的 Jenkins 插件清单

多多指教,多多交流!

Thanks for your time!

/