自动化代码审查平台: 基于Docker Compose整合Jenkins + SonarQube

本文涉及的产品
云原生数据库 PolarDB MySQL 版,通用型 2核4GB 50GB
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
简介: 自动化代码审查平台: 基于Docker Compose整合Jenkins + SonarQube

目录

代码审查平台

本文目标

环境要求

系统环境

组件服务版本

前言

代码评审

SonarQube简介

概述

部署流程

检查系统参数

设置系统参数

拉取代码

进入文件目录

创建数据卷目录

部署文件信息

执行启动脚本

部署成功信息

访问地址

环境配置

SonarQube

admin用户的权限配置:开启执行分析权限

创建访问Token

Jenkins

Jenkins初始密码查看

Jenkins集成Sonarqube

获取Sonarqube的Token

Jenkins中安装Sonar插件

Jenkins中配置Sonar插件

Jenkins集成GitLab

Jenkins集成Maven

Jenkins支持 Docker

Jenkins插件离线下载地址

Maven项目: 集成SonarQube进行代码审查

Idea: SonarLint插件使用

问题记录

SonarQube多分支的扫描

说明

社区版多分支扫描

开源插件

使用yum install java-1.8.0-openjdk 安装jdk后, 找不到安装路径或AVA_HOME没有输出信息



代码审查平台

本文目标

  1. 基于Docker Compose安装Jenkins + SonarQube
  2. 提交SpringBoot+Maven项目代码至GitLab
  3. GitLab通过WebHook自动触发Jenkins执行任务
  4. Jenkins获取代码,执行Sonar(阿里代码规约)分析代码。
  5. 在Sonar的服务器界面查看代码审查结果
  6. 在IDE的SonrLint中实时查看代码审查结果


环境要求

系统环境

CentOS 7

工具/环境 版本
CentOS 7
Docker 20.10.2
Docker-Compose 1.28.2


组件服务版本

工具/环境 版本
Jenkins 2.277.3
Sonarqube 8.5.0-community
postgres 13-alpine
GitLab

 Community Edition 12.5.5

Maven 3.6.3
JDK 1.8.0_292


前言

现如今大家越来越认识到质量前移的重要性。如果一开始就写出优质的、经过测试的代码,那么后面的测试阶段将会减少很多不必要的时间。

如果开发人员迫于业务压力,一味追求项目开发进度,往往会容易形成大量的“烂代码”。 一般的烂代码体现在逻辑混乱、复杂度高、易读性差、没有单元测试和缺乏必要的注释。如果把这样的“烂代码”编译交付测试团队,那么测试人员势必会发现很多低级缺陷,甚至连冒烟测试都无法通过,这样势必会浪费很多时间,延误测试进度。

所以,回到开始,为何不一开始就是写出优质代码呢?


代码评审

我们都知道很多公司都在推行DevOps、推行测试前移,就是让测试人员尽早参与研发过程中来,有很多团队推行了测试人员参与代码评审流程,但是往往效果不是很理想,原因通常是由于测试人员代码能力有限,不熟悉业务代码逻辑,当然也就无法发现正确问题,这样也就而导致测试团队的代码评审变成了摆设。那么问题来了,有什么办法解决这种状况吗?

如果测试人员在执行代码评审的时候可以借助一些代码扫描工具,然后针对这些扫描出的问题再进一步分析,这样轻易地可以发现一些真正代码问题


SonarQube简介

在实际的项目中,我们一般使用的多种编程语言,那么我们需要针对多种编程语言的一种扫描工具。

目前主流的是使用SonarQube代码质量分析平台。

SonarQube是一个开源的代码质量分析平台,便于管理代码的质量,可检查出项目代码的漏洞和潜在的逻辑问题。同时,它提供了丰富的插件,支持多种语言的检测, 如 Java、Python、Groovy、C#、C、C++等几十种编程语言的检测。

它主要的核心价值体现在如下几个方面:

  • 检查代码是否遵循编程标准:如命名规范,编写的规范等。
  • 检查设计存在的潜在缺陷:SonarQube通过插件Findbugs、Checkstyle等工具检测代码存在的缺陷。
  • 检测代码的重复代码量:SonarQube可以展示项目中存在大量复制粘贴的代码。
  • 检测代码中注释的程度:源码注释过多或者太少都不好,影响程序的可读可理解性。
  • 检测代码中包、类之间的关系:分析类之间的关系是否合理,复杂度情况。


概述

