聊一聊如何用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

參考資料

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