Per PR decoration is not working

Hi SonarCloud team,

We are using Sonarcloud Analysis on private repos. The Sonarcloud dashboard is updated with the data but the code coverage seems to be wrong for the per PR analysis.
Also it is not getting posted to the Github PR. We have Sonarcloud App under the Github Authorized Apps.

If we add Sonarcloud in the github workflow(https://github.com/marketplace/actions/sonarcloud-scan.) then it does post on the PR, but that run does not wait for the CI to finish importing the code coverage. Seems like it is run independently of the CI sonar-scanner.

This makes me think that I am missing some configuration as I should not have to use a github workflow for this. Can you please advise.

  • ALM used GitHub
  • CI system used Heroku
  • sonar-scanner with just the organization, projectkey, host.url and login token
  • Ruby, javascript, html, css

Hello @sangram,

What makes you say that the code coverage is wrong. Is there any code coverage reported? Does it not match your expected percentage?

This scan indeed runs completely independently from other CI runs.

You have to tell the sonar-scanner where it can find the code coverage report files. Please see this page for language specific properties that have to be set.

Hope that helps,
Tom

Hi Tom,

I think my main issue here is trying to get sonarcloud scanner to post the results to the PR(PR decoration) from the CI. I would prefer to have the scanner run through the CI process where I am also creating the coverage reports which get imported by scanner. This way I can remove the Github workflow completely.

On the SonarCloud dashboard If I select the branch from the dropdown next to the master, I see the below 2 warnings:

  1. Could not find ref 'master' in refs/heads or refs/remotes/origin. You may see unexpected issues and changes. Please make sure to fetch this ref before pull request analysis. and
  2. Shallow clone detected during the analysis. Some files will miss SCM information. This will affect features like auto-assignment of issues. Please configure your build to disable shallow clone.

Can you please let me know what I am missing?

Regards,
Sangram

Those warnings do seem related. I have no experience with Heroku as a CI, but it seems they perform a shallow clone of your pullrequest. The sonar-scanner needs a full clone, because it needs to compare the pullrequest branch against the base of the branch.
I could not find any further information on this, it seems like that behaviour is not very well documented on Heroku side.

Could you give me the ID of a background task (navigate to Administration > Background tasks) for which you do not get any PR decoration?

Thanks,
Tom

Thanks Tom.

I added the the below properties to the sonar-scanner command

sonar.pullrequest.base=master
sonar.pullrequest.branch=feature/my-new-feature
sonar.pullrequest.key=5

and that is still not decorating the PR. When I select the PR from in the dropdown on the SonarCloud dashboard, there are 2 warning:

1. SCM provider autodetection failed. Please use "sonar.scm.provider" to define SCM of your project, or disable the SCM Sensor in the project settings.
2. Pull request decoration did not happen. No revision information available

If the sonar.scm.provider is not set then the CI test passes without PR decoration. If I set it as git on the SonarCloud dashboard settings, then I get the below error in the CI run.

ERROR: Error during SonarQube Scanner execution
java.lang.IllegalStateException: Unable to load component class org.sonar.scanner.scan.filesystem.ProjectFileIndexer
	at org.sonar.core.platform.ComponentContainer$ExtendedDefaultPicoContainer.getComponent(ComponentContainer.java:51)
	at org.picocontainer.DefaultPicoContainer.getComponent(DefaultPicoContainer.java:678)
	at org.sonar.core.platform.ComponentContainer.getComponentByType(ComponentContainer.java:272)
	at org.sonar.scanner.scan.ProjectScanContainer.doAfterStart(ProjectScanContainer.java:340)
	at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:122)
	at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:108)
	at org.sonar.scanner.bootstrap.GlobalContainer.doAfterStart(GlobalContainer.java:127)
	at org.sonar.core.platform.ComponentContainer.startComponents(ComponentContainer.java:122)
	at org.sonar.core.platform.ComponentContainer.execute(ComponentContainer.java:108)
	at org.sonar.batch.bootstrapper.Batch.doExecute(Batch.java:58)
	at org.sonar.batch.bootstrapper.Batch.execute(Batch.java:52)
	at org.sonarsource.scanner.api.internal.batch.BatchIsolatedLauncher.execute(BatchIsolatedLauncher.java:46)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
	at java.base/java.lang.reflect.Method.invoke(Unknown Source)
	at org.sonarsource.scanner.api.internal.IsolatedLauncherProxy.invoke(IsolatedLauncherProxy.java:60)
	at com.sun.proxy.$Proxy0.execute(Unknown Source)
	at org.sonarsource.scanner.api.EmbeddedScanner.doExecute(EmbeddedScanner.java:189)
	at org.sonarsource.scanner.api.EmbeddedScanner.execute(EmbeddedScanner.java:138)
	at org.sonarsource.scanner.cli.Main.execute(Main.java:112)
	at org.sonarsource.scanner.cli.Main.execute(Main.java:75)
	at org.sonarsource.scanner.cli.Main.main(Main.java:61)
