mc1arke / sonarqube-community-branch-plugin

A plugin that allows branch analysis and pull request decoration in the Community version of Sonarqube

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Decorating Pull Requests

goober opened this issue · comments

I would like to start a discussion for how the plugin would be able to support pull request decorations in a similar way that the commercial plugin does.

A former discussion was made in #3, but the initial issue was not related to supporting pull request decorations so I open a new issue to track the discussion of supporting pull request decorations in one place. Please feel free to close this if it is more preferable to continue the discussion in the other issue.

This is a suggestion for a solution based on my initial investigation on how the plugin lifecycle works in sonarqube.

By hooking in as a ComputeEngine extension with a PostProjectAnalysisTask, where we have access to the necessary metadata like quality gate results, we have the possibility to decorate the pull requests with some metadata.

For Bitbucket Server we would then use the Code Insights API.

However, the PostProjectAnalysisTask does not expose the individual issues reported in the scan so I suggest that we do this in two steps.

Step 1 - Support pull request decoration with the data available within the PostProjectAnalysisTask

Step 2 - Support pull request decoration of individual issues per line.

For step 2 I have not found any internal sdk to use to obtain the issues reported in the scan. Other plugins like quboo-sonarqube-plugin leverages sonarqubes REST api to obtain the necessary data about the scan.
See QubooConnector.java

If it is decided to go with the REST api approach we could still use the PostProjectAnalysisTask to decorate the changed lines within the pull request.

@mc1arke I guess that you have a lot of thoughts on how you want to tackle this?

I'd initially like to aim for parity with how SonarQube currently works for PR decoration, so report the high-level metrics that are provided as part of the PostProjectAnalysisTask. I'm happy to then support per-line decoration with individual issues as part of a subsequent release - with options for users to enable/disable it - but suggest we go for a simple Minimum Viable Product Initially.

I'd started some work on this previously but then ran-out-of-time to carry it forward. I'll try and get it tidied up and pushed to Github to start a conversation from.

@mc1arke looking forward to see your current progress on this feature

+1
and willing to support and help if needed.

+1, I’m also willing to Support if needed

I have made an initial implementation that works with Bitbucket Server.
It includes both the report summary and per line annotations with new issues.

The screenshot is taken from Sonarqubes official site and my implementation will mimic what I can see from their screenshot.
Bitbucket Server decorations

I took the decision to create a separate plugin initially to not interfere with your plugin. I have no problem merging it in when it is stable enough.

You can find my plugin at https://github.com/goober/sonarqube-pullrequest-decorator-plugin

Note that it is a very ruff first iteration to verify that my ideas worked.

I have done some work with the Github integration tonight.

You can see a sneak peek at my demo project

I will submit the underlying code as soon as I have cleaned it up a bit. I haven't been able to test it on a Github Enterprise installation since I do not have access to that.

any update on that please ?

I've pushed my proposed implementation of Pull Request decoration to the 'pr-decoration' branch and raised Pull Request #30 for initial comments. This implementation provides support for decorating Github Pull Requests and has been tested against github.com but not against a Github Enterprise distribution yet.

I've taken an alternative approach to @goober in retrieving Issues, using an implementation of IssueVisitor to collect issues whilst the analysis is executing, rather than using REST to retrieve them when the 'report' starts. The initial implementation provides an equivalent of the report generated by SonarQube, but the implementation should be fairly easy to extend to decorate the individual files/lines as well as providing the current summary.

My code still requires a bit of work to provide unit tests, clean-up the code and formatting, and refactor the APIs to prevent duplicate null/optional checking and duplication of the retrieval of metrics against different Pull Reuqest providers, but I'm happy for people to test is and provide issues/feedback/comments against the code as it currently stands.

@mc1arke amazing work!

Although I know nothing about SonarQube API, I took a look at PR. From my point of view, it looks amazing and it looks like it should be easy to expand with decorating individual files/lines, as you said in your comment.

In case you don't know much about Gitlab, I'd also like to add few things (which might affect your API design):

  1. as far as I know, there's no such thing as Checks API and pushing formatted string
    • in Gitlab, my plan is to generate junit report during sonarqube task (gradle), as that can be easily viewable in Gitlab (Free) [1]
    • if that's really true, decorateQualityGateStatus would probably be empty in Gitlab's case (which is okay)
    • EDIT: on second thought, I guess you could have a comment that you can update on each analysis?
  2. as of Gitlab 10.8 (May 22, 2018) [2], there's a support for creating discussions on lines (in MR)
    • we/I would be willing to contribute support for this in this plugin, once you are ready for such contributions :)

Also, I really don't know if this is a bad idea or not, but... What do you think about automatically resolving issue as false positive (?) if you resolve discussion in Gitlab / not sure what would be similar action in Github/etc. ?

P.S. At work, we use Gitlab, so I can't test this on anything but pet example on GitHub, which you probably also tested... :)

Thank you for adding support to this! 😊

[1] https://docs.gitlab.com/ee/ci/junit_test_reports.html
[2] https://about.gitlab.com/2018/05/22/gitlab-10-8-released/#discussions-in-api

@mfolnovic I've started working on an implementation for Gitlab in #34. Still very basic, but I'm open to hear any suggestions you have for it.

Please help
I can't get property from context

Scanner Context:

  - sonar.pullrequest.vsts.project=SonarQube
  - sonar.pullrequest.vsts.repository=SonarQube

In PullRequestBuildStatusDecorator I use
String repoFromConfig = getMandatoryProperty("sonar.pullrequest.vsts.repository", configuration);

And get

java.lang.IllegalStateException: sonar.pullrequest.vsts.repository must be specified in the project configuration

Definition:

               PropertyDefinition.builder("sonar.pullrequest.vsts.repository")
                        .subCategory(PULL_REQUEST_CATEGORY_LABEL).subCategory(TFS_INTEGRATION_SUBCATEGORY_LABEL)
                        .onQualifiers(Qualifiers.PROJECT)
                        .name("TFS repository name").description("Example: Note - this should be specified within tfs task for each project")
                        .type(PropertyType.STRING).build()

@goober I though PR decoration is only for Github enterprise edition. This is what their docs says at-least. Will the same steps for enterprise work for regular GitHub( github.com) ?

Looks good if you use up to date source code repos.

With the really old version of bitbucket server we are using then the only way to comment is how the https://github.com/AmadeusITGroup/sonar-stash adds a comment. In theory all the logic to post comments is harvestable so probably can end up easily adding support this way as a backup.

