Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pr decoration fix IllegalStateException NO_VALUE #44

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ Either build the project or [download a compatible release version of the plugin

# Features
The plugin is intended to support the [features and parameters specified in the SonarQube documentation](https://docs.sonarqube.org/latest/branches/overview/), with the following caveats
* __Pull Requests:__ Analysis of Pull Requests is fully supported, but the decoration of pull requests with any issues is not currently supported
* __Pull Requests:__ Analysis of Pull Requests is fully supported, but the decoration of pull requests is only currently available for Github, and only as an experimental feature
5 changes: 5 additions & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ group 'com.github.mc1arke.sonarqube.plugin'

repositories {
mavenCentral()
maven {
url 'https://dl.bintray.com/americanexpress/maven/'
}
ivy {
url 'https://binaries.sonarsource.com/'
patternLayout({a ->
Expand Down Expand Up @@ -59,6 +62,8 @@ dependencies {
testCompile group: 'junit', name: 'junit', version: '4.12'
testCompile group: 'org.mockito', name: 'mockito-core', version: '2.24.0'
zip "sonarqube:sonarqube:${sonarqubeVersion}@zip"
compile 'org.bouncycastle:bcpkix-jdk15on:1.62'
compile 'io.aexp.nodes.graphql:nodes:0.5.0'
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,9 @@
*/
public class CommunityBranchPlugin implements Plugin {

private static final String PULL_REQUEST_CATEGORY_LABEL = "Pull Request";
private static final String GITHUB_INTEGRATION_SUBCATEGORY_LABEL = "Integration With Github";

@Override
public void define(Context context) {
if (SonarQubeSide.SCANNER == context.getRuntime().getSonarQubeSide()) {
Expand All @@ -64,7 +67,39 @@ public void define(Context context) {
//the name and description shown on the UI are automatically loaded from core.properties so don't need to be specified here
PropertyDefinition.builder(CoreProperties.LONG_LIVED_BRANCHES_REGEX).onQualifiers(Qualifiers.PROJECT)
.category(CoreProperties.CATEGORY_GENERAL).subCategory(CoreProperties.SUBCATEGORY_BRANCHES)
.defaultValue(CommunityBranchConfigurationLoader.DEFAULT_BRANCH_REGEX).build());
.defaultValue(CommunityBranchConfigurationLoader.DEFAULT_BRANCH_REGEX).build(),

PropertyDefinition.builder("sonar.pullrequest.provider").subCategory(PULL_REQUEST_CATEGORY_LABEL)
.subCategory("General")
.onlyOnQualifiers(Qualifiers.PROJECT).name("Provider").type(PropertyType.SINGLE_SELECT_LIST)
.options("Github").build(),

PropertyDefinition.builder("sonar.alm.github.app.privateKey.secured")
.subCategory(PULL_REQUEST_CATEGORY_LABEL).subCategory(GITHUB_INTEGRATION_SUBCATEGORY_LABEL)
.onQualifiers(Qualifiers.APP).name("App Private Key")
.type(PropertyType.PASSWORD).build(),

PropertyDefinition.builder("sonar.alm.github.app.name").subCategory(PULL_REQUEST_CATEGORY_LABEL)
.subCategory(GITHUB_INTEGRATION_SUBCATEGORY_LABEL).onQualifiers(Qualifiers.APP).name("App Name")
.defaultValue("SonarQube Community Pull Request Analysis").type(PropertyType.STRING).build(),

PropertyDefinition.builder("sonar.alm.github.app.id").subCategory(PULL_REQUEST_CATEGORY_LABEL)
.subCategory(GITHUB_INTEGRATION_SUBCATEGORY_LABEL).onQualifiers(Qualifiers.APP).name("App ID")
.type(PropertyType.STRING).build(),

PropertyDefinition.builder("sonar.pullrequest.github.repository")
.subCategory(PULL_REQUEST_CATEGORY_LABEL).subCategory(GITHUB_INTEGRATION_SUBCATEGORY_LABEL)
.onlyOnQualifiers(Qualifiers.PROJECT)
.name("Repository identifier").description("Example: SonarSource/sonarqube")
.type(PropertyType.STRING).build(),

PropertyDefinition.builder("sonar.pullrequest.github.endpoint").subCategory(PULL_REQUEST_CATEGORY_LABEL)
.subCategory(GITHUB_INTEGRATION_SUBCATEGORY_LABEL).onQualifiers(Qualifiers.APP)
.name("The API URL for a GitHub instance").description(
"The API url for a GitHub instance. https://api.github.com/ for github.com, https://github.company.com/api/ when using GitHub Enterprise")
.type(PropertyType.STRING).defaultValue("https://api.github.com").build()

);

}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,12 @@
*/
package com.github.mc1arke.sonarqube.plugin.ce;

import com.github.mc1arke.sonarqube.plugin.ce.pullrequest.PostAnalysisIssueVisitor;
import com.github.mc1arke.sonarqube.plugin.ce.pullrequest.PullRequestPostAnalysisTask;
import com.github.mc1arke.sonarqube.plugin.ce.pullrequest.github.GithubPullRequestDecorator;
import org.sonar.ce.task.projectanalysis.container.ReportAnalysisComponentProvider;

import java.util.Collections;
import java.util.Arrays;
import java.util.List;

/**
Expand All @@ -30,7 +33,8 @@ public class CommunityReportAnalysisComponentProvider implements ReportAnalysisC

@Override
public List<Object> getComponents() {
return Collections.singletonList(CommunityBranchLoaderDelegate.class);
return Arrays.asList(CommunityBranchLoaderDelegate.class, PullRequestPostAnalysisTask.class,
PostAnalysisIssueVisitor.class, GithubPullRequestDecorator.class);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/*
* Copyright (C) 2019 Michael Clarke
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
package com.github.mc1arke.sonarqube.plugin.ce.pullrequest;

import org.sonar.ce.task.projectanalysis.component.Component;
import org.sonar.ce.task.projectanalysis.issue.IssueVisitor;
import org.sonar.core.issue.DefaultIssue;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class PostAnalysisIssueVisitor extends IssueVisitor {

private final List<DefaultIssue> collectedIssues = new ArrayList<>();

@Override
public void onIssue(Component component, DefaultIssue defaultIssue) {
collectedIssues.add(defaultIssue);
}

public List<DefaultIssue> getIssues() {
return Collections.unmodifiableList(collectedIssues);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright (C) 2019 Michael Clarke
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
package com.github.mc1arke.sonarqube.plugin.ce.pullrequest;

import org.sonar.api.ce.posttask.PostProjectAnalysisTask;

public interface PullRequestBuildStatusDecorator {

String name();

void decorateQualityGateStatus(PostProjectAnalysisTask.ProjectAnalysis projectAnalysis);

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* Copyright (C) 2019 Michael Clarke
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
package com.github.mc1arke.sonarqube.plugin.ce.pullrequest;

import org.sonar.api.ce.posttask.Branch;
import org.sonar.api.ce.posttask.PostProjectAnalysisTask;
import org.sonar.api.config.Configuration;
import org.sonar.api.utils.log.Logger;
import org.sonar.api.utils.log.Loggers;
import org.sonar.ce.task.projectanalysis.component.ConfigurationRepository;

import java.util.List;
import java.util.Optional;

public class PullRequestPostAnalysisTask implements PostProjectAnalysisTask {

private static final Logger LOGGER = Loggers.get(PullRequestPostAnalysisTask.class);

private final List<PullRequestBuildStatusDecorator> pullRequestDecorators;
private final ConfigurationRepository configurationRepository;

public PullRequestPostAnalysisTask(ConfigurationRepository configurationRepository,
List<PullRequestBuildStatusDecorator> pullRequestDecorators) {
super();
this.configurationRepository = configurationRepository;
this.pullRequestDecorators = pullRequestDecorators;
}

@Override
public void finished(PostProjectAnalysisTask.ProjectAnalysis projectAnalysis) {
if (!projectAnalysis.getBranch().filter(branch -> Branch.Type.PULL_REQUEST == branch.getType()).isPresent()) {
LOGGER.trace("Current analysis is not for a Pull Request. Task being skipped");
return;
}

Optional<PullRequestBuildStatusDecorator> optionalPullRequestDecorator =
findCurrentPullRequestStatusDecorator(configurationRepository.getConfiguration(),
pullRequestDecorators);

if (!optionalPullRequestDecorator.isPresent()) {
LOGGER.info("No decorator found for this Pull Request");
return;
}

PullRequestBuildStatusDecorator pullRequestDecorator = optionalPullRequestDecorator.get();
pullRequestDecorator.decorateQualityGateStatus(projectAnalysis);

}

private static Optional<PullRequestBuildStatusDecorator> findCurrentPullRequestStatusDecorator(
Configuration configuration, List<PullRequestBuildStatusDecorator> pullRequestDecorators) {

Optional<String> optionalImplementationName = configuration.get("sonar.pullrequest.provider");

if (!optionalImplementationName.isPresent()) {
LOGGER.debug("'sonar.pullrequest.provider' property not set");
return Optional.empty();
}

String implementationName = optionalImplementationName.get();

for (PullRequestBuildStatusDecorator pullRequestDecorator : pullRequestDecorators) {
if (pullRequestDecorator.name().equals(implementationName)) {
return Optional.of(pullRequestDecorator);
}
}

LOGGER.warn("No decorator could be found matching " + implementationName);
return Optional.empty();
}
}
Loading