Jenkins(六) Jenkins项目构建细节

内置触发器

Jenkins内置4种构建触发器:

  • 触发远程构建,通过一个远程地址触发项目的执行
  • 其他工程构建后触发(Build after other projects are build),就是需要前面一个项目构建完成后触发我的项目构建
  • 定时构建(Build periodically),顾名思义就是 类似于 corn 表达式,定时执行
  • 轮询SCM(Poll SCM),会定时扫描本地代码仓库是否有变更,如果代码有变更就触发项目构建

远程构建

在项目中的配置中,构建触发器选中远程构建。

通过浏览器访问 http://192.168.81.102:7777/job/test01/build?token=6666 进行项目构建

其他工程构建后触发

应用保存后,就可以构建 maven_project 了。

定时构建

定时字符串从左往右分别为: 分 时 日 月 周
一些定时表达式的例子:

每30分钟构建一次:H代表形参(代表小时,测试用 *)
H/30 * * * * 10:02 10:32
每2个小时构建一次: 
H H/2 * * *
每天的8点,12点,22点,一天构建3次: (多个时间点中间用逗号隔开) 
0 8,12,22 * * *
每天中午12点定时构建一次 
H 12 * * *
每天下午18点定时构建一次 
H 18 * * *
在每个小时的前半个小时内的每10分钟 H(0-29)/10 * * * *
每两小时一次,每个工作日上午9点到下午5点(也许是上午10:38,下午12:38,下午2:38,下午4:38) H H(9-16)/2 * * 1-5

轮询SCM

该构建触发器,Jenkins会定时扫描本地整个项目的代码,增大系统的开销,不建议使用。

Git hook自动触发构建

在Jenkins的内置构建触发器中,轮询SCM可以实现Gitlab代码更新,项目自动构建,但是该方案的性能不佳。那有没有更好的方案呢? 有的。就是利用Gitlab的webhook实现代码push到仓库,立即触发项目自动构建。

安装Gitlab Hook插件

需要安装两个插件:Gitlab Hook 和 GitLab,安装好后在项目配置的构建触发器中,会多一个选项

关于 Gitlab 之后的操作请百度,我这里使用的是 gitea。

gitea 需要下载 Generic Webhook Trigger 插件,安装后到项目配置

配置完成后就可以测试了,只要提交了代码就会构建项目。

Jenkins的参数化构建

有时在项目构建的过程中,我们需要根据用户的输入动态传入一些参数,从而影响整个构建结果,这时我们可以使用参数化构建。

Jenkins支持非常丰富的参数类型

String Parameter

这样的方式只能适用于 pipeline 项目

这种方式输入哪个分支,就构建哪个分支

配置邮箱服务器发送构建结果

安装 Email Extension 插件

可以测试发送

如果 jenkins 报错: Can't send command to SMTP host; 有可能是管理员的邮箱没有填写或者和认证者的邮箱不相同。

准备邮件内容

在项目根目录编写 email.html,并把文件推送git

<!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, sansserif">
    <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>项目名称&nbsp;:&nbsp;${PROJECT_NAME}</li>
                <li>构建编号&nbsp;:&nbsp;第${BUILD_NUMBER}次构建</li>
                <li>触发原因:&nbsp;${CAUSE}</li>
                <li>构建日志:&nbsp;
                    <a href="${BUILD_URL}console">${BUILD_URL}console</a>
                </li>
                <li>构建&nbsp;&nbsp;Url&nbsp;:&nbsp;
                    <a href="${BUILD_URL}">${BUILD_URL}</a>
                </li>
                <li>工作目录&nbsp;:&nbsp;
                    <a href="${PROJECT_URL}ws">${PROJECT_URL}ws</a>
                </li>
                <li>项目&nbsp;&nbsp;Url&nbsp;:&nbsp;
                    <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="&nbsp;&nbsp;&nbsp;&nbsp;%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>
            <textarea cols="80" rows="30" readonly="readonly"
                      style="font-family: Courier New">
                ${BUILD_LOG,maxLines=100}
            </textarea>
        </td>
    </tr>
</table>
</body>
</html>

这里的参数都为 Jenkins 的参数,具体参数在 Jenkins 系统配置里可以看到,点击如下的问号就行。

添加 post,post 意思是构建后操作,post 可以根据 stage 的结果执行不同的逻辑,比如 stages 里面都执行完成,他会走 post 里的 success 代码,如果失败会走 failure 代码。而 post 的语法该如何写,可以到 流水线语法 中看到。

  • Always run, regardless of build status 无论构建的结果如何都会执行
  • Run if the build status is "Failure" 构建失败运行
  • Run if the build status is "Success" or hasnt been set yet 构建成功运行

至于,邮件的内容,可以在片段生成器中查出来

    post {
        always {
            emailext(
                # 可以使用 jenkins 里面的参数
                subject: '构建通知:${PROJECT_NAME} - Build # ${BUILD_NUMBER} - ${BUILD_STATUS}!',
                # 读取 email.html 文件
                body: '${FILE,path="email.html"}',
                # 邮件的收件人
                to: 'xxxxxx@qq.com'
            )
        }
    }

${FILE,path="PATH"} 可以在系统配置中了解

然后去构建你的项目,就可以收到 构建项目的邮件了。

jenkins 配置 SonarQube(代码审查)

