We are seeing incorrect branch navigation from SonarQube to Azure DevOps on clicking view on Azure

Environment:

  1. SCM: Azure DevOps Repos
  2. CI: Azure Pipelines
  3. Analyzer pipeline YAML: sonarqube-run.yml
  4. Branch model: SIT, UAT, main
  5. SonarQube project currently has default branch set to main

Problem:

  1. For SIT analysis, when clicking Open in Azure DevOps from SonarQube issue/code links, it opens UAT branch (or sometimes main) instead of SIT.
  2. In Azure Pipelines, default branch for manual and scheduled builds is already set to SIT for the SIT pipeline definition.
  3. Pipeline trigger in SIT branch is SIT-only, and pipeline execution itself works from SIT.
  4. Branch mismatch is specifically in SonarQube generated links.

Expected behavior:

  1. If analysis is for SIT branch, SonarQube links should open the same file in SIT branch in Azure DevOps.

Actual behavior:

  1. SonarQube links open UAT or main branch for the same file.

What we already checked:

  1. Azure pipeline trigger and default branch settings are aligned for SIT pipeline.
  2. Separate branch behavior in Azure UI works as expected in pipeline context.
  3. SonarQube default branch is main.
  4. Issue appears to be branch mapping/context used by SonarQube when generating Azure DevOps links.

Questions:

  1. Does SonarQube Azure DevOps linking always prefer project default branch unless branch metadata is explicitly provided?
  2. What is the exact required configuration so SonarQube issue links respect analyzed branch (SIT/UAT) for Azure DevOps repositories?
  3. Should we use separate SonarQube projects per long-lived branch (SIT and UAT), or is single project branch-aware linking fully supported for Azure DevOps links?
  4. Which SonarQube properties are mandatory to force correct branch mapping for links in CI runs?

Hi @prabhat25,

Thanks for reaching out, welcome to the Community!

The “Open in Azure DevOps” link in SonarQube is generated using the commit SHA from the analysis. When this link doesn’t include an explicit branch qualifier, Azure DevOps resolves it against the ADO repository’s own default branch, which from your description appears to be UAT. That explains why you see UAT (or main as a fallback) rather than SIT.

There are two things to check:

1. Verify sonar.branch.name is being set correctly for SIT

For scheduled or manual ADO pipeline runs, Build.SourceBranchName sometimes returns the pipeline definition’s default branch rather than the actual branch being built. Add sonar.verbose=true to confirm what branch SonarQube actually records:

- task: SonarQubePrepare@8
  inputs:
    ...
    extraProperties: |
      sonar.branch.name=$(Build.SourceBranchName)
      sonar.verbose=true

Look for sonar.branch.name=SIT in the scanner output. If the value is wrong or missing, the analysis is landing on the wrong branch in SonarQube.

2. Check your ADO repository’s default branch

In Azure DevOps, go to Repos → Branches and verify which branch is set as the repository default. If UAT is the ADO repo default, that explains the link behaviour, ADO shows the file in the default branch context when no explicit branch is included in the URL.

3. Ensure you click from the SIT branch context in SonarQube

When navigating to an issue in SonarQube, make sure you’re viewing the analysis for the SIT branch (not the project’s main branch view) before clicking “Open in Azure DevOps”. The link is generated from whichever branch context you’re currently viewing.

To directly answer your questions:

  • Separate projects per branch are not required, the single-project multi-branch model works, but sonar.branch.name must be set correctly per pipeline.
  • There is no additional “branch mapping” property beyond sonar.branch.name,getting that right is the key.

Could you share what sonar.branch.name shows in the verbose logs for a SIT pipeline run? That will tell us if the analysis is being correctly recorded against the SIT branch.

Best regards,

Stevan

Thanks ,our default branch is main only but the issue is that we’re not setting sonar.branch.name. The analysis runs directly against $(Build.SourcesDirectory), so SonarQube associates the scan with whichever branch is checked out by the pipeline at that point. As a result, the links sometimes redirect to different branches instead of the intended one

Hi @prabhat25,

Glad that helped pinpoint it! Once you add sonar.branch.name=$(Build.SourceBranchName) to the SonarQubePrepare extraProperties, the branch will be explicitly recorded for each pipeline run and the “Open in Azure DevOps” links should consistently open the correct branch.

Cheers,

Stevan