基本概念

Sonarqube是一个开源的代码质量检测工具,可以单独使用,也可以作为一个检测步骤放在Jenkins的pipeline CI/CD 流水线。简单的理解,他通过一个snarqube scanner 的工具来扫描代码,然后把结果发给 sonarqube server,用户可以在这个sonarqube server的网页界面查看报告。

每次运行的时候,他会通过一系列条件检测,我们可以看见这些检测的内容,这些检测的内容叫做 quality gate,他最后会显示我们的检测结果是passed或者 failed

当我们把Jenkins和 sonarqube整合的时候,Jenkins调用 sonarqube scanner 扫描,把结果发送给sonarqube 服务器,然后服务器完成报告之后,通过 webhook再把结果发过Jenkins,Jenkins根据结果判断是否继续运行pipeline

安装和配置

配置 docker-compose

本地测试一般可以使用docker-compose 的方式直接部署容器,而且docker-compose有个好处是里面定义的服务,都会默认放入同一个网段,可以直接彼此通过服务名进行访问。

首先创建一个docker-compose.yaml

version: "3"
services:
  sonarqube:
    image: sonarqube
    ports:
      - 9000:9000
      - 9002:9002
  jenkins:
    image: jenkins/jenkins:2.249.2-jdk11
    ports:
      - 8080:8080

执行 docker-compose up -d 就可以启动了

值得注意的一点是Docker的内存分配,如果内存不足,那么容器启动之后会自动关闭!豆子用的是Macbook Pro,需要注意调整Docker Desktop的内存。

启动之后,我们可以通过 http://127.0.0.1:9000 来访问 sonarqube, 和 http://127.0.0.1:8080 来访问 Jenkins

接下来在我们配置Jenkins之前,我们可以直接测试一下 sonarqube是否工作。我直接通过sonarqube scanner的容器来访问我的代码,并把结果发回给服务器。这些参数可以通过命令行传递,也可以通过 sonar-project.properites这个文件配置。

等待1分钟之后 就可以看见结果了

配置Jenkins和 sonarqube

确认sonarqube 工作之后,我们来Jenkins里面配置一下。

Manage Jenkins - Manage Plugins - 安装 sonarQube Scanner for Jenkins的插件

然后我们要在sonarqube里面需要生成一个token,Jenkins里面需要这个token进行验证。

sonarqube里面,右上角点击 my account - > security, generate tokens

Jenkins 里面,Manage Jenkins - >Configure System , 然后添加server的 URL和 token

然后进入 Jenkins的 Manage Jenkins - Global Tool Configuration , 安装 SonarQube Scanner

最后,我们还需要在sonarqube上配置 webhook,当扫描结束的时候,他会自动通知Jenkins

sonarquebe - administration - webhooks

编写 pipeline 文件

准备就绪之后,我们就可以写我们的pipeline文件了。作为对比,我们写两个pipeline,一个是质量比较好的代码,一个是比较差的。pipeline里面有三个stage,分别是下载代码, 扫描代码,以及quality gate的结果判断是否继续

好代码

pipeline {
    agent any
    stages {
        stage('Clone sources') {
            steps {
                git url: 'https://github.com/tkgregory/sonarqube-jacoco-code-coverage.git'
            }
        }
        stage('SonarQube analysis') {
            steps {
                withSonarQubeEnv('SonarQube') {
                    sh "./gradlew sonarqube"
                }
            }
        }
        stage("Quality gate") {
            steps {
                waitForQualityGate abortPipeline: true
            }
        }
    }
}

差代码


pipeline {
    agent any
    stages {
        stage('Clone sources') {
            steps {
                git branch: 'bad-code', url: 'https://github.com/tkgregory/sonarqube-jacoco-code-coverage.git'
            }
        }
        stage('SonarQube analysis') {
            steps {
                withSonarQubeEnv('SonarQube') {
                    sh "./gradlew sonarqube"
                }
            }
        }
        stage("Quality gate") {
            steps {
                waitForQualityGate abortPipeline: true
            }
        }
    }
}

执行pipeline,我们可以看见结果

Good code

Bad code