SonarQube是一个用于管理代码质量的开放平台,可以快速的定位代码中潜在的或者明显的错误。目前支持java,C#,C/C++,Python,PL/SQL,Cobol,JavaScrip,Groovy等二十几种编程语言的代码质量管理与检测。官网:https://www.sonarqube.org/

软件 版本
JDK 1.8
mysql 8.0
SonarQube 6.7.4

下载sonar压缩包:https://www.sonarqube.org/downloads/

# 解压 
unzip sonarqube-6.7.4.zip
# 创建sonar用户,必须sonar用于启动,否则报错
useradd sonar 
# 更改sonar目录及文件权限
chown -R sonar. /opt/software/sonar

修改sonar配置文件

vim /opt/software/sonar/conf/sonar.properties
sonar.jdbc.username=xxxx
sonar.jdbc.password=xxxxxx
jdbc:mysql://xxxxxxxxxxx:3306/sonar?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=false&zeroDateTimeBehavior=convertToNull&&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true&useConfigs=maxPerformance

启动sonar

cd /opt/software/sonar/
# 启动
su sonar ./bin/linux-x86-64/sonar.sh start 
# 查看状态
su sonar ./bin/linux-x86-64/sonar.sh status 
# 停止
su sonar ./bin/linux-x86-64/sonar.sh stop 
# 查看日志
tail -f logs/sonar.log

7.9 以后不支持 mysql,只支持h2、mssql、postgresql ,7.9 以下也只支持 mysql5.7,所以这里就不在继续了,大致说清楚就好,当安装好后访问web页面,默认9000端口,得到一个token记录下来。

1.在Jenkins中安装 SonarQube Scanner 插件
2.在Jenkins->Manager Jenkins->Global Tool Configuration->SonarQube Scanner->新增 SonarQube Scanner

1. 填入 Name,名字可以自己随便起
2. 勾选 Install automatically
3. 选择安装的版本
4. 点击应用并保存

3.在Jenkins->Manager Jenkins->Configure System->SonarQube servers->Add SonarQube

1. 填入 Name,该名字可以随便起
2. 填写安装 SonarQube 的 web 地址 IP:PORT
3. 添加证书,该证书就是访问 SonarQube 获取到的token,也可以在Jenkins的全局凭证里去添加这个证书,但类型需要是 Secret text
4. 应用并保存

4.非结构性项目检查,到项目配置中找到构建,在正常的构建项目名录后可以增加构建步骤,然后再下拉选项中找到 Execute SonarQube Scanner

1. 填写Task to run,执行 SonarQube 的命令,输入 scan(触发代码扫描以及检测)
2. 代码需要的JDK环境,这个JDK环境是在全局配置中配置得到的
3. 在 Analysis properties 填如内容

# must be unique in a given SonarQube instance,项目标记
sonar.projectKey=web_demo
# this is the name and version displayed in the SonarQube UI. Was mandatoryprior to SonarQube 6.1.,项目名称
sonar.projectName=web_demo
# 版本
sonar.projectVersion=1.0
# Path is relative to the sonar-project.properties file. Replace "\" by "/" on
Windows.
# This property is optional if sonar.modules is set. 扫描代码的路径 . 代表当前项目根目录下扫描所有代码及文件,也可以直接扫描指定包代码,如 /src/main/**
sonar.sources=.
# 排除的一些文件不扫描
sonar.exclusions=**/test/**,**/target/**
# jdk版本
sonar.java.source=1.8
sonar.java.target=1.8
# Encoding of the source code. Default is default system encoding,编码格式
sonar.sourceEncoding=UTF-8

4.应用并保存后构建项目

5.流水线项目添加 SonarQube 功能,可以把内容添加到项目中,防止 jenkins 意外的崩溃,导致配置丢失

1. 在项目中根路径下新建 sonar-project.properties,并把内容复制过来
2. 到项目中的 Jenkinsfile 中编写内容

pipeline {
    agent any

    stages {
        stage('pull code') {
            steps {
                echo 'master 分支的事情 参数是=${branch}'
                checkout([$class: 'GitSCM', branches: [[name: '*/${branch}']], extensions: [], userRemoteConfigs: [[credentialsId: '80dfe5c5-1684-47b1-a410-6f53ceb3c543', url: 'http://192.168.81.15:3000/biguncle/test.git']]])
            }
        }
        # 代码检查,可以把该步骤添加到任意位置
        stage('code checking') {
            steps {
                script {
                    # '' 这里写的是在jenkins->Global Tool Configuration->SonarQube Scanner->新增的SonarQube Scanner的Name
                    scannerHome = tool 'sonar-scanner'
                }
                # () 里的内容是在 jenkins->Configure System->SonarQube servers->里的 Name
                withSonarQubeEnv('sonarqube6.7.4') {
                    # 这里是 jenkins 在配置 SonarQube Scanner的时候安装的工具,他自己安装的不需要我们管
                    sh "${scannerHome}/bin/sonar-scanner"
                }
            }
        }
        stage('build project') {
            steps {
                sh 'mvn clean package'
            }
        }
    }
    post {
        always {
            emailext(
                subject: '构建通知:${PROJECT_NAME} - Build # ${BUILD_NUMBER} - ${BUILD_STATUS}!',
                body: '${FILE,path="email.html"}',
                to: '875730567@qq.com'
            )
        }
    }
}

3. 提交后就可以到 jenkins 去构建项目,结果要去 SonarQube web 去看

推荐阅读更多精彩内容