背景
代碼質量其實是一個很容易被忽略的關鍵點,可能有的團隊會有 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 begin
和 dotnet 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