高效研发之——工具篇(4):Jenkins

持续集成

关于持续集成

持续集成(简称CI, Continuous integration)是一种软件开发实践,是敏捷软件开发工作当中的一大组成部分。如果项目开发的规模比较小,比如一个人的项目,如果它对外部系统的依赖很小,那么软件集成不是问题,但是随着软件项目复杂度的增加(即使增加一个人),就会对集成和确保软件组件能够在一起工作提出了更多的要求-要早集成,常集成。早集成,频繁的集成帮助项目在早期发现项目风险和质量问题,如果到后期才发现这些问题,解决问题代价很大,很有可能导致项目延期或者项目失败。


每次集成都通过自动化的构建(包括编译,发布,自动化测试)来验证,从而尽快地发现集成错误。


关于持续集成的更多说明,可参考阮一峰的博客(http://www.ruanyifeng.com/blog/2015/09/continuous-integration.html)


下面笔者主要介绍Jenkins在项目开发中的实践。

Jenkins



Jenkins

Jenkins是一个开源的持续集成工具,应用Jenkins搭建持续集成环境,可以进行自动构建、自动编译和部署,非常方便。

其基本工作流为:(1). 从SCM拉取代码;(2). 执行编译前操作;(3). 执行编译;(4). 执行编译后操作。

基础规划

构建策略

一个建议的构建策略是:

  1. 研发人员每次提交代码到主干,Jenkins自动执行构建任务(一个构建任务可以自定义包括编译、测试、发布等其中的一个或多个,可根据自己团队习惯调整),编译出开发环境的版本,并自动发布到开发环境。

  2. 项目经理在本轮迭代结束时创建版本分支,版本转测试,测试人员执行相关版本的构建任务,编译出测试环境的版本。

  3. 对测试成功的版本,构建出可发布的正式版本。

多版本配置

这里有个小技巧,如果是使用Maven做项目管理工具,能使同一套代码构建出开发环境、测试环境和生产环境的项目包,即将开发环境、测试环境、生产环境的项目配置文件分目录置于resources目录下(具体说明敬请期待后续Maven工具介绍),在Maven的pom.xml中配置profile指定编译时的配置文件路径,编译时带相应参数即可生成相应的版本包。其他如ant等项目管理工具也可以尝试,笔者没实际操作过。

Maven项目多版本的pom配置

Maven的pom多版本配置

源代码目录结构

基于上一篇《高效研发之——工具篇(3):SVN》的代码版本结构配置,即:

主干:svn/{productName}/trunk/{projectName}/pom.xml

分支:svn/{productName}/branches/{branchName}/{projectName}/pom.xml

主干不稳定,研发人员基于主干trunk开发,每天提交本地单元测试通过的更新代码,要提测时拉取一个测试分支,测试人员基于此分支进行集成测试,开发人员继续在主干上开发;分支测试的bug直接提在此分支上修正,bug收敛到可发布状态即形成正式版本。

版本包归档目录结构

开发版本:因为每次commit代码都会产生构建生成一个版本包,当项目比较大时,需要较多存储空间,建议不归档

测试版本:ftp/QA/{productName}/{branchName}/{projectName}/

生产版本:ftp/pub/release/{productName}/{versionName}

其中ftp指我们内部ftp的路径。

版本包的FTP路径


Jenkins任务(Job)规划

Jenkins最佳实践(本文后附)建议“为不同的branch建立不同的job,build来尽早地发现错误。”,基于上述构建策略,我们需要为每个项目创建3个Job,即:开发版本Job,测试版本Job和生产版本Job,这3个Job的配置的不同点有:

  • 源代码路径:

    开发版本Job:svn/{productName}/trunk/{projectName}/

    测试版本Job:svn/{productName}/branches/{branchName}/{projectName}/

    生产版本Job:svn/{productName}/branches/{branchName}/{projectName}/

  • 构建触发条件:

    开发版本Job:代码库变化构建(即项目对应的目录代码有更新即自动触发构建)

    测试版本Job:手动构建

    生产版本Job:手动构建

  • 编译命令参数:

    假设开发版本、测试版本和生产版本在Maven的pom.xml中相应profile的id分别是DEV, TEST, PROD,则

    开发版本Job:编译命令后带参数-P DEV

    测试版本Job:编译命令后带参数-P TEST

    生产版本Job:编译命令后带参数-P PROD

  • 生成包处理方式:

    开发版本Job:自动部署到开发环境的服务器

    测试版本Job:自动部署到测试环境的服务器

    生产版本Job:归档到版本发布库后通过发布工具发布 或 自动部署到生产环境的服务器(不推荐)

Jenkins任务配置

Jenkins的详细操作指导,建议参考官方文档(https://jenkins.io/doc/)

1. 任务效果图

下图是笔者团队的一个产品的项目配置最终效果图

Jenkins的Jobs列表视图

2. 配置项目通用信息选项

这里要注意如果Jenkins服务器硬盘较小而项目又多的话,调小点“保持构建的天数”和“保持构建的最大个数”

项目通用信息

3. 配置源码管理选项

根据自己团队配置库情况进行设置。开发版本的任务中建议check-out strategy设置为Use 'svn update' as much as possible,测试版本、特别是生产版本,建议设置为强制全量拉取(Always check-out a fresh copy)。

源代码管理设置

4. 设置构建触发器选项

构建触发器是Jenkins启动一个Job构建的条件,当条件满足时,Job启动。可以设置为开发人员commit后自动编译(比如5分钟update一次svn,如果有提交则执行构建),或定时构建(比如每天晚上0点定时构建)

构建触发器

5. 设置编译选项

Jenkins的插件非常丰富,在这里,我们使用了源代码静态分析插件checkstyle, findbugs和pmd,结果会以报告形式展示在Jenkins Portal上,非常实用方便。

编译选项

6. 设置自动部署选项

构建后,可以通过Deploy war/ear to a container直接将war包部署到环境,实现持续发布。

自动发布编译到容器

7. 设置邮件提醒和备份生成包选项

团队所有成员都应该有这种意识:持续集成构建失败是开发团队最严重的问题,所以一旦出现构建失败,应该立即发现,立即解决。Jenkins通过Editable Email Notification Templates插件,实现方便的构建邮件通知。

对于构建结果,建议对测试环境和生产环境的构建进行备份,开发环境的构建可以不必备份。

邮件提醒和包备份

8. 结束语

Jenkins是一款非常优秀的持续集成工具,扩展性非常好,且有很多好用的插件,好好利用可以大大提升研发效率和规范产品开发流程,特别是减少人为原因导致的发版失败。

引用一句不记得哪位名人说的话:任何要重复2次以上的动作而不做成自动化的,不是愚蠢就是人品有问题。(别拍我,我确定不是我说的^v^)



附:Jenkins最佳实践

(原文:https://wiki.jenkins.io/display/JENKINS/Jenkins+Best+Practices)

其实大部分对于其他的CI工具同样的适用:

* Jenkins的安全。对Jenkins的用户使用授权和访问控制。默认地Jenkins不执行任何的安全检查,这意味着任何人都可以访问Jenkins来配置Jenkins,修改job,和执行build。这对于在企业内部使用也许可以接受,但是存在很高的安全风险,例如其他人错误滴删除了job,错误地配置你的job在每分钟运行,启动太多的builds等。所以一般使用plugin来对Jenkins增加授权和访问控制。

* 有规律地对Jenkins的home目录的备份。

* 使用file fingerprinting来管理依赖关系。当在Jenkins上你的job依赖其他的job时,可以使用file fingerprinting来帮助定位依赖的版本信息。

* 最可靠的build是clean builds,clean builds意思是与build相关的所有的3rd party,build脚本,发布说明等都需要在Source code control。

* 与issue tracking系统紧密的集成,例如JIRA或bugzilla,从来减少对change log的修改。

* 与repository浏览工具紧密的集成,例如FishEye如果你使用Subversion作为source code管理工具。

* 总是配置job产生趋势报告和自动化测试,当你运行一个Java build。趋势报告帮助项目经理和开发人员快速地了解当前项目的进度和状态。

* 确保Jenkins的home目录拥有足够的空间。

* 在删除不使用的job前请先存档。

* 为不同的branch建立不同的job,build来尽早地发现错误。

* 为并行的项目builds分配不同的端口,来避免多个jobs同时启动时所遇到的冲突。

* 为不同的项目的开发人员建立email aliais,使得项目所有相关的人员都第一时间了解项目的状态。

* 增加额外的步骤来尽早地发现失败。例如log检查,微测试等。

* 对于经常的维护性的工作可以使用job来自动地完成,例如对磁盘的清除工作。

* 在build成功后对远代码Tag,label或baseline。

* 配置Jenkins bootstrapper来在build前更新工作目录。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 222,183评论 6 516
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,850评论 3 399
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 168,766评论 0 361
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,854评论 1 299
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,871评论 6 398
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,457评论 1 311
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,999评论 3 422
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,914评论 0 277
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,465评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,543评论 3 342
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,675评论 1 353
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,354评论 5 351
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 42,029评论 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,514评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,616评论 1 274
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 49,091评论 3 378
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,685评论 2 360

推荐阅读更多精彩内容