静态代码检测配置及集成应用说明
# SonarQube 与 GitLab 集成使用说明
以下为开发环境提交检查(Dev 分支)与目标分支合并检测(Test 分支/MR)的配置说明,涵盖前后端项目。
# 一、前置条件
SonarQube 服务
- 确保已生成项目对应的
PROJECTKEY
和PROJECTNAME
,在 SonarQube 界面中创建同名项目。 - 在 GitLab 的 Settings > CI/CD > Variables 中添加以下变量:
SONAR_HOST_URL = http://192.168.0.184:9000/ # SonarQube 服务地址 SONAR_TOKEN = fd366e29270da8873b9d4477a781e7ee982aa2ba # SonarQube 用户令牌 # 已在公司gitlab上全局配置,不用管
- 确保已生成项目对应的
GitLab Runner 环境
- 确保 Runner 标签(如
build
)与任务匹配,且已激活。 - Java/Node 镜像需包含
git
、mvn
/npm
和sonar-scanner
命令行工具。 - 已配置,不用管!
- 确保 Runner 标签(如
GitLab Runner 环境
找到需要检测的代码仓库->设置->runner 点击在此项目启动
# 二、配置说明
# 1. 后端(Java)项目配置(.gitlab-ci.yml)
# 开发环境检查(Dev 分支)
关键字段说明:
# 项目变量(需修改) variables: PROJECTKEY: "srm:service-auth" # 替换为实际 SonarQube 项目 Key 前缀换成以项目简称命名例如:bdscm-service-auth PROJECTNAME: "产品SRM:service-auth" # 替换为 SonarQube 显示名称 前缀换成以项目简称命名例如:白帝-service-auth only: - dev # 仅 dev 分支提交触发 这个需要换成触发的分支 before_script 中分支操作: - | if [ -d ".git" ]; then echo ".git 目录存在,跳过初始化,直接克隆仓库" git clone -b dev --depth=0 --progress "${CI_REPOSITORY_URL}" . # 强制克隆 dev 分支 这个需要换成触发的分支 else echo ".git 目录不存在,初始化仓库" git init git remote add origin "${CI_REPOSITORY_URL}" git fetch git checkout -b dev origin/dev # 强制克隆 dev 分支 这个需要换成触发的分支
完整配置示例: 使用文中提供的后端 .gitlab-ci.yml,确保镜像、缓存路径与仓库结构匹配。
stages: - sonarqube-check # SonarQube 检查 variables: PROJECTKEY: "srm:service-auth" PROJECTNAME: "产品SRM:service-auth" sonarqube-check: stage: sonarqube-check image: registry.thsrm.com/public/maven:3.6.3-jdk-11 variables: GIT_STRATEGY: none # 禁用 Runner 的自动克隆 SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar" GIT_DEPTH: 0 MAVEN_OPTS: "-Xmx512m" cache: key: "${CI_JOB_NAME}" paths: - ~/.m2/repository before_script: - echo "=== 清理缓存 ===" - rm -rf "${CI_PROJECT_DIR}" || true - mkdir -p "${CI_PROJECT_DIR}" - cd "${CI_PROJECT_DIR}" - | if [ -d ".git" ]; then echo ".git 目录存在,跳过初始化,直接克隆仓库" git clone -b dev --depth=0 --progress "${CI_REPOSITORY_URL}" . else echo ".git 目录不存在,初始化仓库" git init git remote add origin "${CI_REPOSITORY_URL}" git fetch git checkout -b dev origin/dev fi - git log --oneline -n 5 # 打印最近5个提交确认完整历史 - git branch -v # 可选:确保子模块存在(如需) - git submodule update --init --recursive - git checkout -qf "${CI_COMMIT_SHA}" # 精确切换到当前 commit - git branch -v - git rev-parse HEAD # 强制校验当前提交有效性 - git log --oneline -n 5 # 打印最近5个提交确认完整历史 script: - pwd - mvn -v - mvn clean install -Dmaven.test.failure.ignore=true org.sonarsource.scanner.maven:sonar-maven-plugin:3.9.1.2184:sonar -Dsonar.java.binaries=target/classes -Dsonar.projectKey=$PROJECTKEY -Dsonar.scm.disabled=true -Dsonar.projectName=$PROJECTNAME allow_failure: true only: - dev
1,在对应分支下仓库下,新建.gitlab-ci.yml 文件 将上述示例配置示例copy进行并对关键字段修订后提交
2,.gitignore文件增加gitlab-ci.yml忽略,防止误操作
3,以上操作完成后,在对应分支提交后会触发扫描,可观察扫描结果,扫描结束后登录SonarQube网站查看扫描结果
# 目标分支合并检测(Test 分支/MR)
关键变更点:
variables: PROJECTKEY: "srm:service-ai" # 按合并目标服务名修改 PROJECTNAME: "产品SRM:service-ai" # 同步更新名称 only: refs: - merge_requests # MR 触发 - test # 直接推送到 test 分支触发 before_script 中分支操作: git clone -b test # 拉取 test 分支
完整示例:
stages: - sonarqube-check # SonarQube 检查 variables: PROJECTKEY: "srm:service-ai" PROJECTNAME: "产品SRM:service-ai" SONAR_SCAN_ENABLED: "true" # 默认开启扫描 sonarqube-check: stage: sonarqube-check image: registry.thsrm.com/public/maven:3.6.3-jdk-11 variables: GIT_STRATEGY: none # 禁用 Runner 的自动克隆 SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar" GIT_DEPTH: 0 MAVEN_OPTS: "-Xmx512m" cache: key: "${CI_JOB_NAME}" paths: - ~/.m2/repository before_script: - echo "=== 清理缓存 ===" - rm -rf "${CI_PROJECT_DIR}" || true - mkdir -p "${CI_PROJECT_DIR}" - cd "${CI_PROJECT_DIR}" - | if [ -d ".git" ]; then echo ".git 目录存在,跳过初始化,直接克隆仓库" git clone -b test --depth=0 --progress "${CI_REPOSITORY_URL}" . else echo ".git 目录不存在,初始化仓库" git init git remote add origin "${CI_REPOSITORY_URL}" git fetch git checkout -b test origin/dev fi - git log --oneline -n 5 # 打印最近5个提交确认完整历史 - git branch -v # 可选:确保子模块存在(如需) - git submodule update --init --recursive - git checkout -qf "${CI_COMMIT_SHA}" # 精确切换到当前 commit - git branch -v - git rev-parse HEAD # 强制校验当前提交有效性 - git log --oneline -n 5 # 打印最近5个提交确认完整历史 script: - pwd - mvn -v - mvn clean install -Dmaven.test.failure.ignore=true org.sonarsource.scanner.maven:sonar-maven-plugin:3.9.1.2184:sonar -Dsonar.java.binaries=target/classes -Dsonar.projectKey=$PROJECTKEY -Dsonar.scm.disabled=true -Dsonar.projectName=$PROJECTNAME allow_failure: true only: refs: - merge_requests - test # 也允许直接推送到test分支触发
在test分支配置后,再合并后或者直接提交目标分支,触发扫描机制!
# 2. 前端(Node.js)项目配置(ci.yaml
)
# 开发环境检查(Dev 分支)
关键字段说明:
variables: PROJECTKEY: "srm:admin-view" # 替换为前端项目 Key PROJECTNAME: "产品SRM:admin-view" # 同步更新名称 only: - dev # 仅 dev 分支触发 before_script 中分支操作: git clone -b dev # 拉取 dev 分支
关键字段说明:
stages: - sonar sonarqube-scan: stage: sonar image: node:14 variables: GIT_STRATEGY: none SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar" GIT_DEPTH: 0 # 显式继承全局变量 PROJECTKEY: "srm:admin-view" PROJECTNAME: "产品SRM:admin-view" tags: - build before_script: - echo "=== 清理缓存 ===" - echo "正在设置项目名称:" $PROJECTNAME - echo "正在设置项目密钥:" $PROJECTKEY - rm -rf "${CI_PROJECT_DIR}" || true - mkdir -p "${CI_PROJECT_DIR}" - cd "${CI_PROJECT_DIR}" - | if [ -d ".git" ]; then echo ".git 目录存在,跳过初始化,直接克隆仓库" git clone -b dev --depth=0 --progress "${CI_REPOSITORY_URL}" . else echo ".git 目录不存在,初始化仓库" git init git remote add origin "${CI_REPOSITORY_URL}" git fetch git checkout -b dev origin/dev fi - git log --oneline -n 5 - git branch -v - git submodule update --init --recursive - git checkout -qf "${CI_COMMIT_SHA}" - git branch -v - git rev-parse HEAD - git log --oneline -n 5 - npm install script: - > sonar-scanner -Dsonar.projectKey=${PROJECTKEY} -Dsonar.projectName=${PROJECTNAME} -Dsonar.host.url=$SONAR_HOST_URL -Dsonar.login=$SONAR_TOKEN -Dsonar.sources=src -Dsonar.exclusions=node_modules/**,dist/** -Dsonar.qualitygate.wait=true -Dsonar.scm.provider=git -Dsonar.sourceEncoding=UTF-8 # 确保中文支持 cache: paths: - node_modules/ only: - dev
在dev分支下配置后,提交目标分支,会触发前端扫描机制!
# 目标分支合并检测(Test 分支/MR)
关键变更点:
variables: # 保持 PROJECTKEY/PROJECTNAME 与合并后目标分支对应 only: - merge_requests # MR 触发 - test # 直接推送到 test 分支触发 before_script 中分支操作: git clone -b test # 拉取 test 分支 # 注意分支一致性:origin/test 对应目标分支
完整示例:
stages: - sonar sonarqube-scan: stage: sonar image: node:14 variables: GIT_STRATEGY: none SONAR_USER_HOME: "${CI_PROJECT_DIR}/.sonar" GIT_DEPTH: 0 # 显式继承全局变量 PROJECTKEY: "srm:admin-view" PROJECTNAME: "产品SRM:admin-view" tags: - build before_script: - echo "=== 清理缓存 ===" - echo "正在设置项目名称:" $PROJECTNAME - echo "正在设置项目密钥:" $PROJECTKEY - rm -rf "${CI_PROJECT_DIR}" || true - mkdir -p "${CI_PROJECT_DIR}" - cd "${CI_PROJECT_DIR}" - | if [ -d ".git" ]; then echo ".git 目录存在,跳过初始化,直接克隆仓库" git clone -b test --depth=0 --progress "${CI_REPOSITORY_URL}" . else echo ".git 目录不存在,初始化仓库" git init git remote add origin "${CI_REPOSITORY_URL}" git fetch git checkout -b test origin/test fi - git log --oneline -n 5 - git branch -v - git submodule update --init --recursive - git checkout -qf "${CI_COMMIT_SHA}" - git branch -v - git rev-parse HEAD - git log --oneline -n 5 - npm install script: - > sonar-scanner -Dsonar.projectKey=${PROJECTKEY} -Dsonar.projectName=${PROJECTNAME} -Dsonar.host.url=$SONAR_HOST_URL -Dsonar.login=$SONAR_TOKEN -Dsonar.sources=src -Dsonar.exclusions=node_modules/**,dist/** -Dsonar.qualitygate.wait=true -Dsonar.scm.provider=git -Dsonar.sourceEncoding=UTF-8 # 确保中文支持 cache: paths: - node_modules/ only: - merge_requests # MR 触发 - test
在test的分支下配置后,提交test分支或者合并test分支,会触发前端扫描机制!
# 三、操作流程
# 扫描策略定义
根据项目情况是开启提交检查 还是合并检查。集中开发型项目建议开启合并检查,项目后期或改动点不多的项目开启提交检查
# 开发环境提交检查(Dev 分支)
- 推送代码到 Dev 分支:
git push origin dev
- 流水线自动触发:
- 执行 SonarQube 扫描,结果同步至 SonarQube 仪表盘。
- 若
allow_failure: true
,允许扫描失败但不阻断流水线。
# 合并请求(MR)或 Test 分支提交
- 创建 Merge Request 或推送至 Test 分支:
- MR 目标分支需为
test
(根据实际分支策略调整)。
- MR 目标分支需为
- 触发合并检测流水线:
- SonarQube 检查结果将影响 MR 合并权限(需结合 Quality Gate 配置)暂无配置,不需要注意!。
# 四、注意事项
- 分支一致性
before_script
中git clone -b <分支名>
必须与only
规则中的目标分支匹配(如test
)。- 错误示例:拉取
origin/dev
但检测test
分支,将导致代码版本不一致。
- 项目变量更新
- 每次新增服务或模块时,务必更新
PROJECTKEY
和PROJECTNAME
,避免 Key 重复冲突。
- 每次新增服务或模块时,务必更新
- 缓存清理
before_script
中的rm -rf "${CI_PROJECT_DIR}"
用于强制清理残留文件,确保检出最新代码。
# 五、常见问题排查
问题现象 | 解决步骤 |
---|---|
fatal: git fetch-pack: expected shallow list | 将 GIT_DEPTH: 0 设为完整克隆, |
SonarQube 分析超时 | 调增 MAVEN_OPTS 内存(如 -Xmx1024m )或优化扫描范围 |
No files or directories found | 检查 -Dsonar.sources 路径是否包含有效代码(如 src ) |
Quality Gate 未生效 | 确认 -Dsonar.qualitygate.wait=true 参数是否传递 |
# 六、SonarQube修复流程
查看扫描信息
目前给开发部组长开通了相关账号,信息如下:
地址:http://192.168.0.184:9000/
账号:姓名拼音
密码:itonghui登录后,需要开启提醒通知。项目负责人搜索自己的项目
各项目组长查看扫描情况后,可将需要修复的问题,分配给对应的组员,若无账号 联系技术经理创建。
分配后,组员会收到相应通知
修复标准
目前集成阿里的P3C规约,包含51条代码静态规范要求,需要将bug,漏洞,异味中的阻断,严重性问题进行修复。