diff --git a/src/main/java/org/jenkinsci/plugins/github_branch_source/GitHubRepoSizeEstimator.java b/src/main/java/org/jenkinsci/plugins/github_branch_source/GitHubRepoSizeEstimator.java new file mode 100644 index 000000000..68cda612f --- /dev/null +++ b/src/main/java/org/jenkinsci/plugins/github_branch_source/GitHubRepoSizeEstimator.java @@ -0,0 +1,44 @@ +package org.jenkinsci.plugins.github_branch_source; + +import com.cloudbees.plugins.credentials.common.StandardCredentials; +import hudson.Extension; +import hudson.model.Item; +import jenkins.plugins.git.GitToolChooser; +import org.kohsuke.github.GHRepository; +import org.kohsuke.github.GitHub; + +public class GitHubRepoSizeEstimator { + /** + * This extension intends to perform a GET request without any credentials on the provided + * repository URL to return the size of repository. + */ + @Extension + public static class RepositorySizeGithubAPI extends GitToolChooser.RepositorySizeAPI { + + @Override + public boolean isApplicableTo(String repoUrl, Item context, String credentialsId) { + StandardCredentials credentials = + Connector.lookupScanCredentials(context, repoUrl, credentialsId); + try { + GitHubRepositoryInfo info = GitHubRepositoryInfo.forRepositoryUrl(repoUrl); + GitHub gitHub = Connector.connect(info.getApiUri(), credentials); + gitHub.checkApiUrlValidity(); + } catch (Exception e) { + return false; + } + return true; + } + + @Override + public Long getSizeOfRepository(String repoUrl, Item context, String credentialsId) + throws Exception { + StandardCredentials credentials = + Connector.lookupScanCredentials(context, repoUrl, credentialsId); + GitHubRepositoryInfo info = GitHubRepositoryInfo.forRepositoryUrl(repoUrl); + GitHub github = Connector.connect(info.getApiUri(), credentials); + GHRepository ghRepository = + github.getRepository(info.getRepoOwner() + '/' + info.getRepository()); + return (long) ghRepository.getSize(); + } + } +} diff --git a/src/test/java/org/jenkinsci/plugins/github_branch_source/GitHubRepoSizeEstimatorTest.java b/src/test/java/org/jenkinsci/plugins/github_branch_source/GitHubRepoSizeEstimatorTest.java new file mode 100644 index 000000000..5111ef3a9 --- /dev/null +++ b/src/test/java/org/jenkinsci/plugins/github_branch_source/GitHubRepoSizeEstimatorTest.java @@ -0,0 +1,81 @@ +package org.jenkinsci.plugins.github_branch_source; + +import static com.github.tomakehurst.wiremock.client.WireMock.*; +import static com.github.tomakehurst.wiremock.client.WireMock.aResponse; +import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; + +import com.cloudbees.plugins.credentials.*; +import com.cloudbees.plugins.credentials.common.StandardCredentials; +import com.cloudbees.plugins.credentials.domains.Domain; +import com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl; +import hudson.model.Item; +import java.util.Collections; +import jenkins.model.Jenkins; +import jenkins.plugins.git.GitToolChooser; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.jvnet.hudson.test.JenkinsRule; +import org.mockito.Mockito; + +@RunWith(Parameterized.class) +public class GitHubRepoSizeEstimatorTest extends GitSCMSourceBase { + + public GitHubRepoSizeEstimatorTest(GitHubSCMSource source) { + this.source = source; + } + + @Parameterized.Parameters(name = "{index}: revision={0}") + public static GitHubSCMSource[] revisions() { + return new GitHubSCMSource[] { + new GitHubSCMSource("cloudbeers", "yolo", null, false), + new GitHubSCMSource("", "", "https://github.com/cloudbeers/yolo", true) + }; + } + + @Rule public final JenkinsRule j = new JenkinsRule(); + + private CredentialsStore store = null; + + @Before + public void enableSystemCredentialsProvider() { + SystemCredentialsProvider.getInstance() + .setDomainCredentialsMap( + Collections.singletonMap(Domain.global(), Collections.emptyList())); + for (CredentialsStore s : CredentialsProvider.lookupStores(Jenkins.get())) { + if (s.getProvider() instanceof SystemCredentialsProvider.ProviderImpl) { + store = s; + break; + } + } + assertThat("The system credentials provider is enabled", store, notNullValue()); + } + + @Test + public void isApplicableToTest() throws Exception { + GitHubRepoSizeEstimator.RepositorySizeGithubAPI api = + j.jenkins + .getExtensionList(GitToolChooser.RepositorySizeAPI.class) + .get(GitHubRepoSizeEstimator.RepositorySizeGithubAPI.class); + Item context = Mockito.mock(Item.class); + store.addCredentials(Domain.global(), createCredential(CredentialsScope.GLOBAL, "github")); + store.save(); + + githubApi.stubFor( + get(urlEqualTo("/")) + .willReturn( + aResponse() + .withHeader("Content-Type", "application/json; charset=utf-8") + .withBodyFile("../__files/body-(root)-XwEI7.json"))); + + assertThat(api.isApplicableTo(githubApi.baseUrl(), context, "github"), is(false)); + } + + private StandardCredentials createCredential(CredentialsScope scope, String id) { + return new UsernamePasswordCredentialsImpl(scope, id, "desc: " + id, "username", "password"); + } +}