聊一聊如何用SonarQube管理.NET代码质量

背景

代码质量其实是一个很容易被忽略的关键点,可能有的团队会有 Code Review 这些环节来做一定程度的保障,但是这个 Code Review 会很耗费人力和时间,估计大部分团队都不会很经常的来弄,比较多的可能会是有间隔性的来几次。

这个时候就会需要引入一些工具来协助去处理这一块。

sonarqube 在这一个领域是比较不错的存在,所以今天我们就来看看如何用这个工具来管理 .NET Core 时代的 .NET 的代码质量。

搭建 sonarqube

第一步肯定是要搭建一个服务端,这里用 docker-compose 的方式来搭建,相对简单一点。

下面是 yml 文件,主要有两个内容,一个是数据库 postgres,用的是 15-alpine 版本 ,一个是 sonarqube,用的是 9-community。 postgres 主要是存储 sonarqube 的一些内容,如果不用外部数据库的话,就会用默认的 H2 数据库。

version: '3'
services:
  postgres:
    image: postgres:15-alpine
    restart: always
    container_name: postgres
    ports:
      - 5432:5432
    volumes:
      - ./pg/postgresql/:/var/lib/postgresql
      - ./pg/data/:/var/lib/postgresql/data
    environment:
      TZ: Asia/Shanghai
      POSTGRES_USER: sonar
      POSTGRES_PASSWORD: sonar123456
      POSTGRES_DB: sonar
    networks:
      - sonar-network
  sonar:
    image: sonarqube:9-community
    restart: always
    container_name: sonar
    depends_on:
      - postgres
    volumes:
      - ./sonarqube/extensions:/opt/sonarqube/extensions
      - ./sonarqube/logs:/opt/sonarqube/logs
      - ./sonarqube/data:/opt/sonarqube/data
      - ./sonarqube/conf:/opt/sonarqube/conf
    ports:
      - 9000:9000
    networks:
      - sonar-network
networks:
  sonar-network:
    driver: bridge

还需要修改 sonarqube 的配置文件 sonar.properties,来修改数据库。

sonar.jdbc.username=sonar
sonar.jdbc.password=sonar123456
sonar.jdbc.url=jdbc:postgresql://postgres:5432/sonar

这里启动后就可以看到服务端启动了,然后按需选择是否需要汉化。

如何接入?

在创建项目的时候会出现下面这些选择。

这里选择手动的方式,然后创建一个 test 项目。

创建后会让我们选择用什么方式去分析我们的代码,有结合 CI 的方式,也有手动的方式。

这里还是选择手动的方式来演示,需要先创建一个 token,直接点生成就好了。

然后就可以看到选择 .NET Core 相关的内容,也很贴心的把相关脚本都给我们了。

但是直接运行这个脚本的话,dotnet sonarscanner begindotnet build 这两步是可以成功的, dotnet sonarscanner end 这一步是会失败的,因为还需要 JAVA 的环境,还要和 sonarqube 服务端相匹配的 JDK。

为了简化这一步,老黄也是用 docker 来处理这个,下面是 Dockerfile

FROM openjdk:17-slim-bullseye

# change the source, if necessary
# RUN cp /etc/apt/sources.list /etc/apt/sources.list_bak \
#     && sed -i 's/deb.debian.org/mirrors.ustc.edu.cn/g' /etc/apt/sources.list \
#     && sed -i 's|security.debian.org/debian-security|mirrors.ustc.edu.cn/debian-security|g' /etc/apt/sources.list

WORKDIR /project

COPY run.sh ./
COPY nuget.config ./

RUN apt-get update \
    && apt-get install \
    wget \
    gss-ntlmssp \
    -y \
    && wget https://packages.microsoft.com/config/debian/11/packages-microsoft-prod.deb -O packages-microsoft-prod.deb \
    && dpkg -i packages-microsoft-prod.deb \
    && rm packages-microsoft-prod.deb \
    && apt-get update \
    && apt-get install dotnet-sdk-3.1 dotnet-sdk-6.0 -y \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/* \
    && chmod +x /project/run.sh

ENTRYPOINT [ "/project/run.sh" ]

基于 JDK 17,然后安装 dotnet sdk,这里装了 3.1 和 6.0,也可以考虑一个版本一个镜像,最后执行 run.sh 这个脚本。

其中有一个要注意的点是 nuget.config ,因为不少公司会在内部搭建包管理,所以这一块要注意更新。

再来看看 run.sh 这个脚本

#!/bin/bash

set -x

PROJECT_KEY="${PROJECT_KEY:-ConsoleApplication1}"
PROJECT_PATH="${PROJECT_PATH:-.}"
SONAR_HOST="${HOST:-http://localhost:9000}"
SONAR_LOGIN_KEY="${LOGIN_KEY:-admin}"

# install the newest dotnet-sonarscanner
dotnet tool install --global dotnet-sonarscanner
export PATH="$PATH:$HOME/.dotnet/tools/"

# restore with nuget.config
dotnet restore "${PROJECT_PATH}" --configfile /project/nuget.config

# execute scanner
dotnet sonarscanner begin /k:"${PROJECT_KEY}" /d:sonar.host.url="${SONAR_HOST}"  /d:sonar.login="${SONAR_LOGIN_KEY}"
dotnet build "${PROJECT_PATH}"
dotnet sonarscanner end /d:sonar.login="${SONAR_LOGIN_KEY}"

前面半段是一些变量定义,后面半段就是从 sonarque 里面复制出来的脚本。

然后就是执行,示例直接 dotnet new 一个新的控制台程序出来测试

docker run --name dotnet-scanner -it --rm \
    -v PUT_YOUR_PROJECT_DIR_HERE:/project/src \
    -e PROJECT_KEY=PUT_YOUR_PROJECT_KEY_HERE \
    -e PROJECT_PATH=/project/src/PUT_YOUR_PROJECT_PATH_HERE \
    -e HOST=PUT_YOUR_HOST_HERE \
    -e LOGIN_KEY=PUT_YOUR_KEY_HERE \
    dotnet-scanner:v202302

等运行完成后,在网页端就可以看到具体的结果了。

由于是新建的控制台程序,只有一行代码,所以很多指标都是 0。

如果对代码覆盖率这一块还有要求,可以参考 https://docs.sonarqube.org/latest/analyzing-source-code/test-coverage/dotnet-test-coverage/ 集成进去。

到这里的话,一个简单的项目就算 OK 了,后续代码更新的话,重复执行这个就会更新到网页上面。

这里用的规则是默认的,不过规则这一块是可以自定义的,可以按照自己团队的风格来定义。

总结

用 sonarqube 来管理代码质量这一块还是挺不错的,结合 CICD 这些工具的话会更加合适,如果没有 CICD,搞个定时任务去定期执行也是可以的。

本文相关的示例代码:

https://github.com/catcherwong/dotnet-sonarscanner-with-docker

参考资料

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章