Caused by: java.lang.IllegalStateException: Unable to load component class org.sonar.scanner.scan.filesystem.FileIndexer
	at org.sonar.core.platform.ComponentContainer$ExtendedDefaultPicoContainer.getComponent(ComponentContainer.java:51)
	at org.picocontainer.DefaultPicoContainer.getComponent(DefaultPicoContainer.java:632)
	at org.picocontainer.parameters.BasicComponentParameter$1.resolveInstance(BasicComponentParameter.java:118)
	at org.picocontainer.parameters.ComponentParameter$1.resolveInstance(ComponentParameter.java:136)
	at org.picocontainer.injectors.SingleMemberInjector.getParameter(SingleMemberInjector.java:78)
	at org.picocontainer.injectors.ConstructorInjector$CtorAndAdapters.getParameterArguments(ConstructorInjector.java:309)
	at org.picocontainer.injectors.ConstructorInjector$1.run(ConstructorInjector.java:335)
	at org.picocontainer.injectors.AbstractInjector$ThreadLocalCyclicDependencyGuard.observe(AbstractInjector.java:270)
	at org.picocontainer.injectors.ConstructorInjector.getComponentInstance(ConstructorInjector.java:364)
	at org.picocontainer.injectors.AbstractInjectionFactory$LifecycleAdapter.getComponentInstance(AbstractInjectionFactory.java:56)
	at org.picocontainer.behaviors.AbstractBehavior.getComponentInstance(AbstractBehavior.java:64)
	at org.picocontainer.behaviors.Stored.getComponentInstance(Stored.java:91)
	at org.picocontainer.DefaultPicoContainer.getInstance(DefaultPicoContainer.java:699)
	at org.picocontainer.DefaultPicoContainer.getComponent(DefaultPicoContainer.java:647)
	at org.sonar.core.platform.ComponentContainer$ExtendedDefaultPicoContainer.getComponent(ComponentContainer.java:49)
	... 22 more
Caused by: java.lang.IllegalStateException: Unable to load component class org.sonar.scanner.scan.filesystem.MetadataGenerator
	at org.sonar.core.platform.ComponentContainer$ExtendedDefaultPicoContainer.getComponent(ComponentContainer.java:51)
	at org.picocontainer.DefaultPicoContainer.getComponent(DefaultPicoContainer.java:632)
	at org.picocontainer.parameters.BasicComponentParameter$1.resolveInstance(BasicComponentParameter.java:118)
	at org.picocontainer.parameters.ComponentParameter$1.resolveInstance(ComponentParameter.java:136)
	at org.picocontainer.injectors.SingleMemberInjector.getParameter(SingleMemberInjector.java:78)
	at org.picocontainer.injectors.ConstructorInjector$CtorAndAdapters.getParameterArguments(ConstructorInjector.java:309)
	at org.picocontainer.injectors.ConstructorInjector$1.run(ConstructorInjector.java:335)
	at org.picocontainer.injectors.AbstractInjector$ThreadLocalCyclicDependencyGuard.observe(AbstractInjector.java:270)
	at org.picocontainer.injectors.ConstructorInjector.getComponentInstance(ConstructorInjector.java:364)
	at org.picocontainer.injectors.AbstractInjectionFactory$LifecycleAdapter.getComponentInstance(AbstractInjectionFactory.java:56)
	at org.picocontainer.behaviors.AbstractBehavior.getComponentInstance(AbstractBehavior.java:64)
	at org.picocontainer.behaviors.Stored.getComponentInstance(Stored.java:91)
	at org.picocontainer.DefaultPicoContainer.getInstance(DefaultPicoContainer.java:699)
	at org.picocontainer.DefaultPicoContainer.getComponent(DefaultPicoContainer.java:647)
	at org.sonar.core.platform.ComponentContainer$ExtendedDefaultPicoContainer.getComponent(ComponentContainer.java:49)
	... 36 more
Caused by: java.lang.IllegalStateException: Unable to load component class org.sonar.scanner.scan.filesystem.StatusDetection
	at org.sonar.core.platform.ComponentContainer$ExtendedDefaultPicoContainer.getComponent(ComponentContainer.java:51)
	at org.picocontainer.DefaultPicoContainer.getComponent(DefaultPicoContainer.java:632)
	at org.picocontainer.parameters.BasicComponentParameter$1.resolveInstance(BasicComponentParameter.java:118)
	at org.picocontainer.parameters.ComponentParameter$1.resolveInstance(ComponentParameter.java:136)
	at org.picocontainer.injectors.SingleMemberInjector.getParameter(SingleMemberInjector.java:78)
	at org.picocontainer.injectors.ConstructorInjector$CtorAndAdapters.getParameterArguments(ConstructorInjector.java:309)
	at org.picocontainer.injectors.ConstructorInjector$1.run(ConstructorInjector.java:335)
	at org.picocontainer.injectors.AbstractInjector$ThreadLocalCyclicDependencyGuard.observe(AbstractInjector.java:270)
	at org.picocontainer.injectors.ConstructorInjector.getComponentInstance(ConstructorInjector.java:364)
	at org.picocontainer.injectors.AbstractInjectionFactory$LifecycleAdapter.getComponentInstance(AbstractInjectionFactory.java:56)
	at org.picocontainer.behaviors.AbstractBehavior.getComponentInstance(AbstractBehavior.java:64)
	at org.picocontainer.behaviors.Stored.getComponentInstance(Stored.java:91)
	at org.picocontainer.DefaultPicoContainer.getInstance(DefaultPicoContainer.java:699)
	at org.picocontainer.DefaultPicoContainer.getComponent(DefaultPicoContainer.java:647)
	at org.sonar.core.platform.ComponentContainer$ExtendedDefaultPicoContainer.getComponent(ComponentContainer.java:49)
	... 50 more
