mirror of
https://github.com/SAP/jenkins-library.git
synced 2026-06-19 22:58:55 +02:00
Extend sonarExecuteScan parameters (#1982)
* Add projectKey and coverageExclusions params * Also add binary, coverage exclusions and jacoco related options to sonar execution. Co-authored-by: Daniel Kurzynski <daniel.kurzynski@sap.com> Co-authored-by: Kevin Hudemann <kevin.hudemann@sap.com>
This commit is contained in:
co-authored by
Daniel Kurzynski
Kevin Hudemann
parent
7b08b8b3cd
commit
eb09f2d902
+79
-6
@@ -1,6 +1,7 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/bmatcuk/doublestar"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
"os/exec"
|
||||
@@ -32,14 +33,29 @@ func (s *sonarSettings) addEnvironment(element string) {
|
||||
s.environment = append(s.environment, element)
|
||||
}
|
||||
|
||||
func (s *sonarSettings) addOption(element string) { s.options = append(s.options, element) }
|
||||
func (s *sonarSettings) addOption(element string) {
|
||||
s.options = append(s.options, element)
|
||||
}
|
||||
|
||||
var sonar sonarSettings
|
||||
var (
|
||||
sonar sonarSettings
|
||||
|
||||
var execLookPath = exec.LookPath
|
||||
var fileUtilsExists = FileUtils.FileExists
|
||||
var fileUtilsUnzip = FileUtils.Unzip
|
||||
var osRename = os.Rename
|
||||
execLookPath = exec.LookPath
|
||||
fileUtilsExists = FileUtils.FileExists
|
||||
fileUtilsUnzip = FileUtils.Unzip
|
||||
osRename = os.Rename
|
||||
osStat = os.Stat
|
||||
doublestarGlob = doublestar.Glob
|
||||
)
|
||||
|
||||
const (
|
||||
coverageReportPaths = "sonar.coverage.jacoco.xmlReportPaths="
|
||||
javaBinaries = "sonar.java.binaries="
|
||||
javaLibraries = "sonar.java.libraries="
|
||||
coverageExclusions = "sonar.coverage.exclusions="
|
||||
pomXMLPattern = "**/pom.xml"
|
||||
jacocoReportPattern = "**/target/**/jacoco.xml"
|
||||
)
|
||||
|
||||
func sonarExecuteScan(config sonarExecuteScanOptions, _ *telemetry.CustomData, influx *sonarExecuteScanInflux) {
|
||||
runner := command.Command{
|
||||
@@ -84,6 +100,21 @@ func runSonar(config sonarExecuteScanOptions, client piperhttp.Downloader, runne
|
||||
// handleArtifactVersion is reused from cmd/protecodeExecuteScan.go
|
||||
sonar.addOption("sonar.projectVersion=" + handleArtifactVersion(config.ProjectVersion))
|
||||
}
|
||||
if len(config.ProjectKey) > 0 {
|
||||
sonar.addOption("sonar.projectKey=" + config.ProjectKey)
|
||||
}
|
||||
if len(config.M2Path) > 0 && config.InferJavaLibraries {
|
||||
sonar.addOption(javaLibraries + filepath.Join(config.M2Path, "**"))
|
||||
}
|
||||
if len(config.CoverageExclusions) > 0 && !isInOptions(config, coverageExclusions) {
|
||||
sonar.addOption(coverageExclusions + strings.Join(config.CoverageExclusions, ","))
|
||||
}
|
||||
if config.InferJavaBinaries && !isInOptions(config, javaBinaries) {
|
||||
addJavaBinaries()
|
||||
}
|
||||
if !isInOptions(config, coverageReportPaths) {
|
||||
addJacocoReportPaths()
|
||||
}
|
||||
if err := handlePullRequest(config); err != nil {
|
||||
log.SetErrorCategory(log.ErrorConfiguration)
|
||||
return err
|
||||
@@ -131,6 +162,48 @@ func runSonar(config sonarExecuteScanOptions, client piperhttp.Downloader, runne
|
||||
return nil
|
||||
}
|
||||
|
||||
// isInOptions returns true, if the given property is already provided in config.Options.
|
||||
func isInOptions(config sonarExecuteScanOptions, property string) bool {
|
||||
property = strings.TrimSuffix(property, "=")
|
||||
return SliceUtils.ContainsStringPart(config.Options, property)
|
||||
}
|
||||
|
||||
func addJacocoReportPaths() {
|
||||
matches, err := doublestarGlob(jacocoReportPattern)
|
||||
if err != nil {
|
||||
log.Entry().Warnf("failed to glob for Jacoco report paths: %v", err)
|
||||
return
|
||||
}
|
||||
if len(matches) > 0 {
|
||||
sonar.addOption(coverageReportPaths + strings.Join(matches, ","))
|
||||
}
|
||||
}
|
||||
|
||||
func addJavaBinaries() {
|
||||
pomFiles, err := doublestarGlob(pomXMLPattern)
|
||||
if err != nil {
|
||||
log.Entry().Warnf("failed to glob for pom modules: %v", err)
|
||||
return
|
||||
}
|
||||
var binaries []string
|
||||
|
||||
var classesDirs = []string{"classes", "test-classes"}
|
||||
|
||||
for _, pomFile := range pomFiles {
|
||||
module := filepath.Dir(pomFile)
|
||||
for _, classDir := range classesDirs {
|
||||
classesPath := filepath.Join(module, "target", classDir)
|
||||
_, err := osStat(classesPath)
|
||||
if err == nil {
|
||||
binaries = append(binaries, classesPath)
|
||||
}
|
||||
}
|
||||
}
|
||||
if len(binaries) > 0 {
|
||||
sonar.addOption(javaBinaries + strings.Join(binaries, ","))
|
||||
}
|
||||
}
|
||||
|
||||
func handlePullRequest(config sonarExecuteScanOptions) error {
|
||||
if len(config.ChangeID) > 0 {
|
||||
if config.LegacyPRHandling {
|
||||
|
||||
@@ -23,8 +23,13 @@ type sonarExecuteScanOptions struct {
|
||||
CustomTLSCertificateLinks []string `json:"customTlsCertificateLinks,omitempty"`
|
||||
SonarScannerDownloadURL string `json:"sonarScannerDownloadUrl,omitempty"`
|
||||
ProjectVersion string `json:"projectVersion,omitempty"`
|
||||
ProjectKey string `json:"projectKey,omitempty"`
|
||||
CoverageExclusions []string `json:"coverageExclusions,omitempty"`
|
||||
InferJavaBinaries bool `json:"inferJavaBinaries,omitempty"`
|
||||
InferJavaLibraries bool `json:"inferJavaLibraries,omitempty"`
|
||||
Options []string `json:"options,omitempty"`
|
||||
BranchName string `json:"branchName,omitempty"`
|
||||
InferBranchName bool `json:"inferBranchName,omitempty"`
|
||||
ChangeID string `json:"changeId,omitempty"`
|
||||
ChangeBranch string `json:"changeBranch,omitempty"`
|
||||
ChangeTarget string `json:"changeTarget,omitempty"`
|
||||
@@ -35,6 +40,7 @@ type sonarExecuteScanOptions struct {
|
||||
DisableInlineComments bool `json:"disableInlineComments,omitempty"`
|
||||
LegacyPRHandling bool `json:"legacyPRHandling,omitempty"`
|
||||
GithubAPIURL string `json:"githubApiUrl,omitempty"`
|
||||
M2Path string `json:"m2Path,omitempty"`
|
||||
}
|
||||
|
||||
type sonarExecuteScanInflux struct {
|
||||
@@ -136,8 +142,13 @@ func addSonarExecuteScanFlags(cmd *cobra.Command, stepConfig *sonarExecuteScanOp
|
||||
cmd.Flags().StringSliceVar(&stepConfig.CustomTLSCertificateLinks, "customTlsCertificateLinks", []string{}, "List of download links to custom TLS certificates. This is required to ensure trusted connections to instances with custom certificates.")
|
||||
cmd.Flags().StringVar(&stepConfig.SonarScannerDownloadURL, "sonarScannerDownloadUrl", `https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.4.0.2170-linux.zip`, "URL to the sonar-scanner-cli archive.")
|
||||
cmd.Flags().StringVar(&stepConfig.ProjectVersion, "projectVersion", os.Getenv("PIPER_projectVersion"), "The project version that is reported to SonarQube.")
|
||||
cmd.Flags().StringVar(&stepConfig.ProjectKey, "projectKey", os.Getenv("PIPER_projectKey"), "The project key identifies the project in SonarQube.")
|
||||
cmd.Flags().StringSliceVar(&stepConfig.CoverageExclusions, "coverageExclusions", []string{}, "A list of patterns that should be excluded from the coverage scan.")
|
||||
cmd.Flags().BoolVar(&stepConfig.InferJavaBinaries, "inferJavaBinaries", false, "Find the location of generated Java class files in all modules and pass the option `sonar.java.binaries to the sonar tool.")
|
||||
cmd.Flags().BoolVar(&stepConfig.InferJavaLibraries, "inferJavaLibraries", false, "If the parameter `m2Path` is configured for the step `mavenExecute` in the general section of the configuration, pass it as option `sonar.java.libraries` to the sonar tool.")
|
||||
cmd.Flags().StringSliceVar(&stepConfig.Options, "options", []string{}, "A list of options which are passed to the sonar-scanner.")
|
||||
cmd.Flags().StringVar(&stepConfig.BranchName, "branchName", os.Getenv("PIPER_branchName"), "Non-Pull-Request only: Name of the SonarQube branch that should be used to report findings to.")
|
||||
cmd.Flags().BoolVar(&stepConfig.InferBranchName, "inferBranchName", false, "Jenkins only: Whether to infer the `branchName` parameter automatically based on the `BRANCH_NAME` environment variable in non-productive runs of the pipeline.")
|
||||
cmd.Flags().StringVar(&stepConfig.ChangeID, "changeId", os.Getenv("PIPER_changeId"), "Pull-Request only: The id of the pull-request.")
|
||||
cmd.Flags().StringVar(&stepConfig.ChangeBranch, "changeBranch", os.Getenv("PIPER_changeBranch"), "Pull-Request only: The name of the pull-request branch.")
|
||||
cmd.Flags().StringVar(&stepConfig.ChangeTarget, "changeTarget", os.Getenv("PIPER_changeTarget"), "Pull-Request only: The name of the base branch.")
|
||||
@@ -147,7 +158,8 @@ func addSonarExecuteScanFlags(cmd *cobra.Command, stepConfig *sonarExecuteScanOp
|
||||
cmd.Flags().StringVar(&stepConfig.GithubToken, "githubToken", os.Getenv("PIPER_githubToken"), "Pull-Request only: Token for Github to set status on the Pull-Request.")
|
||||
cmd.Flags().BoolVar(&stepConfig.DisableInlineComments, "disableInlineComments", false, "Pull-Request only: Disables the pull-request decoration with inline comments. DEPRECATED: only supported in SonarQube < 7.2")
|
||||
cmd.Flags().BoolVar(&stepConfig.LegacyPRHandling, "legacyPRHandling", false, "Pull-Request only: Activates the pull-request handling using the [GitHub Plugin](https://docs.sonarqube.org/display/PLUG/GitHub+Plugin). DEPRECATED: only supported in SonarQube < 7.2")
|
||||
cmd.Flags().StringVar(&stepConfig.GithubAPIURL, "githubApiUrl", `https://api.github.com`, "Pull-Request only: The URL to the Github API. see [GitHub plugin docs](https://docs.sonarqube.org/display/PLUG/GitHub+Plugin#GitHubPlugin-Usage) DEPRECATED: only supported in SonarQube < 7.2")
|
||||
cmd.Flags().StringVar(&stepConfig.GithubAPIURL, "githubApiUrl", `https://api.github.com`, "Pull-Request only: The URL to the Github API. See [GitHub plugin docs](https://docs.sonarqube.org/display/PLUG/GitHub+Plugin#GitHubPlugin-Usage) DEPRECATED: only supported in SonarQube < 7.2")
|
||||
cmd.Flags().StringVar(&stepConfig.M2Path, "m2Path", os.Getenv("PIPER_m2Path"), "Path to the location of the local repository that should be used.")
|
||||
|
||||
}
|
||||
|
||||
@@ -218,13 +230,45 @@ func sonarExecuteScanMetadata() config.StepData {
|
||||
Aliases: []config.Alias{},
|
||||
},
|
||||
{
|
||||
Name: "options",
|
||||
Name: "projectKey",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||
Type: "string",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{},
|
||||
},
|
||||
{
|
||||
Name: "coverageExclusions",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||
Type: "[]string",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{},
|
||||
},
|
||||
{
|
||||
Name: "inferJavaBinaries",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||
Type: "bool",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{},
|
||||
},
|
||||
{
|
||||
Name: "inferJavaLibraries",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||
Type: "bool",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{},
|
||||
},
|
||||
{
|
||||
Name: "options",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||
Type: "[]string",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{{Name: "sonarProperties"}},
|
||||
},
|
||||
{
|
||||
Name: "branchName",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
@@ -233,6 +277,14 @@ func sonarExecuteScanMetadata() config.StepData {
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{},
|
||||
},
|
||||
{
|
||||
Name: "inferBranchName",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
Scope: []string{"PARAMETERS", "STAGES", "STEPS"},
|
||||
Type: "bool",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{},
|
||||
},
|
||||
{
|
||||
Name: "changeId",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
@@ -313,6 +365,14 @@ func sonarExecuteScanMetadata() config.StepData {
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{},
|
||||
},
|
||||
{
|
||||
Name: "m2Path",
|
||||
ResourceRef: []config.ResourceReference{},
|
||||
Scope: []string{"GENERAL", "STEPS", "STAGES", "PARAMETERS"},
|
||||
Type: "string",
|
||||
Mandatory: false,
|
||||
Aliases: []config.Alias{{Name: "maven/m2Path"}},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/bmatcuk/doublestar"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
@@ -65,6 +67,27 @@ func mockOsRename(t *testing.T, expectOld, expectNew string) func(string, string
|
||||
}
|
||||
}
|
||||
|
||||
func mockOsStat(exists map[string]bool) func(name string) (os.FileInfo, error) {
|
||||
return func(name string) (os.FileInfo, error) {
|
||||
_, exists := exists[name]
|
||||
if exists {
|
||||
// Exploits the fact that FileInfo result from os.Stat() is ignored anyway
|
||||
return nil, nil
|
||||
}
|
||||
return nil, errors.New("something happened")
|
||||
}
|
||||
}
|
||||
|
||||
func mockGlob(matchesForPatterns map[string][]string) func(pattern string) ([]string, error) {
|
||||
return func(pattern string) ([]string, error) {
|
||||
matches, exists := matchesForPatterns[pattern]
|
||||
if exists {
|
||||
return matches, nil
|
||||
}
|
||||
return nil, errors.New("something happened")
|
||||
}
|
||||
}
|
||||
|
||||
func createTaskReportFile(t *testing.T, workingDir string) {
|
||||
require.NoError(t, os.MkdirAll(filepath.Join(workingDir, ".scannerwork"), 0755))
|
||||
require.NoError(t, ioutil.WriteFile(filepath.Join(workingDir, ".scannerwork", "report-task.txt"), []byte("projectKey=piper-test\nserverUrl=https://sonarcloud.io\nserverVersion=8.0.0.12345\ndashboardUrl=https://sonarcloud.io/dashboard/index/piper-test\nceTaskId=AXERR2JBbm9IiM5TEST\nceTaskUrl=https://sonarcloud.io/api/ce/task?id=AXERR2JBbm9IiMTEST"), 0755))
|
||||
@@ -140,6 +163,148 @@ func TestRunSonar(t *testing.T) {
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, sonar.options, "-Dsonar.projectKey=piper")
|
||||
})
|
||||
t.Run("with jacoco reports", func(t *testing.T) {
|
||||
// init
|
||||
tmpFolder, err := ioutil.TempDir(".", "test-sonar-")
|
||||
require.NoError(t, err)
|
||||
defer func() { _ = os.RemoveAll(tmpFolder) }()
|
||||
createTaskReportFile(t, tmpFolder)
|
||||
|
||||
sonar = sonarSettings{
|
||||
workingDir: tmpFolder,
|
||||
binary: "sonar-scanner",
|
||||
environment: []string{},
|
||||
options: []string{},
|
||||
}
|
||||
fileUtilsExists = mockFileUtilsExists(true)
|
||||
globMatches := make(map[string][]string)
|
||||
globMatches[jacocoReportPattern] = []string{"target/site/jacoco.xml", "application/target/site/jacoco.xml"}
|
||||
doublestarGlob = mockGlob(globMatches)
|
||||
defer func() {
|
||||
fileUtilsExists = FileUtils.FileExists
|
||||
doublestarGlob = doublestar.Glob
|
||||
}()
|
||||
options := sonarExecuteScanOptions{}
|
||||
// test
|
||||
err = runSonar(options, &mockClient, &mockRunner)
|
||||
// assert
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, sonar.options, "-Dsonar.coverage.jacoco.xmlReportPaths=target/site/jacoco.xml,application/target/site/jacoco.xml")
|
||||
})
|
||||
t.Run("with binaries option", func(t *testing.T) {
|
||||
// init
|
||||
tmpFolder, err := ioutil.TempDir(".", "test-sonar-")
|
||||
require.NoError(t, err)
|
||||
defer func() { _ = os.RemoveAll(tmpFolder) }()
|
||||
createTaskReportFile(t, tmpFolder)
|
||||
|
||||
sonar = sonarSettings{
|
||||
workingDir: tmpFolder,
|
||||
binary: "sonar-scanner",
|
||||
environment: []string{},
|
||||
options: []string{},
|
||||
}
|
||||
fileUtilsExists = mockFileUtilsExists(true)
|
||||
|
||||
globMatches := make(map[string][]string)
|
||||
globMatches[pomXMLPattern] = []string{"pom.xml", "application/pom.xml"}
|
||||
doublestarGlob = mockGlob(globMatches)
|
||||
|
||||
existsMap := make(map[string]bool)
|
||||
existsMap[filepath.Join("target", "classes")] = true
|
||||
existsMap[filepath.Join("target", "test-classes")] = true
|
||||
existsMap[filepath.Join("application", "target", "classes")] = true
|
||||
osStat = mockOsStat(existsMap)
|
||||
|
||||
defer func() {
|
||||
fileUtilsExists = FileUtils.FileExists
|
||||
doublestarGlob = doublestar.Glob
|
||||
osStat = os.Stat
|
||||
}()
|
||||
options := sonarExecuteScanOptions{
|
||||
InferJavaBinaries: true,
|
||||
}
|
||||
// test
|
||||
err = runSonar(options, &mockClient, &mockRunner)
|
||||
// assert
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, sonar.options, fmt.Sprintf("-Dsonar.java.binaries=%s,%s,%s",
|
||||
filepath.Join("target", "classes"),
|
||||
filepath.Join("target", "test-classes"),
|
||||
filepath.Join("application", "target", "classes")))
|
||||
})
|
||||
t.Run("with binaries option already given", func(t *testing.T) {
|
||||
// init
|
||||
tmpFolder, err := ioutil.TempDir(".", "test-sonar-")
|
||||
require.NoError(t, err)
|
||||
defer func() { _ = os.RemoveAll(tmpFolder) }()
|
||||
createTaskReportFile(t, tmpFolder)
|
||||
|
||||
sonar = sonarSettings{
|
||||
workingDir: tmpFolder,
|
||||
binary: "sonar-scanner",
|
||||
environment: []string{},
|
||||
options: []string{},
|
||||
}
|
||||
fileUtilsExists = mockFileUtilsExists(true)
|
||||
|
||||
globMatches := make(map[string][]string)
|
||||
globMatches[pomXMLPattern] = []string{"pom.xml"}
|
||||
doublestarGlob = mockGlob(globMatches)
|
||||
|
||||
existsMap := make(map[string]bool)
|
||||
existsMap[filepath.Join("target", "classes")] = true
|
||||
osStat = mockOsStat(existsMap)
|
||||
|
||||
defer func() {
|
||||
fileUtilsExists = FileUtils.FileExists
|
||||
doublestarGlob = doublestar.Glob
|
||||
osStat = os.Stat
|
||||
}()
|
||||
options := sonarExecuteScanOptions{
|
||||
Options: []string{"-Dsonar.java.binaries=user/provided"},
|
||||
InferJavaBinaries: true,
|
||||
}
|
||||
// test
|
||||
err = runSonar(options, &mockClient, &mockRunner)
|
||||
// assert
|
||||
assert.NoError(t, err)
|
||||
assert.NotContains(t, sonar.options, fmt.Sprintf("-Dsonar.java.binaries=%s",
|
||||
filepath.Join("target", "classes")))
|
||||
assert.Contains(t, sonar.options, "-Dsonar.java.binaries=user/provided")
|
||||
})
|
||||
t.Run("projectKey, coverageExclusions, m2Path", func(t *testing.T) {
|
||||
// init
|
||||
tmpFolder, err := ioutil.TempDir(".", "test-sonar-")
|
||||
require.NoError(t, err)
|
||||
defer os.RemoveAll(tmpFolder)
|
||||
createTaskReportFile(t, tmpFolder)
|
||||
|
||||
sonar = sonarSettings{
|
||||
workingDir: tmpFolder,
|
||||
binary: "sonar-scanner",
|
||||
environment: []string{},
|
||||
options: []string{},
|
||||
}
|
||||
options := sonarExecuteScanOptions{
|
||||
ProjectKey: "mock-project-key",
|
||||
M2Path: "my/custom/m2", // assumed to be resolved via alias from mavenExecute
|
||||
InferJavaLibraries: true,
|
||||
CoverageExclusions: []string{"one", "**/two", "three**"},
|
||||
}
|
||||
fileUtilsExists = mockFileUtilsExists(true)
|
||||
defer func() {
|
||||
fileUtilsExists = FileUtils.FileExists
|
||||
}()
|
||||
// test
|
||||
err = runSonar(options, &mockClient, &mockRunner)
|
||||
// assert
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, sonar.options, "-Dsonar.projectKey=mock-project-key")
|
||||
assert.Contains(t, sonar.options, fmt.Sprintf("-Dsonar.java.libraries=%s",
|
||||
filepath.Join("my/custom/m2", "**")))
|
||||
assert.Contains(t, sonar.options, "-Dsonar.coverage.exclusions=one,**/two,three**")
|
||||
})
|
||||
}
|
||||
|
||||
func TestSonarHandlePullRequest(t *testing.T) {
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
metadata:
|
||||
name: sonarExecuteScan
|
||||
description: Executes the Sonar scanner
|
||||
longDescription: The step executes the [sonar-scanner](https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner) cli command to scan the defined sources and publish the results to a SonarQube instance.
|
||||
longDescription: "The step executes the [sonar-scanner](https://docs.sonarqube.org/display/SCAN/Analyzing+with+SonarQube+Scanner)
|
||||
cli command to scan the defined sources and publish the results to a SonarQube instance."
|
||||
spec:
|
||||
inputs:
|
||||
params:
|
||||
- name: instance
|
||||
type: string
|
||||
description: "Jenkins only: The name of the SonarQube instance defined in the Jenkins settings. DEPRECATED: use host parameter instead"
|
||||
description: "Jenkins only: The name of the SonarQube instance defined in the Jenkins settings.
|
||||
DEPRECATED: use host parameter instead"
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
@@ -15,7 +17,7 @@ spec:
|
||||
default: "SonarCloud"
|
||||
- name: host
|
||||
type: string
|
||||
description: The URL to the Sonar backend.
|
||||
description: "The URL to the Sonar backend."
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
@@ -24,7 +26,7 @@ spec:
|
||||
- name: sonarServerUrl
|
||||
- name: token
|
||||
type: string
|
||||
description: Token used to authenticate with the Sonar Server.
|
||||
description: "Token used to authenticate with the Sonar Server."
|
||||
scope:
|
||||
- PARAMETERS
|
||||
secret: true
|
||||
@@ -42,7 +44,8 @@ spec:
|
||||
- STEPS
|
||||
- name: customTlsCertificateLinks
|
||||
type: "[]string"
|
||||
description: List of download links to custom TLS certificates. This is required to ensure trusted connections to instances with custom certificates.
|
||||
description: "List of download links to custom TLS certificates.
|
||||
This is required to ensure trusted connections to instances with custom certificates."
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
@@ -50,7 +53,7 @@ spec:
|
||||
- name: sonarScannerDownloadUrl
|
||||
type: string
|
||||
description: "URL to the sonar-scanner-cli archive."
|
||||
default: https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.4.0.2170-linux.zip
|
||||
default: "https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.4.0.2170-linux.zip"
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
@@ -65,13 +68,47 @@ spec:
|
||||
resourceRef:
|
||||
- name: commonPipelineEnvironment
|
||||
param: artifactVersion
|
||||
- name: options
|
||||
type: "[]string"
|
||||
description: A list of options which are passed to the sonar-scanner.
|
||||
- name: projectKey
|
||||
type: string
|
||||
description: "The project key identifies the project in SonarQube."
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
- name: coverageExclusions
|
||||
type: "[]string"
|
||||
description: "A list of patterns that should be excluded from the coverage scan."
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
- name: inferJavaBinaries
|
||||
type: bool
|
||||
description: "Find the location of generated Java class files in all modules
|
||||
and pass the option `sonar.java.binaries to the sonar tool."
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
- name: inferJavaLibraries
|
||||
type: bool
|
||||
description: "If the parameter `m2Path` is configured for the step `mavenExecute`
|
||||
in the general section of the configuration, pass it as option `sonar.java.libraries`
|
||||
to the sonar tool."
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
- name: options
|
||||
type: "[]string"
|
||||
description: "A list of options which are passed to the sonar-scanner."
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
aliases:
|
||||
- name: sonarProperties
|
||||
deprecated: true
|
||||
# Parameters for non-PR scans
|
||||
- name: branchName
|
||||
type: string
|
||||
@@ -80,6 +117,14 @@ spec:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
- name: inferBranchName
|
||||
type: bool
|
||||
description: "Jenkins only: Whether to infer the `branchName` parameter automatically based on the
|
||||
`BRANCH_NAME` environment variable in non-productive runs of the pipeline."
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
# Parameters for PR-Handling
|
||||
- name: changeId
|
||||
type: string
|
||||
@@ -144,34 +189,54 @@ spec:
|
||||
type: secret
|
||||
- name: disableInlineComments
|
||||
type: bool
|
||||
description: "Pull-Request only: Disables the pull-request decoration with inline comments. DEPRECATED: only supported in SonarQube < 7.2"
|
||||
description: "Pull-Request only: Disables the pull-request decoration with inline comments.
|
||||
DEPRECATED: only supported in SonarQube < 7.2"
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
- name: legacyPRHandling
|
||||
type: bool
|
||||
description: "Pull-Request only: Activates the pull-request handling using the [GitHub Plugin](https://docs.sonarqube.org/display/PLUG/GitHub+Plugin). DEPRECATED: only supported in SonarQube < 7.2"
|
||||
description: "Pull-Request only: Activates the pull-request handling using
|
||||
the [GitHub Plugin](https://docs.sonarqube.org/display/PLUG/GitHub+Plugin).
|
||||
DEPRECATED: only supported in SonarQube < 7.2"
|
||||
scope:
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
- name: githubApiUrl
|
||||
type: string
|
||||
description: "Pull-Request only: The URL to the Github API. see [GitHub plugin docs](https://docs.sonarqube.org/display/PLUG/GitHub+Plugin#GitHubPlugin-Usage) DEPRECATED: only supported in SonarQube < 7.2"
|
||||
description: "Pull-Request only: The URL to the Github API.
|
||||
See [GitHub plugin docs](https://docs.sonarqube.org/display/PLUG/GitHub+Plugin#GitHubPlugin-Usage)
|
||||
DEPRECATED: only supported in SonarQube < 7.2"
|
||||
scope:
|
||||
- GENERAL
|
||||
- PARAMETERS
|
||||
- STAGES
|
||||
- STEPS
|
||||
default: https://api.github.com
|
||||
|
||||
# Global maven settings, should be added to all maven steps
|
||||
- name: m2Path
|
||||
type: string
|
||||
description: "Path to the location of the local repository that should be used."
|
||||
scope:
|
||||
- GENERAL
|
||||
- STEPS
|
||||
- STAGES
|
||||
- PARAMETERS
|
||||
aliases:
|
||||
- name: maven/m2Path
|
||||
|
||||
secrets:
|
||||
- name: sonarTokenCredentialsId
|
||||
type: jenkins
|
||||
description: Jenkins 'Secret text' credentials ID containing the token used to authenticate with the Sonar Server.
|
||||
description: "Jenkins 'Secret text' credentials ID containing the token used to authenticate
|
||||
with the Sonar Server."
|
||||
- name: githubTokenCredentialsId
|
||||
type: jenkins
|
||||
description: Jenkins 'Secret text' credentials ID containing the token used to authenticate with the Github Server.
|
||||
description: "Jenkins 'Secret text' credentials ID containing the token used to authenticate
|
||||
with the Github Server."
|
||||
outputs:
|
||||
resources:
|
||||
- name: influx
|
||||
|
||||
@@ -36,7 +36,8 @@ void call(Map parameters = [:]) {
|
||||
config = piperExecuteBin.getStepContextConfig(script, piperGoPath, METADATA_FILE, customDefaultConfig, customConfigArg)
|
||||
echo "Context Config: ${config}"
|
||||
}
|
||||
// get step configuration to access `instance` & `customTlsCertificateLinks` & `owner` & `repository` & `legacyPRHandling`
|
||||
// get step configuration to access `instance` & `customTlsCertificateLinks` & `owner` & `repository`
|
||||
// & `legacyPRHandling` & `inferBranchName`
|
||||
// writeToDisk needs to be called here as owner and repository may come from the pipeline environment
|
||||
script.commonPipelineEnvironment.writeToDisk(script)
|
||||
Map stepConfig = readJSON(text: sh(returnStdout: true, script: "${piperGoPath} getConfig --stepMetadata '.pipeline/tmp/${METADATA_FILE}'${customDefaultConfig}${customConfigArg}"))
|
||||
@@ -52,6 +53,8 @@ void call(Map parameters = [:]) {
|
||||
environment.add("PIPER_changeId=${env.CHANGE_ID}")
|
||||
environment.add("PIPER_changeBranch=${env.CHANGE_BRANCH}")
|
||||
environment.add("PIPER_changeTarget=${env.CHANGE_TARGET}")
|
||||
} else if (!isProductiveBranch(script) && stepConfig.inferBranchName && env.BRANCH_NAME) {
|
||||
environment.add("PIPER_branchName=${env.BRANCH_NAME}")
|
||||
}
|
||||
try {
|
||||
// load certificates into cacerts file
|
||||
@@ -98,6 +101,11 @@ private Boolean isPullRequest(){
|
||||
return env.CHANGE_ID
|
||||
}
|
||||
|
||||
private Boolean isProductiveBranch(Script script) {
|
||||
def productiveBranch = script.commonPipelineEnvironment?.getStepConfiguration('', '')?.productiveBranch
|
||||
return env.BRANCH_NAME == productiveBranch
|
||||
}
|
||||
|
||||
private void loadCertificates(Map config) {
|
||||
String certificateFolder = '.certificates/'
|
||||
List wgetOptions = [
|
||||
|
||||
Reference in New Issue
Block a user