在典型的开发过程中:

  1. 开发人员在IDE中开发和合并代码(最好使用SonarLint在编辑器中接收即时反馈),然后将其代码签入ALM。
  2. 组织的持续集成(CI)工具可以检出,构建和运行单元测试,而集成的SonarQube扫描仪可以分析结果。
  3. 扫描程序将结果发布到SonarQube服务器,该服务器通过SonarQube接口,电子邮件,IDE内通知(通过SonarLint)和对拉取或合并请求的修饰(使用Developer Edition及更高版本时)向开发人员提供反馈。


部署流程

检查系统参数

sysctl vm.max_map_count #vm.max_map_count 大于或等于524288

sysctl fs.file-max #fs.file-max 大于或等于131072

ulimit –n #SonarQube的用户可以打开至少131072个文件描述符

ulimit –u #运行SonarQube的用户可以打开至少8192个线程


设置系统参数

sudo sysctl -w vm.max_map_count=262144
sudo sysctl -w fs.file-max=65536
ulimit -n 65536
ulimit -u 4096


拉取代码

git clone https://github.com/FLY-Open-DevOps/Jenkins-SonarQube-DockerCompose.git


进入文件目录

cd install/jenkins-sonarqube-docker-V2


创建数据卷目录

# Jenkins
mkdir -p /home/data/Jenkins/Jenkins_home
cd /home/data/Jenkins
chown -R 1000 Jenkins_home #把当前目录的拥有者赋值给uid 1000
# Sonarqube
mkdir -p /home/data/Sonarqube/conf
mkdir -p /home/data/Sonarqube/data
mkdir -p /home/data/Sonarqube/logs
# 挂载sonar-l10n-zh-plugin-1.16.jar和sonar-pmd-plugin-3.2.0-SNAPSHOT.jar文件
mkdir -p /home/data/Sonarqube/extensions/plugins
mkdir -p /home/data/Sonarqube/lib/bundled-plugins
# postgresql
mkdir -p /home/data/postgresql
mkdir -p /home/data/postgresql/data
chmod  777 /home/data/Jenkins/Jenkins_home
chmod  777 /home/data/Sonarqube/conf
chmod  777 /home/data/Sonarqube/data
chmod  777 /home/data/Sonarqube/logs
chmod  777 /home/data/Sonarqube/extensions/plugins
chmod  777 /home/data/Sonarqube/lib/bundled-plugins
chmod  777 /home/data/postgresql
chmod  777 /home/data/postgresql/data


拷贝插件和创建Maven环境

  • 拷贝install/jenkins-sonarqube-docker-V2/plugin/sonar-l10n-zh-plugin-1.16.jar和install/jenkins-sonarqube-docker-V2/plugin/sonar-pmd-plugin-3.2.0-SNAPSHOT.jar文件到 /home/data/Sonarqube/extensions/plugins
  • 使用install/jenkins-sonarqube-docker-V2/plugin/apache-maven-3.6.3创建Maven环境


部署文件信息

version: "3"
services:
  jenkins:
    image: jenkinsci/blueocean
    restart: unless-stopped
    container_name: jenkins
    ports:
      - "8080:8080"
    networks:
      - sonarnet
    privileged: true
    user: root
    environment:
      - TZ=Asia/Shanghai
    volumes:
      - /home/data/jenkins/jenkins_home:/var/jenkins_home
      # 保持 docker 中的时区跟 host 保持一致, 否则日志等时间都使用 UTC+0 时区, 跟中国时间差 8 个小时
      - /etc/localtime:/etc/localtime:ro
      # 挂载宿主机本地的maven环境
      - /usr/local/jt/apache-maven-3.6.3:/usr/local/maven
      # 让容器使用宿主的docker
      - /var/run/docker.sock:/var/run/docker.sock
      - /usr/bin/docker:/usr/bin/docker
      - /etc/docker:/etc/docker
  sonarqube:
    image: sonarqube:8.5.0-community
    container_name: sonarqube
    ports:
      - "9090:9000"
    networks:
      - sonarnet
    environment:
      - sonar.jdbc.url=jdbc:postgresql://postgres:5432/sonarqube
      - sonar.jdbc.username=sonar
      - sonar.jdbc.password=sonar
    volumes:
      # 保持 docker 中的时区跟 host 保持一致, 否则日志等时间都使用 UTC+0 时区, 跟中国时间差 8 个小时
      - /etc/localtime:/etc/localtime:ro
      - /home/data/sonarqube/conf:/opt/sonarqube/conf
      - /home/data/sonarqube/data:/opt/sonarqube/data
      - /home/data/sonarqube/logs:/opt/sonarqube/logs
      - /home/data/sonarqube/extensions:/opt/sonarqube/extensions
      - /home/data/sonarqube/lib/bundled-plugins:/opt/sonarqube/lib/bundled-plugins
    depends_on:
      - postgres
    restart: unless-stopped
  postgres:
    image: postgres:latest
    container_name: postgres
    ports:
      - "5432:5432"
    networks:
      - sonarnet
    environment:
      - TZ=Asia/Shanghai
      - POSTGRES_USER=sonar
      - POSTGRES_PASSWORD=sonar
      - POSTGRES_DB=sonarqube
    volumes:
      # 保持 docker 中的时区跟 host 保持一致, 否则日志等时间都使用 UTC+0 时区, 跟中国时间差 8 个小时
      - /etc/localtime:/etc/localtime:ro
      - /home/data/postgresql/:/var/lib/postgresql/
      - /home/data/postgresql/data/:/var/lib/postgresql/data/
    restart: unless-stopped
