本系列文章包含:html
本文是对用“MSBuild和Jenkins搭建持续集成环境(2)”的解读,原文中一些设置并不能获得做者所描述的结果,所以下文会结合实际部署对原文稍做修改。服务器
第一眼看上去,Jenkins像是一个专为Java项目准备的持续集成工具:有为Maven项目设计的job,有诸多为Java项目提供的默认插件,更不要说那些用Java写的插件了。并发
但Jenkins实际上是一个很是灵活的工具,它能够结合各类版本管理系统和构建工具,用来构建任何类型的项目。在这篇文章中,咱们会利用它的灵活性,从Mercurial中pull代码,用MSbuild构建项目。首先,咱们须要下载并安装Jenkins,而后安装Git和MSBuild插件。【原文中使用的是Mercurial,因为我常用Git,所以这里会更改成对Git的配置】框架
从官方网站下载安装程序。它的Windows安装包很简单,会把Jenkins安装成Windows服务。Jenkins的默认的访问路径是“localhost:8080”,请确保8080端口不要被其余应用占用。工具
安装完毕之后就是装插件。请点击“系统管理”连接,而后再点击“插件管理”。post
在“可用插件”标签页能够查看当前可安装的插件──你须要有一个能上网的环境,才能看到这一页的内容。用“过滤框”找到Git Plugin、GitHub Plugin和 MSBuild插件,点击插件名称前面的复选框,进行安装【在选择安装时,会自动关联一些必要的插件进行安装,很方便】。单元测试
你能够点击“已安装”标签页,来确保这两个插件已经被安装成功了。
在安装过程当中,你可能会看到提示信息说Jenkins须要重启才能完成安装,请让它重启,等重启完成后再访问“已安装”标签页,看看是否是安装成功。
因为未来使用GitHub,所以只须要知道一个Code的地址便可,配置很方便。回到“系统管理”这一页上来,点击“系统设置”,找到“Git”这一部分──若是你找不到“Git”的话,就说明Git插件没有装好──点击“Add Git”按钮以后,你须要给这个Git实例起个名字(本身用着越方便越好);还须要输入Git可执行文件的安装路径,这里用的是git.exe文件的所在目录;
点击Jenkins的logo,回到控制面板上来,而后点击“新建”连接。你会看到一组job类型,选择“构建一个自由风格的软件项目”,给它命名为“CIProjectWebDemo1-RunUnitTests”,点击OK。
下一步是job配置页面。这一页有不少配置项,并且大多数都带有详细的描述信息,点击右侧的帮助图标就能够看到。
咱们如今只配置两部分,一是代码库所在位置,二是如何用MSBuild构建项目。
找到“源码管理”,选择Git。在“Repository URL”输入框中输入”你本身的GitHub中的代码地址”。而后在Credentials中选择证书【若是没有就建立一个,一直默认就行,最开始我没有选择证书,在执行Job时,有时会卡在GitHub的通讯上,可能和这个有关,网上也有说和https协议有关】。最后在Branch中输入你想跟踪的分支名,其余的选项看本身喜爱。
接下来到“构建”这部分。点击“增长构建步骤”按钮后,下拉框中就会出现一系列的step类型以供选择,其中便包括“Build a Visual Studio project or solution using MSBuild”,若是你没看到这个选项,就说明MSBuild插件没有正确安装。
点击“Build a Visual Studio project or solution using MSBuild”以后,在“MSBuild Build File”输入框中输入构建脚本的名字:CIProjectWebDemo1.msbuild。咱们想让Jenkins执行“RunUnitTests”这个Target ,若是你没有把DefaultTargets属性设成RunUnitTests的话,能够在“Command Line Arguments”中输入“/t:RunUnitTests”,其中/t是/target的简写。
点击“Save”或“Apply”保存以后,这个job一旦被触发,就能够pull代码下来,编译项目,执行单元测试【这里感受Save的提示很醒目,不知道用的那个UI框架,源码中有看到引用YUI,没用过不知是否是这个,有知道的朋友请留言给我,不胜感激】。
咱们先来手工触发一次,看看配置是否正确。先回到“控制面板”,这时能够在屏幕中央看到咱们的job。点击job名字,而后在左侧的连接中找到“Build Now”连接,点击它,Jenkins就会开始执行。
在这组连接的下方有一个“Build History”列表,它显示的是这个job的全部构建历史,当第一次构建开始运行的时候,你会在列表中看到一个进度条,同时还有一个小圆球显示构建状态。圆球闪烁表示构建正在进行中,它中止闪烁的时候通常会是红色或蓝色,红色表示构建失败,蓝色表示成功。
若是这个job可以访问GitHub版本库,找到了CIProjectWebDemo1.msbuild脚本,“RunUnitTest”执行成功,这个圆球应该会变蓝。这时候你也就顺利完成了第一个Jenkins构建。若是构建失败,请点击“Build History”对应的编号查看详细信息,而后点击“Console Output”,就能够看到Jenkins所执行的每个命令和对应结果,从中能够分析出构建失败的缘由。
构建成功之后,下一步要作的就是让Jenkins检测版本库的变化,一旦有代码提交,Jenkins就要pull代码并执行构建。有好几种方法能够作到这一点。
最简单的就是让Jenkins定时构建,可是若是在这一段时间内没有代码提交,此次构建反而是浪费。
另外一种方式是让Jenkins定时轮询,看看版本库中是否有代码提交。这种方法的缺点是当有了代码提交之后,Jenkins要等到下一个轮询周期才能执行构建。固然,你也可让Jenkins每分钟都轮询一次,尽量缩短等待时间。但咱们还有另外一种更优雅的方案──给版本库中放一个post-commit的钩子,这样一旦版本库接受了新代码,它都会通知Jenkins,让它马上开始构建。【原文是使用Mercurial做为版本管理工具的,所以下面的这种方法,我没有尝试,有兴趣的朋友能够拜读原文,尝试一下】
回到job配置页面,在“Build Trigger”区域选择“Poll SCM”,在“Schedule”输入框中输入轮询周期。它采用的语法格式是cron的风格。若是要每5分钟轮询一次,就输入“H/5 * * * *”。你能够点击输入框右侧的帮助按钮,查看轮询周期的语法介绍。
Jenkins能够在某个构建成功结束以后启动其余job。因而就有了构建流水线,它的概念就是一个job成功以后触发其余job。触发者叫作上游job,被触发者被称做下游job。
构建流水线的应用场景有不少:让耗时较长的测试在单元测试结束以后执行;运行静态代码检查;把构建结果部署到试机环境(staging)或者产品环境中。咱们下面来演示一下这个功能,让Jenkins在构建结束后启动web服务器,运行CIProjectWebDemo1这款应用。
咱们只须要作三件事情:
1. CIProjectWebDemo1-RunUnitTests job成功以后触发一个新job;
2. 把CIProjectWebDemo1-RunUnitTests的构建结果拷贝出来;
3. 启动web服务器。
在开始以前,你还须要安装Copy Artifacts插件。回到Manage Plugins页面,参考以前安装Mercurial插件的方法安装Copy Artifacts。在看到重启的提示信息时重启Jenkins。【这一阶段要链接的源有些是国外的,颇有可能被Q,致使安装失败,到时自行FQ便可】
建立新job以前,咱们须要告诉CIProjectWebDemo1-RunUnitTests job,让它把构建产物保存下来,以供新job使用。回到CIProjectWebDemo1-RunUnitTests job的配置界面,找到“增长构建后操做步骤”,选中“Archive the artifacts”,页面上就会出现一个文本框:“用于存档的文件”。
咱们要存档的目录有两份,一份是BuildArtifacts目录,一份是packages目录,后者是为了让咱们可以访问NuGet package。若是要指定某个目录以及目录下全部内容,就须要在目录后面跟一个斜杠和两个星号。不一样的目录或文件之间用逗号分割。在这里咱们输入的是“BuildArtifacts/**”。
如今建立一个新job,起名叫“CIProjectWebDemo1-StartWebServer”【选择“构建一个自由风格的软件项目”】。在配置页面上“构建触发器”那一节里选中“Build after other projects are built”,把以前那个job配置成要触发当前job的项目。
接下来给job添加一个build step,让这个job所作的第一件事情就是拷贝以前job所保存的构建产物。这里要用到“Copy artifacts from another project”这个step(它是由Copy Artifacts插件提供的)。咱们只须要填入CIProjectWebDemo1-RunUnitTests job的名字就能够。
最后还要添加一个build step,让它启动web server。这里用的是“Execute Windows batch command”,咱们用Visual Studio提供的Cassini来运行应用。
Cassini能够在“C:\Program Files (x86)\Common Files\microsoft shared\DevServer\10.0\WebDev.WebServer40.EXE”找到【我是全盘搜索找到的】。运行Cassini很简单,把web应用存放的路径做为参数传给它就行,若是没有指定端口号的话,它就会使用默认的端口号80。
“Execute Windows batch command”step须要一个能够在BuildArtifacts和packages拷贝后的目录下执行的命令。咱们把下面这个命令复制到“Command”输入框中:
"C:\Program Files (x86)\Common Files\microsoft shared\DevServer\10.0\WebDev.WebServer40.EXE" /port:9988 /vpath:"BuildArtifacts\_PublishedWebsites\CIProjectWebDemo1"
【上面的命令是我本身测试出来的,原文中的命令没法执行,多是Cassini版本不同】
这个命令能够启动Cassini,把它指向拷贝过来的应用,而后在9988端口启动服务器。
全部的配置都已就绪。试着修改一下代码而后提交。Jenkins应该可以监听到变化,运行CIProjectWebDemo1-RunUnitTests。若是代码编译成功,全部测试均以经过,Jenkins应该开始运行CIProjectWebDemo1-StartWebServer job,把CIProjectWebDemo1-RunUnitTests的构建产物拷贝过来,在9988端口启动Cassini。若是这一切都运行无误,咱们的持续集成系统就搭好了。
此配置的结果是网站拷贝完毕后,启动Cassini,指定网站目录,而后这个job就一直处在等待的状态,我以为这就到结果了吧,至关于在Jenkins的进程中开启了一个Web服务,此时在浏览器中输入http://localhost:9988/main.aspx(这里我是用的本身的webFrom网站)就能够访问到你的页面了。
可是,若是不手动结束这个Job,那么就会一直执行下去,当下一次被CIProjectWebDemo1-RunUnitTests运行结束的消息启动,除非在配置里开启并发执行,不然将会一直等待上一个进程的执行;而并发执行又会因为端口被占用,致使Cassini没法启动,并使其崩溃。。感受好乱。
做者写这个例子的目的,多是为了演示Job链吧。
后来想到,若是没有使用Cassini,而是用其余的web服务器来启动网站,可能就不会存在这种问题了。
各位看官,请继续阅读 [独孤九剑]持续集成实践 - 引子