Quality gate pipe depends on the scan pipe

General info about the project:
Using Bitbucket Cloud Pipeline
Languages of the repository: C# dotnet core 5 & 6

Hey there, I’m trying to integrate sonarcloud to our pipeline system on bitbucket cloud.

The project is dotnet core with C#. Our build step was in the dockerfile. Everything went well there. Here is summary of my dockerfile script:

# set all the ARG and ENVs, install required libs etc.
...
...
RUN dotnet sonarscanner begin \
  /k:"$SONAR_PROJECT_KEY" \
  /o:"$SONAR_OGRANIZAION_KEY" \
  /d:sonar.host.url="$SONAR_HOST_URL" \
  /d:sonar.login="$SONAR_TOKEN" \
  /d:sonar.coverageReportPaths=/src/coverage/SonarQube.xml \
  /d:sonar.qualitygate.wait=true
...
...
# end the sonarscanner step

P.S. I know in bitbucket cloud we are not supposed to use the /d:sonar.qualitygate.wait=true and instead we should use the pipes. But they were slow, doing extra work and step, and this solution worked perfectly.

So far everything was fine.

But because we only need to run sonar scanner on PRs, there was no need to include it in the dockerfile.
We decided to move it out in the pipeline and build/test natively on the pipeline without docker.

So my script became:

pipelines:
  pull-requests:
    '**':
      - step:
          name: Sonarcloud scan
          image: mcr.microsoft.com/dotnet/sdk:6.0
          caches:
              - dotnetcore
          script:
              - apt-get update && apt-get install -y openjdk-11-jre
              - dotnet tool install --global dotnet-sonarscanner
              - dotnet tool install --global dotnet-reportgenerator-globaltool
              - export PATH="$PATH:/root/.dotnet/tools"
              - cd src
              - dotnet sonarscanner begin /k:"${SONAR_PROJECT_KEY}" /o:"${SONAR_OGRANIZAION_KEY}" /d:sonar.host.url="${SONAR_HOST_URL}" /d:sonar.login="${SONAR_TOKEN}" /d:sonar.coverageReportPaths=/src/coverage/SonarQube.xml /d:sonar.qualitygate.wait=true
              - cp Nuget.config /root/.nuget/NuGet/NuGet.Config
              - dotnet restore Api.csproj
              - dotnet build --no-restore Api.csproj -c Release
              - dotnet test Api.Test.csproj /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:Exclude="[xunit*]\*" /p:CoverletOutput="./TestResults/"
              - dotnet test Api.Integration.Test.csproj /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:Exclude="[xunit*]\*" /p:CoverletOutput="./TestResults/"
              - reportgenerator "-reports:*/TestResults/coverage.opencover.xml" "-targetdir:/src/coverage" "-reporttypes:SonarQube"
              - dotnet sonarscanner end /d:sonar.login="${SONAR_TOKEN}"

Problems started as the following line didn’t trigger what it was expected to do: /d:sonar.qualitygate.wait=true

So I decided to follow your instructions from doc and added this at the end of my last line:

- pipe: sonarsource/sonarcloud-quality-gate:0.1.6
      variables:
      SONAR_TOKEN: $SONAR_TOKEN

It failed with the following error:

:heavy_multiplication_x: Quality Gate failed: Could not get scanner report: [Errno 2] No such file or directory: ‘/opt/atlassian/pipelines/agent/build/.bitbucket/pipelines/generated/pipeline/pipes/sonarsource/sonarcloud-scan/sonarcloud-scan.log’

It was absurd at this point because for dotnet we can’t use the: sonarsource/sonarcloud-scan:1.3.0
But I added this pipe before the sonarcloud-quality-gate one, and it worked.

Now my question is, how can I achieve the quality gate without using the pipes (because it is actually possible if I build in dockerfile).
And if for some reason the bitbucket VM environment can’t provide that, why do I need to run sonarcloud-scan at all if I already run it at dotnet level.

What I want is to not use the sonarcloud-scan or if possible the sonarcloud-quality-gate too. What am I doing wrong here?

Hey there.

What does happen in your pipeline? By all means this should work. If you change something else about the scanner command (say, removing a parameter or changing your coverage path to an invalid value) – do the change stake effect?

Nothing else has been changed. It is a test repository, so no one changes anything but myself.
The output of the sonarscanner end was the following:

