【Sonarqube+Jenkins】---- 代码质量提升方案

1、工具简介

SonarQube是一个用于代码质量管理的开源平台,用于管理源代码的质量。通过插件机制,SonarQube可以集成不同的测试工具,代码分析工具,以及持续集成工具,比如pmd-cpd、checkstyle、findbugs、Jenkins。通过不同的插件对这些结果进行再加工处理,通过量化的方式度量代码质量的变化,从而可以方便地对不同规模和种类的工程进行代码质量管理。

SonarQube 在进行代码质量管理时,会在七个纬度来分析项目的质量:算法设计,注释,编码规则,潜在缺陷,单元测试,重复块,复杂度。

2、方案介绍

Sonarqube的强大之处在于它可以跟持续集成工具(比如jenkins)非常好的对接,作为工具链的的一环,搭建适合自己公司研发项目模式的持续集成流水线,做到快速扫描即时反馈。

这里提供三种我实践过的方式给大家参考。

2.1 本地化代码扫描

为了能让研发同学在编写代码的过程中,可以随时扫描本地代码以做到尽快修复,我们推荐使用sonarlint插件。

SonarLinthttp://www.sonarlint.org/eclipse/index.html 是一个可以安装在IDE(包括IDEA,Eclipse,Visual Studio,VS Code,Atom)中的插件,它可以向开发人员及时反馈Java、JavaScript、PHP、Python…代码中编码时产生的新的缺陷和质量问题

SonarLint是开源、免费的,使用时需要注意,它需要运行在Java 8 环境下,SonarQube 5.6 +

关于sonarlint的使用,后面会单独在工具介绍里面详细。

本方案实践情况:按需选择,建议开发本地安装。

2.2  代码提交后触发扫描

开发提交或者合并代码到功能分支后,会自动触发Jenkins上配置的代码扫描任务,进行构建静测,并自动将静测结果返回开发人员。目的是为了确保每次提交的代码都经过集成验证,代码质量合格且能通过编译。

 

实现方式:

jenkins中需要创建一个Multibranch Pipeline类型的任务,配置gitlab仓库地址,并且往gitlab仓库中传入一个jenkinsfile文件,用于判断分支是否需要进行代码扫描。(实现方式参考:【Gitlab+Jenkins+Sonarqube】 ---- 多分支类型项目代码提交后 触发静态代码扫描的实现)。

对于提测分支和上线分支,不设置代码提交后触发静测(在我们目前的发布上线流程中,提测分支有单独的流程),只针对功能分支(feature)和热修复(hotfix)分支设置。下面的脚本是针对我目前的设置进行配置的,仅供参考。

脚本示例:

#!groovy
def projectProperties = [
        //设置禁止并发
        disableConcurrentBuilds(),
        //保留历史构建记录为3
        buildDiscarder(logRotator(artifactDaysToKeepStr: '', artifactNumToKeepStr: '', daysToKeepStr: '', numToKeepStr: '3')),

        //预设邮件通知人参数
        parameters([
            string(defaultValue: 'qa-ci@xxxx.cn', description: '', name: 'Mail_List', trim: false)
        ])
]
properties(projectProperties)

def Job_Name = "CI.TEST.JOB"

def failed_text = '''<hr/>
    
        很遗憾的通知这次执行失败啦,一定有哪里出了问题,还请点开构建日志仔细检查,或者跟管理员联系 <br/><hr/>
    
        项目名称:$PROJECT_NAME<br/><hr/>
    
        触发原因:${CAUSE}<br/><hr/>
        
        构建日志地址:<a href="http://xxxxx:8080/blue/organizations/jenkins/${Job_Name}/detail/${env.BRANCH_NAME}/${BUILD_NUMBER}/pipeline">http://xxxxx:8080/blue/organizations/jenkins/${Job_Name}/detail/${JOB_NAME}/${env.BRANCH_NAME}/pipeline</a><br/><hr/>
        
        静测结果:<a href="http://xxxxx:9000/dashboard/index/${Job_Name}.${env.BRANCH_NAME}">http://xxxxx:9000/dashboard/index/${Job_Name}.${env.BRANCH_NAME}</a><br/><hr/>
    
        变更集:\${SCRIPT, template="groovy-html.template"}<br/><hr/>'''

//需要触发提交即刻代码扫描的功能分支和热修复分支,根据前缀匹配判断
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: """<hr/>

			项目名称:\${PROJECT_NAME}<br/><hr/>

			构建日志地址:<a href="http://xxxxx:8080/blue/organizations/jenkins/${Job_Name}/detail/${env.BRANCH_NAME}/${BUILD_NUMBER}/pipeline">http://xxxxx:8080/blue/organizations/jenkins/${Job_Name}/detail/${JOB_NAME}/${env.BRANCH_NAME}/pipeline</a><br/><hr/>	

			静测结果:<a href="http://xxxxx:9000/dashboard/index/${Job_Name}.${env.BRANCH_NAME}">http://xxxxx:9000/dashboard/index/${Job_Name}.${env.BRANCH_NAME}</a><br/><hr/>

			变更集:\${SCRIPT, template="groovy-html.template"}<br/><hr/>""" ,
                    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
}

然后开发同学就能从邮件中收到静测结果报告啦。

2.3  测试版本出包前扫描

在提交构建测试版本时,会在构建后进行代码扫描,在整个过程完成后,将构建以及静测结果返回测试,开发人员等。

脚本示例:

3、人员角色

选用了方案之后,我们需要对人员角色进行定义,确保流程得以贯彻。另外,由于Sonarqube原生的规则非常多,需要经过一段时间的摸索,这期间,我们需要经验丰富的开发人员对扫描问题进行把控,判断是否符合业务场景。所以在使用方案初期,我们队不同的人员角色和承担的职责做了划分,配合Sonarqube6.7版本支持的问题分配功能,定制如下:

根据不同人员将承担的职责,我们针对项目每个项目进行如下角色的定义。

角色(权限群组)

权限

说明

Project-Read

能查看该项目的静测报表,不能看到源码仓库。

非开发人员。

Project-DEV

能查看该项目的静测报表,浏览源码仓库。

一般为开发人员。

Project-Master

能查看该项目的静测报表,浏览源码仓库等,同时拥有项目的管理权限,进行权限分配,以及问题管理权限(包括问题等级验证性修改,是否误判和无需修复等)

一般为项目开发负责人,需要对项目的静测扫描结果进行把控。

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值