]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-11853 SONAR-13161 Auto-configuration pull requests and branches on Jenkins
authorDuarte Meneses <duarte.meneses@sonarsource.com>
Tue, 3 Mar 2020 22:54:40 +0000 (16:54 -0600)
committersonartech <sonartech@sonarsource.com>
Fri, 13 Mar 2020 20:04:14 +0000 (20:04 +0000)
build.gradle
sonar-scanner-engine/build.gradle
sonar-scanner-engine/src/main/java/org/sonar/scanner/ci/vendors/Jenkins.java
sonar-scanner-engine/src/main/resources/org/sonar/scanner/ci/vendors/gitrepo.zip [new file with mode: 0644]
sonar-scanner-engine/src/test/java/org/sonar/scanner/ci/vendors/JenkinsTest.java

index 4f8846cf20adaa4d5b61d985418c45af3b1dc576..e9349ec8367db9a82b69992faf96f9caf1a200e4 100644 (file)
@@ -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'
index 4672dbe8b406f0bdc85e978b8e2cbd5b8da73e56..ac3497147dca058b11bdeea5fffac21f2edcbbd0 100644 (file)
@@ -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'
index 64d98ec4748f4f939d23f2865b35f014eb539d18..d79cbd7c17cdee8b64fc7a15c7e07ce6ea524631 100644 (file)
  */
 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 (file)
index 0000000..847bba8
Binary files /dev/null and b/sonar-scanner-engine/src/main/resources/org/sonar/scanner/ci/vendors/gitrepo.zip differ
index 70bab2ee016b828e62ec294d4c22d27d33d07995..422b5be36bda6c41eb80c2b9a24ff5e65d352f0b 100644 (file)
  */
 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");