Skip to content

Commit

Permalink
[JENKINS-33318] Conflicts with upstream/master
Browse files Browse the repository at this point in the history
  • Loading branch information
recena committed Apr 18, 2016
2 parents 0748599 + 844f9c0 commit 819673c
Show file tree
Hide file tree
Showing 19 changed files with 478 additions and 150 deletions.
4 changes: 4 additions & 0 deletions .gitignore
Expand Up @@ -2,3 +2,7 @@ target
work
/github-branch-source.iml
/.idea
.classpath
.project
.settings
bin
26 changes: 20 additions & 6 deletions pom.xml
Expand Up @@ -7,11 +7,11 @@
<version>2.3</version>
</parent>
<artifactId>github-branch-source</artifactId>
<version>1.4-SNAPSHOT</version>
<version>1.6-SNAPSHOT</version>
<packaging>hpi</packaging>
<name>CloudBees GitHub Branch Source Plugin</name>
<name>GitHub Branch Source Plugin</name>
<url>https://wiki.jenkins-ci.org/display/JENKINS/CloudBees+GitHub+Branch+Source+Plugin</url>
<description>Multibranch projects and organization folders from GitHub.</description>
<description>Multibranch projects and organization folders from GitHub. Maintained by CloudBees, Inc.</description>
<licenses>
<license>
<name>MIT</name>
Expand All @@ -21,6 +21,7 @@

<properties>
<jenkins.version>1.609.3</jenkins.version>
<workflow.version>1.15</workflow.version>
</properties>

<scm>
Expand All @@ -33,7 +34,7 @@
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>scm-api</artifactId>
<version>1.0</version>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
Expand All @@ -48,10 +49,10 @@
</exclusions>
</dependency>
<dependency>
<!-- Update when 1.74 is released -->
<groupId>org.jenkins-ci.plugins</groupId>
<artifactId>github-api</artifactId>
<version>1.74-SNAPSHOT</version>
<!-- Update when 1.75 is released -->
<version>1.75-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins</groupId>
Expand All @@ -63,6 +64,19 @@
<artifactId>github</artifactId>
<version>1.14.0</version>
</dependency>
<!-- Currently just here for interactive testing via hpi:run: -->
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-aggregator</artifactId>
<version>${workflow.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.jenkins-ci.plugins.workflow</groupId>
<artifactId>workflow-multibranch</artifactId>
<version>${workflow.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<repositories>
<repository>
Expand Down
Expand Up @@ -24,6 +24,7 @@

package org.jenkinsci.plugins.github_branch_source;

import com.cloudbees.jenkins.GitHubWebHook;
import com.cloudbees.plugins.credentials.CredentialsMatcher;
import com.cloudbees.plugins.credentials.CredentialsMatchers;
import com.cloudbees.plugins.credentials.CredentialsProvider;
Expand All @@ -33,19 +34,33 @@
import com.cloudbees.plugins.credentials.common.StandardUsernamePasswordCredentials;
import com.cloudbees.plugins.credentials.domains.DomainRequirement;
import com.cloudbees.plugins.credentials.domains.URIRequirementBuilder;
import com.google.common.hash.Hashing;
import com.squareup.okhttp.Cache;
import com.squareup.okhttp.OkHttpClient;
import com.squareup.okhttp.OkUrlFactory;
import hudson.Util;
import hudson.security.ACL;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.Proxy;
import java.util.List;
import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;

import jenkins.model.Jenkins;
import jenkins.scm.api.SCMSourceOwner;
import org.apache.commons.lang.StringUtils;
import org.jenkinsci.plugins.gitclient.GitClient;
import org.jenkinsci.plugins.github.config.GitHubServerConfig;
import org.jenkinsci.plugins.github.internal.GitHubClientCacheOps;
import org.kohsuke.github.GitHub;
import org.kohsuke.github.GitHubBuilder;
import org.kohsuke.github.RateLimitHandler;
import org.kohsuke.github.extras.OkHttpConnector;

import static org.apache.commons.lang3.StringUtils.*;
import static org.jenkinsci.plugins.github.config.GitHubServerConfig.GITHUB_URL;
import static org.jenkinsci.plugins.github.internal.GitHubClientCacheOps.toCacheDir;

/**
* Utilities that could perhaps be moved into {@code github-api}.
Expand All @@ -69,27 +84,43 @@ public class Connector {
}

public static @Nonnull GitHub connect(@CheckForNull String apiUri, @CheckForNull StandardCredentials credentials) throws IOException {
if (Util.fixEmptyAndTrim(apiUri) == null) {
if (credentials == null) {
return new GitHubBuilder().withRateLimitHandler(CUSTOMIZED).build();
} else if (credentials instanceof StandardUsernamePasswordCredentials) {
StandardUsernamePasswordCredentials c = (StandardUsernamePasswordCredentials) credentials;
return GitHub.connectUsingPassword(c.getUsername(), c.getPassword().getPlainText());
} else {
// TODO OAuth support
throw new IOException("Unsupported credential type: " + credentials.getClass().getName());
}
GitHubServerConfig config = new GitHubServerConfig(credentials!=null ? credentials.getId() : null);
String apiUrl = Util.fixEmptyAndTrim(apiUri);
if (apiUrl !=null) {
config.setCustomApiUrl(true);
config.setApiUrl(apiUrl);
}

// Can't do this until github plugin support username/password
// GitHub gh = GitHubServerConfig.loginToGithub().apply(config);

GitHubBuilder gb = new GitHubBuilder();

if (apiUrl !=null) {
gb.withEndpoint(apiUrl);
}

gb.withRateLimitHandler(CUSTOMIZED);
OkHttpClient client = new OkHttpClient().setProxy(getProxy(defaultIfBlank(apiUrl, GITHUB_URL)));
client.setCache(GitHubClientCacheOps.toCacheDir().apply(config));
if (config.getClientCacheSize() > 0) {
Cache cache = toCacheDir().apply(config);
client.setCache(cache);
}

gb.withConnector(new OkHttpConnector(new OkUrlFactory(client)));

if (credentials == null) {
// nothing further to configure
} else if (credentials instanceof StandardUsernamePasswordCredentials) {
StandardUsernamePasswordCredentials c = (StandardUsernamePasswordCredentials) credentials;
gb.withPassword(c.getUsername(), c.getPassword().getPlainText());
} else {
if (credentials == null) {
return GitHub.connectToEnterprise(apiUri, null, null);
} else if (credentials instanceof StandardUsernamePasswordCredentials) {
StandardUsernamePasswordCredentials c = (StandardUsernamePasswordCredentials) credentials;
return GitHub.connectToEnterprise(apiUri, c.getUsername(), c.getPassword().getPlainText());
} else {
// TODO OAuth support
throw new IOException("Unsupported credential type: " + credentials.getClass().getName());
}
// TODO OAuth support
throw new IOException("Unsupported credential type: " + credentials.getClass().getName());
}

return gb.build();
}

public static void fillScanCredentialsIdItems(StandardListBoxModel result, @CheckForNull SCMSourceOwner context, @CheckForNull String apiUri) {
Expand All @@ -109,6 +140,36 @@ private static List<DomainRequirement> githubDomainRequirements(String apiUri) {
return URIRequirementBuilder.fromUri(StringUtils.defaultIfEmpty(apiUri, "https://github.com")).build();
}

/**
* Uses proxy if configured on pluginManager/advanced page
*
* @param apiUrl GitHub's url to build proxy to
*
* @return proxy to use it in connector. Should not be null as it can lead to unexpected behaviour
*/
@Nonnull
private static Proxy getProxy(String apiUrl) {
Jenkins jenkins = GitHubWebHook.getJenkinsInstance();

if (jenkins.proxy == null) {
return Proxy.NO_PROXY;
} else {
return jenkins.proxy.createProxy(apiUrl);
}
}

/**
* @param config url and creds id to be hashed
*
* @return unique id for folder name to create cache inside of base cache dir
*/
private static String hashed(GitHubServerConfig config) {
return Hashing.murmur3_32().newHasher()
.putString(trimToEmpty(config.getApiUrl()))
.putString(trimToEmpty(config.getCredentialsId())).hash().toString();
}


private Connector() {}

/**
Expand Down
Expand Up @@ -92,29 +92,38 @@ private static void createBuildCommitStatus(Run<?,?> build, TaskListener listene
} catch (IllegalStateException ise) {
url = "http://unconfigured-jenkins-location/" + build.getUrl();
}
Result result = build.getResult();
String revisionToNotify = resolveHeadCommit(repo, revision);
if (Result.SUCCESS.equals(result)) {
createCommitStatus(repo, revisionToNotify, GHCommitState.SUCCESS, url, Messages.GitHubBuildStatusNotification_CoomitStatus_Good());
} else if (Result.UNSTABLE.equals(result)) {
createCommitStatus(repo, revisionToNotify, GHCommitState.FAILURE, url, Messages.GitHubBuildStatusNotification_CommitStatus_Unstable());
} else if (Result.FAILURE.equals(result)) {
createCommitStatus(repo, revisionToNotify, GHCommitState./* TODO or ERROR? */FAILURE, url, Messages.GitHubBuildStatusNotification_CommitStatus_Failure());
} else if (result != null) { // ABORTED etc.
createCommitStatus(repo, revisionToNotify, GHCommitState.ERROR, url, Messages.GitHubBuildStatusNotification_CommitStatus_Other());
} else {
createCommitStatus(repo, revisionToNotify, GHCommitState.PENDING, url, Messages.GitHubBuildStatusNotification_CommitStatus_Pending());
}
if (result != null) {
listener.getLogger().format("%n" + Messages.GitHubBuildStatusNotification_CommitStatusSet() + "%n%n");
boolean ignoreError = false;
try {
Result result = build.getResult();
String revisionToNotify = resolveHeadCommit(repo, revision);
if (Result.SUCCESS.equals(result)) {
createCommitStatus(repo, revisionToNotify, GHCommitState.SUCCESS, url, Messages.GitHubBuildStatusNotification_CommitStatus_Good());
} else if (Result.UNSTABLE.equals(result)) {
createCommitStatus(repo, revisionToNotify, GHCommitState.FAILURE, url, Messages.GitHubBuildStatusNotification_CommitStatus_Unstable());
} else if (Result.FAILURE.equals(result)) {
createCommitStatus(repo, revisionToNotify, GHCommitState.FAILURE, url, Messages.GitHubBuildStatusNotification_CommitStatus_Failure());
} else if (result != null) { // ABORTED etc.
createCommitStatus(repo, revisionToNotify, GHCommitState.ERROR, url, Messages.GitHubBuildStatusNotification_CommitStatus_Other());
} else {
ignoreError = true;
createCommitStatus(repo, revisionToNotify, GHCommitState.PENDING, url, Messages.GitHubBuildStatusNotification_CommitStatus_Pending());
}
if (result != null) {
listener.getLogger().format("%n" + Messages.GitHubBuildStatusNotification_CommitStatusSet() + "%n%n");
}
} catch (FileNotFoundException fnfe) {
if (!ignoreError) {
listener.getLogger().format("%nCould not update commit status, please check if your scan " +
"credentials belong to a member of the organization or a collaborator of the " +
"repository and repo:status scope is selected%n%n");
LOGGER.log(Level.FINE, null, fnfe);
}
}
}
}
} catch (FileNotFoundException fnfe) {
listener.getLogger().format("%nCould not update commit status, please check if your scan credentials belong to a member of the organization or a collaborator of the repository%n%n");
} catch (IOException ioe) {
listener.getLogger().format("%nCould not update commit status. Message: %s%n%n", ioe.getMessage());
LOGGER.log(Level.WARNING, "Could not update commit status", ioe);
LOGGER.log(Level.FINE, "Could not update commit status", ioe);
}

}
Expand Down Expand Up @@ -167,7 +176,7 @@ private static GitHubSCMSource getSCMSource(final SCMSourceOwner scmSourceOwner)
@Extension public static class PRJobScheduledListener extends QueueListener {

/**
* Manages the Github Commit Pending Status.
* Manages the GitHub Commit Pending Status.
*/
@Override public void onEnterWaiting(Queue.WaitingItem wi) {
if (wi.task instanceof Job) {
Expand All @@ -191,8 +200,12 @@ private static GitHubSCMSource getSCMSource(final SCMSourceOwner scmSourceOwner)
// In fact the submitter might push another commit before this build even starts.
createCommitStatus(repo, pr.getHead().getSha(), GHCommitState.PENDING, url, "This pull request is scheduled to be built");
}
} catch (FileNotFoundException fnfe) {
LOGGER.log(Level.WARNING, "Could not update commit status to PENDING. Valid scan credentials? Valid scopes?");
LOGGER.log(Level.FINE, null, fnfe);
} catch (IOException ioe) {
LOGGER.log(Level.WARNING, "Could not update commit status", ioe);
LOGGER.log(Level.WARNING, "Could not update commit status to PENDING. Message: " + ioe.getMessage());
LOGGER.log(Level.FINE, null, ioe);
}
}
}
Expand All @@ -202,6 +215,7 @@ private static GitHubSCMSource getSCMSource(final SCMSourceOwner scmSourceOwner)

/**
* With this listener one notifies to GitHub when the SCM checkout process has started.
* Possible option: GHCommitState.PENDING
*/
@Extension public static class JobCheckOutListener extends SCMListener {

Expand All @@ -213,10 +227,10 @@ private static GitHubSCMSource getSCMSource(final SCMSourceOwner scmSourceOwner)

/**
* With this listener one notifies to GitHub the build result.
* Possible options: GHCommitState.SUCCESS, GHCommitState.ERROR or GHCommitState.FAILURE
*/
@Extension public static class JobCompletedListener extends RunListener<Run<?,?>> {

@SuppressWarnings("deprecation") // Run.getAbsoluteUrl appropriate here
@Override public void onCompleted(Run<?, ?> build, TaskListener listener) {
createBuildCommitStatus(build, listener);
}
Expand Down

0 comments on commit 819673c

Please sign in to comment.