Caused by: java.lang.IllegalStateException: Unable to load component class org.sonar.scanner.scm.ScmChangedFiles
	at org.sonar.core.platform.ComponentContainer$ExtendedDefaultPicoContainer.getComponent(ComponentContainer.java:51)
	at org.picocontainer.DefaultPicoContainer.getComponent(DefaultPicoContainer.java:632)
	at org.picocontainer.parameters.BasicComponentParameter$1.resolveInstance(BasicComponentParameter.java:118)
	at org.picocontainer.parameters.ComponentParameter$1.resolveInstance(ComponentParameter.java:136)
	at org.picocontainer.injectors.SingleMemberInjector.getParameter(SingleMemberInjector.java:78)
	at org.picocontainer.injectors.ConstructorInjector$CtorAndAdapters.getParameterArguments(ConstructorInjector.java:309)
	at org.picocontainer.injectors.ConstructorInjector$1.run(ConstructorInjector.java:335)
	at org.picocontainer.injectors.AbstractInjector$ThreadLocalCyclicDependencyGuard.observe(AbstractInjector.java:270)
	at org.picocontainer.injectors.ConstructorInjector.getComponentInstance(ConstructorInjector.java:364)
	at org.picocontainer.injectors.AbstractInjectionFactory$LifecycleAdapter.getComponentInstance(AbstractInjectionFactory.java:56)
	at org.picocontainer.behaviors.AbstractBehavior.getComponentInstance(AbstractBehavior.java:64)
	at org.picocontainer.behaviors.Stored.getComponentInstance(Stored.java:91)
	at org.picocontainer.DefaultPicoContainer.getInstance(DefaultPicoContainer.java:699)
	at org.picocontainer.DefaultPicoContainer.getComponent(DefaultPicoContainer.java:647)
	at org.sonar.core.platform.ComponentContainer$ExtendedDefaultPicoContainer.getComponent(ComponentContainer.java:49)
	... 64 more
Caused by: Not inside a Git work tree: /app

In case you need access to the project, https://sonarcloud.io/dashboard?id=SangramTester_depot2. This is a poc which I am using to implement on the private repos.

Regards,
Sangram

Hello @sangram,

The SCM problems you are having seem to be entirely related to Heroku Pipelines. We need access to git blame information to detect what changed between the PR branch and the base branch. Usually the CI environment provides this information, but it seems that Heroku CI/Pipelines does not do this.

I wanted to try it out myself to see if there is some way to go around this (for example a manual git clone), but it seems that it is a paying feature of Heroku.

So I am sorry to not be able to help you further on this. Using any other CI than Heroku to scan your project should allow you to achieve your goal.

Tom

Thanks Tom,

I sent the Heroku Support Team my question with the error log, your response and screen shots of how the PR decoration looks on Github. Below is their response

I'm not entirely sure what "decoration" is with regards to Pull Requests. Without that context, if I am understanding the rest of the issue, it sounds like you may do well to start with Github support as the issue appears to be between Github and SonarCloud. If Github also corroborates SonarCloud's claim that this seems to be an issue on Heroku's side, then we will certainly be here to support you further.

This would also be helpful since we have zero visibility into what SoundCloud is seeing, but we do have visibility into what Github is seeing. Just another reason why this would likely prove helpful.

Is there any clear data(what SonarCloud is looking for) that I can share with the Heroku team so they understand the issue better? SonarCloud’s requirements to make the PR decoration work?

Regards,
Sangram

Hello @sangram,

The scanner needs the full git log to be present to be able to determine the new code that was added in the PR (diff between the base branch and the pull request branch). We also use the git blame information to automatically assign detected issues to the person who wrote that specific line of code.

It seems that there is no git information available at all when running the scanner in the heroku environment, and because of that you receive the warning SCM provider autodetection failed. Please use "sonar.scm.provider" to define SCM of your project, or disable the SCM Sensor in the project settings..

The warning Pull request decoration did not happen. No revision information available means that we could not determine the SHA1 of the latest commit on the PR branch. This is needed to create a check run on GH side to add the analysis on the PR (see the documentation here).

I hope that makes it clear what we need to achieve PR decoration,
Tom