Azure Pipelines SonarCloudPrepare@3 sonar.exclusions not working

We are using SonarQubeCloud with Azure DevOps and have been running into some issues with excluding some of our folders. This used to work well and the only other thing that changedd is the OS (ubuntu-latest now).

Is there any obvious reason?

New pipeline that doesn’t work

- task: SonarCloudPrepare@3
    timeoutInMinutes: 5
    inputs:
      SonarCloud: Sonarcloud
      organization: ourOrg
      scannerMode: dotnet
      projectKey: ourKey
      projectName: ${{ parameters.projectName }}
      ${{ if parameters.useDotNetCoverage }}:
        extraProperties: |
          sonar.exclusions="**/Migrations/**,${{ join(',',parameters.sonarcloudExclusion) }}"
          sonar.cs.vscoveragexml.reportsPaths=$(Agent.TempDirectory)/coverage.xml
          sonar.scanner.scanAll=false
          sonar.verbose=true

Funny enough our old code for this worked:

variables:
   sonarcloudExclusionString: "**/Migrations/**,${{ join(',',parameters.sonarcloudExclusion) }}"

....

- task: SonarCloudPrepare@3
  timeoutInMinutes: 5
  inputs:
    SonarCloud: "Sonarcloud"
    organization: "myOrg"
    scannerMode: "dotnet"
    projectKey: "myKey"
    projectName: "$(SonarCloudProjectName)"
    extraProperties: |
      sonar.exclusions=${{variables.sonarcloudExclusionString}}

Edit: Add ifwhich is used in the new template

Hi,

I believe this is a question of where / whether interpolation takes place.

Is there a reason you can’t keep it as a separately declared variable?

 
Ann

Hi Ann,

Yes there is a reason as this is part of a template which manages our SonarCloud calls centrally and is only a task (not a job where you would be able to have variables). This is because we have quite a few services which have special need in the CIs, however the SonarCloud steps are the same. It basically wraps around the restore, build, test and a few extra steps depending on the service.

I technically could keep it as an external variable, however this would come with major drawbacks.

The thing is that it interpolates correctly in the logs:
Excluded sources: **/build-wrapper-dump.json, **/Migrations/**,

It just doesn’t do anything and I can’t understand why.

Hi,

I have to wonder if it’s interpolated at log output (i.e by Azure).

I’ll flag this for more expert eyes.

In the meantime, for i-dotting, can you provide the full analysis log?

The analysis / scanner log is what’s output from the analysis command. Hopefully, the log you provide - redacted as necessary - will include that command as well.

This guide will help you find them.

 
Thx,
Ann

Hi Ann,

Here are the logs.

I think this should not be possible. Another thing is that **/Migrations/** should be excluded even if the interpolation doesn’t occur before. However it is still counted towards coverage and analysis. I am just really confused about this behavior.

Kind Regards,
Raphael

debug.txt (328.4 KB)

1 Like

Hi,

I have done some more research on this and it really is the adding of the parameter which breaks the entire exclusion. As soon as I remove it, it works. However I need it for some of our services to be extendable like this.

Kind Regards,
Raphael

Hi Raphael,

Here’s what I see in the log:

2025-02-04T08:30:19.0664785Z sonar.exclusions="**/Migrations/**,"

Are you sure this is available to the task?

 
Ann

Hi Ann,

yes I am, however it’s almost always empty as Sonar does quite a good job at detecting generated files. As soon as I add something in the parameter it shows in the log. However even if the string is just sonar.exclusions="**/Migrations/**,"the migrations folder should be excluded, however it is not! Only if I remove the call of the parameter it excludes it, however the logs about the exclusion is 1:1 the same.

I could theoretically force it into a variable with some Powershell, however this should not be necessary as every other Task I use doesn’t break this way.

Kind Regards,
Raphael

Hi Raphael,

Could you try updating that pattern to **/Migrations/**/*?

 
Thx,
Ann

Hi Ann,