networks:
  sonarnet:
    driver: bridge


执行启动脚本

bash deploy-Jenkins-Sonarqube-stack.sh


部署成功信息

Creating postgres            ... done
Creating Jenkins             ... done
Creating Sonarqube           ... done


访问地址

Jenkins: http://192.168.172.128:8080
SonarQube: http://192.168.172.128:9090


环境配置


SonarQube

默认账号密码 admin,admin登录SonarQube


admin用户的权限配置:开启执行分析权限


创建访问Token

点击右侧头像–我的账号–安全

或者访问 http://192.168.172.128:9000/account/security/


整合阿里Java开发规范(p3c-pmd)

虽然已经集成了阿里P3C,但是使用的还是默认规则,这里我们需要设置为指定规则。

创建规则

管理员帐户登陆Sonarqube,【质量配置】-创建,填写【名称】和选择【语言】,点击【创建】p3c-java

点击创建后进入P3C规则界面,点击【更多激活规则】


激活规则

进入激活界面后,输入【p3c】过滤出规则,规则前都有【p3c】标识,选择【批量修改】,点击【激活p3c-java】

  • 这里只激活了51条规则,有点问题


设置规则

进入【质量配置】,设置默认规则


Jenkins

Jenkins初始密码查看

docker logs Jenkins
或者
# Get the initial admin password
docker exec my-Jenkins-3 cat /var/Jenkins_home/secrets/initialAdminPassword

2021-05-21 06:21:49.809+0000 [id=28] INFO Jenkins.install.SetupWizard#init:




Jenkins initial setup is required. An admin user has been created and a password generated.

Please use the following password to proceed to installation:

67868dccf20d4883a2584804987b3ae4

This may also be found at: /var/Jenkins_home/secrets/initialAdminPassword




2021-05-21 06:22:28.417+0000 [id=28] INFO Jenkins.InitReactorRunner$1#onAttained: Completed initialization


Jenkins集成Sonarqube

获取Sonarqube的Token

打Sonarqube,点击Administrator->security->user,点击token按钮,输入key后再点击generate进行生成,复制该token

2d99bc078e3cd46e4b77aa560ca66b5575a9fc47


Jenkins中安装Sonar插件

Jenkins中要实现代码扫描,需要在Jenkins中安装SonarQube Scanner插件。

从Jenkins的“系统管理”-“管理插件”中找到SonarQube Scanner插件并下载安装,重启Jenkins后生效。


Jenkins中配置Sonar插件

SonarQube servers 配置

系统管理–>系统设置–>SonarQube servers,填写Name和Server URL,Name可以随意填写,Server URL就是SonarQube的url地址,

除此之外,还需要配置token,token需要在在SonarQube中生成。

SonarQube Scanner配置

“系统管理”-“全局工具配置”-“SonarQube Scanner”,点击“SonarQube Scanner 安装”并配置SonarQube Scanner。


Jenkins集成GitLab

Jenkins中添加GitLab插件,选择直接安装,然后服务器中重启Jenkins。

GitLab中生成AccessToken

GitLab,在GitLab中用户设置—>访问令牌选项中生成token,scope为第一个等级:api

Jenkins中添加GitLab中生成的token

测试Jenkins连接GitLab


Jenkins集成Maven

在宿主机环境安装maven, 记得修改和生效/etc/profile

export MAVEN_HOME=/usr/local/jt/apache-maven-3.6.3
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.292.b10-1.el7_9.x86_64/jre/bin/java
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$MAVEN_HOME/bin:$JAVA_HOME/bin:$PATH

配置maven

进入“系统管理”-“全局工具配置”-“Maven”,配置maven

settings.xml配置

安装“Maven Integration”插件


创建Maven任务

