Publishing NuGet Packages with .NET and SonarQube on GitHub

Vitor Gomes
3 min readSep 24, 2023

--

Managers these days are all about streamlining processes and giving their teams more freedom. Thankfully, there are some cool tools and frameworks that make our lives easier.

Today, I want to talk about GitAction. It’s a nifty way to whip up NuGet Packages using .NET and SonarQube.

So, let’s dive in:

First things first, let’s whip up the standard package versions. If you want to dive deeper into this topic, check it out here.

To make life easier with tags and version management in your pipeline, you’ve got GitVersion Tools at your service. Here’s the scoop on how to harness this handy plugin.

- name: Install GitVersion
uses: gittools/actions/gitversion/setup@v0
with:
versionSpec: '5.x'

- name: Determine Version
id: version-git
uses: gittools/actions/gitversion/execute@v0

The initial step for incorporating .Net into your pipeline is setting the URL, dotnet-version and authentication token.

- name: Setup .NET
uses: actions/setup-dotnet@v3
with:
source-url: https://nuget.pkg.github.com/${{ github.repository_owner }}/index.json
dotnet-version: 8.0.x
env:
NUGET_AUTH_TOKEN: ${{secrets.TOKEN_GITHUB}}

To ensure that the application has everything it needs to run, you must restore the project’s packages.

- name: Restore dependencies
run: dotnet restore --configuration Release

I’ve installed two packages below that assist in running SonarQube and generating test execution reports in the pipeline.

- name: Dotnet Install SonarScanner
run: dotnet tool install --global dotnet-sonarscanner

- name: Dotnet Install Coverlet
run: dotnet tool install --global coverlet.console

After installing SonarQube, you can initialize the process of using these tools. They can significantly enhance code quality. Currently, I’m running SonarQube on my QNAP within a ContainerStation. If you’d like to learn more about SonarQube, click here.

- name: SonarScanner Begin
run: dotnet sonarscanner begin /k:${{ vars.SONARQUBE_PROJECT_KEY }} /d:sonar.host.url=${{ vars.SONARQUBE_URL }} /d:sonar.login=${{ secrets.SONAR_TOKEN }} /d:sonar.cs.opencover.reportsPaths=$GITHUB_WORKSPACE/**/coverage.opencover.xml /d:sonar.language=cs /d:sonar.visualstudio.enable=true /d:sonar.verbose=false /v:${{ env.GitVersion_SemVer }}

Next, you should execute the build. Since the dependencies were already restored earlier, you can now add the parameter “ — no-restore”.

- name: Build
run: dotnet build --no-restore --configuration Release

After that, processed with running the tests.

- name: Test
run: dotnet test --configuration release --logger trx /p:CollectCoverage=true /p:CoverletOutputFormat=opencover

After running the test, you can synchronize the results with SonarQube.

- name: SonarScanner End
run: dotnet sonarscanner end /d:sonar.login=${{ secrets.SONAR_TOKEN }}
env:
GITHUB_TOKEN: ${{ secrets.TOKEN_GITHUB }}

The PowerShell Script below is used to check the results of the SonarQube analysis.

- name: Check SonarQube Quality Gate
shell: pwsh
run: |
$token = [System.Text.Encoding]::UTF8.GetBytes("${{ secrets.SONAR_TOKEN }}:")
$base64 = [System.Convert]::ToBase64String($token)

$basicAuth = [string]::Format("Basic {0}", $base64)
$headers = @{ Authorization = $basicAuth }
$result = Invoke-RestMethod -Method Get -Uri ${{ vars.SONARQUBE_URL }}/api/qualitygates/project_status?projectKey=${{ vars.SONARQUBE_PROJECT_KEY }} -Headers $headers
$result | ConvertTo-Json | Write-Host

if ($result.projectStatus.status -eq "OK") {
Write-Host "Quality Gate Succeeded"
}else{
throw "Quality gate failed"
}

After running the tests and Building the application, you can generate the packages.

- name: dotnet pack ToolBox.Framework.* ${{ env.GitVersion_SemVer }}"
if: github.event_name != 'pull_request'
run: |
dotnet pack --no-build --configuration Release --include-symbols -p:PackageVersion=${{ env.GitVersion_SemVer }}

After creating the packages, you can send them to GitHub.

- name: Push GitHub Packages
if: github.event_name != 'pull_request'
run:
dotnet nuget push ${{ github.workspace }}/**/*.nupkg --skip-duplicate

To wrap it up, automate the release generation. In the example below, if the branch is not MAIN, this release is marked as prerelease.

- name: Create Release
id: create_release
if: github.event_name != 'pull_request'
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.TOKEN_GITHUB }}
with:
tag_name: ${{ env.GitVersion_SemVer }}"
release_name: v${{ env.GitVersion_MajorMinorPatch }}
draft: false
prerelease: github.ref != 'refs/heads/main'

--

--

Vitor Gomes
Vitor Gomes

No responses yet