jenkins流水线整合jacoco与sonar(二)

sonar代码质量扫描整合

1.sonar API整合

  • 因业务需要,将sonar的账号、项目、权限的维护等一系列API操作整合进自己的项目中,免去手动配置。
  • 用admin账号准备好一个有解析权限的token供流水线解析项目使用

2.jenkins流水线脚本编写

stage('Sonar Analyze') {
            if (enableSonarTest == "1") {
                println("#############################################开始代码质量检查##################################################")
                withEnv(["JAVA_HOME=/root/jenkins/tools/${jdkVersion}", "MVN_HOME=/root/jenkins/tools/maven3"]) {
                    def consoleLog = sh(script: '"$MVN_HOME/bin/mvn" sonar:sonar  -Dsonar.projectKey=' + sonarKey + '  -Dsonar.host.url=' + sonarUrl + '  -Dsonar.login=' + sonarToken, returnStdout: true)
                    println("#############################################代码质量检查成功##################################################")
                    println("consoleLog:" + consoleLog)
                    println("#############################################开始请求质量检查结果##################################################")
                    def toJson = {
                        input ->
                            groovy.json.JsonOutput.toJson(input)
                    }
                    def body = [
                            projectKey: "$sonarKey",
                            jobName   : "$jobName",
                            pipeLineId: "$pipeLineId",
                            codeType  : "java"
                    ]
                    def response = httpRequest acceptType: 'APPLICATION_JSON', contentType: 'APPLICATION_JSON', httpMode: 'POST', requestBody: toJson(body), timeout: 10000, validResponseCodes: '100:599', url: "http://${host}${qualityApi}sonar/getScoreResult"
                    println("sonar Response:" + response)
                    println("response.content:" + response.content)
                    def responseBodyJson = readJSON text: response.content
                    def data = responseBodyJson.data
                    if (response.status == 200) {
                        if (data.pass) {
                            println("#############代码质量检查通过#################")
                            println("##################################" + responseBodyJson.message + " 分数:" + data.score + "########################################")
                        } else {
                            println("##################################" + responseBodyJson.message + " 分数:" + data.score + "########################################")
                            sh "exit 1"
                        }
                    } else {
                        println("#############代码质量检查失败#################")
                        println("接口响应异常")
                        println(responseBodyJson)
                        sh "exit 1"
                    }

                }
            } else {
                println("#############################################代码质量检测未启用,跳过代码质量检测###################################################")
            }

        }
  • sonar的脚本语法可在sonar官网查到,需要传入项目的projectkey和提前准备好的有解析权限的token
  • sonar解析完成后调用自己写的接口进行扫描结果的处理

3.解析sonar扫描结果

  • 调用相应的API获取项目的扫描结果
  • 解析出需要的参数后,经过自定义的计算模型得出项目的代码质量分数,再根据不同级别项目的标准分数得出测试结果
  • 此处遇见一个问题,服务在第一次解析后,调用获取参数的api有较大几率获取不到参数,增加了判断并进行重试机制解决

4.sonar和AD域账号的集成

在sonar账号的集成方案研究过程中,原本想采取集成公司域账号的形式,但是集成之后发现域账号需要登录一次sonar平台才会在sonar的数据库中生成这个账号信息,这样就会导致不登录一次就无法给该账号分配相应的项目浏览权限,经研究后暂时放弃该方案。但是域账号集成的配置研究了不少时间踩了不少坑,最后成功也是不容易,特此记录一下。

主要修改sonar.properties文件,可以用ADExplore查看域服务器信息

# LDAP configuration
# General Configuration
sonar.security.realm=LDAP
#公司的域账号url
ldap.url=ldap:/**.**.com    
#CN是你的域账号 OU是你的域账号所属的组  DC信息直接复制 
ldap.bindDn=CN=**,OU=**,DC=**,DC=**,DC=com
#你的域账号密码
ldap.bindPassword=***
  
# User Configuration
# 直接复制DC信息
ldap.user.baseDn=DC=**,DC=**,DC=com
ldap.user.request=(&(objectClass=user)(sAMAccountName={login}))
ldap.user.realNameAttribute=displayName
ldap.user.emailAttribute=mail
 
# Group Configuration
# 直接复制组信息
ldap.group.baseDn=OU=**DC=**,DC=**,DC=com
ldap.group.request=(&(objectClass=group)(member={dn}))
ldap.group.idAttribute=sAMAccountName

配置文件修改好后,直接挂载进sonar容器对应的路径下