@mc1arke thank You for creating this plugin, really amazing work.

Do You plan to add PR decoration for Azure Devops? I would appreciate it a lot :).

I would kindly request PR decoration for Azure DevOps as well :).

Thank you for creating this plugin and being awesome!

@wskwierawskiInfoprojekt @RobCoPKC I'm more than happy to look at adding Azure DevOps, but I probably need some initial direction from people like you around what I need to do for authentication and any calls to endpoints as I've never used Azure DevOps before.

There needs to be an option to define a personal access token which is generated in Azure DevOps and needs to have the "Code (Read & Write)" permission:

image

This token should then be used to make an API call (I would assume the one described here) to create a comment for each detected issue under the pull request. It looks like this:

image

I'm sorry I can't be more specific since I don't own the Developer Edition nor can I access SonarCloud logs.

@mc1arke any updates?

@mahmoud-samy Is there any particular work you're looking for an update on?

@mc1arke yes, PRs decoration.
We are looking to the first release 😁

I got the following error when I try to analyze a project with the latest SNAPSHOT version (1.2.1). I have all configured right. It seems to be a bug?

Execution of task class com.github.mc1arke.sonarqube.plugin.ce.pullrequest.PullRequestPostAnalysisTask failed
java.lang.IllegalStateException: Could not decorate Pull Request on Github
	at com.github.mc1arke.sonarqube.plugin.ce.pullrequest.github.GithubPullRequestDecorator.decorateQualityGateStatus(GithubPullRequestDecorator.java:37)
	at com.github.mc1arke.sonarqube.plugin.ce.pullrequest.PullRequestPostAnalysisTask.finished(PullRequestPostAnalysisTask.java:126)
	at org.sonar.ce.task.projectanalysis.api.posttask.PostProjectAnalysisTasksExecutor.executeTask(PostProjectAnalysisTasksExecutor.java:113)
	at org.sonar.ce.task.projectanalysis.api.posttask.PostProjectAnalysisTasksExecutor.finished(PostProjectAnalysisTasksExecutor.java:107)
	at org.sonar.ce.task.step.ComputationStepExecutor.executeListener(ComputationStepExecutor.java:91)
	at org.sonar.ce.task.step.ComputationStepExecutor.execute(ComputationStepExecutor.java:63)
	at org.sonar.ce.task.projectanalysis.taskprocessor.ReportTaskProcessor.process(ReportTaskProcessor.java:81)
	at org.sonar.ce.taskprocessor.CeWorkerImpl$ExecuteTask.executeTask(CeWorkerImpl.java:209)
	at org.sonar.ce.taskprocessor.CeWorkerImpl$ExecuteTask.run(CeWorkerImpl.java:191)
	at org.sonar.ce.taskprocessor.CeWorkerImpl.findAndProcessTask(CeWorkerImpl.java:158)
	at org.sonar.ce.taskprocessor.CeWorkerImpl$TrackRunningState.get(CeWorkerImpl.java:133)
	at org.sonar.ce.taskprocessor.CeWorkerImpl.call(CeWorkerImpl.java:85)
	at org.sonar.ce.taskprocessor.CeWorkerImpl.call(CeWorkerImpl.java:53)
	at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
	at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
	at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at java.base/java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException: null
	at com.github.mc1arke.sonarqube.plugin.ce.pullrequest.github.v3.RestApplicationAuthenticationProvider.createPrivateKey(RestApplicationAuthenticationProvider.java:137)
	at com.github.mc1arke.sonarqube.plugin.ce.pullrequest.github.v3.RestApplicationAuthenticationProvider.getInstallationToken(RestApplicationAuthenticationProvider.java:75)
	at com.github.mc1arke.sonarqube.plugin.ce.pullrequest.github.v4.GraphqlCheckRunProvider.createCheckRun(GraphqlCheckRunProvider.java:108)
	at com.github.mc1arke.sonarqube.plugin.ce.pullrequest.github.GithubPullRequestDecorator.decorateQualityGateStatus(GithubPullRequestDecorator.java:35)
	... 19 common frames omitted

Is the private key you've entered for Github authentication valid? Without some details about your configuration, it's going to be difficult to diagnose this.

Okay, the private key was not valid... The error message could be more detailed about this.

Another thing is, that it doesn't work. I don't got the decoration in my Pull Request without any error message.

That's all logs from the plugin:

2020.01.11 18:39:09 INFO  ce[AW-V5xtzRP75ild_pf_H][c.g.m.s.p.c.p.PullRequestPostAnalysisTask] using pull request decoratorGithub

Project configuration:
sonar.pullrequest.provider=Github
sonar.pullrequest.github.repository=ORG/REPOSITORY

CMD:

mvn sonar:sonar \
            -Dsonar.host.url=*** \
            -Dsonar.pullrequest.key=1 \
            -Dsonar.pullrequest.branch=myBranch \
            -Dsonar.login=*** \
            -Dsonar.java.binaries=./target/classes

My GitHub Application has following rights:

  • Read access to code
  • Read access to members and metadata
  • Read and write access to checks, commit statuses, and pull requests

There was no error handling on the parsing of the key hence a NullPointerException rather than something clearer. If you raise an issue with the details to replicate it then I can fix/enhance it.

For your latest issue, if you turn on debug logging for the Github decoration classes then it will show the request and responses for the Github service calls, which should indicate why you're not seeing any report on Gitlab. To do this, add the following into $SONARQUBE_HOME/conf/sonar.properties then restart your SonarQube instance:

sonar.log.level.ce=DEBUG

At a minimum, please share the lines containing Using request: and Received response: , but generally sharing as much of this log as possible would be useful.

Okay, here are the log messages.

Request:

