问题
- 
gitlab CI cancel 之后,后台 maven 子进程并没有被杀死,导致第二个 runner 服务依旧处于 pedding 状态。前台多次操作 cancel 并重启后,服务器资源直接耗尽,需要重启 sonar 所在的服务器才行。未解决(加了每次服务启动前关闭别的扫描服务,好像并没有什么用) 
- 
虽然之前添加了插件,但是没有使用 sonar 的 PR/MR 扫描模式,每次都是全量进行扫描,并且加上了 merge 阻断,导致每次都需要 merge 前等待,耗时较久。已解决 
- 
sonar 的 webhook 要转发到飞书,之前偷懒没有写一个服务进行转发,导致卡片样式比较难看。已解决 
PR/MR 扫描模式
添加了这种扫描模式之后,由于新代码是与 master 分支进行比较,需要写一个定时的 ci 对 master 分支进行全量的扫描
.gitlab-ci.yml
| 12
 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"
 GIT_DEPTH: "0"
 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:
 
 - 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
- 
创建一个中间服务(建议使用 Spring Boot 或 Node.js)监听 SonarQube Webhook。 
- 
接收到 Webhook 后,解析 payload,构造上面的卡片格式 JSON。 
- 
将卡片格式消息 POST 到飞书机器人地址 
项目结构
| 12
 3
 4
 5
 6
 
 | sonar-feishu-webhook/├── app.js
 ├── feishu.js
 ├── Dockerfile
 ├── package.json
 └── .env
 
 | 
部署
- 
项目文件准备 
- 
构建镜像 
| 1
 | docker build -t sonar-webhook-feishu .
 | 
- 
运行容器 
| 12
 3
 4
 
 | docker run -d --name sonar-feishu \-p 9999:3000 \
 --env-file .env \
 sonar-webhook-feishu
 
 | 
- 
在 SonarQube 后台 Webhook 中配置 
| 1
 | your-address/webhook/sonar
 |