Skip to content

kosli attest sonar fails for non-main branches: missing branch param in project_analyses/search #861

@jalmaas

Description

@jalmaas

Summary

kosli attest sonar cannot resolve scan results for any branch other than the project's main branch. The CLI knows which branch the scan ran on (it's in the CE task response) but never passes it to SonarQube's project_analyses/search API. Without the branch parameter, SonarQube returns analyses for the main branch only, the analysis ID lookup fails, and the CLI exits with:

Error: analysis with ID <uuid> not found on https://sonarcloud.io. Snapshot may have been deleted by SonarQube

Reproduction

  1. Run a SonarQube scan on a non-default branch (any branch other than main/master). The branch must be classified as LONG (or the scan must produce queryable analysis history).
  2. Run kosli attest sonar --sonar-working-dir .scannerwork --flow ... --trail ... --name ... --sonar-api-token ... --max-wait 300.
  3. Observe the CLI exits with analysis with ID <uuid> not found on https://sonarcloud.io.

This is reliably reproducible — every push to a release branch in our repo hits it.

Direct API verification

# Kosli's call (no branch param) — returns 30 analyses, all from main:
GET https://sonarcloud.io/api/project_analyses/search?project=<key>
  → analyses for main only

# Same call WITH branch param — returns the analysis Kosli is looking for:
GET https://sonarcloud.io/api/project_analyses/search?project=<key>&branch=release/11.2.0
  → 1 analysis with key=dbe8a11e-21f8-460d-8765-802d4e0db490 (matches what CE task returned)

The analysis exists; the CLI just can't see it because it's not on the main branch.

Source

internal/sonar/sonar.go:

// GetProjectAnalysisFromAnalysisID
projectAnalysesURL, err := sonarURL(sonarResults.ServerUrl, "api/project_analyses/search",
    url.Values{"project": {project.Key}})    // ← no branch param

// GetProjectAnalysisFromRevision — same omission

The CE task response (internal/sonar/sonar.go:Task) already exposes Branch and BranchType, and GetCETaskData populates sonarResults.Branch from it. The branch name is right there; it's just never used in the project_analyses/search URL.

Expected behavior

When the CE task reports a non-empty branch name, kosli attest sonar should pass it as branch=<name> to project_analyses/search so the analysis can be located on the correct branch.

Suggested fix

In both GetProjectAnalysisFromAnalysisID and GetProjectAnalysisFromRevision:

values := url.Values{"project": {project.Key}}
if sonarResults.Branch != nil && sonarResults.Branch.Name != "" {
    values.Set("branch", sonarResults.Branch.Name)
}
projectAnalysesURL, err := sonarURL(sonarResults.ServerUrl, "api/project_analyses/search", values)

api/qualitygates/project_status (called from GetQualityGate) is already analysis-ID-based so it doesn't need branch — but worth a once-over for the same class of bug.

Affected versions

Confirmed on v2.17.1 (used by kosli-dev/setup-cli-action@v3 default) and verified the bug is still present on main at v2.17.5 — same code path in internal/sonar/sonar.go.

Workaround

There is no CLI-side workaround — there's no --branch flag on kosli attest sonar, and --sonar-revision / --pull-request modes route through the same buggy project_analyses/search lookup. Affected users have to either:

  • Skip sonar attestation for non-main branches.
  • Bypass kosli attest sonar entirely and call SonarQube + kosli attest generic themselves.
  • Or run the scan against main (defeats the purpose).

A small CLI patch is by far the cleanest fix.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions