Jenkins + SonarQube 从原理到实战四:Jenkins 与 Gerrit 集成并实现自动任务

前言

前面我们已经部署了 SonarQube,并加入了 sonar-cxx 插件,实现了 C/C++ 代码扫描,同时打通了 Windows AD 域,实现了 AD 用户登录与权限管控。

原计划本篇(第四篇)完成 Jenkins + Gerrit + Sonar 的 CI 部分集成,但回顾发现,自己对 Jenkins + Gerrit 集成已经忘得七七八八,很多人可能也不太清楚 Jenkins 如何与 Gerrit 仓库集成。因此,本篇我们先单独讲 Jenkins 与 Gerrit 的集成过程,复习一下操作方法,同时演示如何实现自动任务,也给自己记录一下,最后实现自动触发 Jenkins 任务,通过以下三种方式

  • Freestyle Job(Git 源码管理)
  • Freestyle Job( 源码管理,仅执行自定义 Bash)
  • Pipeline Job(带条件触发和 Gerrit 事件信息传递)

下一篇我们再详细讲 Jenkins + Sonar 的集成,下下篇再讲如何分析需求并构建完整 CI 流程。


前期准备

在正式操作之前,需要确保以下环境已经就绪:

  1. Gerrit 仓库

    • 已部署 Gerrit 并可访问。
    • Jenkins 所在机器能访问 Gerrit 服务。
  2. Jenkins

    • 已安装并启动。

    • 已安装插件

      • Gerrit Trigger Plugin(用于监听 Gerrit 事件)
      • Git Plugin(用于拉取 Gerrit 仓库代码)
      • Pipeline Plugin(用于定义 Pipeline Job)
  3. 账号与权限

    • Jenkins 需要在 Gerrit 上有一个用户账号,能读取项目、下载 patch等权限。
      也就是在 Gerrit 服务器的测试仓库上给该账号配置了 Read、Label Code-Review、Label Verified 等权限
    • Gerrit 上应配置相应的 HTTP 或 SSH 访问权限。

原理解析

Jenkins 与 Gerrit 的集成主要依赖 Gerrit Trigger Plugin。其原理如下:

  1. Gerrit 事件

    • 当开发者向 Gerrit 提交 patch(Change)或评论时,Gerrit 会发送事件通知。
    • 事件类型包括:Patchset Created、Change Merged、Comment Added 等。
  2. Jenkins 接收事件

    • Jenkins 安装 Gerrit Trigger Plugin 后,会监听这些事件。
    • 根据预设的规则触发相应 Job,例如 Freestyle Job 或 Pipeline Job。
  3. 代码拉取与执行

    • Jenkins Job 根据 Refspec 下载对应的 patch 或分支代码。
    • Job 可以执行构建、单元测试、静态扫描(如 SonarQube)等操作。
    • 执行结果可反馈给 Gerrit,例如自动打分或发表评论。

Jenkins 与 Gerrit 集成操作步骤

Jenkins 与 Gerrit 集成靠 Jenkins 的 Gerrit Trigger Plugin 插件。

