From: Duarte Meneses Date: Tue, 3 Mar 2020 22:54:40 +0000 (-0600) Subject: SONAR-11853 SONAR-13161 Auto-configuration pull requests and branches on Jenkins X-Git-Tag: 8.3.0.34182~140 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=1290e77dd6f5759354122cecd966074127351e15;p=sonarqube.git SONAR-11853 SONAR-13161 Auto-configuration pull requests and branches on Jenkins --- diff --git a/build.gradle b/build.gradle index 4f8846cf20a..e9349ec8367 100644 --- a/build.gradle +++ b/build.gradle @@ -269,6 +269,7 @@ subprojects { } dependency 'org.elasticsearch:mocksocket:1.0' dependency 'org.codelibs.elasticsearch.module:analysis-common:6.8.4' + dependency 'org.eclipse.jgit:org.eclipse.jgit:5.6.1.202002131546-r' dependency 'org.freemarker:freemarker:2.3.20' dependency 'org.hamcrest:hamcrest-all:1.3' dependency 'org.jsoup:jsoup:1.12.1' diff --git a/sonar-scanner-engine/build.gradle b/sonar-scanner-engine/build.gradle index 4672dbe8b40..ac3497147dc 100644 --- a/sonar-scanner-engine/build.gradle +++ b/sonar-scanner-engine/build.gradle @@ -29,6 +29,7 @@ dependencies { compile 'org.codehaus.staxmate:staxmate' compile 'org.codehaus.woodstox:stax2-api' compile 'org.codehaus.woodstox:woodstox-core-lgpl' + compile 'org.eclipse.jgit:org.eclipse.jgit' compile 'org.picocontainer:picocontainer' compile 'org.slf4j:jcl-over-slf4j' compile 'org.slf4j:jul-to-slf4j' diff --git a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/Jenkins.java b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/Jenkins.java index 64d98ec4748..d79cbd7c17c 100644 --- a/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/Jenkins.java +++ b/sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/Jenkins.java @@ -19,8 +19,15 @@ */ package org.sonar.scanner.ci.vendors; +import java.nio.file.Path; import org.apache.commons.lang.StringUtils; +import org.eclipse.jgit.lib.Ref; +import org.eclipse.jgit.lib.Repository; +import org.eclipse.jgit.lib.RepositoryBuilder; +import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.utils.System2; +import org.sonar.api.utils.log.Logger; +import org.sonar.api.utils.log.Loggers; import org.sonar.scanner.ci.CiConfiguration; import org.sonar.scanner.ci.CiConfigurationImpl; import org.sonar.scanner.ci.CiVendor; @@ -28,10 +35,13 @@ import org.sonar.scanner.ci.CiVendor; import static org.apache.commons.lang.StringUtils.isNotBlank; public class Jenkins implements CiVendor { + private final static Logger log = Loggers.get(Jenkins.class); private final System2 system; + private final DefaultInputProject inputProject; - public Jenkins(System2 system) { + public Jenkins(System2 system, DefaultInputProject inputProject) { this.system = system; + this.inputProject = inputProject; } @Override @@ -51,12 +61,52 @@ public class Jenkins implements CiVendor { // https://wiki.jenkins-ci.org/display/JENKINS/GitHub+pull+request+builder+plugin#GitHubpullrequestbuilderplugin-EnvironmentVariables // https://wiki.jenkins-ci.org/display/JENKINS/Building+a+software+project String revision = system.envVariable("ghprbActualCommit"); - if (StringUtils.isBlank(revision)) { - revision = system.envVariable("GIT_COMMIT"); - if (StringUtils.isBlank(revision)) { - revision = system.envVariable("SVN_COMMIT"); + if (StringUtils.isNotBlank(revision)) { + return new CiConfigurationImpl(revision); + } + + revision = system.envVariable("GIT_COMMIT"); + + if (StringUtils.isNotBlank(revision)) { + if (StringUtils.isNotBlank(system.envVariable("CHANGE_ID"))) { + String jenkinsGitPrSha1 = getJenkinsGitPrSha1(); + if (StringUtils.isNotBlank(jenkinsGitPrSha1)) { + return new CiConfigurationImpl(jenkinsGitPrSha1); + } } + return new CiConfigurationImpl(revision); } + + revision = system.envVariable("SVN_COMMIT"); return new CiConfigurationImpl(revision); } + + private String getJenkinsGitPrSha1() { + String gitBranch = system.envVariable("GIT_BRANCH"); + if (StringUtils.isBlank(gitBranch)) { + return null; + } + + Path baseDir = inputProject.getBaseDir(); + + RepositoryBuilder builder = new RepositoryBuilder() + .findGitDir(baseDir.toFile()) + .setMustExist(true); + + if (builder.getGitDir() == null) { + return null; + } + + String refName = "refs/remotes/origin/" + gitBranch; + try (Repository repo = builder.build()) { + Ref ref = repo.exactRef(refName); + if (ref != null) { + return ref.getObjectId().getName(); + } + } catch (Exception e) { + log.debug("Couldn't find git sha1 in '{}': {}", refName, e.getMessage()); + } + return null; + } + } diff --git a/sonar-scanner-engine/src/main/resources/org/sonar/scanner/ci/vendors/gitrepo.zip b/sonar-scanner-engine/src/main/resources/org/sonar/scanner/ci/vendors/gitrepo.zip new file mode 100644 index 00000000000..847bba8bcd0 Binary files /dev/null and b/sonar-scanner-engine/src/main/resources/org/sonar/scanner/ci/vendors/gitrepo.zip differ diff --git a/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/JenkinsTest.java b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/JenkinsTest.java index 70bab2ee016..422b5be36bd 100644 --- a/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/JenkinsTest.java +++ b/sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/JenkinsTest.java @@ -19,9 +19,16 @@ */ package org.sonar.scanner.ci.vendors; +import java.io.File; +import java.io.IOException; +import java.nio.file.Path; import javax.annotation.Nullable; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.TemporaryFolder; +import org.sonar.api.batch.fs.internal.DefaultInputProject; import org.sonar.api.utils.System2; +import org.sonar.api.utils.ZipUtils; import org.sonar.scanner.ci.CiVendor; import static org.assertj.core.api.Assertions.assertThat; @@ -30,7 +37,11 @@ import static org.mockito.Mockito.when; public class JenkinsTest { private System2 system = mock(System2.class); - private CiVendor underTest = new Jenkins(system); + private DefaultInputProject project = mock(DefaultInputProject.class); + private CiVendor underTest = new Jenkins(system, project); + + @Rule + public TemporaryFolder temp = new TemporaryFolder(); @Test public void getName() { @@ -54,7 +65,6 @@ public class JenkinsTest { @Test public void loadConfiguration_with_deprecated_pull_request_plugin() { - setEnvVariable("CI", "true"); setEnvVariable("ghprbActualCommit", "abd12fc"); assertThat(underTest.loadConfiguration().getScmRevision()).hasValue("abd12fc"); @@ -62,15 +72,41 @@ public class JenkinsTest { @Test public void loadConfiguration_of_git_repo() { - setEnvVariable("CI", "true"); setEnvVariable("GIT_COMMIT", "abd12fc"); assertThat(underTest.loadConfiguration().getScmRevision()).hasValue("abd12fc"); } + @Test + public void loadConfiguration_of_git_repo_with_branch_plugin() throws IOException { + // prepare fake git clone + Path baseDir = temp.newFolder().toPath(); + File unzip = ZipUtils.unzip(this.getClass().getResourceAsStream("gitrepo.zip"), baseDir.toFile()); + when(project.getBaseDir()).thenReturn(unzip.toPath().resolve("gitrepo")); + + setEnvVariable("CHANGE_ID", "3"); + setEnvVariable("GIT_BRANCH", "PR-3"); + // this will be ignored + setEnvVariable("GIT_COMMIT", "abd12fc"); + + assertThat(underTest.loadConfiguration().getScmRevision()).hasValue("e6013986eff4f0ce0a85f5d070070e7fdabead48"); + } + + @Test + public void loadConfiguration_of_git_repo_with_branch_plugin_without_git_repo() throws IOException { + // prepare fake git clone + Path baseDir = temp.newFolder().toPath(); + when(project.getBaseDir()).thenReturn(baseDir); + + setEnvVariable("CHANGE_ID", "3"); + setEnvVariable("GIT_BRANCH", "PR-3"); + setEnvVariable("GIT_COMMIT", "abc"); + + assertThat(underTest.loadConfiguration().getScmRevision()).hasValue("abc"); + } + @Test public void loadConfiguration_of_svn_repo() { - setEnvVariable("CI", "true"); setEnvVariable("SVN_COMMIT", "abd12fc"); assertThat(underTest.loadConfiguration().getScmRevision()).hasValue("abd12fc");