Jenkins代码检查
阅读原文时间:2023年07月08日阅读:8

目录

静态代码分析是指在不允许程序的前提下,对源代码进行分析或检查,范围包括代码风格、可能出现的空指针、代码块大小、重复的代码等。

没有通过编译,静态代码分析就没有意义。所以在整个pipeline中,静态代码分析通常被安排在编译阶段之后。非编译型语言就另当别论了。

写代码时大括号该不该换行?对于这样的问题很容易引起争议,如果公司对代码定标准,那符合与否不可能找一个人总盯着,开发组着虽然管理代码合并,也不可能逐行去看检查是否符合标准。

代码检查规范的方案是使用构建工具或者代码分析器进行代码检查,不通过,pipeline就中止。

PMD进行检查

PMD(https://pmd.github.io)是一款可扩展的静态代码分析器,它不仅可以对代码风格进行检查,还可以检查设计、对线程、性能等方面的问题。

Maven的PMD插件,是我们能在Maven上使用PMD

1.在Maven项目的pom.xml中加入PMD插件

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-pmd-plugin</artifactId>
    <version>3.8</version>
    <configuration>
        <rulesets>
            <ruleset>rulesets/java/ali-comment.xml</ruleset>
            <ruleset>rulesets/java/ali-concurrent.xml</ruleset>
            <ruleset>rulesets/java/ali-exception.xml</ruleset>
            <ruleset>rulesets/java/ali-flowcontrol.xml</ruleset>
            <ruleset>rulesets/java/ali-naming.xml</ruleset>
            <ruleset>rulesets/java/ali-oop.xml</ruleset>
            <ruleset>rulesets/java/ali-orm.xml</ruleset>
            <ruleset>rulesets/java/ali-other.xml</ruleset>
            <ruleset>rulesets/java/ali-set.xml</ruleset>
        </rulesets>
        <printFailingErrors>true</printFailingErrors>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>check</goal>
            </goals>
        </execution>
    </executions>
    <dependencies>
        <dependency>
            <groupId>com.alibaba.p3c</groupId>
            <artifactId>p3c-pmd</artifactId>
            <version>1.3.5</version>
        </dependency>
    </dependencies>
</plugin>

maven-pmd-plugin插件并不会自动使用p3c-pmd,需要在引入dependencies部分手动加入p3c-pmd依赖,然后在rulesets属性中引入p3c的规则。

2.安装Jenkins PMD插件,作用是将PMD报告呈现在任务详情页中。

3.在Jenkkinsfile中加入pmd步骤

pipeline {
    agent any

    tools {
        maven 'mvn-3.5.4'
    }

    stages {
        stage('pmd') {
            steps {
                sh "mvn pmd:pmd"
            }
        }
    }

    post {
        always {
            pmd(canRunOnFailed: true, pattern: '**/target/pmd.xml')
        }
    }
}

执行完成后,可以在任务详情页看到PMD报告的链接

单机链接进入报告页面,可以看到更详细的信息

分析器区别

目前每种语言基本都有自己的静态代码分析器,比如JAVA语言,除了PMD外,还有Check-style、FindBugs等。但是没有一款能“大统一”,实现对所有语言和场景的支持。

另外,同一种语言下的不同分析器,他们在功能上既有区别,又有重叠,读者需要根据自己团队的情况进行选择。但是不论选择哪款分析器,所有进行静态代码分析的地方都必须统一分析规则。比如我们决定使用阿里巴巴的开发规范,那Maven插件、IDE插件以及SonarQube都必须使用;否则,分析结果可能会不一致,进而影响分析结果的可信度。

SonarQube是一个代码质量管理工 具,能对20多种编程语言源码进行代码味道( Code Smells)、Bug、 安全漏洞方面的静态分析。SonarQube有4个版本:开源版、开发者版、企业版、数据中心版( Data Center Edition)。

详细的区别,可前往官方网站进行了解,本篇使用的是开源版6.7.5LTS,假设读者已经安装此版本。

Maven与SonarQube集成

为方便起见,我们就不自己写例子了而是直接使用JUnit 4源码来做示例。将JUnit 4从GitHub克隆下来后,在pom.xml中加入SonarQube插件依赖。

<build>
    <plugins>
        <plugin>
            <groupId>org . codehaus . mojo</ groupId>
            <artifactId>sonar-maven-plugin</artifactId>
            <version>3.4.1.1168< /version>
        </plugin>
    </plugins>
</build>

执行命令:

mvn clean org.sonarsource.scanner.maven:sonar-maven-plugin:3.4.1.1168:sonar -Dsonar.host.url=http://127.0.0.1:9000

sonar.host.url参数用于指定SonarQube服务的地址。这时,就可以在SonarQube的"Projects" 中看到JUnit 4的分析结果,可以看到JUnit 4有11个Bug。

SonarQube服务默认允许任何人执行源码分析,因此在生产环境中使用会有安全隐患,以下几步可以提高其安全性:

1.设置SonarQube禁此非登录用户使用

2.为用户生成Token,Jenkins只能通过Token与SonarQube集成。登陆SonarQube,进入个人设置页面中的Security tab页

3.在执行mvn命令时加入相应的sonar.login参数

mvn clean package org.sonarsource.scanner.maven:sonar-maven- plugin:3.4.1.1168:sonar -Dsonar.host.url=http://192.168.1.8:9000 -Dsonar.login=e2f92b48d047be825fe3c2c06dec818788855a3e

Jenkins与SonarQube集成

将Maven与SonarQube集成,这时SonarQube对于Jenkins来说还是透明的,Jenkins并不知道代码质量如何。将集成Jenkins与SonarQube ,以实现当代码质量不合格时, Jenkins pipeline失败。

具体步骤如下:

1.Jenkins安装SonarQube Scanner插件

2.Jenkins配置SonarQube Scanner插件

3.SonarQube设置Webhooks,不同代码规模的源码,分析过程的耗时是不一样的。所以当分析完成时,由SonarQube主动通知Jenkins。设置方法就是进入SonarQube的Adminstration -》Configuration -》 Webhooks页 ,加入http://jenkins地址/sonarqube-webhook 这个接口地址由SonarQube插件提供

4.在Jenkinsfile中加入SonarQube的stage

pipeline {
    angent any
    tools {
        maven ' mvn- -3.5.4
    }

    stages {
        stage( 'Code Analysis') {
            steps {
                withSonarQubeEnv(' sonarqube') {
                    sh """
                    mvn clean package org.sonarsource.scanner.maven:sonar-maven-plugin:3.4.1.1168:sonar \
                    -Dsonar.host.url=${SONAR_ HOST_ URL} \
                    -Dsonar.login=${ SONAR_ AUTH_ TOKEN}
                    """
                }
            }
        }

        stage("Quality Gate" ) {
            steps {
                timeout(time: 1, unit: 'HOURS') {
                    waitForQualityGate abortPipeline: true
                }
            }
        }
    }
}

withSonarQubeEnv是一个环境变量包装器,读取的是我们所配置的变量。在它的闭包内,我们可以使用以下变量。

  • SONAR_HOST_URL : SonarQube服务的地址
  • SONAR_AUTH_TOKEN : SonarQube认证所需要的Token

waitForQualityGate步骤告诉Jenkins等待SonarQube返回的分析结果。当它的abortPipeline参数为true时,代表当质量不合格,将pipeline的状态设置为UNSTABLE。

我们同时使用了timeout包装器来设置waitForQualityGate步骤的超时时间,避免当网络出问题时, Jenkins任务-直处于等待状态。

5.设置Quality Gates(质量阈值)。 在SonarQube的"Quality Gates"下,我们可以看到系统自带的质量阈值,如图所示。可以看出它是针对新代码的。所以,在初次及没有新代码加入的情况下,执行代码分析是不会报出构建失败的。

代码扫描

使用Maven插件实现代码扫描的,也就是利用构建工具本身提供的插件来实现。在构建I具本身不支持的情况下,我们使用SonarQube本身提供的扫描工具(Scanner )进行代码扫描。

具体步骤如下:

1.在安装SonarQube Scanner插件后,设置扫描工具自动下载并安装(推荐)

也可以取消自动安装, 改成手动安装后指定目录

注意,这里的Name值与图中所设置的值是两码事,此处设置的是SonarScanner工具本身的名称与路径

2.在代码项目根目录下放入sonar-project.properties文件,sonar-scanner会读取其配置,内容如下:

# must be unique in a given SonarQube instance
sonar.projectKey=my:project

# this is the name and version displayed in the SonarQube UI. Was mandatory prior to SonarQube 6.1.
sonar.projectName=My project
sonar.projectVersion=1.0

# This property is optional if sonar . modules is set.
sonar.sources=.

# Encoding of the source code. Default is default system encoding
#sonar.sourceEncoding=UTF-8

3.pipeline部分代码如下:

script{
    def sonarHome = tool name: 'sonarqube3.2.0', type: 'hudson.plugins.sonar.SonarRunnerInstallation'
    withSonarQubeEnv('sonar') {
        sh "${sonarHome}/bin/sonar-scanner -Dsonar.host.url=${SONAR_HOST_URL} -Dsonar.login=${SONAR_AUTH_TOKEN}"
    }
}

SonarQube集成p3c

必须在所有做代码规范检查的地方使用同一套规范,而SonarQube默认使 用的是它自带的规范( SonarQube称为规则),所以也需要设置SonarQube使用p3c的规范。

有好心的朋友开源了SonarQube的p3cPMD插件,我们可以拿来直接使用。

具体步骤如下:

1.从GitHub下载p3c PMD插件,编译打包

2.将上一步打包好的JAR包放到SonarQube所在服务器的<SonarQube的home目录>/extensions/plugins目录下

3.SonarQube:创建p3c profile,单击SonarQube顶部的"Quality Profiles",然后单击面右上角的"Create"按钮,输入新profile名称,选择Java语言。

4.SonarQube在profile列表中找到刚刚创建的p3c profile,单击其最右边的下三角按钮,选择"Set as Default"

5.创建成功

6.SonarQube为p3c profile激活p3c规则,新创建的profile是没有激活任何规则的,需要手动激活。单击下三角按钮,选择“Activate More Rules”

7.跳转到激活页面,激活所有的p3c规则,这样当SonarQube分析Java代码时,就会使用p3c规则了。

将分析报告推送到GitLab

如果希望对每一次代码的commit都进行分析,并将分析结果与该commit关联起来,那么SonarQube的GitLab插件就是一个不错的选择。SonarQube Gitlab插件的功能就是将SonarQube的分析结果推送到GitLab。

1.在SonarQube上安装GitLab插件(https:/github.com/gabrie-allaigre/sonar-gitlab-plugin)如果因为网络原因安装失败,则可进行手动安装。

2.配置SonarQube GitLab插件

配置好SonarQube GitLab插件后,需要为sonar-scanner添加几个参数,以告诉SonarQube将分析结果关联到GitLab的相应commit上。

script{
    def sonarHome = tool name: 'sonarqube3.2.0', type: 'hudson.plugins.sonar.SonarRunnerInstallation'
    def GIT_COMMIT_ID = sh(
        script: "git rev-parse --short=10 HEAD",
        returnStdout: true
    )
    sh "${sonarHome}/bin/sonar-scanner -Dsonar.host.url=${SONAR_HOST_URL} -Dsonar.analysis.mode=preview -Dsonar.gitlab.ref_name=master -Dsonar.gitlab.project_ id=jenkins-book/sonarqube -Dsonar.projectName=jenkins-book -Dsonar.gitlab.commit_sha=${GIT_COMMIT_ID} -Dsonar.login=${SONAR_AUTH_TOKEN}"
}

首先通过sh步骤获取代码的commit ID,然后在执行扫描时加入如下参数。

-Dsonar.analysis.mode :分析报告模式,值为preview,代表将结果推送到GitLab。此参数虽然官方标注SonarQube 6.6后被废弃,但是笔者使用6.7版本依然需要加上它。

-Dsonar.gitlab.ref_name :分支名称

-Dsonar.gitlab.project_id : GitLab对应的项目路径

-Dsonar.projectName :对应SonarQube上的项目名称

-Dsonar.gitlab.commit_sha :代码的commit ID

当SonarQube分析完成后,我们就可以在GitLab的相应commit页面上的代码行内或commit评论区看到分析结果了

分析结果是显示在行内还是评论区,由SonarQube GitLab插件的配置决定。

Allure测试报告

是不是觉得JUnit输出的测试报告不美观。不只是JUnit ,很多其他编程语言的测试框架的测试报告也差不多。Allure测试报告是一个框架,能将各种测试报告更美观地呈现出来。

接下来,我们将Allure、Maven、Jenkins集成。 Allure与其他编程语言及构建工具的集成与此类似。

具体步骤如下:

1.安装Allure Jenkins插件,进入Jenkins的Manage Jenkins ——》Global Tool Configuration-》Allure Commandline页,配置Allure自动下载并安装的版本

2.在pom.xml文件中加入依赖

<dependency>
    <groupId>io.qameta.allure</groupId>
    <artifactId>allure-junit4</artifactId>
    <version>2.0-BETA13</version>
</dependency>

3.在pom.xml文件中加入Allure插件

<p1ugin>
    <groupId>org.apache.maven.plugins</ groupId>
    <artifactId>maven-surefire-plugin</artifactId>
    <version>2.19.1</version>
    <configuration>
        <argLine>
            - javaagent:" ${settings.localRepository}/org/aspectj/aspectjweaver/${aspectj.version}/aspectjweaver-${aspectj.version}.jar"
        </argLine>
        <properties>
            <property>
                <name>listener</name>
                <value>io.qameta.allure.junit4.AllureJunit4</value>
            </property>
        </properties>
        <systemProperties>
            <property>
                <name>allure.results.directory</name>
                <value>${project.build.directory}/allure- results</value>
            </property>
            <property>
                <name>allure.link.issue.pattern</name>
                <value>https://example.org/issue/{}</value>
            </property>
        </systemProperties>
    </configuration>
    <dependencies>
        <dependency>
            <groupId>org.aspectj</groupId>
            <artifactId>aspectjweaver</artifactId>
            <version>${aspectj.version}</version>
        </dependency>
    </dependencies>
</plugin>
<plugin>
    <groupId>io.qameta.allure</groupId>
    <artifactId>allure-maven</artifactId>
    <version>2.8</version>
</plugin>

4.在jenkinsfile中的post阶段加入allure步骤

script {
    allure([
        includeProperties: false,
        jdk:
        properties:[],
        reportBuildPolicy:' ALWAYS',
        results: [[path: 'target/allure-results']]
    ])
}

构建完成后,可以看到在构建历史记录中出现了Allure的logo,单击就可以进入优美的测试报告页面了

手机扫一扫

移动阅读更方便

阿里云服务器
腾讯云服务器
七牛云服务器

你可能感兴趣的文章