nope, still the same issue. What I am starting to notice is that as soon as I add the comma it breaks. It’s actually not the parameter, but the comma. As soon as I have a trailing comma or two values seperated by a comma it breaks.

As the old one works fine which runs on windows-latest I can only imagine it is some issue with ubuntu-latest. I guess the Task itself isn’t open-source, right?

Kind Regards,
Raphael

Hi Raphael,

Is this what you’re looking for?

 
Ann

Hi Ann,

sadly there is no v3 in there as far as I can see. So sadly I cannot debug it myself as it seems…

Kind Regards,
Raphael

You can find the latest v3 release on the repository Ann indicated:

Denis

2 Likes

Hi,

I am sorry, I was in a hurry and didn’t look into the extensions where I would have seen it… I finally had some time on my hands to have a deeper look and experiment a bit.

I played around with quite a few things and found out the issue is the handling of double quotes and commas. The issue I am having with this is, that it doesn’t throw any errors and interpolates correctly in the logs. So it is really hard to spot the error. If I can find the time, I may have a look what causes this issue exactly.

Some examples:

sonar.exclusions=“Migrations/**” => works
sonar.exclusions=“Migrations/**,” => ignores exclusions
sonar.exclusions=“Migrations/**, foo/**” => ignores exclusions
sonar.exclusions=Migrations/**, => works
sonar.exclusions=Migrations/**, foo/** => works

1 Like

Hello @Raphael-Eckmayr,

If I understand you issue correctly, you are not able to exclude correctly when specifying your exclusion value with spaces.

Which OS were you using before? Was it Windows?

The value contains a space, is it a formatting issue when posting here or is the value you passed in your pipeline containing a space?

There is a limitation with some properties of the scanner not working as expected when they contain spaces. I think this is what you are experiencing, especially on Linux.

If I guessed it right, I advise you to make sure your value in your sonar.exclusions do not contain any spaces.

Let me know if it worked for you.

Hi Sebastien,

We were using windows-latest before.

I think that the space alone is not the issue:

sonar.exclusions=Migrations/**, foo/** => works
sonar.exclusions=“Migrations/**, foo/**” => ignores exclusions
sonar.exclusions=“Migrations/**,” => ignores exclusions (which doesn’t have a space)

If I understand your answer correctly, then this should be the outcome with the same inputs:
sonar.exclusions=Migrations/**, foo/** => ignores exclusions
sonar.exclusions=“Migrations/**, foo/**” => ignores exclusions
sonar.exclusions=“Migrations/**,” => works

It works by now. I just removed the double quotes from every sonar.exclusions in our pipelines and everything is working now. I just don’t want others to be as confused as me about such and obscure problem. Another thing, is there a known issues page for the Azure Pipelines Task or Sonar Cloud in general?

Hello @Raphael-Eckmayr,

In the documentation, you can find here and there known issue related to there topics (e.g.: Troubleshooting .NET analysis).

However, I can concede this is not necessarily easy to find what you are looking as it spread across the whole documentation. Also, we might miss some issues there.

I will bring this up to see how we can improve this part of our documentation.

I might have made some assumption then, I was experience similar issue with space when working with Linux that’s why.
It seems to me that you found suitable solution.

To help me understand the underlying issue, did you try with quotes and without spaces?
Like so: sonar.exclusions=“Migrations/**,foo/**”

Thank you,

1 Like

Hi Sebastien,

I am pretty sure I did test exactly that string aswell. In the original code example pretty much this was done, however with a parameter join.

Sadly my colleague deleted my branch where I tested it… If I should retest it, let me know. It would take some time as I am pretty busy right now.

Hello @Raphael-Eckmayr,

Don’t worry about it I just wanted to make sure. And I didn’t check properly that you have done it before.

Thank you for all your inputs!

1 Like

Hi Sebastien,

one other thing I just thought about is that technically double quotes are a valid char in Linux filenames and commands. Does this Task call another program with the sonar exclusions as a parameter?

So basically my theory is that everything within " " must be valid chars in Linux filenames and that’s why it breaks as soon as I add the comma.