配置 Gerrit Trigger Plugin

  1. 进入 Jenkins 管理 → 插件管理 → 安装 Gerrit Trigger Plugin

  2. 安装完成后,进入 Jenkins 系统设置 → Gerrit Trigger → 添加 Gerrit 服务器:

    • Name :自定义(如 gerrit.example.com:8080
    • Hostnamegerrit.example.com
    • Frontend URLhttp://gerrit.example.com:8080/
    • SSH Port:默认 29418
    • Username :Jenkins 用于访问 Gerrit 的账号(我这里用 jenkins 账号)
    • E-mail : Gerrit 用户邮箱(我这里用 jenkins@example.com 邮箱)
    • SSH Keyfile:私钥路径(Jenkins 生成)

    注:这里是要对应的公钥,是要提前上传到 Gerrit 对应 jenkins 账号 ssh 配置里,说白了就是通过 ssh 密钥实现 gerrit 与 jenkins 关联。

其他的则按需配置。

Jenkins 任务配置

实现功能:

  • 自动通过钩子,由 Gerrit 行为自动触发 Jenkins 任务。
  • 指定某仓库某分支下,若新建 Patch 或 Patch 评论出现关键字,就触发了 Jenkins 任务。

以下操作中,仓库我使用 TestProject、分支使用 TestBranch

1、创建 Freestyle Job(Git 源码管理)

  1. 新建 Freestyle 项目。

  2. 源码管理 选择 Git:

    • Repository URL:http://jenkins@gerrit.example.com:8080/TestProject
    • Credentials:(选择 jenkins 连 gerrit 的账号密码)
    • Refspec:+refs/changes/*:refs/changes/*(在高级选项,用于拉取 Gerrit Patch)
    • Branches to build:${GERRIT_REFSPEC}(指定分支,变量由 Gerrit Trigger 提供)
    • Wipe out repository & force clone:(在新增下面添加,用于清空仓库)
  3. 构建触发器 中勾选 Gerrit event

    • Repository URL:(勾选前面配置的 gerrit 服务器)
    • Patchset Created:(Trigger on 新增,新建 Patch 即触发)
    • Comment Added Contains Regular Expression:Value 输入 sonar-scan (Trigger on 新增,Patch 里出现 sonar-scan 触发)
    • Gerrit Project:(Project:TestProject,Branch:TestBranch,监控的仓库和分支)
  4. 构建步骤(Build Steps)可执行 shell 脚本或调用构建工具,如 make等。

效果:开发者提交 Patch 或 Patch 出现关键字,Job 自动触发,拉取 patch 并执行构建。

简要说明:

  1. 配置了 Git 源码管理,可以让 Jenkins 任务在执行任务时先行下载代码再执行后续步骤。
  2. Git 源码管理配置 Refspec 和 Branches to build 为的是下 Patch(未合并)的内容,若不配置,则下的是已合并的最新版本。
  3. 只有配置了 Gerrit event 才能实现自动触发任务。
  4. Git 源码管理(下代码)也可以通过执行 Shell 替换。

2、创建 Freestyle Job(无源码管理)

配置几乎和上面一样,实现一样的效果,但是不配置 Git 源码管理。

通过 Shell 编写命令 git clone 去下载 Patch(未合并)的内容。

  1. 新建 Freestyle 项目。
  2. 源码管理 选择 无:
  3. 构建触发器 中勾选 Gerrit event
    • Repository URL:(勾选前面配置的 gerrit 服务器)
    • Patchset Created:(Trigger on 新增,新建 Patch 即触发)
    • Comment Added Contains Regular Expression:Value 输入 sonar-scan (Trigger on 新增,Patch 里出现 sonar-scan 触发)
    • Gerrit Project:(Project:TestProject,Branch:TestBranch,监控的仓库和分支)
  4. 构建步骤(Build Steps)-执行 shell 脚本,执行下载代码编译等,参考如下:
bash 复制代码
#!/bin/bash

USERNAME="jenkins"
PASSWORD="jenkins"

GERRIT_SERVER="gerrit.example.com:8080" # 替换为真实的 Gerrit 服务器地址和端口
REPO_URL="http://${USERNAME}:${PASSWORD}@${GERRIT_SERVER}/TestProject  "

# === 清理工作区 (模拟 Wipe out) ===
echo "清理工作区..."
rm -rf ./* || true
rm -rf ./.git || true

# === 初始化仓库并下载代码 ===
echo "初始化仓库并设置远程..."
git init .
git remote add origin "${REPO_URL}"

# 关键:检查 $GERRIT_REFSPEC 是否存在(由Gerrit事件触发)
if [ -n "${GERRIT_REFSPEC}" ]; then
    echo "触发自Gerrit事件,使用 REFSPEC: ${GERRIT_REFSPEC}"
    # 拉取Gerrit特定的 change ref
    git fetch origin "${GERRIT_REFSPEC}"
    # 检出该 Patchset 代码
    git checkout FETCH_HEAD
else
    echo "非Gerrit事件触发 (可能是手动触发),使用默认分支(例如:master/TestBranch)"
    # 获取默认分支(可以根据需要调整)
    DEFAULT_BRANCH="master"  # 或者 "TestBranch"
    git fetch origin "${DEFAULT_BRANCH}"
    git checkout -b "${DEFAULT_BRANCH}" "origin/${DEFAULT_BRANCH}" # 或直接 git checkout FETCH_HEAD
fi

# ===(后续是你的构建步骤,例如:执行Maven、SonarQube扫描等)===
echo "代码检出完成。当前工作区内容:"
ls -la

效果:开发者提交 Patch 或 Patch 出现关键字,Job 自动触发,拉取 patch 并执行构建等(与上边用 Git 源码管理效果一致)

注:

上面 USERNAME、PASSWORD 等变量这些可以在 freestyle job 的 创建话构建过程 上面自定义,然后 bash 直接调用 ,并且密码类型可以选择 密码参数,这样就不会明文显示密码、密钥这些了。

3、创建 Pipeline Job

  1. 新建 流水线 项目(Pipeline)。
  2. 构建触发器 中勾选 Gerrit event
    • Repository URL:(勾选前面配置的 gerrit 服务器)
    • Patchset Created:(Trigger on 新增,新建 Patch 即触发)
    • Comment Added Contains Regular Expression:Value 输入 sonar-scan (Trigger on 新增,Patch 里出现 sonar-scan 触发)
    • Gerrit Project:(Project:TestProject,Branch:TestBranch,监控的仓库和分支)
  3. 配置 流水线 - Pipeline script,如下:
pipline 复制代码
pipeline {
    agent { label 'test1' }
    environment {
        REPO_URL = "http://gerrit.example.com:8080/IT/it_test1"
        // 使用WithCredentials绑定的变量名
        GIT_CREDENTIALS = credentials('32598744-3xxx-xxxx-xx...') // 这会生成 GIT_CREDENTIALS_USR 和 GIT_CREDENTIALS_PSW
    }
    stages {
        stage('Checkout') {
            steps {
                cleanWs()
                sh '''
                    # 使用凭证环境变量
                    git init .
                    git remote add origin http://$GIT_CREDENTIALS_USR:$GIT_CREDENTIALS_PSW@gerrit.example.com:8080/TestProject

                    if [ -n "${GERRIT_REFSPEC}" ]; then
                        echo "Gerrit Triggered: ${GERRIT_REFSPEC}"
                        git fetch origin "${GERRIT_REFSPEC}"
                        git checkout FETCH_HEAD
                        pwd
                        ls -l
                    else
                        echo "Manual build, using default branch"
                        git fetch origin TestBranch
                        git checkout FETCH_HEAD
                        pwd
                        ls -l
                    fi
                '''
            }
        }
    }
}

效果:开发者提交 Patch 或 Patch 出现关键字,Job 自动触发,拉取 patch 并执行构建等(与上边效果一致)

简要说明:

  1. agent { label 'test1' },我是放在 test1 节点上运行
  2. GIT_CREDENTIALS = credentials('32598744-3xxx-xxxx-xx...'),后面那串是 Jenkins 系统保存密码的对应 ID,路径:Credentials → System → Global credentials → 在凭据列表中查看 ID 列 ,使用 credentials() 方法,会自动生成会自动生成 GIT_CREDENTIALS_USR和 GIT_CREDENTIALS_PSW变量,并且凭据变量仅在当前 stage或 withEnv块内有效,退出后自动销毁。
  3. Pipeline 亦可通过变量的形式调用参数,如:Gerrit 服务器地址,仓库名,分支名等,均可在 创建话构建过程 上面自定义。
  4. 其他则执行 shell 实现完整流水线。

总结

上面演示的方法很多,但管理起来最方便肯定是第二第三种的,任何复杂不复杂的变动都可以靠自己写shell或其他脚本去执行

但是如果是新部署jenkins,要加入jenkins的节点特别特别多,总不可能每台机都一台一台手动加入jenkins节点(输密码账号什么的,我也不确定能不能批量加入),特别是java版本不匹配的情况下还得给这个节点单独装一个java,这样特别麻烦,

但是,我可以在所有节点上面加一个ansiblie,jenkins的节点只要有一个或者两个ansible就好了,jenkins任务就调用ansblie的一个通用脚本(传不同参数做不同的事情),ansible再去调用指定设备去执行一些任务,后续管理只需要再ansible上做就好了,不用专门维护多个地方,并且这些设备只要被ssh过去就行,还不用安装什么软件,方便得很。缺点就是,一个是能在jenkins上看到节点在线状态,ansible就不行。

下一篇我就讲一下,Jenkins与Sonar+gerrit集成,通过Sonar+gerrit的方式集成进来,自动打分加评论,同时说一下sonar社区版有什么区别,jenkins上面有一个叫gerrit-sonar的插件,但是得对应sonar开发或商业版,我只能找社区版本的解决方案。

思路延伸

上面演示了三种方法,但管理起来最方便的还是 第二种第三种 方式。无论需求复杂还是简单,都可以通过自定义 Shell 或脚本灵活实现,减少对 Jenkins 固有功能的依赖。

不过在实际部署中,如果需要批量加入大量 Jenkins 节点,就会遇到不少麻烦:无法逐一手动添加节点,还要处理各节点 Java 版本不一致的问题,甚至还可能需要额外安装 Java。对此,可以对所有节点上统一部署 Ansible 来简化运维。

只需在 Jenkins 中保留一到两个节点作为 Ansible 控制端,再由 Job 调用一个 通用脚本 (传递参数的方式实现不同功能),最后让 Ansible 去执行具体任务即可。这样一来,后续管理集中在 Ansible 端即可,节点只要能被 SSH 访问就能纳入体系,不需要额外安装软件,维护起来更加轻量。

管理人员只需要维护这个 通用脚本 就行了。

当然缺点是 Jenkins 无法直接显示节点的在线状态,需要通过其他方式来监控。

总结

下一篇文章会说下 Jenkins 与 Sonar + Gerrit 的集成,包括如何通过 Sonar + Gerrit 的方式实现自动打分和评论反馈。同时也会分析 SonarQube 社区版与开发版/商业版的区别。

Jenkins 上的 Sonar Gerrit Plugin 插件可以解决实现这些功能,但该插件需要对应 Sonar 的开发版或商业版才能使用(或旧版本)。所以后面会重点说下当前最新社区版(LTS 9.9x)与 Jenkins 和 Gerrit 集成的解决方案和思路。

相关推荐
Sadsvit41 分钟前
网络聚合链路与软件网桥配置指南
linux·运维·服务器·网络·centos
网硕互联的小客服1 小时前
如何配置安全的SFTP服务器?
运维·服务器·安全
程序员不迷路2 小时前
Nginx学习
运维·nginx
雅菲奥朗2 小时前
雅菲奥朗SRE知识墙分享(一):『SRE对智能运维领域所产生的深远影响』
运维·ai·sre
测试老哥2 小时前
Jmeter自动化性能测试常见问题汇总
自动化测试·软件测试·测试工具·jmeter·接口测试·压力测试·性能测试
--运维实习生--3 小时前
shell脚本第二阶段-----选择结构
linux·运维·shell编程
Hello.Reader4 小时前
Elasticsearch Rails 集成(elasticsearch-model / ActiveRecord)
大数据·elasticsearch·jenkins
果子⌂4 小时前
Git+Jenkins实战(一)
运维·git·jenkins
chenglin0164 小时前
Logstash——输出(Output)
运维·jenkins