Jenkins2.x版本中,可以使用pipeline脚本来进行丰富的构建定制。
比如,对于多分支项目,可以通过multiBranch Pipeline来实现功能分支代码每次提交就触发静态代码扫描。我们只需要做的是:(1)创建的multiBranch Pipeline任务;(2)在每个分支的代码根目录下上传Jenkinsfile,Jenkins会自动为存在Jenkinsfile的分支创建Jenkins任务,并在每次检查更新后执行。
操作指引如下:
首先,创建一个multiBranch Pipeline任务。可以在传统模式下创建,或者在Blue Ocean插件下创建。
传统模式下:
blue ocean插件模式下创建:
主要需要配置的仓库信息,脚本文件名,扫描时间间隔。
git仓库建议填写ssh链接。
文件名填写你即将要上传到gitlab中的脚本文件名,两项对应即可。扫描间隔视情况而定。
我这边的示例项目是nodejs项目,并且根据我制定的分支策略,对feature和bugfix分支进行代码扫描,脚本如下:
(备注:大部分项目静测前构建不是必须的,但是我希望每次提交不只是通过代码扫描,也希望能通过构建,也就是代码可编译。)
#!groovy
def projectProperties = [
//设置禁止并发
disableConcurrentBuilds(),
//保留历史构建记录为3
buildDiscarder(logRotator(artifactDaysToKeepStr: '', artifactNumToKeepStr: '', daysToKeepStr: '', numToKeepStr: '3')),
//预设邮件通知人参数
parameters([
string(defaultValue: '[email protected]', description: '', name: 'Mail_List', trim: false)
])
]
properties(projectProperties)
def Job_Name = "CI.TEST.JOB"
def failed_text = '''
很遗憾的通知这次执行失败啦,一定有哪里出了问题,还请点开构建日志仔细检查,或者跟管理员联系
项目名称:$PROJECT_NAME
触发原因:${CAUSE}
构建日志地址:http://xxxxx:8080/blue/organizations/jenkins/${Job_Name}/detail/${JOB_NAME}/${env.BRANCH_NAME}/pipeline
静测结果:http://xxxxx:9000/dashboard/index/${Job_Name}.${env.BRANCH_NAME}
变更集:\${SCRIPT, template="groovy-html.template"}
'''
//需要触发提交即刻代码扫描的功能分支和热修复分支,根据前缀匹配判断
def Sonar_BranchList = ['feature', 'hotfix']
node('slave-centos') {
permission = SonarRunBranch(Sonar_BranchList)
echo "当前分支名:[${env.BRANCH_NAME}]"
echo "[分支${env.BRANCH_NAME}]:" + "${permission == true ? '将要执行静态代码扫描' : '非feature和hotfix分支无需单独进行代码扫描'}"
if (permission) {
stage('Checkout') {
try {
retry(2) {
checkout scm
}
}
catch (exc) {
echo '代码下载失败了, 请检查配置!'
emailext body: "${failed_text}",
subject: "${JOB_NAME} - Failure!",
to: "${params.Mail_List}"
sh 'exit 1'
}
}
stage('Build') {
try {
retry(2) {
sh "yarn install"
sh "npm run build"
}
}
catch (exc) {
echo '构建失败了, 请检查配置!'
emailext body: "${failed_text}",
subject: "${JOB_NAME} - Failure!",
to: "${params.Mail_List}"
sh 'exit 1'
}
}
stage('SonarAnalysis') {
try {
retry(2) {
echo '静态代码检查开始:'
withSonarQubeEnv('sonarqube6.5') {
sh '/disk1/jenkins/tools/hudson.plugins.sonar.SonarRunnerInstallation/SonarQube_Scanner/bin/sonar-scanner ' +
"-Dsonar.projectKey=${Job_Name}.${env.BRANCH_NAME} " +
"-Dsonar.projectName=${Job_Name}.${env.BRANCH_NAME} " +
'-Dsonar.projectVersion=${BUILD_NUMBER} ' +
'-Dsonar.sources=./ ' +
'-Dsonar.exclusions=**/node_modules/** ' +
'-Dsonar.sourceEncoding=UTF-8'
}
}
}
catch (exc) {
echo '静态代码检查失败了, 请检查配置!'
emailext body: "${failed_text}",
subject: "${JOB_NAME} - Failure!",
to: "${params.Mail_List}"
sh 'exit 1'
}
}
stage ('Mail'){
emailext body: """
项目名称:\${PROJECT_NAME}
构建日志地址:http://xxxxx:8080/blue/organizations/jenkins/${Job_Name}/detail/${JOB_NAME}/${env.BRANCH_NAME}/pipeline
静测结果:http://xxxxx:9000/dashboard/index/${Job_Name}.${env.BRANCH_NAME}
变更集:\${SCRIPT, template="groovy-html.template"}
""" ,
subject: "${JOB_NAME} -静态代码扫描- Successful!",
to: "${params.Mail_List}"
}
}
}
def SonarRunBranch(Sonar_BranchList) {
result = false
for (BranchName in Sonar_BranchList){
if(env.BRANCH_NAME.startsWith(BranchName)){
result = true
}
}
result
}
将脚本命名为Jenkinsfile上传到gitlab的master分支下(上传到哪个分支取决于项目的功能分支是从哪个分支拉取的,这样能确保新的分支根目录下都有这个文件)。
经过一次扫描后(扫描的执行由系统根据时间间隔自动执行,也可以手动执行),项目获取到所有存有Jenkinsfile的分支。如下:
同时,对于我们配置了静测的分支,可以收到邮件通知 ,获取静测结果。