Allow customizing metrics fetch from SonarQube
Signed-off-by: Steven Kriegler <sk.bunsenbrenner@gmail.com>
This commit is contained in:
parent
a2d68ccc12
commit
f187d4f8c6
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -6,3 +6,4 @@
|
|||
/coverage.html
|
||||
/*.log
|
||||
/cover.out
|
||||
/cover.html
|
||||
|
|
|
@ -7,8 +7,8 @@ gitea:
|
|||
# User needs "Read project" permissions with access to "Pull Requests"
|
||||
token:
|
||||
value: ""
|
||||
# # or path to file containing the plain text secret
|
||||
# file: /path/to/gitea/token
|
||||
# # or path to file containing the plain text secret
|
||||
# file: /path/to/gitea/token
|
||||
|
||||
# If the sent webhook has a signature header, the bot validates the request payload. If the value does not match, the
|
||||
# request will be ignored.
|
||||
|
@ -16,8 +16,8 @@ gitea:
|
|||
# exists and no webhookSecret is defined here, the bot will ignore the request, because it cannot be validated.
|
||||
webhook:
|
||||
secret: ""
|
||||
# # or path to file containing the plain text secret
|
||||
# secretFile: /path/to/gitea/webhook/secret
|
||||
# # or path to file containing the plain text secret
|
||||
# secretFile: /path/to/gitea/webhook/secret
|
||||
|
||||
# SonarQube related configuration. Necessary for requesting data from the API and processing the webhook.
|
||||
sonarqube:
|
||||
|
@ -28,8 +28,8 @@ sonarqube:
|
|||
# User needs "Browse on project" permissions
|
||||
token:
|
||||
value: ""
|
||||
# # or path to file containing the plain text secret
|
||||
# file: /path/to/sonarqube/token
|
||||
# # or path to file containing the plain text secret
|
||||
# file: /path/to/sonarqube/token
|
||||
|
||||
# If the sent webhook has a signature header, the bot validates the request payload. If the value does not match, the
|
||||
# request will be ignored.
|
||||
|
@ -38,8 +38,14 @@ sonarqube:
|
|||
# validated.
|
||||
webhook:
|
||||
secret: ""
|
||||
# # or path to file containing the plain text secret
|
||||
# secretFile: /path/to/sonarqube/webhook/secret
|
||||
# # or path to file containing the plain text secret
|
||||
# secretFile: /path/to/sonarqube/webhook/secret
|
||||
|
||||
# Some useful metrics depend on the edition in use. There are various ones like code_smells, vulnerabilities, bugs, etc.
|
||||
# By default the bot will extract "bugs,vulnerabilities,code_smells"
|
||||
# Setting this option you can extend that default list by your own metrics.
|
||||
additionalMetrics: []
|
||||
# - "new_security_hotspots"
|
||||
|
||||
# List of project mappings to take care of. Webhooks for other projects will be ignored.
|
||||
# At least one must be configured. Otherwise all webhooks (no matter which source) because the bot cannot map on its own.
|
||||
|
|
|
@ -55,6 +55,12 @@ app:
|
|||
secret: ""
|
||||
# # or path to file containing the plain text secret
|
||||
# secretFile: /bot/secrets/sonarqube/webhook-secret
|
||||
|
||||
# Some useful metrics depend on the edition in use. There are various ones like code_smells, vulnerabilities, bugs, etc.
|
||||
# By default the bot will extract "bugs,vulnerabilities,code_smells"
|
||||
# Setting this option you can extend that default list by your own metrics.
|
||||
additionalMetrics: []
|
||||
# - "new_security_hotspots"
|
||||
|
||||
# List of project mappings to take care of. Webhooks for other projects will be ignored.
|
||||
# At least one must be configured. Otherwise all webhooks (no matter which source) because the bot cannot map on its own.
|
||||
|
|
|
@ -102,7 +102,7 @@ func (sdk *SonarQubeSdk) GetPullRequest(project string, index int64) (*PullReque
|
|||
}
|
||||
|
||||
func (sdk *SonarQubeSdk) GetMeasures(project string, branch string) (*MeasuresResponse, error) {
|
||||
url := fmt.Sprintf("%s/api/measures/component?additionalFields=metrics&metricKeys=bugs,vulnerabilities,new_security_hotspots,code_smells&component=%s&pullRequest=%s", sdk.baseUrl, project, branch)
|
||||
url := fmt.Sprintf("%s/api/measures/component?additionalFields=metrics&metricKeys=%s&component=%s&pullRequest=%s", sdk.baseUrl, settings.SonarQube.GetMetricsList(), project, branch)
|
||||
req, err := http.NewRequest(http.MethodGet, url, nil)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("cannot initialize Request: %w", err)
|
||||
|
|
|
@ -32,6 +32,7 @@ func newConfigReader() *viper.Viper {
|
|||
v.SetDefault("sonarqube.token.file", "")
|
||||
v.SetDefault("sonarqube.webhook.secret", "")
|
||||
v.SetDefault("sonarqube.webhook.secretFile", "")
|
||||
v.SetDefault("sonarqube.additionalMetrics", []string{})
|
||||
v.SetDefault("projects", []Project{})
|
||||
|
||||
return v
|
||||
|
@ -43,14 +44,14 @@ func Load(configPath string) {
|
|||
|
||||
err := r.ReadInConfig()
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("Fatal error while reading config file: %w \n", err))
|
||||
panic(fmt.Errorf("fatal error while reading config file: %w", err))
|
||||
}
|
||||
|
||||
var projects []Project
|
||||
|
||||
err = r.UnmarshalKey("projects", &projects)
|
||||
if err != nil {
|
||||
panic(fmt.Errorf("Unable to load project mapping: %s", err.Error()))
|
||||
panic(fmt.Errorf("unable to load project mapping: %s", err.Error()))
|
||||
}
|
||||
|
||||
if len(projects) == 0 {
|
||||
|
@ -67,8 +68,9 @@ func Load(configPath string) {
|
|||
Webhook: NewWebhook(r, "gitea", errCallback),
|
||||
}
|
||||
SonarQube = sonarQubeConfig{
|
||||
Url: r.GetString("sonarqube.url"),
|
||||
Token: NewToken(r, "sonarqube", errCallback),
|
||||
Webhook: NewWebhook(r, "sonarqube", errCallback),
|
||||
Url: r.GetString("sonarqube.url"),
|
||||
Token: NewToken(r, "sonarqube", errCallback),
|
||||
Webhook: NewWebhook(r, "sonarqube", errCallback),
|
||||
AdditionalMetrics: r.GetStringSlice("sonarqube.additionalMetrics"),
|
||||
}
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ sonarqube:
|
|||
value: a09eb5785b25bb2cbacf48808a677a0709f02d8e
|
||||
webhook:
|
||||
secret: haxxor-sonarqube-secret
|
||||
additionalMetrics: []
|
||||
projects:
|
||||
- sonarqube:
|
||||
key: gitea-sonarqube-pr-bot
|
||||
|
@ -107,6 +108,45 @@ func TestLoadSonarQubeStructure(t *testing.T) {
|
|||
}
|
||||
|
||||
assert.EqualValues(t, expected, SonarQube)
|
||||
assert.EqualValues(t, expected.GetMetricsList(), "bugs,vulnerabilities,code_smells")
|
||||
}
|
||||
|
||||
func TestLoadSonarQubeStructureWithAdditionalMetrics(t *testing.T) {
|
||||
WriteConfigFile(t, []byte(
|
||||
`gitea:
|
||||
url: https://example.com/gitea
|
||||
token:
|
||||
value: fake-gitea-token
|
||||
sonarqube:
|
||||
url: https://example.com/sonarqube
|
||||
token:
|
||||
value: fake-sonarqube-token
|
||||
additionalMetrics: "new_security_hotspots"
|
||||
projects:
|
||||
- sonarqube:
|
||||
key: gitea-sonarqube-pr-bot
|
||||
gitea:
|
||||
owner: example-organization
|
||||
name: pr-bot
|
||||
`))
|
||||
Load(os.TempDir())
|
||||
|
||||
expected := sonarQubeConfig{
|
||||
Url: "https://example.com/sonarqube",
|
||||
Token: &token{
|
||||
Value: "fake-sonarqube-token",
|
||||
},
|
||||
Webhook: &webhook{
|
||||
Secret: "",
|
||||
},
|
||||
AdditionalMetrics: []string{
|
||||
"new_security_hotspots",
|
||||
},
|
||||
}
|
||||
|
||||
assert.EqualValues(t, expected, SonarQube)
|
||||
assert.EqualValues(t, expected.AdditionalMetrics, []string{"new_security_hotspots"})
|
||||
assert.EqualValues(t, "bugs,vulnerabilities,code_smells,new_security_hotspots", SonarQube.GetMetricsList())
|
||||
}
|
||||
|
||||
func TestLoadSonarQubeStructureInjectedEnvs(t *testing.T) {
|
||||
|
@ -189,6 +229,7 @@ projects:
|
|||
Secret: "sonarqube-totally-secret",
|
||||
secretFile: sonarqubeWebhookSecretFile,
|
||||
},
|
||||
AdditionalMetrics: []string{},
|
||||
}
|
||||
|
||||
Load(os.TempDir())
|
||||
|
|
|
@ -1,7 +1,22 @@
|
|||
package settings
|
||||
|
||||
import "strings"
|
||||
|
||||
type sonarQubeConfig struct {
|
||||
Url string
|
||||
Token *token
|
||||
Webhook *webhook
|
||||
Url string
|
||||
Token *token
|
||||
Webhook *webhook
|
||||
AdditionalMetrics []string
|
||||
}
|
||||
|
||||
func (c *sonarQubeConfig) GetMetricsList() string {
|
||||
metrics := []string{
|
||||
"bugs",
|
||||
"vulnerabilities",
|
||||
"code_smells",
|
||||
}
|
||||
if len(c.AdditionalMetrics) != 0 {
|
||||
metrics = append(metrics, c.AdditionalMetrics...)
|
||||
}
|
||||
return strings.Join(metrics, ",")
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue