一、Jenkins 简介
Jenkins是一个可扩展的持续集成引擎。
主要用于:
l 持续、自动地构建/测试软件项目。
l 监控一些定时执行的任务。
Jenkins拥有的特性包括:
l 易于安装-只要把jenkins.war部署到servlet容器,不需要数据库支持。
l 易于配置-所有配置都是通过其提供的web界面实现。
l 集成RSS/E-mail通过RSS发布构建结果或当构建完成时通过e-mail通知。
l 生成JUnit/TestNG测试报告。
l 分布式构建支持Jenkins能够让多台计算机一起构建/测试。
l 文件识别:Jenkins能够跟踪哪次构建生成哪些jar,哪次构建使用哪个版本的jar等。
l 插件支持:支持扩展插件,你可以开发适合自己团队使用的工具。
1 Jenkins的由来
目前持续集成(CI)已成为当前许多软件开发团队在整个软件开发生命周期内侧重于保证代码质量的常见做法。它是一种实践,旨在缓和和稳固软件的构建过程。并且能够帮助您的开发团队应对如下挑战:
l 软件构建自动化 :配置完成后,CI系统会依照预先制定的时间表,或者针对某一特定事件,对目标软件进行构建。
l 构建可持续的自动化检查 :CI系统能持续地获取新增或修改后签入的源代码,也就是说,当软件开发团队需要周期性的检查新增或修改后的代码时,CI系统会不断确认这些新代码是否破坏了原有软件的成功构建。这减少了开发者们在检查彼此相互依存的代码中变化情况需要花费的时间和精力(说直接一点也是钱啊,呵呵)。
l 构建可持续的自动化测试 :构建检查的扩展部分,构建后执行预先制定的一套测试规则,完成后触发通知(Email,RSS等等)给相关的当事人。
l 生成后后续过程的自动化 :当自动化检查和测试成功完成,软件构建的周期中可能也需要一些额外的任务,诸如生成文档、打包软件、部署构件到一个运行环境或者软件仓库。这样,构件才能更迅速地提供给用户使用。
部署一个CI系统需要的最低要求是,一个可获取的源代码的仓库,一个包含构建脚本的项目。
二、jenkins 关闭和重启方法
1、关闭Jenkins
只需要在访问jenkins服务器的网址url地址后加上exit。例如我jenkins的地址http://localhost:8080/,那么我只需要在浏览器地址栏上敲下http://localhost:8080/exit 网址就能关闭jenkins服务.
2、启动Jenkins
A:如果是使用自带的Jetty服务器,启动可以使用命令:sudo service jenkins start。
B:如果是部署在Tomcat服务器上,直接启动Tomcat即可。
3、重启Jenkies
http://localhost:8080/restart
4、重新加载配置信息
http://localhost:8080/reload
三、jenkins 中新建任务
如果你想根据一个已经存在的任务创建,可以使用选项【复制】
本例中选择:构建一个自由风格的软件项目
一、General
1. 丢弃旧的构建
自定义丢弃旧的构建策略设置
一般将“保持构建的天数”以及“发布包保留天数”均设置为相同天;
而jar包或war包一般我们只想获取最新版本,只保存最新版的软件版本信息,因而“发布包最大保留#个构建”中填写1
2. 参数化构建
创建参数,在这创建的参数可以在下边命令行用{名字}的方式调用。
注意:创建完成了,需要点击左侧的Build with Parameters开始构建任务,
二、源码管理 -- SVN
- Module: 指svn上的模块。一个任务中可以添加多个不同来源的svn模块。
- Repository URL: svn代码仓库的地址。
- Credentials: 访问svn代码仓库所需的账号密码。
- Local module directory:svn检出到本机的文件夹路径
- Repository depth: 需要检出的文件夹深度,一般设为infinity(配置文件夹下的所有文件,包括子文件夹)具体说明可见插件帮助。
- Ignore externals / Additional Credentials:未用到,不作说明。
- Check-out Strategy:更新svn到本地的几种方式。建议使用 Use 'svn update' as much as possible, with 'svn revert' before update (先放弃所有本地修改,然后尽可能进行svn更新。避免本地修改导致本地项目与代码仓库不一致)
三. 构建触发器
设置有四个选项,可以多选
1. 触发远程构建
2. Build after other projects are built(其他工程构建后触发)
可以依赖多个job,用逗号隔开
Trigger only if build is stable:只有构建稳定时触发
Trigger even if the build is unstable :即使构建不稳定时也会触发
Trigger even if the build fails : 即使构建失败时也会触发
3. Build periodically(定时构建)
通过查看设置说明,可以看出此处定时任务的格式遵循 cron 的语法(可以与 cron 的语法有轻微的差异)。具体格式,每行包含五个字段,通过 Tab 或空格分隔。
crontab命令常见于Unix和类Unix的操作系统之中,用于设置周期性被执行的指令。该命令从标准输入设备读取指令,并将其存放于“crontab”文件中,以供之后读取和执行。该词来源于希腊语 chronos(χρνο),原意是时间。通常,crontab储存的指令被守护进程激活, crond常常在后台运行,每一分钟检查是否有预定的作业需要执行。这类作业一般称为cron jobs。参考资料
若要指定一个字段的多个值,可以使用以下运算符,按先后顺序。
- *指定所有值
- M-N 指定范围值
- M-N/X 或 */X 在指定范围或整个有效范围内按 X 间隔的步骤
- A,B,...,Z 列举了多个值
- 如果使用 H, Jenkins会自动提前一段时间连接节点,避免出现同一时间高并发的问题
4. Poll SCM(轮询SCM)
定时检查源码变更(根据SCM软件的版本号),如果有更新就checkout最新code下来,然后执行构建动作
四. 构建环境
Delete workspace before build starts
构建前删除工作空间
Use secret text(s) or file(s)
Send files or execute commands over SSH before the build starts
Send files or execute commands over SSH after the build runs
Abort the build if it's stuck
Add timestamps to the Console Output
Custom Ant in Workspace
Execute shell script on remote host using ssh
Generate Release Notes
五. 构建
Ant buid.xml 文件模板
<?xml version="1.0" encoding="UTF-8" ?> <project name="isc" default="generwar" basedir="."> <!--Linux env.JAVA_HOME:编译jdk版本;tomcat.lib:项目所依赖tomcat_jar--> <property name="env.JAVA_HOME" value="/data/jenkins/jdk1.6.0_45"/> <property name="tomcat.lib" value="/data/jenkins/tomcat_lib"></property> <property name="build" value="${basedir}/build" /> <property name="build.class" value="${build}/classes" /> <property name="src" value="${basedir}/src" /> <!-- 非和收付写法 --> <!--<property name="src" value="${basedir}/src/main/java" />--> <!-- 车和收付需要,异步不需要 --> <!-- <property name="resources" value="${basedir}/src/main/resources" />--> <property name="webApp" value="${basedir}/WebContent" /> <property name="lib" value="${webApp}/WEB-INF/lib" /> <!--定义CLASSPACH,编译时用到你外部加入的包--> <path id="classpath"> <pathelement location="${src}" /> <fileset dir="${lib}" includes="***.jar" /> <fileset dir="${tomcat.lib}"> <include name="jsp-api.jar"/> </fileset> </path> <!--删除任务--> <target name="clean1" description="删除"> <echo message="删除目录" /> <delete dir="${build}" /> </target> <!--创建一个临时目录--> <target name="init" description="创建目录" depends="clean1"> <echo message="创建目录--以执行" /> <mkdir dir="${build.class}" /> <copy todir="${build.class}"> <!-- 车和收付需要 --> <!-- <fileset dir="${resources}"> <include name="**" /> </fileset> --> <fileset dir="${src}"> <include name="**/*.xml"/> <include name="**/*.properties"/> <include name="**/*.xls"/> <include name="**/*.xlsx"/> </fileset> </copy> </target> <!--编译java源文件--> <target name="compile" description="编译文件" depends="init"> <echo message="编译文件" /> <javac encoding="utf-8" fork="true" source="1.6" executable="${env.JAVA_HOME}/bin/javac" srcdir="${src}" destdir="${build.class}" includeAntRuntime="false" includeantruntime ="on" bootclasspath="${env.JAVA_HOME}/jre/lib/rt.jar;${env.JAVA_HOME}/jre/lib/jce.jar;${env.JAVA_HOME}/jre/lib/jsse.jar"> <classpath refid="classpath" /> <compilerarg line="-encoding UTF-8 " /> <compilerarg line="-source 1.6" /> <compilerarg value="-Xlint:unchecked"/> </javac> </target> <!--打成WAR包--> <target name="generwar" depends="compile"> <echo message="打成WAR" /> <war destfile="${build}/${ant.project.name}.war" webxml="${webApp}/WEB-INF/web.xml"> <fileset dir="WebContent"> </fileset> <lib dir="${lib}" /> <classes dir="${build.class}" /> </war> </target> </project>
六. 构建后操作
1. Editable Email Notification
邮件通知配置
-
系统管理 → 系统设置 → 邮件通知
- SMTP 服务器:配置 SMTP 服务器。(不填默认本地运行服务器)
- 用户默认邮件后缀:注册用户邮件只需填写用户名即可,后缀会加该后缀,如果填写,则会覆盖该配置。
- SMTP 端口:填写 SMTP 端口。
- Test configuration:可以进行邮件测试。
Project From:发件人
Project Recipient List:这是一个以逗号(或者空格)分隔的收件人邮件的邮箱地址列表。允许您为每封邮件指定单独的列表。Ps:如果你想在默认收件人的基础上添加收件人:$DEFAULT_RECIPIENTS,<新的收件人>
Project Reply-To List:
Default Subject:允许你配置此项目邮件的主题。
Default Content:跟Default Subject的作用一样,但是是替换邮件内容。
Attach Build Log:附件构建日志。
----Compress Build Log before sending:发送前压缩生成日志(zip格式)。
Default Subject
【JENKINS构建】$PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS!
Default Content
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>${ENV, var="JOB_NAME"}-第${BUILD_NUMBER}次构建日志</title>
</head>
<body leftmargin="8" marginwidth="0" topmargin="8" marginheight="4"
offset="0">
<table width="95%" cellpadding="0" cellspacing="0"
style="font-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans-serif">
<tr>
<td>(本邮件是程序自动下发的,请勿回复!)</td>
</tr>
<tr>
<td><h2>
<font color="#0000FF">构建结果 - ${BUILD_STATUS}</font>
</h2></td>
</tr>
<tr>
<td><br />
<b><font color="#0B610B">构建信息</font></b>
<hr size="2" width="100%" align="center" /></td>
</tr>
<tr>
<td>
<ul>
<li>项目名称 : ${PROJECT_NAME}</li>
<li>构建编号 : 第${BUILD_NUMBER}次构建</li>
<li>SVN 版本: ${SVN_REVISION}</li>
<li>触发原因: ${CAUSE}</li>
<li>构建日志: <a href="${BUILD_URL}console">${BUILD_URL}console</a></li>
<li>构建 Url : <a href="${BUILD_URL}">${BUILD_URL}</a></li>
<li>工作目录 : <a href="${PROJECT_URL}ws">${PROJECT_URL}ws</a></li>
<li>项目 Url : <a href="${PROJECT_URL}">${PROJECT_URL}</a></li>
</ul>
</td>
</tr>
<tr>
<td><b><font color="#0B610B">Changes Since Last
Successful Build:</font></b>
<hr size="2" width="100%" align="center" /></td>
</tr>
<tr>
<td>
<ul>
<li>历史变更记录 : <a href="${PROJECT_URL}changes">${PROJECT_URL}changes</a></li>
</ul> ${CHANGES_SINCE_LAST_SUCCESS,reverse=true, format="Changes for Build #%n:<br />%c<br />",showPaths=true,changesFormat="<pre>[%a]<br />%m</pre>",pathFormat=" %p"}
</td>
</tr>
<tr>
<td><b>Failed Test Results</b>
<hr size="2" width="100%" align="center" /></td>
</tr>
<tr>
<td><pre
style="font-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans-serif">$FAILED_TESTS</pre>
<br /></td>
</tr>
<tr>
<td><b><font color="#0B610B">构建日志 (最后 100行):</font></b>
<hr size="2" width="100%" align="center" /></td>
</tr>
<!-- <tr>
<td>Test Logs (if test has ran): <a
href="${PROJECT_URL}ws/TestResult/archive_logs/Log-Build-${BUILD_NUMBER}.zip">${PROJECT_URL}/ws/TestResult/archive_logs/Log-Build-${BUILD_NUMBER}.zip</a>
<br />
<br />
</td>
</tr> -->
<tr>
<td><textarea cols="80" rows="30" readonly="readonly"
style="font-family: Courier New">${BUILD_LOG, maxLines=100}</textarea>
</td>
</tr>
</table>
</body>
</html>
构建的项目中 → 构建后操作 → E-mail Notification
- Recipients:邮件列表,多人用英文逗号间隔。
2. Send build artifacts over SSH
Source File : 需要上传的文件(注意:相对于工作区的路径。看后面的配置可以填写多个,默认用,分隔)
Remove prefix:移除目录(只能指定Transfer Set Source files中的目录)
Remote directory:远程目录(根据你的需求填写吧,因为我这儿是测试,所以偷懒没有填写。默认会继承系统配置)
Exec command:把你要执行的命令写在里面
高级:
Exclude files:排除的文件(在你传输目录的时候很有用,使用通配符,例如:**/*.log,**/*.tmp,.git/)
Pattern separator:分隔符(配置Transfer Set Source files的分隔符。如果你这儿更改了,上面的内容也需要更改)
No default excludes:禁止默认的排除规则(具体的自己看帮助)
Make empty dirs:此选项会更改插件的默认行为。默认行为是匹配该文件是否存在,如果存在则创建目录存放。选中此选项会直接创建一个目录存放文件,即使是空目录。(个人理解)
Flatten files:只上传文件,不创建目录(除了远程目录)
Remote directory is a date format:远程目录建立带日期的文件夹(需要在Remote directory中配置日期格式),具体格式参考下表:
Remote directory | Directories created |
---|---|
'qa-approved/'yyyyMMddHHmmss |
qa-approved/20101107154555 |
'builds/'yyyy/MM/dd/'build-${BUILD_NUMBER}' |
builds/2010/11/07/build-456 (if the build was number 456) |
yyyy_MM/'build'-EEE-d-HHmmss |
2010_11/build-Sun-7-154555 |
yyyy-MM-dd_HH-mm-ss |
2010-11-07_15-45-55 |
Exec timeout (ms):运行脚步的超时时间(毫秒)
Exec in pty:模拟一个终端执行脚步
Add Transfer Set:增加一个配置
JenkinsHome=/data/jenkins
FolderName=cas
WebPath=/data/weblogic/webapp/$FolderName
ServerName=cas_server95
LogPath=$ServerName'.log'
WarName=cas.war
CachePath=/data/weblogic/servers/m95/servers/$ServerName/tmp
echo '======日志名称:'$LogPath
cd $JenkinsHome/sh
echo '=======停止服务======='
sh ./stopAppServer.sh $ServerName >> $LogPath
echo '=======备份应用======='
sh ./backup.sh $FolderName >> $LogPath
echo '=======发布应用======='
cd $JenkinsHome/war
mv ./$WarName $WebPath
echo '========'$WebPath
cd $WebPath
jar -xvf $WarName
rm -rf ./*.war
echo '=======清除缓存======='
rm -rf $CachePath
echo '=======启动服务======='
cd $JenkinsHome/sh
sh ./startAppServer.sh $ServerName >> $LogPath
3. 钉钉通知器配置
配置jenkins URL和钉钉access token
4. 归档成品(Archive the Artifacts)
四、不同Job之间依赖关系的配置
1. Job中配置上游
2. Job中配置下游
五、Jenkins任务构建中遇到的问题
1. Exception when publishing, exception message [Exec timed out or was interrupted after 120,001 ms
适当调大超时时间
2. ERROR: Exception when publishing, exception message [Failed to connect and initialize SSH connection. Message: [Failed to connect session for config [10.20.22.105]. Message [java.net.UnknownHostException: weblogic]]]
原因:系统管理-->系统设置中,配置密码手滑,配置到Jump Host中了,所以Test Configuration 成功,但是发版时SSH Connection连接失败
Jenkins的环境变量 详情查看:http://xxxx/env-vars.html