From 60cf7e04fc3356926ad77025069e6727c8591799 Mon Sep 17 00:00:00 2001 From: Diego Paes Ramalho Pereira Date: Sat, 31 Jul 2021 12:08:30 -0300 Subject: [PATCH 001/106] Quality Gateway --- Dockerfile | 28 +++--- LICENSE | 28 +++--- README.md | 35 +------- go.mod | 9 ++ logo.svg | 26 ++---- main.go | 148 ++++++++++++++++--------------- plugin.go | 255 +++++++++++++++++++++++++++++++++++++++++++---------- 7 files changed, 324 insertions(+), 205 deletions(-) create mode 100755 go.mod diff --git a/Dockerfile b/Dockerfile index 71ad9b5..6d0cabe 100755 --- a/Dockerfile +++ b/Dockerfile @@ -1,27 +1,21 @@ -FROM golang:1.13.4-alpine as build -RUN mkdir -p /go/src/github.com/aosapps/drone-sonar-plugin -WORKDIR /go/src/github.com/aosapps/drone-sonar-plugin -COPY *.go ./ -COPY vendor ./vendor/ -RUN GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o drone-sonar +FROM openjdk:8-jre-alpine -FROM openjdk:11.0.8-jre +LABEL maintainer="Daniel Ramirez " -ARG SONAR_VERSION=4.5.0.2216 +ARG SONAR_VERSION=4.0.0.1744 ARG SONAR_SCANNER_CLI=sonar-scanner-cli-${SONAR_VERSION} ARG SONAR_SCANNER=sonar-scanner-${SONAR_VERSION} -RUN apt-get update \ - && apt-get install -y nodejs curl \ - && apt-get clean - -COPY --from=build /go/src/github.com/aosapps/drone-sonar-plugin/drone-sonar /bin/ +# RUN apk add --no-cache --update nodejs curl +COPY sonar-scanner-plugin /bin/ +COPY sonar-scanner-cli-4.0.0.1744.zip /bin/${SONAR_SCANNER_CLI}.zip WORKDIR /bin -RUN curl https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/${SONAR_SCANNER_CLI}.zip -so /bin/${SONAR_SCANNER_CLI}.zip -RUN unzip ${SONAR_SCANNER_CLI}.zip \ - && rm ${SONAR_SCANNER_CLI}.zip +# curl -fsSLO https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/${SONAR_SCANNER_CLI}.zip && \ +RUN unzip -q ${SONAR_SCANNER_CLI}.zip && \ + rm -f ${SONAR_SCANNER_CLI}.zip ENV PATH $PATH:/bin/${SONAR_SCANNER}/bin +ENV SONAR_SCANNER_OPTS -Xmx512m -ENTRYPOINT /bin/drone-sonar +ENTRYPOINT /bin/sonar-scanner-plugin diff --git a/LICENSE b/LICENSE index dd04e51..533e496 100644 --- a/LICENSE +++ b/LICENSE @@ -1,21 +1,15 @@ -MIT License +Copyright (c) 2019 Daniel Ramirez -Copyright (c) 2018 AosApps +Apache License, Version 2.0 -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. + http://www.apache.org/licenses/LICENSE-2.0 -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. diff --git a/README.md b/README.md index d4838c8..42b98c3 100644 --- a/README.md +++ b/README.md @@ -1,34 +1 @@ -# drone-sonar-plugin -The plugin of Drone CI to integrate with SonarQube (previously called Sonar), which is an open source code quality management platform. - -Detail tutorials: [DOCS.md](DOCS.md). - -### Build process -build go binary file: -`GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o drone-sonar` - -build docker image -`docker build -t aosapps/drone-sonar-plugin .` - - -### Testing the docker image: -```commandline -docker run --rm \ - -e DRONE_REPO=test \ - -e PLUGIN_SOURCES=. \ - -e SONAR_HOST=http://localhost:9000 \ - -e SONAR_TOKEN=60878847cea1a31d817f0deee3daa7868c431433 \ - aosapps/drone-sonar-plugin -``` - -### Pipeline example -```yaml -steps -- name: code-analysis - image: aosapps/drone-sonar-plugin - settings: - sonar_host: - from_secret: sonar_host - sonar_token: - from_secret: sonar_token -``` +# drone-sonar-scanner \ No newline at end of file diff --git a/go.mod b/go.mod new file mode 100755 index 0000000..2997439 --- /dev/null +++ b/go.mod @@ -0,0 +1,9 @@ +module github.com/dxas90/drone-plugin-sonar + +go 1.13 + +require ( + github.com/pelletier/go-toml v1.4.0 + github.com/sirupsen/logrus v1.4.2 + github.com/urfave/cli v1.22.1 +) diff --git a/logo.svg b/logo.svg index 5ab2d96..5778bff 100755 --- a/logo.svg +++ b/logo.svg @@ -1,20 +1,8 @@ - - - - - - - - - + + + + + + + diff --git a/main.go b/main.go index d23168f..339c58f 100755 --- a/main.go +++ b/main.go @@ -1,124 +1,128 @@ package main import ( + "encoding/base64" "fmt" - "github.com/codegangsta/cli" "os" + + "github.com/urfave/cli" ) -var build = "1" // build number set at compile time +var version string // build number set at compile-time -func main() { +func amain() { app := cli.NewApp() - app.Name = "Drone-Sonar-Plugin" - app.Usage = "Drone plugin to integrate with SonarQube." + app.Name = "drone-sonar-scanner" + app.Usage = "Drone plugin integrate sonar-scanner and results of SonarQube Quality Gates." app.Action = run - app.Version = fmt.Sprintf("1.0.%s", build) + app.Version = version app.Flags = []cli.Flag{ cli.StringFlag{ - Name: "key", - Usage: "project key", - EnvVar: "DRONE_REPO", + Name: "name", + Usage: "repository full name", + EnvVar: "PLUGIN_NAME,DRONE_REPO", }, cli.StringFlag{ - Name: "name", - Usage: "project name", - EnvVar: "DRONE_REPO", + Name: "branch", + Usage: "repository default branch", + EnvVar: "PLUGIN_BRANCH,DRONE_REPO_BRANCH", }, cli.StringFlag{ - Name: "host", - Usage: "SonarQube host", - EnvVar: "PLUGIN_SONAR_HOST", + Name: "remote", + Usage: "git remote url", + EnvVar: "PLUGIN_REMOTE,DRONE_REMOTE_URL", }, cli.StringFlag{ - Name: "token", - Usage: "SonarQube token", - EnvVar: "PLUGIN_SONAR_TOKEN", + Name: "path", + Usage: "git clone path", + EnvVar: "PLUGIN_PATH,DRONE_WORKSPACE", }, - - // advanced parameters cli.StringFlag{ - Name: "ver", - Usage: "Project version", - EnvVar: "DRONE_BUILD_NUMBER", + Name: "host", + Usage: "Sonar host URL", + EnvVar: "SONAR_HOST,PLUGIN_HOST", }, cli.StringFlag{ - Name: "branch", - Usage: "Project branch", - EnvVar: "DRONE_BRANCH", + Name: "token", + Usage: "sonar token", + EnvVar: "SONAR_TOKEN,PLUGIN_TOKEN", }, cli.StringFlag{ - Name: "timeout", - Usage: "Web request timeout", - Value: "60", - EnvVar: "PLUGIN_TIMEOUT", + Name: "key", + Usage: "Project Key", + EnvVar: "PLUGIN_KEY,DRONE_REPO", }, cli.StringFlag{ - Name: "sources", - Usage: "analysis sources", - Value: ".", - EnvVar: "PLUGIN_SOURCES", + Name: "buildnum", + Usage: "Project version", + EnvVar: "PLUGIN_BUILD_NUMBER,DRONE_BUILD_NUMBER", }, cli.StringFlag{ Name: "inclusions", - Usage: "code inclusions", + Usage: "Project sources inclusions", EnvVar: "PLUGIN_INCLUSIONS", }, cli.StringFlag{ Name: "exclusions", - Usage: "code exclusions", + Usage: "Project sources exclusions", EnvVar: "PLUGIN_EXCLUSIONS", }, cli.StringFlag{ - Name: "level", - Usage: "log level", - Value: "INFO", - EnvVar: "PLUGIN_LEVEL", + Name: "language", + Usage: "Project language", + EnvVar: "PLUGIN_LANGUAGE", + }, + cli.StringFlag{ + Name: "profile", + Usage: "Project profile", + EnvVar: "PLUGIN_PROFILE", }, cli.StringFlag{ - Name: "showProfiling", - Usage: "showProfiling during analysis", - Value: "false", - EnvVar: "PLUGIN_SHOWPROFILING", + Name: "encoding", + Usage: "Project source encondig", + EnvVar: "PLUGIN_ENCODING", + Value: "UTF-8", }, - cli.BoolFlag{ - Name: "branchAnalysis", - Usage: "execute branchAnalysis", - EnvVar: "PLUGIN_BRANCHANALYSIS", + cli.StringFlag{ + Name: "quality", + Usage: "QualityGate status", + EnvVar: "SONAR_QUALITYGATE,PLUGIN_QUALITYGATE", + Value: "OK", }, - cli.BoolFlag{ - Name: "usingProperties", - Usage: "using sonar-project.properties", - EnvVar: "PLUGIN_USINGPROPERTIES", + cli.StringFlag{ + Name: "settings", + Usage: "Project settings", + EnvVar: "SONAR_PROJECT_SETTINGS,PLUGIN_PROJECT_SETTINGS", + Value: "sonar-project.properties", }, } - app.Run(os.Args) + if err := app.Run(os.Args); err != nil { + fmt.Println(err) + os.Exit(1) + } } func run(c *cli.Context) { plugin := Plugin{ - Config: Config{ - Key: c.String("key"), - Name: c.String("name"), - Host: c.String("host"), - Token: c.String("token"), - - Version: c.String("ver"), - Branch: c.String("branch"), - Timeout: c.String("timeout"), - Sources: c.String("sources"), - Inclusions: c.String("inclusions"), - Exclusions: c.String("exclusions"), - Level: c.String("level"), - ShowProfiling: c.String("showProfiling"), - BranchAnalysis: c.Bool("branchAnalysis"), - UsingProperties: c.Bool("usingProperties"), - - }, + Host: c.String("host"), + Token: c.String("token"), + Key: c.String("key"), + Name: c.String("name"), + Version: c.String("buildnum"), + Sources: c.String("path"), + Inclusions: c.String("inclusions"), + Exclusions: c.String("exclusions"), + Language: c.String("language"), + Profile: c.String("profile"), + Encoding: c.String("encoding"), + Remote: c.String("remote"), + Branch: c.String("branch"), + Quality: c.String("quality"), + Settings: c.String("settings"), } - + os.Setenv("TOKEN", base64.StdEncoding.EncodeToString([]byte(c.String("token")+":"))) if err := plugin.Exec(); err != nil { fmt.Println(err) os.Exit(1) diff --git a/plugin.go b/plugin.go index c9bf783..9e55c11 100755 --- a/plugin.go +++ b/plugin.go @@ -1,71 +1,234 @@ package main import ( + "encoding/json" + "errors" "fmt" + "io/ioutil" + "net" + "net/http" + "net/url" "os" "os/exec" "strings" + "time" + + "github.com/pelletier/go-toml" + "github.com/sirupsen/logrus" ) +var netClient *http.Client + type ( - Config struct { - Key string - Name string - Host string - Token string - - Version string - Branch string - Sources string - Timeout string - Inclusions string - Exclusions string - Level string - ShowProfiling string - BranchAnalysis bool - UsingProperties bool - } + // Plugin defines the sonar-scaner plugin parameters. Plugin struct { - Config Config + Host string + Token string + Key string + Name string + Version string + Sources string + Inclusions string + Exclusions string + Language string + Profile string + Encoding string + Remote string + Branch string + Quality string + Settings string + } + // SonarReport it is the representation of .scannerwork/report-task.txt + SonarReport struct { + ProjectKey string `toml:"projectKey"` + ServerURL string `toml:"serverUrl"` + DashboardURL string `toml:"dashboardUrl"` + CeTaskID string `toml:"ceTaskId"` + CeTaskURL string `toml:"ceTaskUrl"` + } + // TaskResponse Give Compute Engine task details such as type, status, duration and associated component. + TaskResponse struct { + Task struct { + ID string `json:"id"` + Type string `json:"type"` + ComponentID string `json:"componentId"` + ComponentKey string `json:"componentKey"` + ComponentName string `json:"componentName"` + AnalysisID string `json:"analysisId"` + Status string `json:"status"` + } `json:"task"` + } + // ProjectStatusResponse Get the quality gate status of a project or a Compute Engine task + ProjectStatusResponse struct { + ProjectStatus struct { + Status string `json:"status"` + } `json:"projectStatus"` } ) +func init() { + netClient = &http.Client{ + Timeout: time.Second * 10, + Transport: &http.Transport{ + Dial: (&net.Dialer{ + Timeout: 5 * time.Second, + }).Dial, + TLSHandshakeTimeout: 5 * time.Second, + }, + } +} + +// Exec executes the plugin step func (p Plugin) Exec() error { - args := []string{ - "-Dsonar.host.url=" + p.Config.Host, - "-Dsonar.login=" + p.Config.Token, - } - - if !p.Config.UsingProperties { - argsParameter := []string{ - "-Dsonar.projectKey=" + strings.Replace(p.Config.Key, "/", ":", -1), - "-Dsonar.projectName=" + p.Config.Name, - "-Dsonar.projectVersion=" + p.Config.Version, - "-Dsonar.sources=" + p.Config.Sources, - "-Dsonar.ws.timeout=" + p.Config.Timeout, - "-Dsonar.inclusions=" + p.Config.Inclusions, - "-Dsonar.exclusions=" + p.Config.Exclusions, - "-Dsonar.log.level=" + p.Config.Level, - "-Dsonar.showProfiling=" + p.Config.ShowProfiling, - "-Dsonar.scm.provider=git", - } - args = append(args, argsParameter...) + + report, err := staticScan(&p) + if err != nil { + logrus.WithFields(logrus.Fields{ + "error": err, + }).Fatal("Unable to scan") } + logrus.WithFields(logrus.Fields{ + "job url": report.CeTaskURL, + }).Info("Job url") - if p.Config.BranchAnalysis { - args = append(args, "-Dsonar.branch.name=" + p.Config.Branch) + task, err := waitForSonarJob(report) + if err != nil { + logrus.WithFields(logrus.Fields{ + "error": err, + }).Fatal("Unable to get Job state") + } + + status := getStatus(task, report) + + if status != p.Quality { + logrus.WithFields(logrus.Fields{ + "status": status, + }).Fatal("QualityGate status failed") + } + + return nil +} + +func staticScan(p *Plugin) (*SonarReport, error) { + if _, err := os.Stat(p.Settings); errors.Is(err, os.ErrExist) { + cmd := exec.Command("sed", "-e", "s/=/=\"/", "-e", "s/$/\"/", p.Settings) + output, err := cmd.CombinedOutput() + if err != nil { + logrus.WithFields(logrus.Fields{ + "error": err, + }).Fatal("Run command sed failed") + return nil, err + } + // log.Printf("%s\n",output) + + report := SonarReport{} + err = toml.Unmarshal(output, &report) + if err != nil { + logrus.WithFields(logrus.Fields{ + "error": err, + }).Fatal("Toml Unmarshal failed") + return nil, err + } + + } + args := []string{ + "-Dsonar.projectKey=" + strings.Replace(p.Key, "/", ":", -1), + "-Dsonar.projectName=" + p.Name, + "-Dsonar.host.url=" + p.Host, + "-Dsonar.login=" + p.Token, + "-Dsonar.projectVersion=" + p.Version, + "-Dsonar.sources=" + p.Sources, + "-Dproject.settings=" + p.Settings, + "-Dsonar.ws.timeout=360", + "-Dsonar.inclusions=" + p.Inclusions, + "-Dsonar.exclusions=" + p.Exclusions, + "-Dsonar.profile=" + p.Profile, + "-Dsonar.branch=" + p.Branch, + "-Dsonar.scm.provider=git", } cmd := exec.Command("sonar-scanner", args...) - // fmt.Printf("==> Executing: %s\n", strings.Join(cmd.Args, " ")) - cmd.Stdout = os.Stdout - cmd.Stderr = os.Stderr - fmt.Printf("==> Code Analysis Result:\n") - err := cmd.Run() + output, err := cmd.CombinedOutput() if err != nil { - return err + logrus.WithFields(logrus.Fields{ + "error": err, + }).Fatal("Run command sonar-scanner failed") + return nil, err } + fmt.Printf("out:\n%s", output) + cmd = exec.Command("sed", "-e", "s/=/=\"/", "-e", "s/$/\"/", ".scannerwork/report-task.txt") + output, err = cmd.CombinedOutput() + if err != nil { + logrus.WithFields(logrus.Fields{ + "error": err, + }).Fatal("Run command sed failed") + return nil, err + } + // log.Printf("%s\n",output) - return nil + report := SonarReport{} + err = toml.Unmarshal(output, &report) + if err != nil { + logrus.WithFields(logrus.Fields{ + "error": err, + }).Fatal("Toml Unmarshal failed") + return nil, err + } + + return &report, nil +} + +func getStatus(task *TaskResponse, report *SonarReport) string { + reportRequest := url.Values{ + "analysisId": {task.Task.AnalysisID}, + } + projectRequest, err := http.NewRequest("GET", report.ServerURL+"/api/qualitygates/project_status?"+reportRequest.Encode(), nil) + projectRequest.Header.Add("Authorization", "Basic "+os.Getenv("TOKEN")) + projectResponse, err := netClient.Do(projectRequest) + if err != nil { + logrus.WithFields(logrus.Fields{ + "error": err, + }).Fatal("Failed get status") + } + buf, _ := ioutil.ReadAll(projectResponse.Body) + project := ProjectStatusResponse{} + if err := json.Unmarshal(buf, &project); err != nil { + logrus.WithFields(logrus.Fields{ + "error": err, + }).Fatal("Failed") + } + return project.ProjectStatus.Status +} + +func getSonarJobStatus(report *SonarReport) *TaskResponse { + + taskRequest, err := http.NewRequest("GET", report.CeTaskURL, nil) + taskRequest.Header.Add("Authorization", "Basic "+os.Getenv("TOKEN")) + taskResponse, err := netClient.Do(taskRequest) + if err != nil { + logrus.WithFields(logrus.Fields{ + "error": err, + }).Fatal("Failed get sonar job status") + } + buf, _ := ioutil.ReadAll(taskResponse.Body) + task := TaskResponse{} + json.Unmarshal(buf, &task) + return &task +} + +func waitForSonarJob(report *SonarReport) (*TaskResponse, error) { + timeout := time.After(300 * time.Second) + tick := time.Tick(500 * time.Millisecond) + for { + select { + case <-timeout: + return nil, errors.New("timed out") + case <-tick: + job := getSonarJobStatus(report) + if job.Task.Status == "SUCCESS" { + return job, nil + } + } + } } From a0c3e75c189dc6acf1d61ba1bb2a54c79e5d2be2 Mon Sep 17 00:00:00 2001 From: Diego Paes Ramalho Pereira Date: Sat, 31 Jul 2021 12:47:26 -0300 Subject: [PATCH 002/106] Sonar with Quality Gateways Check + Java binaries setting --- .gitignore | 1 + Dockerfile | 4 +-- README.md | 60 ++++++++++++++++++++++++++++++++++++++++++- drone-sonar | Bin 0 -> 9407277 bytes drone-sonar-scanner | Bin 0 -> 9407277 bytes go.mod | 4 +-- go.sum | 26 +++++++++++++++++++ main.go | 10 ++++++-- plugin.go | 2 ++ sonar-scanner-plugin | Bin 0 -> 9407277 bytes 10 files changed, 100 insertions(+), 7 deletions(-) create mode 100755 drone-sonar create mode 100755 drone-sonar-scanner create mode 100644 go.sum create mode 100755 sonar-scanner-plugin diff --git a/.gitignore b/.gitignore index 4ab6684..5db0225 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ *.dll *.so *.dylib +*.zip # Test binary, build with `go test -c` *.test diff --git a/Dockerfile b/Dockerfile index 6d0cabe..ece211b 100755 --- a/Dockerfile +++ b/Dockerfile @@ -1,6 +1,6 @@ FROM openjdk:8-jre-alpine -LABEL maintainer="Daniel Ramirez " +LABEL maintainer="Diego Pereira " ARG SONAR_VERSION=4.0.0.1744 ARG SONAR_SCANNER_CLI=sonar-scanner-cli-${SONAR_VERSION} @@ -8,7 +8,7 @@ ARG SONAR_SCANNER=sonar-scanner-${SONAR_VERSION} # RUN apk add --no-cache --update nodejs curl COPY sonar-scanner-plugin /bin/ -COPY sonar-scanner-cli-4.0.0.1744.zip /bin/${SONAR_SCANNER_CLI}.zip +COPY sonar-scanner-cli-4.4.0.2170.zip /bin/${SONAR_SCANNER_CLI}.zip WORKDIR /bin # curl -fsSLO https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/${SONAR_SCANNER_CLI}.zip && \ diff --git a/README.md b/README.md index 42b98c3..9279331 100644 --- a/README.md +++ b/README.md @@ -1 +1,59 @@ -# drone-sonar-scanner \ No newline at end of file +# drone-sonar-scanner-plugin +The plugin of Drone CI to integrate with SonarQube (previously called Sonar), which is an open source code quality management platform. + +### Notice +- This branch adds a new environment parameter `java_binaries` to fix the following problem: + ``` + Please provide compiled classes of your project with sonar.java.binaries property + ``` +- Another optional parameter `custom_ding_token` is for personal use, adding `-Dsonar.analysis.dingtalktoken=${custom_ding_token} ` to sonar-scanner command, then sonarqube's webhook would pass it to an Dingtalk IM sender. + + +Find the details at "Pipeline example" + +Detail tutorials: [DOCS.md](DOCS.md). + +### Build process +build go binary file: +`GOOS=linux GOARCH=amd64 CGO_ENABLED=0 go build -o drone-sonar` + +build docker image +`docker build -t diegokoala/drone-sonar-plugin:latest .` + +### Testing the docker image: +```commandline +docker run --rm \ + -e DRONE_REPO=test \ + -e PLUGIN_SOURCES=. \ + -e SONAR_HOST=http://localhost:9000 \ + -e SONAR_TOKEN=60878847cea1a31d817f0deee3daa7868c431433 +``` + +### Pipeline example +```yaml +steps +- name: code-analysis + image: diegopereiraeng/drone-sonar-plugin + settings: + sonar_host: + from_secret: sonar_host + sonar_token: + from_secret: sonar_token + java_binaries: target/classes + # optional, for sonarqube webhook + custom_ding_token: + from_secret: dingtalk_token +``` + +### Available settings +* key: The project key the project is going to be build with +* sonar_host: The SonarQube host +* sonar_token: The token to authenticate to the SonarQube host with +* timeout: The web request timeout, standard set to 60 seconds +* sources: The sources that have to be scanned, comma separated +* inclusions: SonarQube property, extends the sources property +* exclusions: The source files that should not be analysed, comma separated +* level: The log level used during analysing the source code +* showProfiling: Show profiling information during scanning +* branchAnalysis: Only used with a licensed SonarQube version +* usingProperties: If set to true, the settings will be overridden by the sonar.properties file \ No newline at end of file diff --git a/drone-sonar b/drone-sonar new file mode 100755 index 0000000000000000000000000000000000000000..e85e38fb869d0f5a7ac5be4acb995016f5309d46 GIT binary patch literal 9407277 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