Inspired by https://github.com/SonarCommunity/sonar-github
Only SonarQube 9.9+
Only SonarQube 9.5+
bumped plugin version to 9.5.0.56709
dropped deprecated (and in 9.5 removed) PostJobIssue that was not used anyway
Only SonarQube 9.3+
merged Rename codeclimate.json to gl-code-quality-report.json
Requires GL >= 11.0 and adjustment of JOBS to use new name of config gl-code-quality-report.json
Only GitLab >= 11.0
Only SonarQube 8.6
Only SonarQube 8.2
Only SonarQube < 7.9.x
Only SonarQube < 7.7, because preview mode is removed
Others versions, go to ChangeLog section
Add to each commit GitLab in a global commentary on the new anomalies added by this commit and add comment lines of modified files.
Comment commits:
Comment line:
Add build line:
With quality gate global comment
With generate code quality json file
With generate SAST json file
Works with Java, Php, Android, JavaScript, C#, etc..
For SonarQube < 5.4:
SONARQUBE_HOME/extensions/plugins
For SonarQube >= 5.4 and < 5.6:
SONARQUBE_HOME/extensions/plugins
For SonarQube >= 5.6 and < 6.7:
SONARQUBE_HOME/extensions/plugins
For SonarQube >= 6.7 and < 7.0:
SONARQUBE_HOME/extensions/plugins
For SonarQube >= 7.0:
SONARQUBE_HOME/extensions/plugins
Optional Plugin: Add Single Sign-On with GitLab in SonarQube
Example:
With Maven
mvn --batch-mode verify sonar:sonar -Dsonar.host.url=$SONAR_URL -Dsonar.login=$SONAR_LOGIN -Dsonar.analysis.mode=preview -Dsonar.gitlab.commit_sha=$CI_COMMIT_SHA -Dsonar.gitlab.ref_name=$CI_COMMIT_REF_NAME -Dsonar.gitlab.project_id=$CI_PROJECT_ID
or for comment inline in all commits of branch:
mvn --batch-mode verify sonar:sonar -Dsonar.host.url=$SONAR_URL -Dsonar.login=$SONAR_LOGIN -Dsonar.analysis.mode=preview -Dsonar.gitlab.commit_sha=$(git log --pretty=format:%H origin/master..$CI_COMMIT_SHA | tr '\n' ',') -Dsonar.gitlab.ref_name=$CI_COMMIT_REF_NAME -Dsonar.gitlab.project_id=$CI_PROJECT_ID -Dsonar.gitlab.unique_issue_per_inline=true
With SonarScanner
sonar-scanner -Dsonar.host.url=$SONAR_URL -Dsonar.login=$SONAR_LOGIN -Dsonar.analysis.mode=preview -Dsonar.gitlab.commit_sha=$CI_COMMIT_SHA -Dsonar.gitlab.ref_name=$CI_COMMIT_REF_NAME -Dsonar.gitlab.project_id=$CI_PROJECT_ID
With SonarScanner and node
npm run sonar-scanner -- -Dsonar.host.url=$SONAR_URL -Dsonar.login=$SONAR_LOGIN -Dsonar.analysis.mode=preview -Dsonar.gitlab.commit_sha=$CI_COMMIT_SHA -Dsonar.gitlab.ref_name=$CI_COMMIT_REF_NAME -Dsonar.gitlab.project_id=$CI_PROJECT_ID
With Gradle
./gradlew sonarqube -Dsonar.host.url=$SONAR_URL -Dsonar.login=$SONAR_LOGIN -Dsonar.analysis.mode=preview -Dsonar.gitlab.commit_sha=$CI_COMMIT_SHA -Dsonar.gitlab.ref_name=$CI_COMMIT_REF_NAME -Dsonar.gitlab.project_id=$CI_PROJECT_ID
With Maven
mvn --batch-mode verify sonar:sonar -Dsonar.host.url=$SONAR_URL -Dsonar.login=$SONAR_LOGIN -Dsonar.gitlab.commit_sha=$CI_COMMIT_SHA -Dsonar.gitlab.ref_name=$CI_COMMIT_REF_NAME -Dsonar.gitlab.project_id=$CI_PROJECT_ID -Dsonar.branch.name=$CI_COMMIT_REF_NAME
Works with sonar-scanner
and gradle
Set secret variable
SONAR_URL
andSONAR_LOGIN
.gitlab-ci.yml sample for Maven project, comment last commit:
This plugin requires the Community Branch Plugin for SonarQube CE
sonarqube_master_job:
stage: test
only:
- master
script:
- mvn --batch-mode verify sonar:sonar -Dsonar.host.url=$SONAR_URL -Dsonar.login=$SONAR_LOGIN -Dsonar.gitlab.project_id=$CI_PROJECT_PATH -Dsonar.gitlab.commit_sha=$CI_COMMIT_SHA -Dsonar.gitlab.ref_name=$CI_COMMIT_REF_NAME
sonarqube_feature_job:
stage: test
only:
- /^feature\/*/
script:
- git checkout origin/master
- git merge $CI_COMMIT_SHA --no-commit --no-ff
- mvn --batch-mode verify sonar:sonar -Dsonar.host.url=$SONAR_URL -Dsonar.login=$SONAR_LOGIN -Dsonar.gitlab.project_id=$CI_PROJECT_PATH -Dsonar.gitlab.commit_sha=$CI_COMMIT_SHA -Dsonar.gitlab.ref_name=$CI_COMMIT_REF_NAME -Dsonar.branch.name=$CI_COMMIT_REF_NAME
For get code quality (gl-code-quality-report.json
) in merge request (only GitLab EE https://docs.gitlab.com/ee/user/project/merge_requests/code_quality_diff.html)
Warning, master must have a
codequality.json
, usecommit-status
for notification mode (not mandatory)
stages:
...
- test
- quality
...
sonarqube_master_job:
stage: test
only:
- master
script:
- mvn --batch-mode verify sonar:sonar -Dsonar.host.url=$SONAR_URL -Dsonar.login=$SONAR_LOGIN -Dsonar.gitlab.project_id=$CI_PROJECT_PATH -Dsonar.gitlab.commit_sha=$CI_COMMIT_SHA -Dsonar.gitlab.ref_name=$CI_COMMIT_REF_NAME -Dsonar.gitlab.json_mode=CODECLIMATE -Dsonar.gitlab.failure_notification_mode=commit-status
artifacts:
expire_in: 1 day
paths:
- gl-code-quality-report.json
sonarqube_feature_job:
stage: test
only:
- /^feature\/*/
script:
- git checkout origin/master
- git merge $CI_COMMIT_SHA --no-commit --no-ff
- mvn --batch-mode verify sonar:sonar -Dsonar.host.url=$SONAR_URL -Dsonar.login=$SONAR_LOGIN -Dsonar.gitlab.project_id=$CI_PROJECT_PATH -Dsonar.gitlab.commit_sha=$CI_COMMIT_SHA -Dsonar.gitlab.ref_name=$CI_COMMIT_REF_NAME -Dsonar.gitlab.json_mode=CODECLIMATE -Dsonar.gitlab.failure_notification_mode=commit-status
artifacts:
expire_in: 1 day
paths:
- gl-code-quality-report.json
codequality:
stage: quality
variables:
GIT_STRATEGY: none
script:
- echo ok
artifacts:
paths:
- gl-code-quality-report.json
For get SAST (gl-sast-report.json
) information in merge request (only GitLab EE https://docs.gitlab.com/ee/user/project/merge_requests/sast.html)
stages:
...
- test
- quality
...
sonarqube_feature_job:
stage: test
only:
- /^feature\/*/
script:
- git checkout origin/master
- git merge $CI_COMMIT_SHA --no-commit --no-ff
- mvn --batch-mode verify sonar:sonar -Dsonar.host.url=$SONAR_URL -Dsonar.login=$SONAR_LOGIN -Dsonar.gitlab.project_id=$CI_PROJECT_PATH -Dsonar.gitlab.commit_sha=$CI_COMMIT_SHA -Dsonar.gitlab.ref_name=$CI_COMMIT_REF_NAME -Dsonar.gitlab.json_mode=SAST -Dsonar.gitlab.failure_notification_mode=commit-status
artifacts:
expire_in: 1 day
paths:
- gl-sast-report.json
sast:
stage: quality
only:
- /^feature\/*/
variables:
GIT_STRATEGY: none
artifacts:
paths:
- gl-sast-report.json
To enable discussions instead of comments
NOTE: This CI variable CI_MERGE_REQUEST_IID
is available from version 11.6 on.
mvn --batch-mode verify sonar:sonar \
-Dsonar.host.url=$SONAR_URL
-Dsonar.login=$SONAR_LOGIN \
-Dsonar.gitlab.api_version=v4 \
-Dsonar.gitlab.project_id=$CI_PROJECT_PATH \
-Dsonar.gitlab.commit_sha=$CI_COMMIT_SHA \
-Dsonar.gitlab.ref_name=$CI_COMMIT_REF_NAME \
-Dsonar.gitlab.user_token=<your_user_token> \
-Dsonar.gitlab.url=http://<your_gitlab_url> \
-Dsonar.gitlab.ci_merge_request_iid=$CI_MERGE_REQUEST_IID \
-Dsonar.gitlab.merge_request_discussion=true
GitLab 8.x name | GitLab 9.x name |
---|---|
CI_BUILD_REF | CI_COMMIT_SHA |
CI_BUILD_REF_NAME | CI_COMMIT_REF_NAME |
https://docs.gitlab.com/ce/ci/variables/#9-0-renaming
Variable | Comment | Type | Version |
---|---|---|---|
sonar.gitlab.url | GitLab url | Administration, Variable | >= 1.6.6 |
sonar.gitlab.max_global_issues | Maximum number of anomalies to be displayed in the global comment | Administration, Variable | >= 1.6.6 |
sonar.gitlab.user_token | Token of the user who can make reports on the project, either global or per project | Administration, Project, Variable | >= 1.6.6 |
sonar.gitlab.project_id | Project ID in GitLab or internal id or namespace + name or namespace + path or url http or ssh url or url or web | Project, Variable | >= 1.6.6 |
sonar.gitlab.commit_sha | SHA of the commit comment | Variable | >= 1.6.6 |
sonar.gitlab.ref | Branch name or reference of the commit | Variable | < 3.0.0 |
sonar.gitlab.ref_name | Branch name or reference of the commit | Variable | >= 1.6.6 |
sonar.gitlab.max_blocker_issues_gate | Max blocker issue for build failed (default 0). | Project, Variable | >= 2.0.0 |
sonar.gitlab.max_critical_issues_gate | Max critical issues for build failed (default 0). | Project, Variable | >= 2.0.0 |
sonar.gitlab.max_major_issues_gate | Max major issues for build failed (default -1 no fail). | Project, Variable | >= 2.0.0 |
sonar.gitlab.max_minor_issues_gate | Max minor issues for build failed (default -1 no fail). | Project, Variable | >= 2.0.0 |
sonar.gitlab.max_info_issues_gate | Max info issues for build failed (default -1 no fail). | Project, Variable | >= 2.0.0 |
sonar.gitlab.ignore_certificate | Ignore Certificate for access GitLab, use for auto-signing cert (default false) | Administration, Variable | >= 2.0.0 |
sonar.gitlab.comment_no_issue | Add a comment even when there is no new issue (default false) | Administration, Variable | >= 2.0.0 |
sonar.gitlab.disable_inline_comments | Disable issue reporting as inline comments (default false) | Administration, Variable | >= 2.0.0 |
sonar.gitlab.only_issue_from_commit_file | Show issue for commit file only (default false) | Variable | >= 2.0.0 |
sonar.gitlab.only_issue_from_commit_line | Show issue for commit line only (default false) | Variable | >= 2.1.0 |
sonar.gitlab.build_init_state | State that should be the first when build commit status update is called (default pending) | Administration, Variable | >= 2.0.0 |
sonar.gitlab.disable_global_comment | Disable global comment, report only inline (default false) | Administration, Variable | >= 2.0.0 |
sonar.gitlab.failure_notification_mode | Notification is in current build (exit-code) or in commit status (commit-status) (default commit-status) | Administration, Variable | >= 2.0.0 |
sonar.gitlab.global_template | Template for global comment in commit | Administration, Variable | >= 2.0.0 |
sonar.gitlab.ping_user | Ping the user who made an issue by @ mentioning. Only for default comment (default false) | Administration, Variable | >= 2.0.0 |
sonar.gitlab.unique_issue_per_inline | Unique issue per inline comment (default false) | Administration, Variable | >= 2.0.0 |
sonar.gitlab.prefix_directory | Add prefix when create link for GitLab | Variable | >= 2.1.0 |
sonar.gitlab.api_version | GitLab API version (default v4 ) |
Administration, Variable | >= 2.1.0 |
sonar.gitlab.all_issues | All issues new and old (default false, only new) | Administration, Variable | >= 2.1.0 |
sonar.gitlab.json_mode | Create a json report in root for GitLab EE (gl-code-quality-report.json or gl-sast-report.json) | Project, Variable | >= 3.0.0 |
sonar.gitlab.query_max_retry | Max retry for wait finish analyse for publish mode | Administration, Variable | >= 3.0.0 |
sonar.gitlab.query_wait | Max retry for wait finish analyse for publish mode | Administration, Variable | >= 3.0.0 |
sonar.gitlab.quality_gate_fail_mode | Quality gate fail mode: ERROR, WARN or NONE (default ERROR) | Administration, Variable | >= 3.0.0 |
sonar.gitlab.issue_filter | Filter on issue, if MAJOR then show only MAJOR, CRITICAL and BLOCKER (default INFO) | Administration, Variable | >= 3.0.0 |
sonar.gitlab.load_rules | Load rules for all issues (default false) | Administration, Variable | >= 3.0.0 |
sonar.gitlab.disable_proxy | Disable proxy if system contains proxy config (default false) | Administration, Variable | >= 4.0.0 |
sonar.gitlab.merge_request_discussion | Allows to post the comments as discussions (default false) | Project, Variable | >= 4.0.0 |
sonar.gitlab.ci_merge_request_iid | The IID of the merge request if it’s pipelines for merge requests | Project, Variable | >= 4.0.0 |
sonar.gitlab.fail_on_qualitygate | Fail scan if the quality gate fails (default false), this is required to fail the scanner since the plugin requires the sonar.qualitygate.wait=false to run |
Project, Variable | >= 5.0.2 |
sonar.gitlab.status_name | The name of the commit status created by the plugin (default sonarqube ) |
Project, Variable | >= 5.2.2 |
pom.xml
either from the command line with-D
If sonar.gitlab.failure_notification_mode is commit-status then role is Developer else Reporter.
Custom global/inline comment : Change language, change image, change order, print all issues, etc
Use FreeMarker syntax http://freemarker.org/
Usage : ${name}
name | type | description |
---|---|---|
url | String | GitLab url |
projectId | String | Project ID in GitLab or internal id or namespace + name or namespace + path or url http or ssh url or url or web |
commitSHA | String[] | SHA of the commit comment. Get first commitSHA[0] |
refName | String | Branch name or reference of the commit |
maxGlobalIssues | Integer | Maximum number of anomalies to be displayed in the global comment |
maxBlockerIssuesGate | Integer | Max blocker issue for build failed |
maxCriticalIssuesGate | Integer | Max critical issue for build failed |
maxMajorIssuesGate | Integer | Max major issue for build failed |
maxMinorIssuesGate | Integer | Max minor issue for build failed |
maxInfoIssuesGate | Integer | Max info issue for build failed |
disableIssuesInline | Boolean | Disable issue reporting as inline comments |
disableGlobalComment | Boolean | Disable global comment, report only inline |
onlyIssueFromCommitFile | Boolean | Show issue for commit file only |
commentNoIssue | Boolean | Add a comment even when there is no new issue |
revision | String | Current revision |
author | String | Commit's author for inline |
lineNumber | Integer | Current line number for inline issues only |
BLOCKER | Severity | Blocker |
CRITICAL | Severity | Critical |
MAJOR | Severity | Major |
MINOR | Severity | Minor |
INFO | Severity | Info |
sonarUrl | String | Url of SonarQube |
publishMode | Boolean | true if publish mode |
qualityGate | QualityGate | QualityGate |
OK | Status | Passed QualityGate & Condition status only Global Comment |
WARN | Status | Warning QualityGate & Condition status only Global Comment |
ERROR | Status | Failed QualityGate & Condition status only Global Comment |
Usage : ${name(arg1,arg2,...)}
name | arguments | type | description |
---|---|---|---|
issueCount | none | Integer | Get new issue count |
issueCount | Boolean | Integer | Get new issue count if true only reported else false only not reported |
issueCount | Severity | Integer | Get new issue count by Severity |
issueCount | Boolean, Severity | Integer | Get new issue count by Severity if true only reported else false only not reported |
issues | none | List |
Get new issues |
issues | Boolean | List |
Get new issues if true only reported else false only not reported |
issues | Severity | List |
Get new issues by Severity |
issues | Boolean, Severity | List |
Get new issues by Severity if true only reported else false only not reported |
Issue | String | Print a issue line (same default template) | |
emojiSeverity | Severity | String | Print a emoji by severity |
imageSeverity | Severity | String | Print a image by severity |
ruleLink | String | String | Get URL for rule in SonarQube |
Usage : ${qualityGate.name(arg1,arg2,...)}
name | arguments | type | description |
---|---|---|---|
conditions | Function none argument | List |
Get all conditions |
conditions | Function Status argument | List |
Get all conditions with Status |
conditionCount | Function none argument | Integer | Get size of all conditions |
conditionCount | Function Status argument | Integer | Get size conditions with Status |
Usage : ${Issue.name}
name | type | description |
---|---|---|
reportedOnDiff | Boolean | Reported inline |
url | String | URL of file/line in GitLab |
componentKey | String | Component key |
severity | Severity | Severity of issue |
line | Integer | Line (maybe null) |
key | String | Key |
message | String | Message (maybe null) |
ruleKey | String | Rule key on SonarQube |
new | Boolean | New issue |
ruleLink | String | URL of rule in SonarQube |
src | String | File source |
rule | Rule | Rule information |
Usage : ${Issue.rule.name}
name | type | description |
---|---|---|
key | String | Rule key |
repo | String | Rule repository |
name | String | Name of rule |
description | String | Description of rule |
type | String | CODE_SMELL, BUG, VULNERABILITY, SECURITY_HOTSPOT |
debtRemFnType | String | Debt type |
debtRemFnBaseEffort | String | Debt effort |
Usage : ${qualityGate.name}
name | type | description |
---|---|---|
status | Status | Status of quality gate |
Usage : ${Condition.name}
name | type | description |
---|---|---|
status | Status | Status of condition |
actual | String | Actual value for metric |
warning | String | Warning value |
error | String | Error value |
metricKey | String | Metric key |
metricName | String | Metric name |
symbol | String | Symbol of condition <,>,=,!= |
<#if qualityGate??>
SonarQube analysis indicates that quality gate is <@s status=qualityGate.status/>.
<#list qualityGate.conditions() as condition>
<@c condition=condition/>
</#list>
</#if>
<#macro c condition>* ${condition.metricName} is <@s status=condition.status/>: Actual value ${condition.actual} is ${condition.symbol}<#if condition.status != OK && condition.message?? && condition.message?trim?has_content> (${condition.message})</#if></#macro>
<#macro s status><#if status == OK>passed<#elseif status == WARN>warning<#elseif status == ERROR>failed<#else>unknown</#if></#macro>
<#assign newIssueCount = issueCount() notReportedIssueCount = issueCount(false)>
<#assign hasInlineIssues = newIssueCount gt notReportedIssueCount extraIssuesTruncated = notReportedIssueCount gt maxGlobalIssues>
<#if newIssueCount == 0>
SonarQube analysis reported no issues.
<#else>
SonarQube analysis reported ${newIssueCount} issue<#if newIssueCount gt 1>s</#if>
<#assign newIssuesBlocker = issueCount(BLOCKER) newIssuesCritical = issueCount(CRITICAL) newIssuesMajor = issueCount(MAJOR) newIssuesMinor = issueCount(MINOR) newIssuesInfo = issueCount(INFO)>
<#if newIssuesBlocker gt 0>
* ${emojiSeverity(BLOCKER)} ${newIssuesBlocker} blocker
</#if>
<#if newIssuesCritical gt 0>
* ${emojiSeverity(CRITICAL)} ${newIssuesCritical} critical
</#if>
<#if newIssuesMajor gt 0>
* ${emojiSeverity(MAJOR)} ${newIssuesMajor} major
</#if>
<#if newIssuesMinor gt 0>
* ${emojiSeverity(MINOR)} ${newIssuesMinor} minor
</#if>
<#if newIssuesInfo gt 0>
* ${emojiSeverity(INFO)} ${newIssuesInfo} info
</#if>
<#if !disableIssuesInline && hasInlineIssues>
Watch the comments in this conversation to review them.
</#if>
<#if notReportedIssueCount gt 0>
<#if !disableIssuesInline>
<#if hasInlineIssues || extraIssuesTruncated>
<#if notReportedIssueCount <= maxGlobalIssues>
#### ${notReportedIssueCount} extra issue<#if notReportedIssueCount gt 1>s</#if>
<#else>
#### Top ${maxGlobalIssues} extra issue<#if maxGlobalIssues gt 1>s</#if>
</#if>
</#if>
Note: The following issues were found on lines that were not modified in the commit. Because these issues can't be reported as line comments, they are summarized here:
<#elseif extraIssuesTruncated>
#### Top ${maxGlobalIssues} issue<#if maxGlobalIssues gt 1>s</#if>
</#if>
<#assign reportedIssueCount = 0>
<#list issues(false) as issue>
<#if reportedIssueCount < maxGlobalIssues>
1. ${print(issue)}
</#if>
<#assign reportedIssueCount++>
</#list>
<#if notReportedIssueCount gt maxGlobalIssues>
* ... ${notReportedIssueCount-maxGlobalIssues} more
</#if>
</#if>
</#if>
Others examples for global :
<#list issues() as issue>
<@p issue=issue/>
</#list>
<#macro p issue>
${emojiSeverity(issue.severity)} ${issue.message} [:blue_book:](${issue.ruleLink})
</#macro>
Others examples for inline :
If you don't already have you certificate on the SonarQube server, run openssl s_client -connect mygitlab.com:443 -showcerts > /home/${USER}/mygitlab.crt
Import it into your JRE cacerts (you can check from the "System Info" page in the Administration section of your sonarqube instance), running sudo $JDK8/bin/keytool -import -file ~/mygitlab.crt -keystore $JDK8/jre/lib/security/cacerts -alias mygitlab
.
Restart your SonarQube instance.
mvn --batch-mode verify sonar:sonar
-Dsonar.gitlab.api_version=v4
-Dsonar.host.url=http://<your_sonar_url>:9000
-Dsonar.login=<your_sonar_login>
-Dsonar.gitlab.commit_sha=$CI_COMMIT_SHA
-Dsonar.gitlab.ref_name=$CI_COMMIT_REF_NAME
-Dsonar.gitlab.project_id=$CI_PROJECT_ID
-Dsonar.gitlab.url=http://<your_gitlab_url>
-Dsonar.gitlab.user_token=<your_user_token>
Only SonarQube < 7.7, because preview mode is removed
This version is directly in the SonarQube update center, only SonarQube >= 7.0
This version is directly in the SonarQube update center, only SonarQube 6.7
This version is directly in the SonarQube update center, only SonarQube < 6.7