持续集成软件包括两个部分java
经过部署本身私有的Docker镜像registry,并创建本身的自动化构建,将Docker集成到持续集成工做流中。
除了持续集成和持续部署以外的自动化测试部分,只须要从Jenkins创建一个hook来启动自动化脚本并生成测试报告。
关于本节须要作到git
经过Jenkins系统的Job触发机制,咱们能够方便的建立各类类型的集成Job用例。但缺少统一标准的Job用例使用方法,会致使项目Job用例使用的混乱,难于管理维护。这也让开发团队没法充分利用好集成系统的优点,固然这也不是咱们指望的结果。因此,敏捷实践方法提出了一个能够持续交付的概念 DeploymentPipeline(管道部署)。经过Docker技术,咱们能够很方便的理解并实施这个方法。
Jenkins的管道部署把部署的流程形象化成为一个长长的管道,每间隔一小段会有一个节点,也就是Job,完成这个Job工做后才能够进入下一个环节。形式以下: 正则表达式
开发同窗经过git push上传代码,经Git和Jenkins配合,自动完成程序部署、发布,全程无需运维人员参与。
这是一种真正的容器级的实现,这个带来的好处,不只仅是效率的提高,更是一种变革:
难者不会,会者不难。经过简单的4个配置,便可优雅地实现持续部署。docker
在本例中,假设咱们JAVA项目的名称为hello。简要的技术思路以下。 数据库
本案例中假设代码托管在git.oschina.com上,Jenkins和Docker Registry(相似于yum源)各运行在一个Docker容器中。JAVA项目本身也单独运行在一个叫hello的容器中。
本文采起的持续部署方案,是从私有的Docker Reistry拉取代码。有些变通的方案,把代码放在宿主机上,让容器经过卷组映射来读取。这种方法不建议的缘由是,将代码拆分出容器,这违背了Docker的集装箱原则:
这也致使装卸复杂度增长。从货运工人角度考虑,总体才是最经济的。这样,也才能实现真正意义的容器级迁移。
或者说,容器时代,抛弃过去文件分发的思想,才是正途。本文最后的问答环节对此有更多阐述。
容器即进程。咱们采用上述方案作Docker持续部署的缘由和意义,也在于此。容器的生命周期,应该远远短于虚拟机,容器出现问题,应该是当即杀掉,而不是试图恢复。安全
本文最后实现的效果,究竟有多惊艳呢?且看以下的演示。服务器
咱们以时间戳来简洁、显式的表述程序更新状况。 网络
本例中,咱们把首页的时间戳从201506181750,修改成201506191410(见以下)。 app
顺序执行以下操做,输入正确的git帐号密码。 运维
而后呢?
而后什么都不用作了。端杯茶(若是不喜欢咖啡的话),静静地等待自动部署的发生, 旁观一系列被自动触发的过程,机器人似的运转起来(请容稍候再加以描述)。
为何须要3~5分钟?只是由于本案例中的JAVA项目,须要从国外download Maven程序包,以供Jenkins调用和编译JAVA。正式应用环境中,能够把Maven源放在国内或机房。若是仅仅须要对PHP项目作持续部署,那就更快捷了。
在静静地等待几分钟后,新的代码确实已经自动部署完毕。
那么,这一切怎么实现的呢?要按照以下几步,即可快速实现。
这个过程也是难者不会,会者不难。主要分为以下三步。
Jenkins中新建项目java-app,并配置从Git拉取程序代码。具体以下:
Jenkins中配置token,以供git远程调用时使用。
怎么让Git在接收到用户更新的代码后,把消息和任务传递给Jenkins呢?这借助于Git的hook功能,配置起来也很是简单,以下。
Jekins在接收到Git传递过来的消息后,再触发一个远程构建(到目标服务器),按照预约义的任务列表,执行一系列的工做,重建容器等。详见以下:
咱们把其中最关键的Shell脚本内容摘抄出来。
在2.3这个章节中,咱们当时的操做以下,这个目的是向Git提交更新代码。
当时并无细说后续发生的事情,既然上面已经说清楚了原理,那咱们就能够接下来讲说实际发生的事情啦。
这里貌似整个过程已经完成并顺利退出。其实,后台的工做才刚刚开始。
这时会触发Git服务器向相应的Jenkins服务器发出一个操做请求,此工做太过迅速,也没啥好说的,咱们接下来看Jenkins都干啥子了。
Jenkins会自动冒出来一个构建任务。
咱们点进来,看看具体操做日志。是的,正在接受来自Git的任务。
下载Maven相关的软件包(就是这个过程慢)。
下载完成后,就开始利用maven BUILD 新的hello项目包。
而后重建Maven容器,构建新的Image并Push到Docker私有库中。
最后,从新把Docker容器run起来。这样,又新生了。
问题1:采用这么相对复杂的办法(而不是把更新代码放在宿主机而后卷组映射),是由于项目基于JAVA么;是否PHP项目就能够采用更新代码放在宿主机而后卷组映射这种方式?
回答1:将代码拆分出容器,违背了集装箱原则。致使装卸复杂度增长。从货运工人角度考虑,总体才是最经济的。一切版本化。抛弃过去的文件分发。这是正途。至于文件大小,大的war包也就50M或100M,在现有网络下不成问题,性能问题最好优化。另外建议关注docker 2 docker,p2p传输。
问题2:若是总体代码超过500m或者1g以上,总体集装箱是否就不太好了?若是容器与代码分离,镜像就100m左右(2层,base+服务),而后代码的话,是放到共享存储里,每一个代码有更新,好比svn的代码,能够直接在共享存储里进行svn update就能够控制版本
回答2:若是你的代码500M,说明就须要精简了。
根据项目需求,现要在团队内部搭建一个统一的打包平台,实现对iOS和Android项目的打包。并且为了方便团队内部的测试包分发,但愿在打包完成后能生成一个二维码,体验用户(产品、运营、测试等人员)经过手机扫描二维码后就能直接安装测试包。
该需求具备必定的广泛性,基本上全部开发APP的团队均可能会用到,所以我将整个需求实现的过程整理后造成此文,而且真正地作到了零基础上手,到手即飞、开箱即用,但愿能对你们有所帮助。
首先,先给你们展现下平台建设完成后的总体效果: 该平台主要实现的功能有3点:
Jenkins依赖于Java运行环境,所以须要首先安装Java。
安装Jenkins的方式有多种,能够运行对应系统类型的安装包,能够经过docker获取镜像,也能够直接运行war包。
我我的倾向于直接运行war包的形式,只需下载jenkins.war后,运行以下命令便可启动Jenkins。
$ nohup java -jar jenkins_located_path/jenkins.war --httpPort=88 &
若是不指定httpPort,Jenkins的默认端口为8080。
Jenkins有很是多的插件,能够实现各类功能的扩展。
针对搭建的iOS/Android持续集成打包平台,我使用到了以下几个插件。
在Jenkins中,构建项目以Job的形式存在,所以须要针对每一个项目建立一个Job。有时候,一个项目中可能有多个分支同时在进行开发,为了分别进行构建,也能够针对每一个分支建立一个Job。
建立Job的方式有多种,本次只须要建立Freestyle project类型的便可。
Main page -> New Item -> Freestyle project
对于一个持续集成打包平台,每次打包都由4步组成:触发构建、拉取代码、执行构建、构建后处理。对应的,在每一个Job中也对应了这几项的配置。
要对项目进行构建,配置项目的代码仓库是必不可少的。因为当前咱们的项目托管在GitHub私有仓库中,所以在此须要对Git进行配置。
在【Source Code Management】配置栏目下,若是以前GIT plugin安装成功,则会出现Git选项。
配置Git代码仓库时,有三项是必须配置的:仓库URL地址(Repository URL)、仓库权限校验方式(Credentials),以及当前Job须要构建的代码分支(Branches to build)。
在配置Repository URL时,选择HTTPS URL或SSH URL都可。不过须要注意的是,Credentials要和Repository URL对应,也就是说:
代码仓库配置好了,意味着Jenkins具备了访问GitHub代码仓库的权限,能够成功地拉取代码。
那Jenkins何时执行构建呢?
这就须要配置构建触发策略,即构建触发器,配置项位于【Build Triggers】栏目。
触发器支持多种类型,经常使用的有:
触发策略配置好以后,Jenkins就会按照设定的策略自动执行构建。但如何执行构建操做,这还须要咱们经过配置构建方式来进行设定。
经常使用的构建方式是根据构建对象的具体类型,安装对应的插件,而后采用相应的构建方式。例如,如果构建Android应用,安装Gradle plugin以后,就能够选择Invoke Gradle script,而后采用Gradle进行构建;如果构建iOS应用,安装Xcode integration插件以后,就能够选择Xcode,而后选择Xcode进行构建。
该种方式的优点是操做简单,UI可视化,在场景不复杂的状况下能够快速知足需求。不过缺点就是依赖于插件已有的功能,若是场景较复杂时可能单个插件还没法知足需求,须要再安装其它插件。并且,有些插件可能还存在一些问题,例如对某些操做系统版本或XCode版本兼容不佳,出现问题时咱们就会比较被动。
我我的更倾向于另一种方式,就是本身编写打包脚本,在脚本中自定义实现全部的构建功能,而后在Execute Shell中执行。这种方式的灵活度更高,各类场景的构建需求都能知足,出现问题后也能自行快速修复。
另外,对于iOS应用的构建,还有一个须要额外关注的点,就是开发者证书的配置。
若是是采用Xcode integration插件进行构建,配置会比较复杂,须要在Jenkins中导入开发证书,并填写多个配置项。不过,若是是采用打包脚本进行构建的话,状况就会简单许多。只要在Jenkins所运行的计算机中安装好开发者证书,打包命令在Shell中能正常工做,那么在Jenkins中执行打包脚本也不会有什么问题。
完成构建后,生成的编译成果物(ipa/apk)会位于指定的目录中。可是,若是要直接在手机中安装ipa/apk文件还比较麻烦,不只在分发测试包时须要将好几十兆的安装包进行传送,体验用户在安装时也还须要经过数据线将手机与计算机进行链接,而后再使用PP助手或豌豆荚等工具进行安装。
当前比较优雅的一种方式是借助蒲公英(pgyer)或http://fir.im等平台,将ipa/apk文件上传至平台后由平台生成二维码,而后只须要对二维码连接进行分发,体验用户经过手机扫描二维码后便可实现快速安装,效率获得了极大的提高。
无论是蒲公英仍是http://fir.im,都有对应的Jenkins插件,安装插件后能够在Post-build中实现对安装包的上传。
除了使用Jenkins插件,http://fir.im还支持命令上传的方式,蒲公英还支持HTTP Post接口上传的方式。
我我的推荐采用命令或接口上传的方法,并在构建脚本中进行调用。灵活是一方面,更大的好处是若是上传失败后还能进行重试,这在网络环境不是很稳定的状况下极其必要。
Jenkins成功完成安装包上传后,pgyer/http://fir.im平台会生成一个二维码图片,并在响应中将图片的URL连接地址进行返回。
二维码图片的URL连接有了,那要怎样才能将二维码图片展现在Jenkins项目的历史构建列表中呢?
这里须要用到另一个插件,description setter plugin。安装该插件后,在【Post-build Actions】栏目中会多出description setter功能,能够实现构建完成后设置当次build的描述信息。这个描述信息不只会显示在build页面中,同时也会显示在历史构建列表中。
有了这个前提,要将二维码图片展现在历史构建列表中貌似就能够实现了,能直观想到的方式就是采用HTML的img标签,将写入到build描述信息中。
这个方法的思路是正确的,不过这么作之后并不会实现咱们预期的效果。
这是由于Jenkins出于安全的考虑,全部描述信息的Markup Formatter默认都是采用Plain text模式,在这种模式下是不会对build描述信息中的HTML编码进行解析的。
要改变也很容易,Manage Jenkins -> Configure Global Security,将Markup Formatter的设置更改成Safe HTML便可。
更改配置后,咱们就能够在build描述信息中采用HTML的img标签插入图片了。
另外还须要补充一个点。若是是使用蒲公英(pyger)平台,会发现每次上传安装包后返回的二维码图片是一个短连接,神奇的是这个短链接竟然是固定的(对同一个帐号而言)。这个短链接老是指向最近生成的二维码图片,可是对于二维码图片的惟一URL地址,平台并无在响应中进行返回。在这种状况下,咱们每次构建完成后保存二维码图片的URL连接就没有意义了。
应对的作法是,每次上传完安装包后,经过返回的二维码图片短连接将二维码图片下载并保存到本地,而后在build描述信息中引用该图片的Jenkins地址便可。
每次完成构建后,编译生成的文件较多,可是并非全部的文件都是咱们须要的。 一般状况下,咱们可能只须要其中的部分文件,例如.ipa/.app/.plist/.apk等,这时咱们能够将这部分文件单独收集起来,并在构建页面中展现出来,以便在须要时进行下载。 要实现这样一个功能,须要在【Post-build Actions】栏目中新增Archive the artifacts,而后在Files to archive中经过正则表达式指定成果物文件的路径。 设置完毕后,每次构建完成后,Jenkins会在Console Output中采用设定的正则表达式进行搜索匹配,若是能成功匹配到文件,则会将文件收集起来。