8. 在Jenkins中集成Sonar Qube和Sonar Scanner

1 SonarQube和SonarScan的安装配置

1.1 Windows环境下的安装和使用

1.1.1 启动sonarqube服务

image.png
image.png
image.png
image.png

1.1.2 在mysql里面创建一个存储扫描结果的库(比如sonarDB)

image.png

1.1.3 配置sonar qube的sonar.properties

image.png
sonar.jdbc.url=jdbc:mysql://localhost:3306/sonarDB?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance&useSSL=false

sonar.jdbc.username=root  

sonar.jdbc.password=root

sonar.sorceEncoding=UTF-8

1.1.4 重启sonar qube(使用ctrl + c)

停止sonar qube(使用ctrl + c)

image.png

然后重新启动sonar qube...

1.1.5 Sonar Scanner插件配置

image.png
sonar.jdbc.url=jdbc:mysql://localhost:3306/sonarDB?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance

sonar.jdbc.username=root

sonar.jdbc.password=root

# 如果测试项目与服务器不在同一台机子,则需要添加SonarQube服务器的IP:
sonar.host.url=http://localhost:9000

1.1.6 运行Sonar scanner

注意:需要提前把sonar qube运行起来

1.1.6.1 下载代码到本地

1.1.6.2 创建一个sonar-project.properties


sonar.projectKey=yay:project

# this is the name displayed in the SonarQube UI

sonar.projectName=whatproject.0project

sonar.projectVersion=1.0

# Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows.

# Since SonarQube 4.2, this property is optional if sonar.modules is set.

# If not set, SonarQube starts looking for source code from the directory containing

# the sonar-project.properties file.

sonar.sources=personrecord

sonar.java.binaries=newtarget

sonar.language=java

# Encoding of the source code. Default is default system encoding

sonar.sourceEncoding=UTF-8
image.png

1.1.6.3 运行sonar-scanner执行代码扫描

D:\svncode>D:\softwareback\devops\sonar\sonar-scanner-3.0.3.778-windows\bin\sonar-scanner
image.png

注意,在执行过程中很可能会遇到这种错误:
image.png

这主要是由于生产的报告大于mysql允许的最大包大小(比如默认值只允许4M)。
解决方法为修改mysql根目录里面的my.ini文件,增加一行:max_allowed_packet= 100M
我们可以查看mysql现有的包大小配置:
SHOW VARIABLES LIKE 'max_allowed_packet';


image.png
 [mysqld]
#设置3306端口
port = 3306

# 设置mysql的安装目录
basedir=D:/softwareback/db/mysql-5.7.26

# 设置mysql数据库的数据的存放目录
datadir=D:/softwareback/db/mysql-5.7.26/data


# 服务端使用的字符集默认为8比特编码的latin1字符集
character-set-server=utf8

default-storage-engine=INNODB
sql_mode=NO_ENGINE_SUBSTITUTION,STRICT_TRANS_TABLES

# 解决sonarscanner插件允许时候出错:ERROR: Failed to upload report - 500: An error has occurred. Please contact your administrator
max_allowed_packet= 100M

[mysql]
# 设置mysql客户端默认字符集
default-character-set=utf8

1.1.7 查看扫描结果

image.png

1.2 Centeros环境下的安装和使用

1.2.1 大多数安装环境和windows差不多

。。。

2. 和Jenkins集成

2.1 Mysql和Sonarqube加入到PATH中

image.png

2.2 SonarScanner Jenkins插件的安装

注意SonarScanner仍然需要在本地环境现安装好


image.png

image.png

image.png

2.3 在Jenkins上某个task上增加这个步骤

2.3.1 直接在Jenkins上配置

image.png

接下来是这个步骤的配置:
image.png
sonar.projectKey=HGARCH1.0.01:project
sonar.projectName=HGARCH1.0.01.0project
sonar.projectVersion=1.0.01
sonar.sources=.
sonar.java.binaries=output
sonar.language=java
sonar.sourceEncoding=UTF-8

然后到sonar系统修改一个地方,否则在运行Jenkins的job时候会出错


image.png

然后重启sonar
image.png

然后运行,注意上一步配置如果不做可能会出错:


image.png

运行成功后可以在Jenkins看到sonar上相关工程执行结果链接:


image.png

image.png

2.3.2 在pipeline脚本里面配置