Using request: mutation { createCheckRun (input:{conclusion:SUCCESS,output:{summary:"![Passed](https://raw.githubusercontent.com/mc1arke/sonarqube-community-branch-plugin/master/src/main/resources/pr-decoration-images/checks/QualityGateBadge/passed.svg?sanitize=true)

# Analysis Details
## 0 Issues
- ![Bug](https://raw.githubusercontent.com/mc1arke/sonarqube-community-branch-plugin/master/src/main/resources/pr-decoration-images/common/bug.svg?sanitize=true) 0 Bugs
- ![Vulnerability](https://raw.githubusercontent.com/mc1arke/sonarqube-community-branch-plugin/master/src/main/resources/pr-decoration-images/common/vulnerability.svg?sanitize=true) 0 Vulnerabilities
- ![Code Smell](https://raw.githubusercontent.com/mc1arke/sonarqube-community-branch-plugin/master/src/main/resources/pr-decoration-images/common/vulnerability.svg?sanitize=true) 0 Code Smells

## Coverage and Duplications
- ![100 percent coverage](https://raw.githubusercontent.com/mc1arke/sonarqube-community-branch-plugin/master/src/main/resources/pr-decoration-images/checks/CoverageChart/100.svg?sanitize=true) 100.00% Coverage (59.10% Estimated after merge)
- ![No duplication information](https://raw.githubusercontent.com/mc1arke/sonarqube-community-branch-plugin/master/src/main/resources/pr-decoration-images/checks/Duplications/NoDuplicationInfo.svg?sanitize=true) No duplication information (0.00% Estimated after merge)

",annotations:[],title:"Quality Gate success"},completedAt:"2020-01-11T22:41:48Z",detailsUrl:"https://***",repositoryId:"MDEwOlJlcG9zaXRvcnkyMTk3NTY4OTk=",name:"SonarQube Community Pull Request Analysis Results",startedAt:"2020-01-11T22:41:17Z",externalId:"AW-WxTS2bfTDYhM-qS2C",headSha:"33b17145172808db917db98befb64c47377134b8",status:COMPLETED}) { clientMutationId checkRun { id } } }

Response:

Received response: GraphQLResponseEntity{errors=null, headers=[Status:200 OK][null:HTTP/1.1 200 OK][Server:GitHub.com][Access-Control-Allow-Origin:*][X-Content-Type-Options:nosniff][X-RateLimit-Reset:1578786108][Date:Sat, 11 Jan 2020 22:41:48 GMT][Referrer-Policy:origin-when-cross-origin, strict-origin-when-cross-origin][X-Frame-Options:deny][Strict-Transport-Security:max-age=31536000; includeSubdomains; preload][Access-Control-Expose-Headers:ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type][X-RateLimit-Remaining:6299][Cache-Control:no-cache][X-GitHub-Media-Type:github.antiope-preview; format=json][Content-Security-Policy:default-src 'none'][Vary:Accept-Encoding][X-RateLimit-Limit:6300][X-XSS-Protection:1; mode=block][Content-Length:102][X-GitHub-Request-Id:ED28:26795:83FD280:A035FC5:5E1A4F2C][Content-Type:application/json; charset=utf-8], response=com.github.mc1arke.sonarqube.plugin.ce.pullrequest.github.v4.CreateCheckRun@3445a131}

Given errors came back as null in the response, that should indicate that Github found the commit, so should have been able to add the check run to it. Are you able to run this against a repository that I can see (e.g. a public repository on Github.com) so I can check commit and repository IDs?

I got it working now. The problem was, that I have the installed App in my organization configured to have access to all repositories. If I select only one specific, it works!

This is my exception, when I have the app configured to have access to all repositories:

java.lang.IllegalStateException: Could not decorate Pull Request on Github
	at com.github.mc1arke.sonarqube.plugin.ce.pullrequest.github.GithubPullRequestDecorator.decorateQualityGateStatus(GithubPullRequestDecorator.java:37)
	at com.github.mc1arke.sonarqube.plugin.ce.pullrequest.PullRequestPostAnalysisTask.finished(PullRequestPostAnalysisTask.java:130)
	at org.sonar.ce.task.projectanalysis.api.posttask.PostProjectAnalysisTasksExecutor.executeTask(PostProjectAnalysisTasksExecutor.java:113)
	at org.sonar.ce.task.projectanalysis.api.posttask.PostProjectAnalysisTasksExecutor.finished(PostProjectAnalysisTasksExecutor.java:107)
	at org.sonar.ce.task.step.ComputationStepExecutor.executeListener(ComputationStepExecutor.java:91)
	at org.sonar.ce.task.step.ComputationStepExecutor.execute(ComputationStepExecutor.java:63)
	at org.sonar.ce.task.projectanalysis.taskprocessor.ReportTaskProcessor.process(ReportTaskProcessor.java:81)
	at org.sonar.ce.taskprocessor.CeWorkerImpl$ExecuteTask.executeTask(CeWorkerImpl.java:209)
	at org.sonar.ce.taskprocessor.CeWorkerImpl$ExecuteTask.run(CeWorkerImpl.java:191)
	at org.sonar.ce.taskprocessor.CeWorkerImpl.findAndProcessTask(CeWorkerImpl.java:158)
	at org.sonar.ce.taskprocessor.CeWorkerImpl$TrackRunningState.get(CeWorkerImpl.java:133)
	at org.sonar.ce.taskprocessor.CeWorkerImpl.call(CeWorkerImpl.java:85)
	at org.sonar.ce.taskprocessor.CeWorkerImpl.call(CeWorkerImpl.java:53)
	at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Unknown Source)
	at java.base/java.util.concurrent.FutureTask.run(Unknown Source)
	at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(Unknown Source)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source)
	at java.base/java.lang.Thread.run(Unknown Source)
Caused by: java.lang.IllegalStateException: No token could be found with access to the requested repository with the given application ID and key
	at com.github.mc1arke.sonarqube.plugin.ce.pullrequest.github.v3.RestApplicationAuthenticationProvider.getInstallationToken(RestApplicationAuthenticationProvider.java:130)
	at com.github.mc1arke.sonarqube.plugin.ce.pullrequest.github.v4.GraphqlCheckRunProvider.createCheckRun(GraphqlCheckRunProvider.java:108)
	at com.github.mc1arke.sonarqube.plugin.ce.pullrequest.github.GithubPullRequestDecorator.decorateQualityGateStatus(GithubPullRequestDecorator.java:35)
	... 19 common frames omitted

It seems that this don't work with GitHub Actions. When I run the sonar analyse from command line on my local machine, the decoration will be published to the Pull Request. With GitHub Actions pipeline, it doesn't.

Here are some Logs:

Without GitHub Actions:

# Without CI Pipeline
2020.02.06 09:04:16 INFO  ce[AXAZvhfbj2mf94ksGoUY][c.g.m.s.p.c.p.PullRequestPostAnalysisTask] using pull request decoratorGithub
2020.02.06 09:04:17 DEBUG ce[AXAZvhfbj2mf94ksGoUY][jdk.event.security] X509Certificate: Alg:SHA256withRSA, Serial:3370ab628bf98d2bbcde1c2797d4634, Subject:CN=*.github.com, O="GitHub, Inc.", L=San Francisco, ST=California, C=US, Issuer:CN=DigiCert SHA2 High Assurance Server CA, OU=www.digicert.com, O=DigiCert Inc, C=US, Key type:RSA, Length:2048, Cert Id:-1712238821, Valid from:7/8/19, 12:00 AM, Valid until:7/16/20, 12:00 PM
2020.02.06 09:04:17 DEBUG ce[AXAZvhfbj2mf94ksGoUY][jdk.event.security] X509Certificate: Alg:SHA256withRSA, Serial:4e1e7a4dc5cf2f36dc02b42b85d159f, Subject:CN=DigiCert SHA2 High Assurance Server CA, OU=www.digicert.com, O=DigiCert Inc, C=US, Issuer:CN=DigiCert High Assurance EV Root CA, OU=www.digicert.com, O=DigiCert Inc, C=US, Key type:RSA, Length:2048, Cert Id:-599509715, Valid from:10/22/13, 12:00 PM, Valid until:10/22/28, 12:00 PM
2020.02.06 09:04:17 DEBUG ce[AXAZvhfbj2mf94ksGoUY][jdk.event.security] ValidationChain: -1410680354, -599509715, -1712238821
2020.02.06 09:04:17 DEBUG ce[AXAZvhfbj2mf94ksGoUY][jdk.event.security]  TLSHandshake: api.github.com:443, TLSv1.3, TLS_AES_128_GCM_SHA256, -1712238821
2020.02.06 09:04:17 DEBUG ce[AXAZvhfbj2mf94ksGoUY][s.n.w.p.h.HttpURLConnection] sun.net.www.MessageHeader@362ec0806 pairs: {GET /app/installations HTTP/1.1: null}{Accept: application/vnd.github.machine-man-preview+json}{Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE1ODA5Nzk4NDYsImV4cCI6MTU4MDk3OTk2NiwiaXNzIjoiNDY3NTcifQ.VR9xvmOHzVrgOVkkKD4GmswKVvFzzRbwuShvJmnbFbFsTZw_SCzw-vMtfQtgIEui00UVqgTelwfsNlcFUAg3PyApmzlxuaHPaURTIQnWPXaa6o1DdXimi8BXAsyasHLruT3Zj9Q4zZk_U9MVW3n1zp7mkFtunLMrXku7fbEPOAbuI8vZ6oSM7Z9GysSDKO1WG1ISifp7fxCtFSyArEwsdIOdXlE85xA7b-xxm1cr_9C3rkF95F3sQtsIV47hGhOvV8Dm1Tyi5TUSKYqwQg5EYQa0hpCCnV4MApeDsMpJ38QUp1AzxhifuwzQ4lnyHFZ__V2RHSsZ0mfcuJmkdh3PsA}{User-Agent: Java/11.0.5}{Host: api.github.com}{Connection: keep-alive}
2020.02.06 09:04:17 DEBUG ce[AXAZvhfbj2mf94ksGoUY][s.n.w.p.h.HttpURLConnection] sun.net.www.MessageHeader@2c68e7ee20 pairs: {null: HTTP/1.1 200 OK}{Date: Thu, 06 Feb 2020 09:04:17 GMT}{Content-Type: application/json; charset=utf-8}{Content-Length: 1521}{Server: GitHub.com}{Status: 200 OK}{Cache-Control: public, max-age=60, s-maxage=60}{Vary: Accept}{ETag: "7f1cd4c1c866ab81a9534c9362f1c429"}{X-GitHub-Media-Type: github.machine-man-preview; format=json}{Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type}{Access-Control-Allow-Origin: *}{Strict-Transport-Security: max-age=31536000; includeSubdomains; preload}{X-Frame-Options: deny}{X-Content-Type-Options: nosniff}{X-XSS-Protection: 1; mode=block}{Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin}{Content-Security-Policy: default-src 'none'}{Vary: Accept-Encoding}{X-GitHub-Request-Id: EBA2:1251E:684961:7C7B3E:5E3BD691}
2020.02.06 09:04:17 DEBUG ce[AXAZvhfbj2mf94ksGoUY][s.n.w.p.h.HttpURLConnection] sun.net.www.MessageHeader@23372e0a6 pairs: {POST /app/installations/5199089/access_tokens HTTP/1.1: null}{Accept: application/vnd.github.machine-man-preview+json}{Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE1ODA5Nzk4NDYsImV4cCI6MTU4MDk3OTk2NiwiaXNzIjoiNDY3NTcifQ.VR9xvmOHzVrgOVkkKD4GmswKVvFzzRbwuShvJmnbFbFsTZw_SCzw-vMtfQtgIEui00UVqgTelwfsNlcFUAg3PyApmzlxuaHPaURTIQnWPXaa6o1DdXimi8BXAsyasHLruT3Zj9Q4zZk_U9MVW3n1zp7mkFtunLMrXku7fbEPOAbuI8vZ6oSM7Z9GysSDKO1WG1ISifp7fxCtFSyArEwsdIOdXlE85xA7b-xxm1cr_9C3rkF95F3sQtsIV47hGhOvV8Dm1Tyi5TUSKYqwQg5EYQa0hpCCnV4MApeDsMpJ38QUp1AzxhifuwzQ4lnyHFZ__V2RHSsZ0mfcuJmkdh3PsA}{User-Agent: Java/11.0.5}{Host: api.github.com}{Connection: keep-alive}
2020.02.06 09:04:17 DEBUG ce[AXAZvhfbj2mf94ksGoUY][s.n.w.p.h.HttpURLConnection] sun.net.www.MessageHeader@ae02e3f20 pairs: {null: HTTP/1.1 201 Created}{Date: Thu, 06 Feb 2020 09:04:17 GMT}{Content-Type: application/json; charset=utf-8}{Content-Length: 234}{Server: GitHub.com}{Status: 201 Created}{Cache-Control: public, max-age=60, s-maxage=60}{Vary: Accept}{ETag: "a3bc3dddf52ef10d4dbf61543c90d58a"}{X-GitHub-Media-Type: github.machine-man-preview; format=json}{Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type}{Access-Control-Allow-Origin: *}{Strict-Transport-Security: max-age=31536000; includeSubdomains; preload}{X-Frame-Options: deny}{X-Content-Type-Options: nosniff}{X-XSS-Protection: 1; mode=block}{Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin}{Content-Security-Policy: default-src 'none'}{Vary: Accept-Encoding}{X-GitHub-Request-Id: EBA2:1251E:68497A:7C7B54:5E3BD691}
2020.02.06 09:04:17 DEBUG ce[AXAZvhfbj2mf94ksGoUY][s.n.w.p.h.HttpURLConnection] sun.net.www.MessageHeader@3d1f32b46 pairs: {GET /installation/repositories HTTP/1.1: null}{Accept: application/vnd.github.machine-man-preview+json}{Authorization: Bearer v1.ab758eb3958cfa5bc8f82fdb28460b07b973faf5}{User-Agent: Java/11.0.5}{Host: api.github.com}{Connection: keep-alive}
2020.02.06 09:04:18 DEBUG ce[AXAZvhfbj2mf94ksGoUY][s.n.w.p.h.HttpURLConnection] sun.net.www.MessageHeader@62a77ceb23 pairs: {null: HTTP/1.1 200 OK}{Date: Thu, 06 Feb 2020 09:04:18 GMT}{Content-Type: application/json; charset=utf-8}{Content-Length: 124454}{Server: GitHub.com}{Status: 200 OK}{X-RateLimit-Limit: 5250}{X-RateLimit-Remaining: 5246}{X-RateLimit-Reset: 1580981368}{Cache-Control: private, max-age=60, s-maxage=60}{Vary: Accept, Authorization, Cookie, X-GitHub-OTP}{ETag: "18d37cdac143771fa7a97540b8d4278b"}{X-GitHub-Media-Type: github.machine-man-preview; format=json}{Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type}{Access-Control-Allow-Origin: *}{Strict-Transport-Security: max-age=31536000; includeSubdomains; preload}{X-Frame-Options: deny}{X-Content-Type-Options: nosniff}{X-XSS-Protection: 1; mode=block}{Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin}{Content-Security-Policy: default-src 'none'}{Vary: Accept-Encoding}{X-GitHub-Request-Id: EBA2:1251E:684997:7C7B76:5E3BD691}
2020.02.06 09:04:18 DEBUG ce[AXAZvhfbj2mf94ksGoUY][c.g.m.s.p.c.p.g.v.GraphqlCheckRunProvider] Using request: mutation { createCheckRun (input:{conclusion:SUCCESS,output:{summary:"![Passed](https://raw.githubusercontent.com/mc1arke/sonarqube-community-branch-plugin/master/src/main/resources/pr-decoration-images/checks/QualityGateBadge/passed.svg?sanitize=true)

# Analysis Details
## 0 Issues
- ![Bug](https://raw.githubusercontent.com/mc1arke/sonarqube-community-branch-plugin/master/src/main/resources/pr-decoration-images/common/bug.svg?sanitize=true) 0 Bugs
- ![Vulnerability](https://raw.githubusercontent.com/mc1arke/sonarqube-community-branch-plugin/master/src/main/resources/pr-decoration-images/common/vulnerability.svg?sanitize=true) 0 Vulnerabilities
- ![Code Smell](https://raw.githubusercontent.com/mc1arke/sonarqube-community-branch-plugin/master/src/main/resources/pr-decoration-images/common/vulnerability.svg?sanitize=true) 0 Code Smells

## Coverage and Duplications
- ![No coverage information](https://raw.githubusercontent.com/mc1arke/sonarqube-community-branch-plugin/master/src/main/resources/pr-decoration-images/checks/CoverageChart/NoCoverageInfo.svg?sanitize=true) No coverage information (0.00% Estimated after merge)
- ![No duplication information](https://raw.githubusercontent.com/mc1arke/sonarqube-community-branch-plugin/master/src/main/resources/pr-decoration-images/checks/Duplications/NoDuplicationInfo.svg?sanitize=true) No duplication information (0.00% Estimated after merge)

[View in SonarQube](https://sonarqube-server/dashboard?id=com.avides.sonarqube-pr-dec%3Asonarqube-pr-decoration-test&pullRequest=1)",annotations:[],title:"Quality Gate success"},completedAt:"2020-02-06T09:04:18Z",detailsUrl:"https://sonarqube/dashboard?id=com.avides.sonarqube-pr-dec%3Asonarqube-pr-decoration-test&pullRequest=1",repositoryId:"MDEwOlJlcG9zaXRvcnkyMzUxMzUyODA=",name:"sonarqube-avides Results",startedAt:"2020-02-06T09:04:08Z",externalId:"AXAZvh3iZMDBAUGhho05",headSha:"1260182021bb887c46cbb150f49e00b165352715",status:COMPLETED}) { clientMutationId checkRun { id } } } 
2020.02.06 09:04:18 DEBUG ce[AXAZvhfbj2mf94ksGoUY][s.n.w.p.h.HttpURLConnection] sun.net.www.MessageHeader@1735f28d11 pairs: {POST /graphql HTTP/1.1: null}{Content-Type: application/json}{Accept: application/vnd.github.antiope-preview+json}{charset: utf-8}{Authorization: Bearer v1.ab758eb3958cfa5bc8f82fdb28460b07b973faf5}{Cache-Control: no-cache}{Pragma: no-cache}{User-Agent: Java/11.0.5}{Host: api.github.com}{Connection: keep-alive}{Content-Length: 2074}
2020.02.06 09:04:19 DEBUG ce[AXAZvhfbj2mf94ksGoUY][s.n.w.p.h.HttpURLConnection] sun.net.www.MessageHeader@57ee092221 pairs: {null: HTTP/1.1 200 OK}{Date: Thu, 06 Feb 2020 09:04:19 GMT}{Content-Type: application/json; charset=utf-8}{Content-Length: 102}{Server: GitHub.com}{Status: 200 OK}{Cache-Control: no-cache}{X-GitHub-Media-Type: github.antiope-preview; format=json}{X-RateLimit-Limit: 5250}{X-RateLimit-Remaining: 5246}{X-RateLimit-Reset: 1580981368}{Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type}{Access-Control-Allow-Origin: *}{Strict-Transport-Security: max-age=31536000; includeSubdomains; preload}{X-Frame-Options: deny}{X-Content-Type-Options: nosniff}{X-XSS-Protection: 1; mode=block}{Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin}{Content-Security-Policy: default-src 'none'}{Vary: Accept-Encoding}{X-GitHub-Request-Id: EBA2:1251E:6849EF:7C7BD8:5E3BD692}
2020.02.06 09:04:19 DEBUG ce[AXAZvhfbj2mf94ksGoUY][c.g.m.s.p.c.p.g.v.GraphqlCheckRunProvider] Received response: GraphQLResponseEntity{errors=null, headers=[Status:200 OK][null:HTTP/1.1 200 OK][Server:GitHub.com][Access-Control-Allow-Origin:*][X-Content-Type-Options:nosniff][X-RateLimit-Reset:1580981368][Date:Thu, 06 Feb 2020 09:04:19 GMT][Referrer-Policy:origin-when-cross-origin, strict-origin-when-cross-origin][X-Frame-Options:deny][Strict-Transport-Security:max-age=31536000; includeSubdomains; preload][Access-Control-Expose-Headers:ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type][X-RateLimit-Remaining:5246][Cache-Control:no-cache][X-GitHub-Media-Type:github.antiope-preview; format=json][Content-Security-Policy:default-src 'none'][Vary:Accept-Encoding][X-RateLimit-Limit:5250][X-XSS-Protection:1; mode=block][Content-Length:102][X-GitHub-Request-Id:EBA2:1251E:6849EF:7C7BD8:5E3BD692][Content-Type:application/json; charset=utf-8], response=com.github.mc1arke.sonarqube.plugin.ce.pullrequest.github.v4.CreateCheckRun@66f05c1c}
2020.02.06 09:04:19 INFO  ce[AXAZvhfbj2mf94ksGoUY][o.s.c.t.CeWorkerImpl] Executed task | project=com.avides.sonarqube-pr-dec:sonarqube-pr-decoration-test | type=REPORT | pullRequest=1 | id=AXAZvhfbj2mf94ksGoUY | submitter=github-actions | status=SUCCESS | time=5176ms

With GitHub Actions:

2020.02.06 09:05:44 INFO  ce[AXAZv3eOj2mf94ksGoUa][c.g.m.s.p.c.p.PullRequestPostAnalysisTask] using pull request decoratorGithub
2020.02.06 09:05:44 DEBUG ce[AXAZv3eOj2mf94ksGoUa][jdk.event.security] ValidationChain: -1410680354, -599509715, -1712238821
2020.02.06 09:05:44 DEBUG ce[AXAZv3eOj2mf94ksGoUa][jdk.event.security]  TLSHandshake: api.github.com:443, TLSv1.3, TLS_AES_128_GCM_SHA256, -1712238821
2020.02.06 09:05:44 DEBUG ce[AXAZv3eOj2mf94ksGoUa][s.n.w.p.h.HttpURLConnection] sun.net.www.MessageHeader@3dfdb8b96 pairs: {GET /app/installations HTTP/1.1: null}{Accept: application/vnd.github.machine-man-preview+json}{Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE1ODA5Nzk5MzQsImV4cCI6MTU4MDk4MDA1NCwiaXNzIjoiNDY3NTcifQ.Z-w4rTN0dJ1vBP_9UxK660o9r5XdUSfzGjcZEqjFQd2lK4NLtTi73fEWFoN7NQtVLf3jwQx_oEhT836-u-2KsDmH1jVlUfcbbzs5WUVjuZNNWd14aRz2kFiAKjKdigp9u5hAQ3OZfns5xmMl1X6ukqlgVpMEs_9qw9HvdegfnzJS-P8X85UkspgqhgdXax3UlhAU8WuEnMJ1Hax3o5Zxq_KEEfdideNx07fZsx42J75J9C0WVdMsD6RGLxtEsSL4BOHiUaXURphTS9DmjfoTC0yuRQegTvsU9YpHK25MUrwAbLtwMK4GfaD8ufe4WZG6Zi-TQWP80f2UZ4sXInQXMQ}{User-Agent: Java/11.0.5}{Host: api.github.com}{Connection: keep-alive}
2020.02.06 09:05:44 DEBUG ce[AXAZv3eOj2mf94ksGoUa][s.n.w.p.h.HttpURLConnection] sun.net.www.MessageHeader@4fbff0be20 pairs: {null: HTTP/1.1 200 OK}{Date: Thu, 06 Feb 2020 09:05:44 GMT}{Content-Type: application/json; charset=utf-8}{Content-Length: 1521}{Server: GitHub.com}{Status: 200 OK}{Cache-Control: public, max-age=60, s-maxage=60}{Vary: Accept}{ETag: "7f1cd4c1c866ab81a9534c9362f1c429"}{X-GitHub-Media-Type: github.machine-man-preview; format=json}{Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type}{Access-Control-Allow-Origin: *}{Strict-Transport-Security: max-age=31536000; includeSubdomains; preload}{X-Frame-Options: deny}{X-Content-Type-Options: nosniff}{X-XSS-Protection: 1; mode=block}{Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin}{Content-Security-Policy: default-src 'none'}{Vary: Accept-Encoding}{X-GitHub-Request-Id: EC0C:3FFCC:E113FB:10BDEFB:5E3BD6E8}
2020.02.06 09:05:44 DEBUG ce[AXAZv3eOj2mf94ksGoUa][s.n.w.p.h.HttpURLConnection] sun.net.www.MessageHeader@6f3887cf6 pairs: {POST /app/installations/5199089/access_tokens HTTP/1.1: null}{Accept: application/vnd.github.machine-man-preview+json}{Authorization: Bearer eyJhbGciOiJSUzI1NiJ9.eyJpYXQiOjE1ODA5Nzk5MzQsImV4cCI6MTU4MDk4MDA1NCwiaXNzIjoiNDY3NTcifQ.Z-w4rTN0dJ1vBP_9UxK660o9r5XdUSfzGjcZEqjFQd2lK4NLtTi73fEWFoN7NQtVLf3jwQx_oEhT836-u-2KsDmH1jVlUfcbbzs5WUVjuZNNWd14aRz2kFiAKjKdigp9u5hAQ3OZfns5xmMl1X6ukqlgVpMEs_9qw9HvdegfnzJS-P8X85UkspgqhgdXax3UlhAU8WuEnMJ1Hax3o5Zxq_KEEfdideNx07fZsx42J75J9C0WVdMsD6RGLxtEsSL4BOHiUaXURphTS9DmjfoTC0yuRQegTvsU9YpHK25MUrwAbLtwMK4GfaD8ufe4WZG6Zi-TQWP80f2UZ4sXInQXMQ}{User-Agent: Java/11.0.5}{Host: api.github.com}{Connection: keep-alive}
2020.02.06 09:05:44 DEBUG ce[AXAZv3eOj2mf94ksGoUa][s.n.w.p.h.HttpURLConnection] sun.net.www.MessageHeader@1b0f2e4920 pairs: {null: HTTP/1.1 201 Created}{Date: Thu, 06 Feb 2020 09:05:44 GMT}{Content-Type: application/json; charset=utf-8}{Content-Length: 234}{Server: GitHub.com}{Status: 201 Created}{Cache-Control: public, max-age=60, s-maxage=60}{Vary: Accept}{ETag: "adfb96d9b1f1e37c3353acf47c183692"}{X-GitHub-Media-Type: github.machine-man-preview; format=json}{Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type}{Access-Control-Allow-Origin: *}{Strict-Transport-Security: max-age=31536000; includeSubdomains; preload}{X-Frame-Options: deny}{X-Content-Type-Options: nosniff}{X-XSS-Protection: 1; mode=block}{Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin}{Content-Security-Policy: default-src 'none'}{Vary: Accept-Encoding}{X-GitHub-Request-Id: EC0C:3FFCC:E11424:10BDF24:5E3BD6E8}
2020.02.06 09:05:44 DEBUG ce[AXAZv3eOj2mf94ksGoUa][s.n.w.p.h.HttpURLConnection] sun.net.www.MessageHeader@4b6765e16 pairs: {GET /installation/repositories HTTP/1.1: null}{Accept: application/vnd.github.machine-man-preview+json}{Authorization: Bearer v1.6238c95ddec6440cd0fdc691c63de645cd7ab2b2}{User-Agent: Java/11.0.5}{Host: api.github.com}{Connection: keep-alive}
2020.02.06 09:05:45 DEBUG ce[AXAZv3eOj2mf94ksGoUa][s.n.w.p.h.HttpURLConnection] sun.net.www.MessageHeader@7b6d563323 pairs: {null: HTTP/1.1 200 OK}{Date: Thu, 06 Feb 2020 09:05:45 GMT}{Content-Type: application/json; charset=utf-8}{Content-Length: 124454}{Server: GitHub.com}{Status: 200 OK}{X-RateLimit-Limit: 5250}{X-RateLimit-Remaining: 5245}{X-RateLimit-Reset: 1580981368}{Cache-Control: private, max-age=60, s-maxage=60}{Vary: Accept, Authorization, Cookie, X-GitHub-OTP}{ETag: "c832a837d7082ad952d8918ab465c741"}{X-GitHub-Media-Type: github.machine-man-preview; format=json}{Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type}{Access-Control-Allow-Origin: *}{Strict-Transport-Security: max-age=31536000; includeSubdomains; preload}{X-Frame-Options: deny}{X-Content-Type-Options: nosniff}{X-XSS-Protection: 1; mode=block}{Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin}{Content-Security-Policy: default-src 'none'}{Vary: Accept-Encoding}{X-GitHub-Request-Id: EC0C:3FFCC:E1145B:10BDF63:5E3BD6E8}
2020.02.06 09:05:45 DEBUG ce[AXAZv3eOj2mf94ksGoUa][c.g.m.s.p.c.p.g.v.GraphqlCheckRunProvider] Using request: mutation { createCheckRun (input:{conclusion:SUCCESS,output:{summary:"![Passed](https://raw.githubusercontent.com/mc1arke/sonarqube-community-branch-plugin/master/src/main/resources/pr-decoration-images/checks/QualityGateBadge/passed.svg?sanitize=true)

# Analysis Details
## 0 Issues
- ![Bug](https://raw.githubusercontent.com/mc1arke/sonarqube-community-branch-plugin/master/src/main/resources/pr-decoration-images/common/bug.svg?sanitize=true) 0 Bugs
- ![Vulnerability](https://raw.githubusercontent.com/mc1arke/sonarqube-community-branch-plugin/master/src/main/resources/pr-decoration-images/common/vulnerability.svg?sanitize=true) 0 Vulnerabilities
- ![Code Smell](https://raw.githubusercontent.com/mc1arke/sonarqube-community-branch-plugin/master/src/main/resources/pr-decoration-images/common/vulnerability.svg?sanitize=true) 0 Code Smells

## Coverage and Duplications
- ![No coverage information](https://raw.githubusercontent.com/mc1arke/sonarqube-community-branch-plugin/master/src/main/resources/pr-decoration-images/checks/CoverageChart/NoCoverageInfo.svg?sanitize=true) No coverage information (0.00% Estimated after merge)
- ![No duplication information](https://raw.githubusercontent.com/mc1arke/sonarqube-community-branch-plugin/master/src/main/resources/pr-decoration-images/checks/Duplications/NoDuplicationInfo.svg?sanitize=true) No duplication information (0.00% Estimated after merge)

[View in SonarQube](https://sonarqube-server/dashboard?id=com.avides.sonarqube-pr-dec%3Asonarqube-pr-decoration-test&pullRequest=1)",annotations:[],title:"Quality Gate success"},completedAt:"2020-02-06T09:05:45Z",detailsUrl:"https://sonarqube-server/dashboard?id=com.avides.sonarqube-pr-dec%3Asonarqube-pr-decoration-test&pullRequest=1",repositoryId:"MDEwOlJlcG9zaXRvcnkyMzUxMzUyODA=",name:"sonarqube-avides Results",startedAt:"2020-02-06T09:05:37Z",externalId:"AXAZv3guZMDBAUGhho2N",headSha:"fe013614ba7b987c2954750cd589500ffb9a67a2",status:COMPLETED}) { clientMutationId checkRun { id } } } 
2020.02.06 09:05:45 DEBUG ce[AXAZv3eOj2mf94ksGoUa][s.n.w.p.h.HttpURLConnection] sun.net.www.MessageHeader@6bc11f411 pairs: {POST /graphql HTTP/1.1: null}{Content-Type: application/json}{Accept: application/vnd.github.antiope-preview+json}{charset: utf-8}{Authorization: Bearer v1.6238c95ddec6440cd0fdc691c63de645cd7ab2b2}{Cache-Control: no-cache}{Pragma: no-cache}{User-Agent: Java/11.0.5}{Host: api.github.com}{Connection: keep-alive}{Content-Length: 2074}
2020.02.06 09:05:45 DEBUG ce[AXAZv3eOj2mf94ksGoUa][s.n.w.p.h.HttpURLConnection] sun.net.www.MessageHeader@49a63d9321 pairs: {null: HTTP/1.1 200 OK}{Date: Thu, 06 Feb 2020 09:05:45 GMT}{Content-Type: application/json; charset=utf-8}{Content-Length: 102}{Server: GitHub.com}{Status: 200 OK}{Cache-Control: no-cache}{X-GitHub-Media-Type: github.antiope-preview; format=json}{X-RateLimit-Limit: 5250}{X-RateLimit-Remaining: 5245}{X-RateLimit-Reset: 1580981368}{Access-Control-Expose-Headers: ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type}{Access-Control-Allow-Origin: *}{Strict-Transport-Security: max-age=31536000; includeSubdomains; preload}{X-Frame-Options: deny}{X-Content-Type-Options: nosniff}{X-XSS-Protection: 1; mode=block}{Referrer-Policy: origin-when-cross-origin, strict-origin-when-cross-origin}{Content-Security-Policy: default-src 'none'}{Vary: Accept-Encoding}{X-GitHub-Request-Id: EC0C:3FFCC:E11504:10BE02D:5E3BD6E9}
2020.02.06 09:05:45 DEBUG ce[AXAZv3eOj2mf94ksGoUa][c.g.m.s.p.c.p.g.v.GraphqlCheckRunProvider] Received response: GraphQLResponseEntity{errors=null, headers=[Status:200 OK][null:HTTP/1.1 200 OK][Server:GitHub.com][Access-Control-Allow-Origin:*][X-Content-Type-Options:nosniff][X-RateLimit-Reset:1580981368][Date:Thu, 06 Feb 2020 09:05:45 GMT][Referrer-Policy:origin-when-cross-origin, strict-origin-when-cross-origin][X-Frame-Options:deny][Strict-Transport-Security:max-age=31536000; includeSubdomains; preload][Access-Control-Expose-Headers:ETag, Link, Location, Retry-After, X-GitHub-OTP, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset, X-OAuth-Scopes, X-Accepted-OAuth-Scopes, X-Poll-Interval, X-GitHub-Media-Type][X-RateLimit-Remaining:5245][Cache-Control:no-cache][X-GitHub-Media-Type:github.antiope-preview; format=json][Content-Security-Policy:default-src 'none'][Vary:Accept-Encoding][X-RateLimit-Limit:5250][X-XSS-Protection:1; mode=block][Content-Length:102][X-GitHub-Request-Id:EC0C:3FFCC:E11504:10BE02D:5E3BD6E9][Content-Type:application/json; charset=utf-8], response=com.github.mc1arke.sonarqube.plugin.ce.pullrequest.github.v4.CreateCheckRun@56122c3c}
2020.02.06 09:05:45 INFO  ce[AXAZv3eOj2mf94ksGoUa][o.s.c.t.CeWorkerImpl] Executed task | project=com.avides.sonarqube-pr-dec:sonarqube-pr-decoration-test | type=REPORT | pullRequest=1 | id=AXAZv3eOj2mf94ksGoUa | submitter=github-actions | status=SUCCESS | time=2428ms

Here is the public repository: https://github.com/avides/sonarqube-pr-decoration-test/pull/1

This build was triggered from Command Line:
https://github.com/avides/sonarqube-pr-decoration-test/pull/1/checks?sha=2a314b3316668968c92691243ebab32ce53a78a5

This build was triggered by GitHub Actions:
https://github.com/avides/sonarqube-pr-decoration-test/pull/1/checks?sha=37dc20897256e77b545cdc07f8283aa8cdafeed7

Is there any plan to support bitbucket cloud pull request decoration? I would assume the API would be more or less the same - however bitbucket cloud does not support app password, but oauth authentication - based on what I saw there is an API operation to retrieve app password based on those parameters which can be used in bearer token as basic authentication later on.

@goober @mc1arke We all need to pitch in and buy you guys some beers or something, amazing work.
Question, How do i enable bitbucket server decorator, i have a url and a token and was browsing through the PRs here to try to figure out which sonarqube property i need to set for that to happen.
here's what i have and it doesn't appear to do anything, probably because i mushed together configs from two different PRs.

sonar.pullrequest.provider=BitbucketServer 
sonar.pullrequest.bitbucket.token=REDACTED
sonar.pullrequest.bitbucket.endpoint=https://bitbucket.example.com

Never mind. I just realized it was not in the latest release. Building from source works.
Couple of things that i found:

  1. Is there no way to specify the
-D com.github.mc1arke.sonarqube.plugin.branch.pullrequest.bitbucket.projectKey=KEY 
-D com.github.mc1arke.sonarqube.plugin.branch.pullrequest.bitbucket.repositorySlug=SLUG

via scanner invocation? It doesn't appear to work for me. Manually setting these in the project settings will be tedious for hundreds of repos.
2. It appears that pull request comments somehow breaks jenkins's wait for quality gate feature.

   def waitForScan() {
      script.withSonarQubeEnv("${script.env.SONARQUBE}") {
         script.timeout(time: 120, unit: 'MINUTES') {
            script.waitForQualityGate abortPipeline: true
         }
      }
   }

With the above code what i get in jenkins logs is:

org.sonarqube.ws.client.HttpException: Error 404 on https://sonarqube.example.com/api/qualitygates/project_status?analysisId=AXA4ZVJqJ-SZM71PvHG0 : {"errors":[{"msg":"Analysis with id 'AXA4ZVJqJ-SZM71PvHG0' is not found"}]}

Which is quite correct. I can't figure out where it comes up with this analysis ID.

EDIT: point 2 was internal issue. Works fine now with sonarqube 8.1 and latest snapshot from sq81 branch

Hi there, I'm working on a bitbucket cloud integration and was already testing the API authentication. It seems that we can use app passwords for the authentication. At least I was able to call the related endpoints successfully.

However, using app password for this would require the integrator (i.e. you and me) to have an additional (mostly paid) user just for sonarqube (yes, you could use your own user but I personally wouldn't do that as it looks kinda weird, right?). That's why I'm unsure if we should continue using this approach or come up with something different. In the end at least I wouldn't mind that but if it can be done easier (OAuth) then I'd also be up for that.

Sources: https://confluence.atlassian.com/bitbucket/app-passwords-828781300.html

Ideas?

@mc1arke any idea about my problems above?

@loefflefarn from the logs you gave, the plugin was finding a commit to comment on, but that commit wasn't visible whilst browsing your repository in the UI. From looking at the logs for the various Github actions you fired, I can see that they use a ref to checkout a specific Pull Request, however I couldn't tell from your logs and repository what that commit actually was. Given you'd had multiple attempts at running your actions with various commits in-between, I wasn't able to pinpoint exactly which action execution matched up to your Sonarqube log, so couldn't tell if you'd potentially forced pushed over a commit, or if Github had effectively removed the original ref at the point you pushed more commits.

I'm going to close this current issue just now since it's moved from being an feature request (which has been delivered) to covering issues people have discovered whilst testing that feature. Could you see if you can re-create the issue without over-writing any relevant evidence (i.e. only fire the action once) and raise it in a new issue please?

Delivered in 1.3.0