INFO: ------------- Check Quality Gate status
INFO: Waiting for the analysis report to be processed (max 300s)
INFO: QUALITY GATE STATUS: PASSED - View details on https://sonarcloud.io/dashboard?id=...
INFO: Analysis total time: 19.197 s

But when I add the external pipe of quality gate, the output is:

✖ Quality Gate failed
- Coverage on New Code: 0.0 (is less than 90)

sonarcloud-scan and sonarcloud-quality-gate should not be used when using the Scanner for .NET. I would suggest removing both if you haven’t already, especially as it appears sonar.qualitygate.wait is having the desired outcome (it’s querying SonarCloud for the Quality Gate, as you’ve shown in the logs). Unless I’m misunderstanding something?

2 Likes

Yes, that is what I want! To not use the two mentioned pipes and only depend on .Net Scanner.
The issue is that the sonar.qualitygate.wait is not checking properly where the external pipe does.

But if I move my build process inside dockerfile, it works properly.

Hey @aaronsarkissian

Maybe I misunderstood. These logs:

Are coming from when the build process is in the dockerfile, or outside?

This is from the pipe sonar.qualitygate.wait, the latter one is from sonarcloud-quality-gate.

So this:

QUALITY GATE STATUS: PASSED

is different from what you see in the SonarCloud UI?

Make sure you have removed sonarcloud-scan and sonarcloud-quality-gate from your pipeline before making this determination. You may be rewriting analysis results by adding sonarcloud-scan.

1 Like

Ok let me clarify again.
I set the sonar quality gates from the UI. That I’m sure they will fail. (e.g. code-coverage is 100% both on new code and overall code)

Now, I run my pipeline:

pipelines:
  pull-requests:
    '**':
      - step:
          name: Sonarcloud scan
          image: mcr.microsoft.com/dotnet/sdk:6.0
          caches:
              - dotnetcore
          script:
              - apt-get update && apt-get install -y openjdk-11-jre
              - dotnet tool install --global dotnet-sonarscanner
              - dotnet tool install --global dotnet-reportgenerator-globaltool
              - export PATH="$PATH:/root/.dotnet/tools"
              - cd src
             - dotnet sonarscanner begin \
                /k:"${SONAR_PROJECT_KEY}" \
                /o:"${SONAR_OGRANIZAION_KEY}" \
                /d:sonar.host.url="${SONAR_HOST_URL}" \
                /d:sonar.login="${SONAR_TOKEN}" \
                /d:sonar.coverageReportPaths=/src/coverage/SonarQube.xml \
                /d:sonar.qualitygate.wait=true
              - cp Nuget.config /root/.nuget/NuGet/NuGet.Config
              - dotnet restore Api.csproj
              - dotnet build --no-restore Api.csproj -c Release
              - dotnet test Api.Test.csproj /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:Exclude="[xunit*]\*" /p:CoverletOutput="./TestResults/"
              - dotnet test Api.Integration.Test.csproj /p:CollectCoverage=true /p:CoverletOutputFormat=opencover /p:Exclude="[xunit*]\*" /p:CoverletOutput="./TestResults/"
              - reportgenerator "-reports:*/TestResults/coverage.opencover.xml" "-targetdir:/src/coverage" "-reporttypes:SonarQube"
              - dotnet sonarscanner end /d:sonar.login="${SONAR_TOKEN}"

This results in the following output:

INFO: ------------- Check Quality Gate status
INFO: Waiting for the analysis report to be processed (max 300s)
INFO: QUALITY GATE STATUS: PASSED - View details on https://sonarcloud.io/dashboard?id=...
INFO: Analysis total time: 18.282 s
INFO: ------------------------------------------------------------------------
INFO: EXECUTION SUCCESS
INFO: ------------------------------------------------------------------------
INFO: Total time: 55.676s
INFO: Final Memory: 32M/117M
INFO: ------------------------------------------------------------------------
The SonarScanner CLI has finished
11:36:32.338  Post-processing succeeded.

So it not fails in pipeline, and does not fail in Sonar UI.

BUT, if I add the quality gate pipe (which I shouldn’t), then it fails both the pipeline and Sonar UI.

Again BUT, if I move the dotnet build steps into the dockerfile, then it starts working properly.

I hope I explained it better this time.

Let me suggest sharing a screenshot of the dashboard for both cases, as well as the Code tab.