This plugin performs static code analysis as part of a Buildkite pipeline and reports back to Sonarqube.
This plugin is still in alpha release publicly and is not ready for prime-time usage.
You must first create a project in Sonarqube instance.
Copy the user login token. This must be added to the buildkite pipeline using the environment variable SONARQUBE_LOGIN
Make sure to store it securely!
To ensure the sonar scan step does not fail the pipeline overall (e.g. in the case of a Sonarqube outage), make sure to set the soft_fail
attribute (example below).
# .buildkite/pipeline.yml
steps:
- label: ":sonarqube: Sonarqube"
branches: "master" # only report on the master branch
plugins:
- wayfair-incubator/sonarscanner#v0.1.1:
sonarqube_host: https://sonarqube.example.com
project_key: sonarqube_project_key
soft_fail: # Ensures a Sonarqube error does not fail the pipeline
- exit_status: "*"
The plugin supports paid Sonarqube features, such as enabling scans for a branch
and/or a pull request
.
# .buildkite/pipeline.yml
steps:
- label: ":sonarqube: Sonarqube"
plugins:
- wayfair-incubator/sonarscanner#v0.1.1:
sonarqube_host: https://sonarqube_enterprise.example.com
project_key: sonarqube_project_key
uses_community_edition: false
enable_branch_scan: true
enable_pull_request_scan: true
soft_fail: # Ensures a Sonarqube error does not fail the pipeline
- exit_status: "*"
# .buildkite/pipeline.yml
# Python example
steps:
- label: "Run unit tests"
command: test.sh
artifact_paths: tmp/*coverage-*.xml
- wait: ~
- label: ":sonarqube: Sonarqube"
plugins:
- wayfair-incubator/sonarscanner#v0.1.1:
sonarqube_host: https://sonarqube.example.com
project_key: sonarqube_project_key
artifacts: tmp/*coverage-*.xml
additional_flags:
- -Dsonar.tests=tests
- -Dsonar.exclusions=test*/**/*
- -Dsonar.python.coverage.reportPaths=tmp/*coverage-*.xml
soft_fail: # Ensures a Sonarqube error does not fail the pipeline
- exit_status: "*"
# .buildkite/pipeline.yml
# .NET example
steps:
- label: "Run unit tests"
commands:
- >
dotnet test --logger:"trx;LogFileName=testresult.xml"
/p:CollectCoverage=true
/p:CoverletOutputFormat=opencover
/p:CoverletOutput="TestResults/opencover.xml"
- buildkite-agent artifact upload "**/testresult*.xml"
- buildkite-agent artifact upload "**/opencover*.xml"
plugins:
- docker#v3.3.0:
image: "..."
- wait: ~
- label: ":sonarqube: Sonarqube"
plugins:
- wayfair-incubator/sonarscanner#v0.1.1:
sonarqube_host: https://sonarqube.example.com
project_key: sonarqube_project_key
is_dotnet: true
dotnet_build_project: My.App.sln
artifacts:
- '**/testresult*.xml'
- '**/opencover*.xml'
additional_flags:
- /s:/root/.dotnet/tools/SonarQube.Analysis.xml
soft_fail: # Ensures a Sonarqube error does not fail the pipeline
- exit_status: "*"
Sonarscanner does not independently calculate code coverage. Instead, it consumes coverage reports (generally XML files) generated by the test suite for your project. The steps needed to generate coverage reports are language specific. Below are instructions for a few common languages.
In general, unit test steps should be run using either the docker
or docker-compose
buildkite plugins. This ensures that the absolute file paths in the generated coverage reports can be set deterministically. When running tests in other agents, you cannot guarantee the file paths, which will result in Sonarqube reporting 0% coverage.
This plugin has been tested on projects that use coverlet. This can be added by running dotnet add package coverlet.msbuild
in the project directory. Refer to the .NET pipeline example above for the specific arguments that should be passed to dotnet test
. Reports can be accessed using the globs **/testresult*.xml
and **/testresult*.xml
.
The unique key associated with a Sonarqube project
Example: sonarqube_project_key
URL of Sonarqube Server where sonarscanner should upload its report.
Example: https://sonarqube.example.com
Pass additional flags to sonar-scanner
. Useful for defining additional properties (-D
). Available properties can be found here. Can also be used to run sonar-scanner
in debug mode (-X
)
Examples:
# string
additional_flags: -Dsonar.ws.timeout=120
# array
additional_flags:
- -Dsonar.ws.timeout=120
- -Dsonar.tests=unit_tests,integration_tests
The artifact glob path to find test and coverage reports that should be passed to Sonarqube. Be sure let Sonarqube know where to find artifacts using the additional_flags
property. The correct property for your language can be found here.
Examples:
# string
artifacts: tmp/*coverage-*.xml
# array
artifacts:
- tmp/*coverage-*.xml
- tmp/foo/**/*.html
Used when enable_branch_scan
is set to be true
. If the scanner analyses this branch, it will perform a standard analysis. Otherwise, it assumes the branch is a feature branch and performs branch analysis.
Default: master
Used only if is_dotnet: true
. The build project name is passed to dotnet build
.
Example: My.App.sln
If enabled, Branch analysis will be run. This parameter is only supported in the Enterprise trial. PR scans take precedence over branch scans.
Default: false
If enabled, Pull Request analysis will be run. This parameter is only supported in the Enterprise trial.
Default: false
If the project being scanned is a dotnet
project.
Default: false
Only execute the scanner if commit includes changes to files defined in the sources
argument. Useful for creating pipelines that only respond to changes to specific code in monorepo contexts.
Default: false
Comma-separated paths to directories containing main source files.
Default: .
If you are using the open source community edition of Sonarqube
Default: true
Directory where source code should be mounted inside of the docker container. Useful if uploading coverage reports to Sonarqube that contain absolute paths that need to be matched.
Example: /app
Ensure your pipeline has the environment variable SONARQUBE_LOGIN
set.
My pipeline is failing with the error FATAL Failed to download artifacts: No artifacts found for downloading
If the artifacts
parameter is used, at least one matching artifact from a previous step must be available. Additional information about buildkite artifacts can be found here. If you are generating an artifact in a step that uses the docker-compose
plugin, review the plugin documentation; notably, artifacts must be generated in a directory that is mounted to the host agent.
Sonarscanner parses the repository's file tree and attempts to match files against entries from the coverage report. Matches only occur when the absolute paths of the files are the same.
If the repository under test is mounted to a custom directory, Sonarscanner will not match the file paths correctly. You may encounter this if unit tests are executed using the docker-compose-buildkite-plugin
and the code is made available via a volume mount (for example, - ./:/app
). In such a case, set the workdir
parameter equal to the root project directory used when generating the coverage report (in the above case, /app
).
The workdir
parameter does not need to be set by default, particularly if the coverage report was generated using the docker-buildkite-plugin
.
See the Contributing Guide for additional information.
To execute tests locally (requires that docker
and docker-compose
are installed):
bin/execute_tests
This plugin was originally written by James Curtin for Wayfair.