Jenkins SonarQube CI 流水线集成 命令行方式优化

本次集成重点演示两种方式: 1. 使用命令行方式 2. 使用Jenkins扩展插件的方式。 

命令行方式


流水线中添加代码扫描阶段, 然后在script标签中定义一段脚本。 (其实这段脚本就是我们手动在服务器上面执行的sonar-scanner的命令和参数组成的)【可以先运行该段代码确保扫描成功,然后进一步优化

	stage("SonarScan"){
            steps{
                script{
                    sh """
                        sonar-scanner \
                          -Dsonar.projectKey=demo-devops-service \
                          -Dsonar.projectName=demo-devops-service \
                          -Dsonar.sources=src \
                          -Dsonar.host.url=http://192.168.1.200:9000 \
                          -Dsonar.login=0809881d71f2b06b64786ae3f81a9acf22078e8b \
                          -Dsonar.projectVersion=1.0 \
                          -Dsonar.ws.timeout=30 \
                          -Dsonar.projectDescription="my first project!" \
                          -Dsonar.links.homepage=http://192.168.1.200/devops/devops-maven-service \
                          -Dsonar.links.ci=http://192.168.1.200:8080/job/demo-pipeline-service/ \
                          -Dsonar.sourceEncoding=UTF-8 \
                          -Dsonar.java.binaries=target/classes \
                          -Dsonar.java.test.binaries=target/test-classes \
                          -Dsonar.java.surefire.report=target/surefire-reports
                       """
                }
            }
        }
   } 

通过上面的代码可以发现一些问题:

  • 扫描参数值都是写死的,无法使其他项目通用。
  • 代码中存在敏感数据信息。

既然想通用,就要制定规范。 例如:

  • 我们统一使用Jenkins的作业名称做为SonarQube项目名称。
  • 将Sonar在进行扫描时用到的认证信息,也存储到Jenkins的系统凭据中(Secret Text类型),避免流水线中存在敏感信息。然后使用withCredentials将凭据的值内容赋值给变量SONAR_TOKEN引用。
  • 使用BUILD_NUMBER作为sonarqube项目版本(可以使用时间戳、版本号、commitid)。
  • -Dsonar.links.ci=${BUILD_URL} SonarQube的扩展链接, 方便在系统中跳转。
  • -Dsonar.links.homepage=${env.srcUrl} SonarQube的扩展链接, 方便在系统中跳转。

优化后:

// 凭据列表
credentials = ["sonar" : '06bf5ee4-f571-4fe4-9b52-d17190ce54e5']

//服务器列表
servers = ["sonar": 'http://192.168.1.200:9000']

pipeline {
    
    ...

        stage("CodeScan"){
            steps{
                script {
                    withCredentials([string(credentialsId: "${credentials['sonar']}", variable: 'SONAR_TOKEN')]) {
                        sh """
                            sonar-scanner \
                              -Dsonar.projectKey=${JOB_NAME.split('/')[-1]} \
                              -Dsonar.projectName=${JOB_NAME.split('/')[-1]} \
                              -Dsonar.sources=src \
                              -Dsonar.host.url=${servers['sonar']} \
                              -Dsonar.login=${SONAR_TOKEN} \
                              -Dsonar.projectVersion=${BUILD_NUMBER} \
                              -Dsonar.ws.timeout=30 \
                              -Dsonar.projectDescription="my first project!" \
                              -Dsonar.links.homepage=${env.srcUrl} \
                              -Dsonar.links.ci=${BUILD_URL} \
                              -Dsonar.sourceEncoding=UTF-8 \
                              -Dsonar.java.binaries=target/classes \
                              -Dsonar.java.test.binaries=target/test-classes \
                              -Dsonar.java.surefire.report=target/surefire-reports
                        """
                    }
                }
            }
        }
}

上面我们完成了,一个Java类型项目的扫描参数设置。 但是是否想过在企业中存在多种语言类型的项目? 此时我们要让代码扫描变的更加灵活一些,支持多种类型的代码扫描。

  • 根据不同的构建工具,使用不同的代码扫描参数;
  • 例如: maven 对应java类型项目, npm对应前端类型项目

 最终将上述代码,纳入共享库。创建sonar.groovy。

package org.devops

def scanner(buildType,token,projectDescription,srcUrl){
    switch(buildType){
        case "maven":
         sh """
               sonar-scanner \
                -Dsonar.host.url=http://139.198.166.235:9000 \
                -Dsonar.projectKey=${env.JOB_NAME} \
                -Dsonar.projectName=${env.JOB_NAME} \
                -Dsonar.projectVersion=${env.BUILD_NUMBER} \
                -Dsonar.login=${token} \
                -Dsonar.ws.timeout=30 \
                -Dsonar.projectDescription="my first project!" \
                -Dsonar.links.homepage=${env.srcUrl} \
                -Dsonar.links.ci=${env.BUILD_URL} \
                -Dsonar.sources=src \
                -Dsonar.sourceEncoding=UTF-8 \
                -Dsonar.java.binaries=target/classes \
                -Dsonar.java.test.binaries=target/test-classes \
                -Dsonar.java.surefire.report=target/surefire-reports
                """
          break
        case "npm":
          sh """
          sonar-scanner \
                -Dsonar.projectKey=${env.JOB_NAME} \
                -Dsonar.projectName=${env.JOB_NAME} \
                -Dsonar.sources=src \
                -Dsonar.host.url=http://139.198.166.235:9000 \
                -Dsonar.login=${token} \
                -Dsonar.projectVersion=${env.BUILD_NUMBER} \
                -Dsonar.ws.timeout=30 \
                -Dsonar.projectDescription="my first project!" \
                -Dsonar.links.homepage=${env.srcUrl} \
                -Dsonar.links.ci=${env.BUILD_URL} \
                -Dsonar.sourceEncoding=UTF-8

          """
          break
        default:
        println("sonar error !")
    }
}

Jenkinsfile内容: 

@Library("devopslib@main") _

def project = new org.devops.build()
def sonar = new org.devops.sonarquebscanner()

def buildTools = ["maven": "/usr/local/apache-maven-3.8.1"]
def credentials = ["devops-maven-sonarqube": "f8b33d17-c1cf-428e-aa31-99d4038e59d0"]

String buildType = "${env.buildType}"
String projectDescription = "this is maven project"

currentBuild.description = "maven project"


pipeline {
    
   agent {
      label 'build'
   }

    stages {
        stage('CheckOut') {
            steps {
                checkout([$class: 'GitSCM', 
                          branches: [[name: "${branchName}"]], 
                          extensions: [], userRemoteConfigs: 
                          [[credentialsId: "${credentialsId}", 
                          url: "${srcUrl}"]]])
            }
        }
        
        stage('Build'){
           steps{
             script{
                project.build(buildType,buildTools)
             }
         }
     }
     
       stage("UnitTest"){
          steps{
             script{
               sh "${buildTools["maven"]}/bin/mvn test"
             }
         }
          post{
             success{
                script{
                     junit 'target/surefire-reports/*.xml'
                }
             }
         }
     }
      stage('CodeScan'){
           steps{
             script{
                 withCredentials([string(credentialsId: "${credentials['devops-maven-sonarqube']}", variable: 'token')]) {
        
                    sonar.scanner(buildType,token,projectDescription,srcUrl)
                 }
             }
         }
      }
   }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值