image.png
pipeline{
    agent any
     tools {
        //工具名称必须在Jenkins 管理Jenkins → 全局工具配置中预配置。
        maven 'maven3'
    }

    environment{     
        def SRCCODE_DIR = "/var/jenkins_home/workspace/${env.JOB_NAME}"
        def DAILYCI_DIR = "/var/ciOutput/dailyCiOutput"
        def SVN_FOLD = "personrecord"  
    }
    

    options { 
        //pipeline保持构建的最大个数
        buildDiscarder(logRotator(numToKeepStr: '28')) 
    }

    triggers { cron('H 0,12 * * *') }

    stages{     
        stage('Checkout'){
             steps{
    
                checkout([
                      $class: 'SubversionSCM', 
                      additionalCredentials: [], 
                      excludedCommitMessages: '', 
                      excludedRegions: '', 
                      excludedRevprop: '', 
                      excludedUsers: '', 
                      filterChangelog: false, 
                      ignoreDirPropChanges: false, 
                      includedRegions: '', 
                      locations: [[credentialsId: '6aab1014-b1c9-4a8a-adba-f1cd0d27a483', 
                                   depthOption: 'infinity', 
                                   ignoreExternalsOption: true,                                    
                                   remote: "https://10.xxx.xxx.xxx/svn/ZYN/xxx/branch/V1.0/code/personrecord"]], 
                      workspaceUpdater: [$class: 'UpdateUpdater']])
            }
        }

        stage('Build'){
            steps{
                compileAllFiles()                                          
            }           
        }

        stage('Backend Unit Test') {
            steps {
                sh 'mvn -f $SVN_FOLD/algorithm/pom.xml test'
                sh 'mvn -f $SVN_FOLD/pom.xml test'

                //junit '**/target/surefire-reports/TEST-*.xml'
                //archive 'target/*.jar'                    
            }
        }


        stage('SonarQube Analysis') {
            steps {
                withSonarQubeEnv('snoar-6.7.7') {
                    script {
                        def sonarScanner = tool name: 'sonarscanner', type: 'hudson.plugins.sonar.SonarRunnerInstallation'
                        sh "${sonarScanner}/bin/sonar-scanner " +
                        "-Dsonar.projectKey=HGARCHMain:project " +
                        "-Dsonar.projectName=HGARCHMainProject " +
                        "-Dsonar.projectVersion=1 " +
                        "-Dsonar.sources=$SVN_FOLD " +
                        "-Dsonar.java.binaries=$SVN_FOLD/output " +                     
                        "-Dsonar.sourceEncoding=UTF-8"
                    }
                }
                //timeout(time: 15, unit: 'MINUTES') {
                //    script {
                //        def qg = waitForQualityGate()
                //        if (qg.status != 'OK') {
                            error "代码不满足Pipelin中Sonar设定的质量门限: ${qg.status}"
                //        }
                //    }
               // }             
            }
        }


        stage('UploadToRepository'){
            steps{                  
                    rmDailyCIOutputFiles() 
                    copyJarsToDailyCIOutoutDir()               
            }   
        }
        
        stage('copy to 118'){
            steps{              
            sshPublisher(publishers: [sshPublisherDesc(configName: 'fornanjing118', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: '', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: 'dailyOutput', remoteDirectorySDF: false, removePrefix: 'personrecord/output', sourceFiles: 'personrecord/output/**/*')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])
            }
        }

        stage('Deploy to 117'){
            steps{
                //调用Publish Over SSH插件,上传docker-compose.yaml文件并且执行deploy脚本
            sshPublisher(publishers: [sshPublisherDesc(configName: 'forchongqing117', transfers: [sshTransfer(cleanRemote: false, excludes: '', execCommand: 'sh /root/hgarchDevops/redeploy.sh', execTimeout: 120000, flatten: false, makeEmptyDirs: false, noDefaultExcludes: false, patternSeparator: '[, ]+', remoteDirectory: 'dailyOutput', remoteDirectorySDF: false, removePrefix: 'personrecord/output', sourceFiles: 'personrecord/output/**/*')], usePromotionTimestamp: false, useWorkspaceInPromotion: false, verbose: false)])

            //sh /root/hgarchDevops/redeploy.sh
            //remoteDirectory: '/root/hgarchDevops/dailyOutput'
            //flatten: true会避免copy过来的jar包在personrecord/output中
            //personrecord/output/*.jar

            //. ./hgarchDevops/dailyOutput/redeploy.sh
            }
        }       
    }

    post {      
        failure
            {
                sh '$mail'
            }       
    }
}
def compileAllFiles()
{
    //执行shell命令
    sh 'mvn -f $SVN_FOLD/algorithm/pom.xml clean scala:compile compile package -DskipTests=true'
    sh 'mvn -f $SVN_FOLD/pom.xml clean package' 
}

def rmDailyCIOutputFiles()
{   
    sh 'rm -rf $DAILYCI_DIR.'
}
def copyJarsToDailyCIOutoutDir()
{
    if (isUnix())
    {
        sh 'cp -r $SVN_FOLD/output/* $DAILYCI_DIR'              
    }
    else
    {       
        bat 'cp -r $SVN_FOLD/output/* $DAILYCI_DIR'
    }   
}

def mail=
{
    emailext body: emailBody(),//"${env.DEFAULT_CONTENT}",
    recipientProviders: [ //[$class: 'CulpritsRecipientProvider'],
    //[$class: 'DevelopersRecipientProvider'],
    //[$class: 'RequesterRecipientProvider'],
    //[$class: 'FailingTestSuspectsRecipientProvider'],
    [$class: 'FirstFailingBuildSuspectsRecipientProvider'],
    [$class: 'UpstreamComitterRecipientProvider']
    ],
    subject: '构建失败',
    mimeType: "text/html"
}

def emailBody()
{
    return '''    
        
        
        
    ${ENV, var="JOB_NAME"}-第${BUILD_NUMBER}次构建日志    
        
        
        
            
                本邮件由系统自动发出,无需回复!
各位同事,大家好,以下为${PROJECT_NAME }项目构建信息
构建结果 - ${BUILD_STATUS}

构建信息

失败用例


$FAILED_TESTS

最近提交(#$SVN_REVISION)


    ${CHANGES_SINCE_LAST_SUCCESS, reverse=true, format="%c", changesFormat="
  • %d [%a] %m
  • "}
详细提交: ${PROJECT_URL}changes
''' }

你可能感兴趣的:(8. 在Jenkins中集成Sonar Qube和Sonar Scanner)