]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-14564 Update SonarQube main branch name during Azure DevOps project onboarding
authorPhilippe Perrin <philippe.perrin@sonarsource.com>
Wed, 10 Mar 2021 08:33:56 +0000 (09:33 +0100)
committersonartech <sonartech@sonarsource.com>
Tue, 16 Mar 2021 20:08:15 +0000 (20:08 +0000)
server/sonar-alm-client/src/main/java/org/sonar/alm/client/azure/GsonAzureRepo.java
server/sonar-alm-client/src/test/java/org/sonar/alm/client/azure/AzureDevOpsHttpClientTest.java
server/sonar-alm-client/src/test/java/org/sonar/alm/client/azure/GsonAzureRepoTest.java [new file with mode: 0644]
server/sonar-webserver-webapi/src/main/java/org/sonar/server/almintegration/ws/azure/ImportAzureProjectAction.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/almintegration/ws/azure/ImportAzureProjectActionTest.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/almintegration/ws/azure/SearchAzureReposActionTest.java

index 60327fc5c633771f7c3607dc6a11c5ed6ec2968a..b843980981780cd1bb8bfd360ea6d2733b124e96 100644 (file)
 package org.sonar.alm.client.azure;
 
 import com.google.gson.annotations.SerializedName;
+import java.util.regex.Pattern;
 
 public class GsonAzureRepo {
+  private static final String BRANCH_FULL_NAME_PREFIX = "refs/heads/";
+
   @SerializedName("id")
   private String id;
 
@@ -34,15 +37,19 @@ public class GsonAzureRepo {
   @SerializedName("project")
   private GsonAzureProject project;
 
+  @SerializedName("defaultBranch")
+  private String defaultBranchFullName;
+
   public GsonAzureRepo() {
     // http://stackoverflow.com/a/18645370/229031
   }
 
-  public GsonAzureRepo(String id, String name, String url, GsonAzureProject project) {
+  public GsonAzureRepo(String id, String name, String url, GsonAzureProject project, String defaultBranchFullName) {
     this.id = id;
     this.name = name;
     this.url = url;
     this.project = project;
+    this.defaultBranchFullName = defaultBranchFullName;
   }
 
   public String getId() {
@@ -60,4 +67,15 @@ public class GsonAzureRepo {
   public GsonAzureProject getProject() {
     return project;
   }
+
+  public String getDefaultBranchName() {
+    if (defaultBranchFullName == null || defaultBranchFullName.equals("")) {
+      return null;
+    }
+
+    return Pattern
+      .compile(Pattern.quote(BRANCH_FULL_NAME_PREFIX), Pattern.CASE_INSENSITIVE)
+      .matcher(defaultBranchFullName)
+      .replaceAll("");
+  }
 }
index 40d3407943f0d2d1c181e2f9f177916ab99e9e1e..da1ea680661b92afdae29bafdda1b6702e7584d9 100644 (file)
@@ -243,6 +243,7 @@ public class AzureDevOpsHttpClientTest {
       "    \"name\": \"Project-Name\",\n" +
       "    \"description\": \"Project's description\" \n" +
       "  },\n" +
+      "  \"defaultBranch\": \"refs/heads/default-branch\",\n" +
       "  \"size\": 0" +
       "}");
 
@@ -260,6 +261,7 @@ public class AzureDevOpsHttpClientTest {
     assertThat(repo.getName()).isEqualTo("Repo-Name-1");
     assertThat(repo.getUrl()).isEqualTo("https://ado.sonarqube.com/DefaultCollection/Repo-Id-1");
     assertThat(repo.getProject().getName()).isEqualTo("Project-Name");
+    assertThat(repo.getDefaultBranchName()).isEqualTo("default-branch");
   }
 
   @Test
diff --git a/server/sonar-alm-client/src/test/java/org/sonar/alm/client/azure/GsonAzureRepoTest.java b/server/sonar-alm-client/src/test/java/org/sonar/alm/client/azure/GsonAzureRepoTest.java
new file mode 100644 (file)
index 0000000..f5f12aa
--- /dev/null
@@ -0,0 +1,58 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 SonarSource SA
+ * mailto:info AT sonarsource DOT com
+ *
+ * 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 org.sonar.alm.client.azure;
+
+import com.tngtech.java.junit.dataprovider.DataProvider;
+import com.tngtech.java.junit.dataprovider.DataProviderRunner;
+import com.tngtech.java.junit.dataprovider.UseDataProvider;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+@RunWith(DataProviderRunner.class)
+public class GsonAzureRepoTest {
+  @Test
+  @UseDataProvider("data")
+  public void extract_branch_name_from_full_branch_name(String actualFullBranchName, String expectedBranchName) {
+    GsonAzureRepo repo = new GsonAzureRepo(
+      "repo_id",
+      "repo_name",
+      "repo_url",
+      new GsonAzureProject(),
+      actualFullBranchName
+    );
+
+    assertThat(repo.getDefaultBranchName()).isEqualTo(expectedBranchName);
+  }
+
+  @DataProvider
+  public static Object[][] data() {
+    return new Object[][]{
+      {"refs/heads/default_branch_name", "default_branch_name"},
+      {"refs/HEADS/default_branch_name", "default_branch_name"},
+      {"refs/heads/Default_branch_name", "Default_branch_name"},
+      {"branch_Name_without_prefix", "branch_Name_without_prefix"},
+      {"", null},
+      {null, null}
+    };
+  }
+}
index de7a2a6fc8ba0845195cf9ee9cdebc5ee1c3426f..ae2854cf85e3d451542eb0199e3a4c61e1d503e6 100644 (file)
@@ -122,6 +122,7 @@ public class ImportAzureProjectAction implements AlmIntegrationsWsAction {
 
       ComponentDto componentDto = createProject(dbSession, repo);
       populatePRSetting(dbSession, repo, componentDto, almSettingDto);
+      componentUpdater.commitAndIndex(dbSession, componentDto);
 
       return toCreateResponse(componentDto);
     }
@@ -129,13 +130,16 @@ public class ImportAzureProjectAction implements AlmIntegrationsWsAction {
 
   private ComponentDto createProject(DbSession dbSession, GsonAzureRepo repo) {
     boolean visibility = projectDefaultVisibility.get(dbSession).isPrivate();
-    return componentUpdater.create(dbSession, newComponentBuilder()
-      .setKey(generateProjectKey(repo.getProject().getName(), repo.getName()))
-      .setName(repo.getName())
-      .setPrivate(visibility)
-      .setQualifier(PROJECT)
-      .build(),
-      userSession.isLoggedIn() ? userSession.getUuid() : null);
+    return componentUpdater.createWithoutCommit(dbSession, newComponentBuilder()
+        .setKey(generateProjectKey(repo.getProject().getName(), repo.getName()))
+        .setName(repo.getName())
+        .setPrivate(visibility)
+        .setQualifier(PROJECT)
+        .build(),
+      userSession.isLoggedIn() ? userSession.getUuid() : null,
+      repo.getDefaultBranchName(),
+      s -> {
+      });
   }
 
   private void populatePRSetting(DbSession dbSession, GsonAzureRepo repo, ComponentDto componentDto, AlmSettingDto almSettingDto) {
@@ -146,7 +150,6 @@ public class ImportAzureProjectAction implements AlmIntegrationsWsAction {
       .setProjectUuid(componentDto.uuid())
       .setMonorepo(false);
     dbClient.projectAlmSettingDao().insertOrUpdate(dbSession, projectAlmSettingDto);
-    dbSession.commit();
   }
 
   @VisibleForTesting
index 22b2439e19778c94da0dbed6a6b6dc59c5a197e5..710f2df4ac74ba14587fa20a585063db3cbfda1a 100644 (file)
@@ -36,6 +36,7 @@ import org.sonar.db.DbTester;
 import org.sonar.db.alm.pat.AlmPatDto;
 import org.sonar.db.alm.setting.AlmSettingDto;
 import org.sonar.db.alm.setting.ProjectAlmSettingDto;
+import org.sonar.db.component.BranchDto;
 import org.sonar.db.project.ProjectDto;
 import org.sonar.db.user.UserDto;
 import org.sonar.server.almintegration.ws.ImportHelper;
@@ -114,10 +115,53 @@ public class ImportAzureProjectActionTest {
 
     Optional<ProjectDto> projectDto = db.getDbClient().projectDao().selectProjectByKey(db.getSession(), result.getKey());
     assertThat(projectDto).isPresent();
+
     Optional<ProjectAlmSettingDto> projectAlmSettingDto = db.getDbClient().projectAlmSettingDao().selectByProject(db.getSession(), projectDto.get());
     assertThat(projectAlmSettingDto.get().getAlmRepo()).isEqualTo("repo-name");
     assertThat(projectAlmSettingDto.get().getAlmSettingUuid()).isEqualTo(almSetting.getUuid());
     assertThat(projectAlmSettingDto.get().getAlmSlug()).isEqualTo("project-name");
+
+    Optional<BranchDto> mainBranch = db.getDbClient()
+      .branchDao()
+      .selectByProject(db.getSession(), projectDto.get())
+      .stream()
+      .filter(BranchDto::isMain)
+      .findFirst();
+    assertThat(mainBranch).isPresent();
+    assertThat(mainBranch.get().getKey()).hasToString("repo-default-branch");
+  }
+
+  @Test
+  public void import_project_from_empty_repo() {
+    UserDto user = db.users().insertUser();
+    userSession.logIn(user).addPermission(PROVISION_PROJECTS);
+    AlmSettingDto almSetting = db.almSettings().insertAzureAlmSetting();
+    db.almPats().insert(dto -> {
+      dto.setAlmSettingUuid(almSetting.getUuid());
+      dto.setPersonalAccessToken(almSetting.getPersonalAccessToken());
+      dto.setUserUuid(user.getUuid());
+    });
+    GsonAzureRepo repo = getEmptyGsonAzureRepo();
+    when(azureDevOpsHttpClient.getRepo(almSetting.getUrl(), almSetting.getPersonalAccessToken(), "project-name", "repo-name"))
+      .thenReturn(repo);
+
+    Projects.CreateWsResponse response = ws.newRequest()
+      .setParam("almSetting", almSetting.getKey())
+      .setParam("projectName", "project-name")
+      .setParam("repositoryName", "repo-name")
+      .executeProtobuf(Projects.CreateWsResponse.class);
+
+    Projects.CreateWsResponse.Project result = response.getProject();
+    Optional<ProjectDto> projectDto = db.getDbClient().projectDao().selectProjectByKey(db.getSession(), result.getKey());
+    Optional<BranchDto> mainBranch = db.getDbClient()
+      .branchDao()
+      .selectByProject(db.getSession(), projectDto.get())
+      .stream()
+      .filter(BranchDto::isMain)
+      .findFirst();
+
+    assertThat(mainBranch).isPresent();
+    assertThat(mainBranch.get().getKey()).hasToString("master");
   }
 
   @Test
@@ -232,7 +276,13 @@ public class ImportAzureProjectActionTest {
 
   private GsonAzureRepo getGsonAzureRepo() {
     return new GsonAzureRepo("repo-id", "repo-name", "repo-url",
-      new GsonAzureProject("project-name", "project-description"));
+      new GsonAzureProject("project-name", "project-description"),
+      "refs/heads/repo-default-branch");
+  }
+
+  private GsonAzureRepo getEmptyGsonAzureRepo() {
+    return new GsonAzureRepo("repo-id", "repo-name", "repo-url",
+      new GsonAzureProject("project-name", "project-description"), null);
   }
 
 }
index ed7365530466037c2e227216eb704ef8183bcf85..5b01fc6062a7e5fe931d257294b85a01c4294a3d 100644 (file)
@@ -361,7 +361,7 @@ public class SearchAzureReposActionTest {
 
   private GsonAzureRepo getGsonAzureRepo(String projectName, String repoName) {
     GsonAzureProject project = new GsonAzureProject(projectName, "the best project ever");
-    GsonAzureRepo gsonAzureRepo = new GsonAzureRepo("repo-id", repoName, "url", project);
+    GsonAzureRepo gsonAzureRepo = new GsonAzureRepo("repo-id", repoName, "url", project, "repo-default-branch");
     return gsonAzureRepo;
   }
 }