Skip to content

Commit 23250e4

Browse files
feat: [CI-7838]: Add support for custom API URL in Gitlab Connector (#47106)
* feat: [CI-7838]: Add support for custom API URL in Gitlab Connector * feat: [CI-7838]: Add support for git status on PR * feat: [CI-7838]: Fix git status for account connector * feat: [CI-7838]: Fix git status for account connector * fix --------- Co-authored-by: Dev Mittal <[email protected]>
1 parent 1479a7e commit 23250e4

File tree

8 files changed

+151
-8
lines changed

8 files changed

+151
-8
lines changed

332-ci-manager/service/src/main/java/io/harness/ci/execution/execution/GitBuildStatusUtility.java

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,13 +35,17 @@
3535
import io.harness.ci.states.codebase.CodeBaseTaskStepParameters;
3636
import io.harness.delegate.beans.ci.pod.ConnectorDetails;
3737
import io.harness.delegate.beans.connector.ConnectorType;
38+
import io.harness.delegate.beans.connector.scm.GitAuthType;
39+
import io.harness.delegate.beans.connector.scm.gitlab.GitlabConnectorDTO;
40+
import io.harness.delegate.beans.connector.scm.gitlab.GitlabTokenSpecDTO;
3841
import io.harness.delegate.task.ci.CIBuildStatusPushParameters;
3942
import io.harness.delegate.task.ci.GitSCMType;
4043
import io.harness.encryption.Scope;
4144
import io.harness.exception.ngexception.CIStageExecutionException;
4245
import io.harness.git.GitClientHelper;
4346
import io.harness.git.checks.GitStatusCheckHelper;
4447
import io.harness.git.checks.GitStatusCheckParams;
48+
import io.harness.gitsync.beans.GitRepositoryDTO;
4549
import io.harness.ng.core.NGAccess;
4650
import io.harness.plancreator.steps.common.StageElementParameters;
4751
import io.harness.pms.contracts.ambiance.Ambiance;
@@ -215,6 +219,34 @@ private GitStatusCheckParams convertParams(CIBuildStatusPushParameters params) {
215219
.build();
216220
}
217221

222+
private GitRepositoryDTO getRepositoryFromApiUrl(ConnectorDetails gitConnector, String url) {
223+
if (gitConnector.getConnectorConfig() instanceof GitlabConnectorDTO) {
224+
GitlabConnectorDTO gitlabConnectorDTO = (GitlabConnectorDTO) gitConnector.getConnectorConfig();
225+
226+
if (!GitAuthType.HTTP.equals(gitlabConnectorDTO.getAuthentication().getAuthType())
227+
|| gitlabConnectorDTO.getApiAccess() == null
228+
|| !(gitlabConnectorDTO.getApiAccess().getSpec() instanceof GitlabTokenSpecDTO)) {
229+
return null;
230+
}
231+
GitlabTokenSpecDTO gitlabTokenSpecDTO = (GitlabTokenSpecDTO) gitlabConnectorDTO.getApiAccess().getSpec();
232+
String apiUrl = gitlabTokenSpecDTO.getApiUrl();
233+
if (StringUtils.isBlank(apiUrl)) {
234+
return null;
235+
}
236+
url = StringUtils.removeEnd(url, PATH_SEPARATOR);
237+
apiUrl = StringUtils.removeEnd(apiUrl, PATH_SEPARATOR) + PATH_SEPARATOR;
238+
String ownerAndRepo = StringUtils.removeStart(url, apiUrl);
239+
ownerAndRepo = StringUtils.removeEnd(ownerAndRepo, ".git");
240+
if (ownerAndRepo.contains("/")) {
241+
String[] parts = ownerAndRepo.split("/");
242+
String repo = parts[parts.length - 1];
243+
String owner = StringUtils.removeEnd(ownerAndRepo, "/" + repo);
244+
return GitRepositoryDTO.builder().name(repo).org(owner).build();
245+
}
246+
}
247+
return null;
248+
}
249+
218250
public CIBuildStatusPushParameters getCIBuildStatusPushParams(
219251
Ambiance ambiance, BuildStatusUpdateParameter buildStatusUpdateParameter, Status status, String commitSha) {
220252
NGAccess ngAccess = AmbianceUtils.getNgAccess(ambiance);
@@ -229,6 +261,12 @@ public CIBuildStatusPushParameters getCIBuildStatusPushParams(
229261
String finalRepo = GitClientHelper.getGitRepo(url);
230262
String ownerName = GitClientHelper.getGitOwner(url, false);
231263

264+
GitRepositoryDTO gitRepositoryDTO = getRepositoryFromApiUrl(gitConnector, url);
265+
if (gitRepositoryDTO != null) {
266+
finalRepo = gitRepositoryDTO.getName();
267+
ownerName = gitRepositoryDTO.getOrg();
268+
}
269+
232270
GitSCMType gitSCMType = retrieveSCMType(gitConnector);
233271

234272
String stageSetupId = AmbianceUtils.getStageSetupIdAmbiance(ambiance);

930-delegate-tasks/src/main/java/io/harness/delegate/task/gitapi/client/impl/GitlabApiClient.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,9 @@
3131
import io.harness.delegate.task.gitpolling.github.GitHubPollingDelegateRequest;
3232
import io.harness.exception.GitClientException;
3333
import io.harness.exception.InvalidRequestException;
34+
import io.harness.git.GitClientHelper;
3435
import io.harness.gitpolling.github.GitPollingWebhookData;
36+
import io.harness.impl.scm.ScmGitProviderMapper;
3537
import io.harness.logging.CommandExecutionStatus;
3638
import io.harness.security.encryption.SecretDecryptionService;
3739

@@ -73,7 +75,8 @@ public DelegateResponseData mergePR(GitApiTaskParams gitApiTaskParams) {
7375
}
7476
GitlabConnectorDTO gitConfigDTO = (GitlabConnectorDTO) gitConnector.getConnectorConfig();
7577
String token = retrieveAuthToken(gitConnector);
76-
String gitApiURL = getGitApiURL(gitConfigDTO.getUrl());
78+
String gitApiURL =
79+
GitClientHelper.getGitlabApiURL(gitConfigDTO.getUrl(), ScmGitProviderMapper.getGitlabApiUrl(gitConfigDTO));
7780
String slug = gitApiTaskParams.getSlug();
7881
String prNumber = gitApiTaskParams.getPrNumber();
7982
boolean deleteSourceBranch = gitApiTaskParams.isDeleteSourceBranch();

933-ci-commons/src/main/java/io/harness/git/checks/GitStatusCheckHelper.java

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import io.harness.exception.ConnectorNotFoundException;
3333
import io.harness.git.GitClientHelper;
3434
import io.harness.git.GitTokenRetriever;
35+
import io.harness.impl.scm.ScmGitProviderMapper;
3536

3637
import com.google.inject.Inject;
3738
import com.google.inject.Singleton;
@@ -194,8 +195,10 @@ private boolean sendBuildStatusToGitLab(GitStatusCheckParams gitStatusCheckParam
194195

195196
return Failsafe.with(retryPolicy)
196197
.get(()
197-
-> gitlabService.sendStatus(
198-
GitlabConfig.builder().gitlabUrl(getGitlabApiURL(gitConfigDTO.getUrl())).build(),
198+
-> gitlabService.sendStatus(GitlabConfig.builder()
199+
.gitlabUrl(getGitlabApiURL(gitConfigDTO.getUrl(),
200+
ScmGitProviderMapper.getGitlabApiUrl(gitConfigDTO)))
201+
.build(),
199202
gitStatusCheckParams.getUserName(), token, null, gitStatusCheckParams.getSha(),
200203
gitStatusCheckParams.getOwner(), gitStatusCheckParams.getRepo(), bodyObjectMap));
201204
} else {
@@ -302,9 +305,11 @@ private static String fetchCustomBitbucketDomain(String url, String domain) {
302305
return domain + customEndpoint;
303306
}
304307

305-
private String getGitlabApiURL(String url) {
308+
private String getGitlabApiURL(String url, String apiUrl) {
306309
if (url.contains("gitlab.com")) {
307310
return GITLAB_API_URL;
311+
} else if (!StringUtils.isBlank(apiUrl)) {
312+
return StringUtils.stripEnd(apiUrl, "/") + "/api/";
308313
} else {
309314
String domain = GitClientHelper.getGitSCM(url);
310315
return "https://" + domain + "/api/";

952-scm-java-client/src/main/java/io/harness/impl/scm/ScmGitProviderHelper.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import static io.harness.annotations.dev.HarnessTeam.DX;
1111

1212
import io.harness.annotations.dev.OwnedBy;
13+
import io.harness.delegate.beans.connector.scm.GitAuthType;
1314
import io.harness.delegate.beans.connector.scm.ScmConnector;
1415
import io.harness.delegate.beans.connector.scm.azurerepo.AzureRepoConnectorDTO;
1516
import io.harness.delegate.beans.connector.scm.bitbucket.BitbucketConnectorDTO;
@@ -32,7 +33,7 @@ public String getSlug(ScmConnector scmConnector) {
3233
if (scmConnector instanceof GithubConnectorDTO) {
3334
return getSlugFromUrl(((GithubConnectorDTO) scmConnector).getUrl());
3435
} else if (scmConnector instanceof GitlabConnectorDTO) {
35-
return getSlugFromUrl(((GitlabConnectorDTO) scmConnector).getUrl());
36+
return getSlugFromUrlForGitlab((GitlabConnectorDTO) scmConnector);
3637
} else if (scmConnector instanceof BitbucketConnectorDTO) {
3738
return getSlugFromUrlForBitbucket(((BitbucketConnectorDTO) scmConnector).getUrl());
3839
} else if (scmConnector instanceof AzureRepoConnectorDTO) {
@@ -53,6 +54,19 @@ private String getSlugFromUrl(String url) {
5354
return ownerName + "/" + repoName;
5455
}
5556

57+
private String getSlugFromUrlForGitlab(GitlabConnectorDTO gitlabConnectorDTO) {
58+
String url = gitlabConnectorDTO.getUrl();
59+
String apiUrl = ScmGitProviderMapper.getGitlabApiUrl(gitlabConnectorDTO);
60+
if (!StringUtils.isBlank(apiUrl) && gitlabConnectorDTO.getAuthentication().getAuthType() == GitAuthType.HTTP) {
61+
apiUrl = StringUtils.stripEnd(apiUrl, "/") + "/";
62+
String slug = StringUtils.removeStart(url, apiUrl);
63+
return StringUtils.removeEnd(slug, ".git");
64+
}
65+
String repoName = gitClientHelper.getGitRepo(url);
66+
String ownerName = gitClientHelper.getGitOwner(url, false);
67+
return ownerName + "/" + repoName;
68+
}
69+
5670
private String getSlugFromUrlForBitbucket(String url) {
5771
String repoName = gitClientHelper.getGitRepo(url);
5872
String ownerName = gitClientHelper.getGitOwner(url, false);

952-scm-java-client/src/main/java/io/harness/impl/scm/ScmGitProviderMapper.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ private String getOauthToken(GithubConnectorDTO githubConnector) {
259259
return String.valueOf(githubOauthDTO.getTokenRef().getDecryptedValue());
260260
}
261261

262-
private String getGitlabApiUrl(GitlabConnectorDTO gitlabConnector) {
262+
public static String getGitlabApiUrl(GitlabConnectorDTO gitlabConnector) {
263263
if (gitlabConnector.getApiAccess() == null || gitlabConnector.getApiAccess().getSpec() == null) {
264264
// not expected
265265
return null;

952-scm-java-client/src/test/java/io/harness/impl/scm/ScmServiceClientImplTest.java

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,11 @@
1515
import static io.harness.delegate.beans.connector.ConnectorType.GITHUB;
1616
import static io.harness.rule.OwnerRule.BHAVYA;
1717
import static io.harness.rule.OwnerRule.DEEPAK;
18+
import static io.harness.rule.OwnerRule.DEV_MITTAL;
1819
import static io.harness.rule.OwnerRule.MEET;
1920
import static io.harness.rule.OwnerRule.MOHIT_GARG;
2021

22+
import static junit.framework.TestCase.assertEquals;
2123
import static org.assertj.core.api.Assertions.assertThat;
2224
import static org.assertj.core.api.Assertions.assertThatThrownBy;
2325
import static org.mockito.Matchers.any;
@@ -48,12 +50,17 @@
4850
import io.harness.connector.ConnectorInfoDTO;
4951
import io.harness.constants.Constants;
5052
import io.harness.data.structure.UUIDGenerator;
53+
import io.harness.delegate.beans.connector.scm.GitAuthType;
5154
import io.harness.delegate.beans.connector.scm.GitConnectionType;
5255
import io.harness.delegate.beans.connector.scm.ScmConnector;
5356
import io.harness.delegate.beans.connector.scm.bitbucket.BitbucketApiAccessDTO;
5457
import io.harness.delegate.beans.connector.scm.bitbucket.BitbucketConnectorDTO;
5558
import io.harness.delegate.beans.connector.scm.github.GithubApiAccessDTO;
5659
import io.harness.delegate.beans.connector.scm.github.GithubConnectorDTO;
60+
import io.harness.delegate.beans.connector.scm.gitlab.GitlabApiAccessDTO;
61+
import io.harness.delegate.beans.connector.scm.gitlab.GitlabAuthenticationDTO;
62+
import io.harness.delegate.beans.connector.scm.gitlab.GitlabConnectorDTO;
63+
import io.harness.delegate.beans.connector.scm.gitlab.GitlabTokenSpecDTO;
5764
import io.harness.exception.InvalidRequestException;
5865
import io.harness.exception.UnexpectedException;
5966
import io.harness.product.ci.scm.proto.Commit;
@@ -452,6 +459,45 @@ public void testGetBatchFile() {
452459
assertThat(gitFileResponse.getObjectId()).isEqualTo(objectId);
453460
}
454461

462+
@Test
463+
@Owner(developers = DEV_MITTAL)
464+
@Category(UnitTests.class)
465+
public void testGetSlugGitlab() {
466+
ScmGitProviderHelper helper = new ScmGitProviderHelper();
467+
GitlabConnectorDTO gitlabConnectorDTO =
468+
GitlabConnectorDTO.builder()
469+
.url("http://34.170.133.206/gitlab/gitlab-instance-9ca8a1ea/subgroup/repo1.git")
470+
.authentication(GitlabAuthenticationDTO.builder().authType(GitAuthType.HTTP).build())
471+
.apiAccess(GitlabApiAccessDTO.builder()
472+
.spec(GitlabTokenSpecDTO.builder().apiUrl("http://34.170.133.206/gitlab/").build())
473+
.build())
474+
.build();
475+
String slug = helper.getSlug(gitlabConnectorDTO);
476+
assertEquals(slug, "gitlab-instance-9ca8a1ea/subgroup/repo1");
477+
478+
gitlabConnectorDTO.setUrl("http://34.170.133.206/gitlab/gitlab-instance-9ca8a1ea/repo1.git");
479+
slug = helper.getSlug(gitlabConnectorDTO);
480+
assertEquals(slug, "gitlab-instance-9ca8a1ea/repo1");
481+
482+
gitlabConnectorDTO.setUrl("[email protected]:gitlab-instance-9ca8a1ea/subgroup/repo1.git");
483+
gitlabConnectorDTO.setAuthentication(GitlabAuthenticationDTO.builder().authType(GitAuthType.SSH).build());
484+
slug = helper.getSlug(gitlabConnectorDTO);
485+
assertEquals(slug, "gitlab-instance-9ca8a1ea/subgroup/repo1");
486+
487+
gitlabConnectorDTO.setUrl("[email protected]:gitlab-instance-9ca8a1ea/repo1.git");
488+
slug = helper.getSlug(gitlabConnectorDTO);
489+
assertEquals(slug, "gitlab-instance-9ca8a1ea/repo1");
490+
491+
gitlabConnectorDTO.setApiAccess(
492+
GitlabApiAccessDTO.builder().spec(GitlabTokenSpecDTO.builder().apiUrl("").build()).build());
493+
slug = helper.getSlug(gitlabConnectorDTO);
494+
assertEquals(slug, "gitlab-instance-9ca8a1ea/repo1");
495+
496+
gitlabConnectorDTO.setUrl("http://34.170.133.206/gitlab/gitlab-instance-9ca8a1ea/repo1.git");
497+
slug = helper.getSlug(gitlabConnectorDTO);
498+
assertEquals(slug, "gitlab/gitlab-instance-9ca8a1ea/repo1");
499+
}
500+
455501
private GitFileDetails getGitFileDetailsDefault() {
456502
return GitFileDetails.builder()
457503
.filePath(filepath)

954-connector-beans/src/main/java/io/harness/delegate/beans/connector/scm/gitlab/GitlabConnectorDTO.java

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
import lombok.EqualsAndHashCode;
4141
import lombok.NoArgsConstructor;
4242
import lombok.experimental.FieldDefaults;
43+
import org.apache.commons.lang3.StringUtils;
4344
import org.hibernate.validator.constraints.NotBlank;
4445

4546
@Data
@@ -116,7 +117,18 @@ public String getGitConnectionUrl(GitRepositoryDTO gitRepositoryDTO) {
116117

117118
@Override
118119
public GitRepositoryDTO getGitRepositoryDetails() {
119-
return GitRepositoryDTO.builder().build();
120+
if (GitConnectionType.REPO.equals(connectionType)) {
121+
GitRepositoryDTO gitRepositoryDTO = getRepositoryFromApiUrl();
122+
if (gitRepositoryDTO != null) {
123+
return gitRepositoryDTO;
124+
}
125+
126+
return GitRepositoryDTO.builder()
127+
.name(GitClientHelper.getGitRepo(url))
128+
.org(GitClientHelper.getGitOwner(url, false))
129+
.build();
130+
}
131+
return GitRepositoryDTO.builder().org(GitClientHelper.getGitOwner(url, true)).build();
120132
}
121133

122134
@Override
@@ -141,4 +153,29 @@ public ConnectorConfigOutcomeDTO toOutcome() {
141153
.executeOnDelegate(this.executeOnDelegate)
142154
.build();
143155
}
156+
157+
private GitRepositoryDTO getRepositoryFromApiUrl() {
158+
if (!GitConnectionType.REPO.equals(connectionType) || !GitAuthType.HTTP.equals(authentication.getAuthType())) {
159+
return null;
160+
}
161+
if (apiAccess == null || !(apiAccess.getSpec() instanceof GitlabTokenSpecDTO)) {
162+
return null;
163+
}
164+
GitlabTokenSpecDTO gitlabTokenSpecDTO = (GitlabTokenSpecDTO) apiAccess.getSpec();
165+
String apiUrl = gitlabTokenSpecDTO.getApiUrl();
166+
if (StringUtils.isBlank(apiUrl)) {
167+
return null;
168+
}
169+
apiUrl = StringUtils.removeEnd(apiUrl, "/") + "/";
170+
String ownerAndRepo = StringUtils.removeStart(url, apiUrl);
171+
ownerAndRepo = StringUtils.removeEnd(ownerAndRepo, ".git");
172+
if (ownerAndRepo.contains("/")) {
173+
String[] parts = ownerAndRepo.split("/");
174+
String repo = parts[parts.length - 1];
175+
String owner = StringUtils.removeEnd(ownerAndRepo, "/" + repo);
176+
return GitRepositoryDTO.builder().name(repo).org(owner).build();
177+
}
178+
179+
return null;
180+
}
144181
}

build.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
build.majorVersion=1
22
build.minorVersion=0
3-
build.number=78928
3+
build.number=78929
44
build.patch=000
55
delegate.version=23.03.12
66
delegate.patch=000

0 commit comments

Comments
 (0)