Go SDK
Create a client
The root type is Client. Create one with NewClient, configured with functional options:
client, err := sonar.NewClient(nil,
sonar.WithBaseURL("https://sonarqube.example.com/api/"),
sonar.WithToken("my-token"),
)
if err != nil {
panic(err)
}
result, _, err := client.Projects.Search(context.Background(), &sonar.ProjectsSearchOptions{
Query: "my-service",
})
if err != nil {
panic(err)
}
for _, project := range result.Components {
fmt.Println(project.Key)
}or with a ClientCreateOptions struct (both can be combined, the options are applied after the struct):
url := "https://sonarqube.example.com/api/"
token := "my-token"
client, err := sonar.NewClient(&sonar.ClientCreateOptions{
URL: &url,
Token: &token,
})
if err != nil {
panic(err)
}/api/: https://sonarqube.example.com/api/.Authentication
A user token is recommended (WithToken, above). Basic authentication is also supported:
client, err := sonar.NewClient(nil,
sonar.WithBaseURL("https://sonarqube.example.com/api/"),
sonar.WithBasicAuth("admin", "my-password"),
)
if err != nil {
panic(err)
}From the environment
In CI/CD, NewClientFromEnv reads the configuration from the environment:
| Environment variable | Description |
|---|---|
SONAR_URL | Base API URL of the SonarQube instance |
SONAR_TOKEN | Authentication token, takes precedence over basic authentication |
SONAR_USERNAME | Username for basic authentication |
SONAR_PASSWORD | Password for basic authentication |
SONAR_USER_AGENT | Overrides the default User-Agent header |
SONAR_TIMEOUT | HTTP request timeout, as a Go duration (30s, 2m) |
client, err := sonar.NewClientFromEnv()
if err != nil {
panic(err)
}Options passed to NewClientFromEnv are applied after the environment is read, so they take precedence over it.
Call the API
Each API area is a typed service field of the client: client.Projects, client.Issues, client.Qualitygates, … (see the services). Every method takes a context.Context and, when the endpoint has parameters, a *<Service><Method>Options struct. It returns the decoded response, the raw *http.Response and an error.
client, err := sonar.NewClientFromEnv()
if err != nil {
panic(err)
}
status, _, err := client.Qualitygates.ProjectStatus(context.Background(), &sonar.QualitygatesProjectStatusOptions{
ProjectKey: "my-project",
})
if err != nil {
panic(err)
}
if status.ProjectStatus.Status != "OK" {
panic("quality gate failed: " + status.ProjectStatus.Status)
}client, err := sonar.NewClientFromEnv()
if err != nil {
panic(err)
}
issues, _, err := client.Issues.Search(context.Background(), &sonar.IssuesSearchOptions{
PaginationArgs: sonar.PaginationArgs{Page: 1, PageSize: 100},
Projects: []string{"my-project"},
IssueStatuses: []string{"OPEN", "CONFIRMED"},
})
if err != nil {
panic(err)
}
fmt.Printf("page %d: %d of %d issues\n", issues.Paging.PageIndex, len(issues.Issues), issues.Paging.Total)
for _, issue := range issues.Issues {
fmt.Println(issue.Key, issue.Message)
}V1 and V2 APIs
SonarQube exposes two web APIs. The V1 services are fields of the client (client.Issues), and encode their parameters in the query string. The V2 services are grouped under client.V2 (client.V2.System), use JSON request bodies, and get the v2/ path prefix automatically:
client, err := sonar.NewClientFromEnv()
if err != nil {
panic(err)
}
health, _, err := client.V2.System.GetHealth(context.Background(), &sonar.SystemPasscodeOptionV2{
Passcode: "my-monitoring-passcode",
})
if err != nil {
panic(err)
}
fmt.Println(health.Status)The services page lists both.