The master branch becomes the parent of our feature branches instead of the develop branch, resulting in too much "new code"

We’re using Azure DevOps pipelines and GitHub with Sonarcloud.

When creating the Sonarcloud project, the master branch is created automatically, and it is marked as “main branch”. We also have our develop branch, and create feature branches off of it. When running the Azure DevOps build pipeline, Sonarcloud analysis succeeds, and the feature branches appear with analysis results in Sonarcloud. However, we notice that they are listed with the master branch as parent, not the develop branch. And it seems that the diff between the master branch and the feature branch is used for determining “new code” in the feature branch. So the feature branch gets “blamed” for more than it should. When we create pull requests, the develop branch is recognized as the parent, so this problem does not arise with pull requests.

We solved the parenting issue by setting “sonar.branch.target=develop” in the extraProperties of the SonarCloudPrepare step of our feature branch build pipeline. Unfortunately, it turned out that this was incompatible with pull requests, which turned up reporting

ERROR: A pull request analysis cannot have the branch analysis parameter 'sonar.branch.target'

As a workaround, we’ve deleted the existing develop branch and feature branches in Sonarcloud and renamed the master/main branch to “develop”. That seems to work for the feature branches and the develop branch (now, both feature branches and pull requests are children of the develop branch in Sonarcloud). But when analyzing the master branch, the analysis ends up being recorded in the develop branch (the default branch) in Sonarcloud. We’re not yet using the master branch or release branches actively, but it seems like this could become a major issue.

Is this a bug? Are we doing something wrong? How are the parent-child relations between branches captured?

We’ve set up our long living branches pattern as “(master|develop|release/).*”.

1 Like

How did you create the SonarCloud project? Normally the default branch defined on your ALM (Azure Dev Ops) should be the name, and get marked as the “main branch”.

Indeed, sonar.branch.* and sonar.pullrequest.* properties cannot be used together.

I think you were looking for sonar.pullrequest.base=develop. (Assuming the branch develop exists at SonarCloud side.)

Thanks, Janos. Actually, I think the master branch was the default branch in our github repository. I still wouldn’t expect it to be the source for diffing the feature branches, as they’re branched out from the develop branch.

I’ll try with sonar.pullrequest.base=develop on Tuesday, when I’m back from my vacation.

Jonas Bjelkerud

When you try with -Dsonar.pullrequest.base=develop, make sure that develop exists in SonarCloud (was analyzed). If it doesn’t exist, we fall back to the default branch (so master in your case).

Let us know how your testing goes!

I’m having similar issues with a GitHub/DevOps setup.

I have a /develop branch that is my default/MAIN/HEAD branch, and a master branch that is usually way behind because it’s only updated when I push a release (this particular project is a NuGet packaged library).

When I first set up the project, SonarCloud set my MAIN branch as ‘master’. I renamed it to ‘develop’ and the /develop CI builds seem to work OK, but SonarCloud absolutely refuses to track my /master branch with this configuration. My long-lived branch pattern is develop|master|releases?[-/].*

If I rename the MAIN to ‘master’, then SonarCloud tracks both the /master and /develop branch CI builds, but of course it shows the MAIN as ‘master’ and that’s the default stats I get on the dashboard as a result.

It seems to track PRs to the releases/* branches properly, so far as I can tell. I’m still setting up initial code (migrating an old project and doing a lot of improvement/cleanup/pruning) and pushing direct updates instead of doing PRs for the most part, so I haven’t actually done a PR to the /develop branch at this point. I’m guessing I’m going to have similar problems to the OP in that the “new code” calculation is going to be made against the wrong branch.

My main problem at this point is that I want the MAIN to be ‘develop’, but I also want to track the ‘master’ branch CI status separately, and I just can’t seem to make that happen.

What I don’t see in the conversation above is a clear “This is what’s happening, and this is how you fix it” answer, nor do I see a “We’ll look into this and see what’s happening” answer. I don’t typically do release management, so getting all of the pipelines, static analysis, etc, etc set up and working has already been somewhat of a slog for me. I would really like to just get this working so I can get back to writing code.

1 Like

We’ve now tried using sonar.pullrequest.base=develop in our feature branch build yaml setup instead of sonar.branch.target=develop. We (of course) no longer have the pull request error message (that was triggered by adding sonar.branch.target=develop), but now we get the following message when doing non-PR builds:

"ERROR: Error during SonarQube Scanner execution ERROR: A pull request analysis cannot have the branch analysis parameter 'sonar.branch.name' ERROR:"

So, as we obviously need to set the target branch for non-PR builds in another way, we’d need something like (pseudocode):

if (Build.Reason=PullRequest)
	sonar.pullrequest.base=develop
else
	sonar.branch.target=develop

That’s not easy to do in the Azure DevOps yaml, but the best way we found of doing it is by holding the extraProperties in a variable being set to sonar.branch.target=develop initially, and changing it to sonar.pullrequest.base=develop for PR builds. The following definition works. Develop is now recognized as the parent of both feature branch builds and pull request builds, even when the develop branch is not main branch in sonarcloud (master is currently our main branch again). The “new code” calculation is now correct. Just wish we didn’t have to do this to get it right.

  - job: Build
    pool:
      vmImage: 'ubuntu-latest'
    variables:
      sonarTargetBranchExtraProperty: 'sonar.branch.target=develop'
    steps:
    - ${{ if eq(variables['Build.Reason'], 'PullRequest') }}:
      - bash: echo "##vso[task.setvariable variable=sonarTargetBranchExtraProperty]sonar.pullrequest.base=develop"
        displayName: 'SonarCloud set sonar.pullrequest.base instead of sonar.branch.target for pull requests (to get correct parent in sonarcloud)'
    - task: SonarCloudPrepare@1
      inputs:
        SonarCloud: 'sonarcloud'
        organization: <our-organization>
        scannerMode: 'MSBuild'
        projectKey: 'orbit-portal-api'
        projectName: 'orbit-portal-api'
        extraProperties: |
          $(sonarTargetBranchExtraProperty)
...

We also experience the issue that Toby Herring reports. Analysis results from our github master branch always end up at the main branch in sonarcloud, regardless if it’s called master or develop in sonarcloud. For now, that’s not critical, as we currently have set up master as our main branch in sonarcloud. But we’d really like develop to be the main branch (so it’s shown as default), but still being able to track master as a separate branch in sonarcloud.

Will you fix the parent/target issue and/or the master branch mapping issue in the nearest future?

1 Like

There is a set of sonar.branch.* parameters to use with branch analysis, and a set of sonar.pullrequest.* parameters to use with pull request analysis. When a mixture is detected, we fail fast, and you get the error in your post. The bottom line is, you need to use a different (distinct) set of parameters when doing branch analysis and pull request analysis.

The analysis is for the main branch when no sonar.branch.* and sonar.pullrequest.* were specified, or when sonar.branch.name is set explicitly to the name of the main branch. You can see the main branch in the Adminstration / Branches & Pull Requests menu. So if you see some other branch that “ends up” at the main branch in SonarCloud, that can be explained by the specific analysis parameters that were used.

To sum it up:

  • To analyze the main branch, don’t use sonar.branch.* and sonar.pullrequest.*
    • Alternatively, use sonar.branch.name=name-of-your-main-branch
  • To analyze a branch as a long-living branch different the main branch, use sonar.branch.name=... and also make sure the name will match the pattern for long-living branches. (You can review and set the pattern in the Adminstration / Branches & Pull Requests menu.)
  • To analyze a pull request, use the sonar.pullreqest.* properties

The moment you import a project to SonarCloud, it detects the default branch. If develop was the default branch, SonarCloud use it as the “main”, and show it so on the admin page. Analyses without sonar.branch.* and sonar.pullrequest.* will end up in that branch on SonarCloud.

Let me know if something is still not clear enough!

When you go to Adminstration / Branches & Pull Requests of the project, what do you see as MAIN branch? And do you see both develop and master as long-lived branches?

If you pass the correct sonar.pullrequest.* parameters, I expect everything will go just fine :wink:

If you can manage to tweak your branch names so that on Adminstration / Branches & Pull Requests you see develop as MAIN, and master as a long-living branch, and if you analyze those branches with sonar.branch.name=... (the appropriate name, master or develop), then it should do the trick.

Let me know if you still experience issues, and sorry for the delayed response.

Thanks for the clarification, Janos. We were hoping that the correct branch mapping would be out of the box when using the Azure DevOps and GitHub plugins, but we’re doing fine with our current setup.

Right now, it shows ‘develop’, but only because I changed it manually. In this scenario, there is no ‘master’ branch in the list of branches.

When the MAIN branch is set to ‘master’, then the develop branch also appears in the list, but since it’s not the MAIN branch my understanding from this conversation is that it is not used as the baseline.

I was kind of expecting it to “just work”. Or, if it doesn’t, I was expecting it to at least be documented. It’s not like this is an edge case. Even more so because it doesn’t work on SonarQube, either.

If we can detect whether a build is a CI build or a PR build and set those properties in the build, then why can’t the SonarXxxxx app figure it out? It makes much more sense for you guys to do it once in the app itself than to require thousands of developers around the world to figure this out in a vacuum.

So at this point, I know there are some properties that I need to set, but since you used wildcards in your response, I have no idea what they actually are. Nor do I have any idea at this point how I’m supposed to go about finding/building the values to set on those properties once I figure out what properties exist and which ones matter.

And BTW, if SonarXxxxx is supposed to automatically detect the default branch the first time a project is reported, that feature doesn’t work.

Hi,

For GitHub and BitBucket Cloud repo, we don’t have currently the possibility to retrieve the default branch of the repository, so we assume that this is master.

This is definitely something to improve on our side (or at least as you said to document it), so i’ve created a ticket to track this : https://jira.sonarsource.com/browse/VSTS-221

Thank you.

Mickaël

Mickaël, thanks for that response.

For my personal stuff, I use GitHub repos, Azure DevOps pipelines, and SonarCloud, so that explains why it didn’t pick up my “develop” branch there.

But at work, we use Azure DevOps repos and pipelines with SonarQube. I don’t know what version of SonarQube we were running when we first added the projects I work on, but it didn’t pick up the “develop” branch as the default, either.

Right now I’m working on stories to convert our build pipelines to code-first YAML pipelines, and fix the static analysis and coverage reporting as I do it, so this is particularly frustrating. (Not so much the devlop/master issue as the problem of figuring out which properties I need to set, and when, to get the analysis reporting to work right.)

For Azure DevOps / SonarQube scenario, you need at least the version 7.2 of SonarQube, and at least the developer edition to get branch/pr decoration working and correct information filled. (Please note that in this case, all properties related to PR / branches are automatically filled and sent to the scanner with the extension)

Mickaël

It doesn’t work like you say it should:

Yes, sorry, this is munderstandable.

What i wanted to say is that, as long as we don’t yet provide any onboarding for Azure DevOps projects, there’s no check of the main branch, such as we do on GitHub and BitBucket projects.

So it will remain master, even for auto-provisioned projects, and you’ll have to change it manually.

We will clarify that in the near future.

Mickaël