SonarQube 与 GitLab 集成(二)
Kiml Lv5
  • 前言
    sonar 脚本之前一直在测试分支上跑,虽然有每次构建拉取事件很长的毛病,但影响不大还能忍受。最近把 sonar 上到 master 环境中,出现了大问题。。。

  • 更新

1
25-04-11 初始记录

问题

  1. gitlab CI cancel 之后,后台 maven 子进程并没有被杀死,导致第二个 runner 服务依旧处于 pedding 状态。前台多次操作 cancel 并重启后,服务器资源直接耗尽,需要重启 sonar 所在的服务器才行。未解决(加了每次服务启动前关闭别的扫描服务,好像并没有什么用)

  2. 虽然之前添加了插件,但是没有使用 sonar 的 PR/MR 扫描模式,每次都是全量进行扫描,并且加上了 merge 阻断,导致每次都需要 merge 前等待,耗时较久。已解决

  3. sonar 的 webhook 要转发到飞书,之前偷懒没有写一个服务进行转发,导致卡片样式比较难看。已解决

PR/MR 扫描模式

添加了这种扫描模式之后,由于新代码是与 master 分支进行比较,需要写一个定时的 ci 对 master 分支进行全量的扫描

.gitlab-ci.yml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
stages:  
- sonarqube
- noop
sonarqube-check:
stage: sonarqube
tags:
- sonar
variables:
SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar" # Defines the location of the analysis task cache
GIT_DEPTH: "0" # Tells git to fetch all the branches of the project, required by the analysis task
cache:
key: sonar-cache
paths:
- .sonar/cache
before_script:
- echo "检查并终止之前的 Maven 进程..."
- |
# 查找并终止之前的 Maven 进程
maven_pids=$(pgrep -f "gitlab_sonarci_run" || true)
if [ -n "$maven_pids" ]; then
echo "发现之前的 Maven 进程,正在终止..."
echo "$maven_pids" | xargs kill -TERM || true
echo "$maven_pids " | xargs wait || true
else
echo "未发现之前的 Maven 进程。"
fi
script:
- JAVA_HOME=你的服务地址 && export JAVA_HOME
- export SONAR_JAVA_OPTS="-Xmx2G -Xms1G"
- |
echo "启动 SonarQube 分析..."
run_scan() {
mvn verify sonar:sonar -T 2 \
-Dsonar.projectKey=你的key \
# 这部分数据会在 merge_request_event 时由 gitlab 进行填充
-Dsonar.pullrequest.key=$CI_MERGE_REQUEST_IID \
-Dsonar.pullrequest.branch=$CI_COMMIT_REF_NAME \
-Dsonar.pullrequest.base=$CI_MERGE_REQUEST_TARGET_BRANCH_NAME \
-Dmaven.test.skip=true \
-Dsonar.qualitygate.wait=true \
-Dsonar.ce.parallel=1 \
-Dmaven.repo.local=你的本地仓库 \
-s 你的maven配置地址 \
-Dci.tag=gitlab_sonarci_run &
}
run_scan
allow_failure: false
rules:
# 如果 SKIP_SONAR 为 "true",跳过任务
- if: '$SKIP_SONAR == "true"'
when: never
# 在合并请求时触发
- if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"'

noop:
tags:
- sonar
stage: noop
script:
- echo "Pipeline skipped all main jobs."
rules:
# 在合并请求时触发
- if: '$CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"'

sonarqube-master-daily:
tags:
- sonar
stage: sonarqube
script:
- JAVA_HOME=你的服务地址 && export JAVA_HOME
- export SONAR_JAVA_OPTS="-Xmx2G -Xms1G"
- |
echo "启动 SonarQube 分析..."
run_scan() {
mvn verify sonar:sonar -T 2 \
-Dsonar.projectKey=你的key \
-Dsonar.branch.name=master \
-Dmaven.test.skip=true \
-Dsonar.qualitygate.wait=true \
-Dsonar.ce.parallel=1 \
-Dmaven.repo.local=你的仓库地址 \
-s 你的maven配置文件地址 \
-Dci.tag=gitlab_sonarci_run &
}
run_scan
rules:
- if: '$CI_COMMIT_BRANCH == "master" && $CI_PIPELINE_SOURCE == "schedule"'

定时 ci 添加

gitlab 定时 CI 会去扫 master 下的 .gitlab-ci.yml 文件,

webhook 转发

node.js 代码地址:https://github.com/kiml-rgb/sonar-feishu-webhook.git

  1. 创建一个中间服务(建议使用 Spring Boot 或 Node.js)监听 SonarQube Webhook。

  2. 接收到 Webhook 后,解析 payload,构造上面的卡片格式 JSON。

  3. 将卡片格式消息 POST 到飞书机器人地址

项目结构

1
2
3
4
5
6
sonar-feishu-webhook/
├── app.js
├── feishu.js
├── Dockerfile
├── package.json
└── .env

部署

  1. 项目文件准备

  2. 构建镜像

1
docker build -t sonar-webhook-feishu .
  1. 运行容器

1
2
3
4
docker run -d --name sonar-feishu \
-p 9999:3000 \
--env-file .env \
sonar-webhook-feishu
  1. 在 SonarQube 后台 Webhook 中配置

1
your-address/webhook/sonar
 评论
评论插件加载失败
正在加载评论插件
由 Hexo 驱动 & 主题 Keep
访客数 访问量