├── .vscode └── settings.json ├── LICENSE ├── Dockerfile └── README.md /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "markdownlint.config": { 3 | "MD028": false, 4 | "MD025": { 5 | "front_matter_title": "" 6 | } 7 | } 8 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2017, NOS Inovação 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/dotnet/sdk:10.0.100 2 | 3 | # Dockerfile meta-information 4 | LABEL maintainer="NOS Inovação S.A." \ 5 | app_name="dotnet-sonar" 6 | 7 | ENV SONAR_SCANNER_MSBUILD_VERSION=11.0.0.126294 \ 8 | DOTNETCORE_SDK=10.0.100 \ 9 | DOTNETCORE_RUNTIME=10.0.0 \ 10 | NETAPP_VERSION=net \ 11 | DOCKER_VERSION=5:28.5.2-1~ubuntu.24.04~noble \ 12 | CONTAINERD_VERSION=1.7.29-1~ubuntu.24.04~noble \ 13 | OPENJDK_VERSION=17 \ 14 | NODEJS_VERSION=20 15 | 16 | # Linux update 17 | RUN apt-get update \ 18 | && apt-get dist-upgrade -y \ 19 | && apt-get install -y \ 20 | apt-transport-https \ 21 | ca-certificates-java \ 22 | ca-certificates \ 23 | curl \ 24 | locales \ 25 | gnupg-agent \ 26 | lsb-release \ 27 | software-properties-common 28 | 29 | RUN mkdir -p /usr/share/man/man1mkdir -p /usr/share/man/man1 30 | 31 | # Set locale to UTF-8 32 | # The locale-gen must be run first to create config files 33 | RUN locale-gen && \ 34 | sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \ 35 | locale-gen 36 | ENV LC_ALL en_US.UTF-8 37 | ENV LANG en_US.UTF-8 38 | ENV LANGUAGE en_US:en 39 | 40 | # Install Java 41 | RUN apt-get install -y openjdk-$OPENJDK_VERSION-jre 42 | 43 | # Install NodeJs 44 | RUN wget https://deb.nodesource.com/setup_$NODEJS_VERSION.x \ 45 | && bash setup_$NODEJS_VERSION.x \ 46 | && apt-get install -y nodejs 47 | 48 | # Install all necessary additional software 49 | RUN mkdir -p /etc/apt/keyrings \ 50 | && curl -fsSL https://download.docker.com/linux/ubuntu/gpg | gpg --dearmor -o /etc/apt/keyrings/docker.gpg \ 51 | && echo \ 52 | "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \ 53 | $(lsb_release -cs) stable" | tee /etc/apt/sources.list.d/docker.list > /dev/null \ 54 | && apt-get update \ 55 | && apt-get install -y \ 56 | docker-ce=$DOCKER_VERSION \ 57 | docker-ce-cli=$DOCKER_VERSION \ 58 | containerd.io=$CONTAINERD_VERSION 59 | 60 | # Install Sonar Scanner 61 | RUN apt-get install -y unzip \ 62 | && wget https://github.com/SonarSource/sonar-scanner-msbuild/releases/download/$SONAR_SCANNER_MSBUILD_VERSION/sonar-scanner-$SONAR_SCANNER_MSBUILD_VERSION-$NETAPP_VERSION.zip \ 63 | && unzip sonar-scanner-$SONAR_SCANNER_MSBUILD_VERSION-$NETAPP_VERSION.zip -d /sonar-scanner \ 64 | && rm sonar-scanner-$SONAR_SCANNER_MSBUILD_VERSION-$NETAPP_VERSION.zip \ 65 | && chmod +x -R /sonar-scanner 66 | 67 | # Cleanup 68 | RUN apt-get -q autoremove \ 69 | && apt-get -q clean -y \ 70 | && rm -rf /var/lib/apt/lists/* /var/cache/apt/*.bin -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # dotnet-sonar 2 | 3 | This is a container used to build dotnet projects and provide SonarQube analysis using SonarQube MSBuild Scanner. 4 | 5 | It also allows you to run Docker in Docker using a docker.sock mount. 6 | 7 | ---- 8 | 9 | > [!IMPORTANT] 10 | > This project has been transferred from a different GitHub organization. All history and context have been preserved. Images up to version `25.11.7` are also available at the [previous location](https://github.com/orgs/nosinovacao/packages/container/package/dotnet-sonar). 11 | 12 | ---- 13 | 14 | This latest image was built with the following components: 15 | 16 | * dotnetcore-sdk 10.0.100 17 | * dotnetcore-runtime 10.0.0 (required by Sonar-Scanner) 18 | * SonarQube MSBuild Scanner 11.0.0.126294 19 | * Docker binaries 24.0.x (for running Docker in Docker using the docker.sock mount) 20 | * OpenJDK Java Runtime 17 (required by Sonar-Scanner and some Sonar-Scanner plugins) 21 | * NodeJS 20 (required by Sonar-Scanner web analysis plugins) 22 | 23 | ## Supported tags and respective `Dockerfile` links 24 | 25 | > Tags are written using the following pattern: `dotnet-sonar:..` 26 | 27 | * `25.11.7`, `latest10`, `25.11-dotnet10`, `latest` [(25.11.7/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/25.11.7/Dockerfile) 28 | * DotNet 10.0.100 29 | * SonarScanner 11.0.0.126294 30 | * `25.11.6`, `latest9`, `25.11-dotnet9` [(25.11.6/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/25.11.6/Dockerfile) 31 | * DotNet 9.0.307 32 | * SonarScanner 11.0.0.126294 33 | * `25.11.5`, `latest8`, `25.11-dotnet8` [(25.11.5/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/25.11.5/Dockerfile) 34 | * DotNet 8.0.416 35 | * SonarScanner 11.0.0.126294 36 | > :warning: **[(THIS VERSION HAS REACHED END OF LIFE)](https://dotnet.microsoft.com/en-us/download/dotnet/6.0)** 37 | * `24.11.3`, `latest6`, `24.11-dotnet6` [(24.11.3/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/24.11.3/Dockerfile) 38 | * DotNet 6.0.428-1 39 | * SonarScanner 9.0.2.104486 40 | > :warning: **[(THIS VERSION HAS REACHED END OF LIFE)](https://dotnet.microsoft.com/en-us/download/dotnet/7.0)** 41 | * `24.05.4`, `latest7`, `24.05-dotnet7` [(24.05.4/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/24.05.4/Dockerfile) 42 | * DotNet 7.0.409 43 | * SonarScanner 6.2.0.85879 44 | > :warning: **[(THIS VERSION HAS REACHED END OF LIFE)](https://dotnet.microsoft.com/en-us/download/dotnet/5.0)** 45 | * `22.07.1`, `latest5` [(22.07.1/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/22.07.1/Dockerfile) 46 | * DotNet 5.0.408 47 | * SonarScanner 5.7.1.49528 48 | * `25.09.6` [(25.09.6/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/25.09.6/Dockerfile) 49 | * `25.09.5` [(25.09.5/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/25.09.5/Dockerfile) 50 | * `25.07.6` [(25.07.6/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/25.07.6/Dockerfile) 51 | * `25.07.5` [(25.07.5/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/25.07.5/Dockerfile) 52 | * `25.06.6` [(25.06.6/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/25.06.6/Dockerfile) 53 | * `25.06.5` [(25.06.5/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/25.06.5/Dockerfile) 54 | * `25.04.6` [(25.04.6/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/25.04.6/Dockerfile) 55 | * `25.04.5` [(25.04.5/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/25.04.5/Dockerfile) 56 | * `25.03.6` [(25.03.6/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/25.03.6/Dockerfile) 57 | * `25.03.5` [(25.03.5/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/25.03.5/Dockerfile) 58 | * `25.02.6` [(25.02.6/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/25.02.6/Dockerfile) 59 | * `25.02.5` [(25.02.5/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/25.02.5/Dockerfile) 60 | * `24.11.6` [(24.11.6/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/24.11.6/Dockerfile) 61 | * `24.11.5` [(24.11.5/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/24.11.5/Dockerfile) 62 | * `24.10.5` [(24.10.5/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/24.10.5/Dockerfile) 63 | * `24.10.3` [(24.10.3/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/24.10.3/Dockerfile) 64 | * `24.08.5` [(24.08.5/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/24.08.5/Dockerfile) 65 | * `24.08.3` [(24.08.3/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/24.08.3/Dockerfile) 66 | * `24.07.5` [(24.07.5/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/24.07.5/Dockerfile) 67 | * `24.07.3` [(24.07.3/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/24.07.3/Dockerfile) 68 | * `24.06.5` [(24.06.5/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/24.06.5/Dockerfile) 69 | * `24.06.3` [(24.06.3/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/24.06.3/Dockerfile) 70 | * `24.05.5` [(24.05.5/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/24.05.5/Dockerfile) 71 | * `24.05.3` [(24.05.3/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/24.05.3/Dockerfile) 72 | * `24.02.5` [(24.02.5/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/24.02.5/Dockerfile) 73 | * `24.02.4` [(24.02.4/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/24.02.4/Dockerfile) 74 | * `24.02.3` [(24.02.3/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/24.02.3/Dockerfile) 75 | * `24.01.5` [(24.01.5/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/24.01.5/Dockerfile) 76 | * `24.01.4` [(24.01.4/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/24.01.4/Dockerfile) 77 | * `24.01.3` [(24.01.3/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/24.01.3/Dockerfile) 78 | * `23.12.5` [(23.12.5/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/23.12.5/Dockerfile) 79 | * `23.12.4` [(23.12.4/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/23.12.4/Dockerfile) 80 | * `23.12.3` [(23.12.3/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/23.12.3/Dockerfile) 81 | * `23.10.4` [(23.10.4/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/23.10.4/Dockerfile) 82 | * `23.10.3` [(23.10.3/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/23.10.3/Dockerfile) 83 | * `23.09.4` [(23.09.4/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/23.09.4/Dockerfile) 84 | * `23.09.3` [(23.09.3/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/23.09.3/Dockerfile) 85 | * `23.08.4` [(23.08.4/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/23.08.4/Dockerfile) 86 | * `23.08.3` [(23.08.3/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/23.08.3/Dockerfile) 87 | * `23.06.4` [(23.06.4/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/23.06.4/Dockerfile) 88 | * `23.06.3` [(23.06.3/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/23.06.3/Dockerfile) 89 | * `23.02.4` [(23.02.4/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/23.02.4/Dockerfile) 90 | * `23.02.3` [(23.02.3/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/23.02.3/Dockerfile) 91 | * `22.12.4` [(22.12.4/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/22.12.4/Dockerfile) 92 | * `22.12.3` [(22.12.3/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/22.12.3/Dockerfile) 93 | * `22.11.4` [(22.11.4/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/22.11.4/Dockerfile) 94 | * `22.11.3` [(22.11.3/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/22.11.3/Dockerfile) 95 | * `22.10.3` [(22.10.3/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/22.10.3/Dockerfile) 96 | * `22.07.3` [(22.07.3/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/22.07.3/Dockerfile) 97 | * `22.07.0`, `latest31` [(22.07.0/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/22.07.0/Dockerfile) 98 | * DotNetCore 3.1.420 99 | * SonarScanner 5.7.1.49528 100 | * `21.11.3` [(21.11.3/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/21.11.3/Dockerfile) 101 | * `21.11.1` [(21.11.1/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/21.11.1/Dockerfile) 102 | * `21.11.0` [(21.11.0/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/21.11.0/Dockerfile) 103 | * `21.07.1` [(21.07.1/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/21.07.1/Dockerfile) 104 | * `21.07.0` [(21.07.0/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/21.07.0/Dockerfile) 105 | * `21.06.1` [(21.06.1/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/21.06.1/Dockerfile) 106 | * `21.06.0` [(21.06.0/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/21.06.0/Dockerfile) 107 | * `21.05.1` [(21.05.1/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/21.05.1/Dockerfile) 108 | * `21.05.0` [(21.05.0/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/21.05.0/Dockerfile) 109 | * `21.04.1` [(21.04.1/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/21.04.1/Dockerfile) 110 | * `21.04.0` [(21.04.0/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/21.04.0/Dockerfile) 111 | * `21.01.1` [(21.01.1/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/21.01.1/Dockerfile) 112 | * `21.01.0` [(21.01.0/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/21.01.0/Dockerfile) 113 | * `20.12.2` [(20.12.2/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/20.12.2/Dockerfile) 114 | * `20.12.1` [(20.12.1/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/20.12.1/Dockerfile) 115 | * `20.12.0` [(20.12.0/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/20.12.0/Dockerfile) 116 | * DotNetCore 2.2.207 117 | * SonarScanner 5.0.4.24009 118 | * `20.10.1` [(20.10.1/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/20.10.1/Dockerfile) 119 | * `20.10.0` [(20.10.0/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/20.10.0/Dockerfile) 120 | * `20.07.0` [(20.07.0/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/20.07.0/Dockerfile) 121 | * `19.12.0` [(19.12.0/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/19.12.0/Dockerfile) 122 | * `19.10.1` [(19.10.1/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/19.10.1/Dockerfile) 123 | * `19.09.0` [(19.09-0/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/19.09.0/Dockerfile) 124 | * `19.08.0` [(19.08.0/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/19.08.0/Dockerfile) 125 | * `19.01.0` [(19.01.0/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/19.01.0/Dockerfile) 126 | * `18.12.1` [(18.12.1/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/18.12.1/Dockerfile) 127 | * `18.09.0` [(18.09.0/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/18.09.0/Dockerfile) 128 | * `18.07.0` [(18.07.0/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/18.07.0/Dockerfile) 129 | * `18.05.0` [(18.05.0/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/18.05.0/Dockerfile) 130 | * `18.03.1` [(18.03.1/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/18.03.1/Dockerfile) 131 | * `18.03.0` [(18.03.0/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/18.03.0/Dockerfile) 132 | * `2-4.0.2` [(2-4.0.2/Dockerfile)](https://github.com/nosinovacao/dotnet-sonar/blob/2-4.0.2/Dockerfile) 133 | 134 | ## Compiling dotnet code with SonarQube Analysis 135 | 136 | Full documentation: 137 | 138 | ### Inside container 139 | 140 | ### Using Docker 141 | 142 | **Inside container:** 143 | 144 | ```bash 145 | $ dotnet /sonar-scanner/SonarScanner.MSBuild.dll begin /k:sonarProjectKey 146 | $ dotnet build 147 | $ dotnet /sonar-scanner/SonarScanner.MSBuild.dll end 148 | ``` 149 | 150 | **Configure external SonarQube Server:** 151 | 152 | ```bash 153 | $ dotnet /sonar-scanner/SonarScanner.MSBuild.dll begin /k:sonarProjectKey /d:sonar.host.url="" /d:sonar.login="" 154 | $ dotnet build 155 | $ dotnet /sonar-scanner/SonarScanner.MSBuild.dll end /d:sonar.login="" 156 | ``` 157 | 158 | **Outside container:** 159 | 160 | Simple Usage: 161 | ```bash 162 | $ docker run -it --rm -v :/source ghcr.io/nosinovacao/dotnet-sonar:latest bash -c "cd source \ 163 | && dotnet /sonar-scanner/SonarScanner.MSBuild.dll begin /k:sonarProjectKey /name:sonarProjectName /version:buildVersion \ 164 | && dotnet restore \ 165 | && dotnet build -c Release \ 166 | && dotnet /sonar-scanner/SonarScanner.MSBuild.dll end" 167 | ``` 168 | 169 | Advance Usage: 170 | 171 | ```bash 172 | $ docker run -it --rm \ 173 | -v :/source \ 174 | -v :/nuget \ 175 | dotnet-sonar:latest \ 176 | bash -c \ 177 | "cd source \ 178 | && dotnet /sonar-scanner/SonarScanner.MSBuild.dll begin \ 179 | /k: /name: /version: \ 180 | /d:sonar.host.url="" \ 181 | /d:sonar.login="" \ 182 | /d:sonar.password="" \ 183 | /d:sonar.cs.opencover.reportsPaths='tests/**/coverage.opencover.xml' \ 184 | && dotnet restore --configfile /nuget/NuGet.Config \ 185 | && dotnet build -c Release \ 186 | && dotnet publish -c Release -r linux-x64 -o deployment \ 187 | && dotnet test --no-build -c Release --filter "Category=Unit" --logger trx --results-directory testResults /p:CollectCoverage=true / p:CoverletOutputFormat=\"opencover\" \ 188 | && dotnet /sonar-scanner/SonarScanner.MSBuild.dll end \ 189 | /d:sonar.login="" \ 190 | /d:sonar.password=""" 191 | ``` 192 | 193 | The script above does the following: 194 | 195 | * Mounts your project folder to the container's /source folder 196 | * Mounts your nuget config to the container's /nuget folder (optional if no private nuget server is used) 197 | * Begins the sonarscanner with the sonarqube server credentials 198 | * Performs a dotnet restore with the nuget config in /nuget folder 199 | * Executes the build command 200 | * Publishes the build to the deployment folder 201 | * Runs the tests and stores the test results in testResults folder. Change this command to your unit tests needs 202 | * Ends the sonarscanner and publishes the sonarqube analysis results to the sonarqube server 203 | 204 | ### Using Jenkins pipeline 205 | 206 | The following pipeline code will: 207 | 208 | * Start a sonar scanning session 209 | * Build dotnet projects 210 | * Run tests with coverage analysis (using coverlet) and publish them using the Jenkins XUnit publisher 211 | * End a sonar scanning session 212 | * [OPTIONAL] In the end, it waits for sonar's quality gate status and sets the build outcome 213 | 214 | *Note that in order for coverage analysis to work, you need to add the coverlet NuGet package to the unit test project.* 215 | 216 | ```groovy 217 | def envVariables = [ 218 | 'HOME=/tmp/home', 219 | 'DOTNET_CLI_TELEMETRY_OPTOUT=1' 220 | ] 221 | 222 | node('somenode-with-docker') 223 | { 224 | withSonarQubeEnv('my-jenkins-configured-sonar-environment') 225 | { 226 | docker.image('ghcr.io/nosinovacao/dotnet-sonar:latest').inside() 227 | { 228 | withEnv(envVariables) 229 | { 230 | stage('build') 231 | { 232 | checkout scm 233 | sh "dotnet /sonar-scanner/SonarScanner.MSBuild.dll begin /k:someKey /name:someName /version:someVersion /d:sonar.cs.opencover.reportsPaths='tests/**/coverage.opencover.xml'" 234 | sh "dotnet build -c Release /property:Version=someVersion" 235 | sh "rm -drf ${env.WORKSPACE}/testResults" 236 | sh (returnStatus: true, script: "find tests/**/* -name \'*.csproj\' -print0 | xargs -L1 -0 -P 8 dotnet test --no-build -c Release --logger trx --results-directory ${env.WORKSPACE}/testResults /p:CollectCoverage=true /p:CoverletOutputFormat=opencover") 237 | step([$class: 'XUnitPublisher', testTimeMargin: '3000', thresholdMode: 1, thresholds: [[$class: 'FailedThreshold', unstableThreshold: '0'] 238 | , [$class: 'SkippedThreshold']], tools: [[$class: 'MSTestJunitHudsonTestType', deleteOutputFiles: true, failIfNotNew: false 239 | , pattern: 'testResults/**/*.trx', skipNoTestFiles: true, stopProcessingIfError: true]]]) 240 | sh "dotnet /sonar-scanner/SonarScanner.MSBuild.dll end" 241 | } 242 | } 243 | } 244 | } 245 | } 246 | 247 | timeout(time: 1, unit: 'HOURS') 248 | { 249 | def qualityGate = waitForQualityGate() 250 | if (qualityGate.status == 'ERROR') 251 | { 252 | currentBuild.result = 'UNSTABLE' 253 | } 254 | } 255 | ``` 256 | 257 | **If you want to use Docker in Docker**: 258 | 259 | Please note that if you want to use Docker inside Docker (DinD) you need to perform additional actions when mounting the docker image in the pipeline. 260 | 261 | **The following actions will expose your host to several security vulnerabilities** and therefore this should only be used when you absolutely must to: 262 | 263 | ```groovy 264 | docker.image('ghcr.io/nosinovacao/dotnet-sonar:latest').inside("--group-add docker -v /var/run/docker.sock:/var/run/docker.sock") 265 | { 266 | // Some stuff 267 | docker.image.('hello-world:latest').inside() 268 | { 269 | sh "echo 'hello from docker inside docker'" 270 | } 271 | } 272 | ``` 273 | 274 | The above code will: 275 | 276 | * Add current jenkins user to the Docker group 277 | * Mount the docker socket into the container so that you can control the Docker instance on the host machine 278 | 279 | ## Code Coverage 280 | 281 | The above examples already implement the code-coverage analysis, **provided you add the coverlet NuGet package to your unit test project**. 282 | 283 | If you want to know more, check: . 284 | 285 | Also, coverlet documentation here: . 286 | --------------------------------------------------------------------------------