进入任务的配置界面,在源码管理设置部分,选择“Git”,配置好工程的git地址以及获取代码的凭证信息。

然后在“Additional Behaviours”中添加“Clean before checkout”。可以根据自己的需要在“Branches to build”中设置所需要获取的代码分支。


源码管理

在源码管理设置部分,选择“Git”,配置好工程的git地址以及获取代码的凭证信息。然后在“Additional Behaviours”中添加“Clean before checkout”。可以根据自己的需要在“Branches to build”中设置所需要获取的代码分支。


在“构建环境”配置中勾选“Prepare SonarQube Scanner environment”。

添加“Execute SonarQube Scanner”

在“Post Steps”中点击“Add post-build step”,添加“Execute SonarQube Scanner”。

在“Task to run”中输入scan,即分析代码。

在“Analysis properties”中输入下面内容。

sonar.projectKey=webvr-end
sonar.projectName=webvr-end
sonar.language=java
sonar.java.binaries=$WORKSPACE/target/classes/ 
sonar.sources=$WORKSPACE/src

参数说明:

参数项 说明
sonar.projectKey 项目Key,需要唯一,建议使用GroupId+ArtifactId
sonar.projectName 项目名称,跟ArtifactId保持一致即可
sonar.projectVersion 项目版本,跟pom.xml保持一致即可
sonar.sources 源码目录,Java项目默认就是src,如果项目有多个module,那就需要配置为{moduleDirectory}/src
sonar.java.binaries 编译产出的classes目录,如果项目有多个module,那就需要配置为{moduleDirectory}/target/classes
sonar.language 项目语言,例如 Java、NodeJS、C#、PHP 等

Sonar报表指标简介

指标 简介
Bugs bug个数及评分
Vulnerabilities 安全漏洞个数及评分
Debt 债务(代码问题)持续时间
Code Smells 轻微问题:代码风格等等
Coverage 单元测试覆盖率
Duplications 代码重复率
Duplicated Blocks 代码重复块数


Jenkins支持 Docker

Docker-in-Docker: Jenkins CI 内部如何运行 docker


Jenkins插件离线下载地址

http://updates.jenkins-ci.org/download/plugins/


Maven项目: 集成SonarQube进行代码审查

https://glory.blog.csdn.net/article/details/117303914


Idea: SonarLint插件使用

https://glory.blog.csdn.net/article/details/117303504


问题记录

SonarQube多分支的扫描

说明

SonarQube Community 版本不支持多分支扫描,

SonarQube Developer Edition 及以上版本是支持多分支扫描的,扫描时指定分支参数-DSonar.branch=develop即可,就可以实现多分支代码扫描。

$ mvn clean verify Sonar:Sonar -Dmaven.test.skip=true -DSonar.branch=master


社区版多分支扫描

经过搜索和分析 Sonar 扫描原理,目前有2种方式可以实现。

  • 开源插件:Sonarqube-community-branch-plugin
  • 替换 Sonar.projectKey,porjectKey 相等于 Sonar 中每个项目的主键 ID,替换后就会以新项目创建


开源插件

插件地址:https://github.com/mc1arke/Sonarqube-community-branch-plugin

大致操作步骤:

  • 下载插件放到${Sonar_HOME}/extensions/plugins目录下,重启 Sonar。
  • 扫描时,增加-DSonar.branch.name=${GIT_BRANCH}即可。

替换 Sonar.projectKey

扫描时,指定不同的 Sonar.projectKey 即可。


使用yum install java-1.8.0-openjdk 安装jdk后, 找不到安装路径或AVA_HOME没有输出信息

https://glory.blog.csdn.net/article/details/117250344




相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
目录
相关文章
|
17天前
|
jenkins 持续交付 开发者
自动化部署:使用Jenkins和Docker实现持续集成与交付
【8月更文挑战第31天】本文旨在为读者揭示如何通过Jenkins和Docker实现自动化部署,从而加速软件开发流程。我们将从基础概念讲起,逐步深入到实际操作,确保即使是初学者也能跟上步伐。文章将提供详细的步骤说明和代码示例,帮助读者理解并应用这些工具来优化他们的工作流程。
|
4天前
|
运维 Docker 微服务
掌握 Docker Compose:简化你的多容器应用部署
在微服务架构和容器化技术普及的今天,管理多容器部署变得颇具挑战。Docker Compose 通过一个 YAML 文件定义和运行多容器应用,简化了部署和运维。本文介绍其基本概念、使用方法及优势,包括服务、项目、卷和网络等核心概念,并提供从安装到管理服务的详细步骤,助你轻松掌握 Docker Compose,提高开发效率和应用运维质量。
|
17天前
|
持续交付 jenkins Devops
WPF与DevOps的完美邂逅:从Jenkins配置到自动化部署,全流程解析持续集成与持续交付的最佳实践
【8月更文挑战第31天】WPF与DevOps的结合开启了软件生命周期管理的新篇章。通过Jenkins等CI/CD工具,实现从代码提交到自动构建、测试及部署的全流程自动化。本文详细介绍了如何配置Jenkins来管理WPF项目的构建任务,确保每次代码提交都能触发自动化流程,提升开发效率和代码质量。这一方法不仅简化了开发流程,还加强了团队协作,是WPF开发者拥抱DevOps文化的理想指南。
36 1
|
17天前
|
Kubernetes jenkins 持续交付
Jenkins 插件生态:提升自动化能力
【8月更文第31天】Jenkins 是一个开源的持续集成/持续交付(CI/CD)平台,广泛应用于软件开发的各个阶段。Jenkins 的一大特色就是其丰富的插件生态系统,这些插件极大地扩展了 Jenkins 的功能,使其能够适应各种各样的应用场景。本文将深入探讨 Jenkins 的插件生态系统,并指导如何选择和配置插件以满足特定需求。
40 1
|
27天前
|
jenkins Linux 持续交付
在Linux中,如何使用Jenkins和Ansible进行虚拟化环境的自动化和持续集成/持续部署(CI/CD)?
在Linux中,如何使用Jenkins和Ansible进行虚拟化环境的自动化和持续集成/持续部署(CI/CD)?
|
27天前
|
测试技术 Android开发 iOS开发
Appium 是一个开源的自动化测试框架,它支持多种平台和多种编程语言
Appium是一款开源自动化测试框架,支持iOS和Android多平台及多种编程语言。通过WebDriver协议,开发者可编写自动化测试脚本。在iPhone上实现屏幕点击等操作需安装Appium及其依赖,启动服务器,并设置所需的测试环境参数。利用Python等语言编写测试脚本,模拟用户交互行为,最后运行测试脚本来验证应用功能。对于iPhone测试,需准备真实设备或Xcode模拟器。
59 1
|
17天前
|
持续交付 jenkins C#
“WPF与DevOps深度融合:从Jenkins配置到自动化部署全流程解析,助你实现持续集成与持续交付的无缝衔接”
【8月更文挑战第31天】本文详细介绍如何在Windows Presentation Foundation(WPF)项目中应用DevOps实践,实现自动化部署与持续集成。通过具体代码示例和步骤指导,介绍选择Jenkins作为CI/CD工具,结合Git进行源码管理,配置构建任务、触发器、环境、构建步骤、测试及部署等环节,显著提升开发效率和代码质量。
34 0
|
17天前
|
JavaScript jenkins 持续交付
自动化部署与持续集成:使用Jenkins和Docker优化开发流程
【8月更文挑战第31天】在软件开发的世界里,时间就是一切。本文将引导你通过Jenkins和Docker的强大组合,实现自动化部署和持续集成,让你的开发流程如丝般顺滑。我们将从基础设置开始,逐步深入到构建管道,最终实现一键部署的梦想。准备好让你的开发效率飞跃,一起探索这个令人兴奋的旅程吧!
|
17天前
|
jenkins Shell 持续交付
自动化部署:使用Jenkins和Docker实现CI/CD
【8月更文挑战第31天】 本文旨在引导读者了解如何通过Jenkins和Docker来实现持续集成和持续部署(CI/CD),从而优化开发流程,提升工作效率。文章将详细介绍配置Jenkins服务器、创建Docker镜像以及设置自动化构建和部署的步骤。通过实际操作案例,我们将展示如何将代码变更快速部署到测试或生产环境,确保软件质量与发布速度的双重保障。
|
17天前
|
Kubernetes jenkins 持续交付
Jenkins 与 Kubernetes 的集成:实现高效的资源管理和自动化部署
【8月更文第31天】随着微服务架构的普及,Kubernetes 已经成为了容器编排的事实标准。Kubernetes 提供了一种强大的方式来管理容器化的应用程序,而 Jenkins 则是持续集成与持续部署(CI/CD)领域的一个重要工具。将 Jenkins 与 Kubernetes 集成,不仅可以充分利用 Kubernetes 的资源管理能力,还能通过 Jenkins 实现自动化构建、测试和部署,从而提高开发效率和部署速度。本文将详细介绍如何将 Jenkins 集成到 Kubernetes 环境中,并提供具体的代码示例。
50 0