Skip to content

Commit

Permalink
chore: added git controller layer (#38446)
Browse files Browse the repository at this point in the history
## Description
 - Added controller layer for the new git implementation
 
Fixes #`Issue Number`  

## Automation

/ok-to-test tags="@tag.Git"

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/12582917398>
> Commit: 3fa98cd
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=12582917398&attempt=2"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.Git`
> Spec:
> <hr>Thu, 02 Jan 2025 15:04:31 UTC
<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [ ] No


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

- **New Features**
- Enhanced Git integration with new endpoints for managing Git
repositories.
	- Added support for Git application and artifact operations.
- Introduced new methods for branch management, SSH key generation, and
metadata retrieval.
	- Expanded Git-related functionality with new controllers and services.

- **Improvements**
	- Added more comprehensive Git analytics tracking.
	- Improved Git repository interaction capabilities.
	- Enhanced support for Git operations across different artifact types.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
  • Loading branch information
sondermanish authored Jan 2, 2025
1 parent dffabc2 commit bd116cd
Show file tree
Hide file tree
Showing 12 changed files with 847 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ public class UrlCE {
public static final String PRODUCT_ALERT = BASE_URL + VERSION + "/product-alert";
public static final String SEARCH_ENTITY_URL = BASE_URL + VERSION + "/search-entities";
public static final String CONSOLIDATED_API_URL = BASE_URL + VERSION + "/consolidated-api";
public static final String GIT_APPLICATION_URL = BASE_URL + VERSION + "/git/applications";
public static final String GIT_ARTIFACT_URL = BASE_URL + VERSION + "/git/artifacts";

// Sub-paths
public static final String MOCKS = "/mocks";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,18 @@
package com.appsmith.server.git.central;

import com.appsmith.external.dtos.GitBranchDTO;
import com.appsmith.external.dtos.GitRefDTO;
import com.appsmith.external.dtos.GitStatusDTO;
import com.appsmith.external.git.constants.ce.RefType;
import com.appsmith.git.dto.CommitDTO;
import com.appsmith.server.constants.ArtifactType;
import com.appsmith.server.domains.Artifact;
import com.appsmith.server.domains.GitArtifactMetadata;
import com.appsmith.server.domains.GitAuth;
import com.appsmith.server.dtos.ArtifactImportDTO;
import com.appsmith.server.dtos.AutoCommitResponseDTO;
import com.appsmith.server.dtos.GitConnectDTO;
import com.appsmith.server.dtos.GitDocsDTO;
import com.appsmith.server.dtos.GitPullDTO;
import reactor.core.publisher.Mono;

Expand All @@ -31,6 +35,9 @@ Mono<String> commitArtifact(

Mono<? extends Artifact> detachRemote(String branchedArtifactId, ArtifactType artifactType, GitType gitType);

Mono<List<GitBranchDTO>> listBranchForArtifact(
String branchedArtifactId, Boolean pruneBranches, ArtifactType artifactType, GitType gitType);

Mono<String> fetchRemoteChanges(
String referenceArtifactId,
boolean isFileLock,
Expand Down Expand Up @@ -67,4 +74,10 @@ Mono<List<String>> updateProtectedBranches(

Mono<AutoCommitResponseDTO> getAutoCommitProgress(
String baseArtifactId, String branchName, ArtifactType artifactType);

Mono<GitAuth> generateSSHKey(String keyType);

Mono<GitArtifactMetadata> getGitArtifactMetadata(String baseArtifactId, ArtifactType artifactType);

Mono<List<GitDocsDTO>> getGitDocUrls();
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.appsmith.server.helpers.GitPrivateRepoHelper;
import com.appsmith.server.imports.internal.ImportService;
import com.appsmith.server.plugins.base.PluginService;
import com.appsmith.server.repositories.GitDeployKeysRepository;
import com.appsmith.server.services.SessionUserService;
import com.appsmith.server.services.UserDataService;
import com.appsmith.server.services.WorkspaceService;
Expand All @@ -34,6 +35,7 @@ public CentralGitServiceCECompatibleImpl(
GitArtifactHelperResolver gitArtifactHelperResolver,
GitHandlingServiceResolver gitHandlingServiceResolver,
GitPrivateRepoHelper gitPrivateRepoHelper,
GitDeployKeysRepository gitDeployKeysRepository,
DatasourceService datasourceService,
DatasourcePermission datasourcePermission,
WorkspaceService workspaceService,
Expand All @@ -52,6 +54,7 @@ public CentralGitServiceCECompatibleImpl(
gitArtifactHelperResolver,
gitHandlingServiceResolver,
gitPrivateRepoHelper,
gitDeployKeysRepository,
datasourceService,
datasourcePermission,
workspaceService,
Expand Down

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.appsmith.server.helpers.GitPrivateRepoHelper;
import com.appsmith.server.imports.internal.ImportService;
import com.appsmith.server.plugins.base.PluginService;
import com.appsmith.server.repositories.GitDeployKeysRepository;
import com.appsmith.server.services.SessionUserService;
import com.appsmith.server.services.UserDataService;
import com.appsmith.server.services.WorkspaceService;
Expand All @@ -33,6 +34,7 @@ public CentralGitServiceImpl(
GitArtifactHelperResolver gitArtifactHelperResolver,
GitHandlingServiceResolver gitHandlingServiceResolver,
GitPrivateRepoHelper gitPrivateRepoHelper,
GitDeployKeysRepository gitDeployKeysRepository,
DatasourceService datasourceService,
DatasourcePermission datasourcePermission,
WorkspaceService workspaceService,
Expand All @@ -51,6 +53,7 @@ public CentralGitServiceImpl(
gitArtifactHelperResolver,
gitHandlingServiceResolver,
gitPrivateRepoHelper,
gitDeployKeysRepository,
datasourceService,
datasourcePermission,
workspaceService,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ Mono<List<String>> listBranches(
Mono<List<String>> listReferences(
ArtifactJsonTransformationDTO artifactJsonTransformationDTO, Boolean checkRemoteReferences);

Mono<String> getDefaultBranchFromRepository(
ArtifactJsonTransformationDTO jsonTransformationDTO, GitArtifactMetadata gitArtifactMetadata);

Mono<Boolean> validateEmptyRepository(ArtifactJsonTransformationDTO artifactJsonTransformationDTO);

Mono<Boolean> initialiseReadMe(
Expand Down Expand Up @@ -77,6 +80,8 @@ Mono<? extends ArtifactExchangeJson> recreateArtifactJsonFromLastCommit(

Mono<String> createGitReference(ArtifactJsonTransformationDTO artifactJsonTransformationDTO, GitRefDTO gitRefDTO);

Mono<String> checkoutRemoteReference(ArtifactJsonTransformationDTO jsonTransformationDTO);

Mono<Boolean> deleteGitReference(ArtifactJsonTransformationDTO jsonTransformationDTO);

Mono<Boolean> checkoutArtifact(ArtifactJsonTransformationDTO jsonTransformationDTO);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.appsmith.server.git.controllers;

import com.appsmith.server.constants.Url;
import com.appsmith.server.git.autocommit.AutoCommitService;
import com.appsmith.server.git.central.CentralGitService;
import com.appsmith.server.git.utils.GitProfileUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Slf4j
@RestController
@RequestMapping(Url.GIT_APPLICATION_URL)
public class GitApplicationController extends GitApplicationControllerCE {

public GitApplicationController(
CentralGitService centralGitService, GitProfileUtils gitProfileUtils, AutoCommitService autoCommitService) {
super(centralGitService, gitProfileUtils, autoCommitService);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,225 @@
package com.appsmith.server.git.controllers;

import com.appsmith.external.dtos.GitBranchDTO;
import com.appsmith.external.dtos.GitRefDTO;
import com.appsmith.external.dtos.GitStatusDTO;
import com.appsmith.external.git.constants.ce.RefType;
import com.appsmith.external.views.Views;
import com.appsmith.git.dto.CommitDTO;
import com.appsmith.server.constants.ArtifactType;
import com.appsmith.server.constants.FieldName;
import com.appsmith.server.constants.Url;
import com.appsmith.server.domains.Artifact;
import com.appsmith.server.domains.GitArtifactMetadata;
import com.appsmith.server.dtos.AutoCommitResponseDTO;
import com.appsmith.server.dtos.BranchProtectionRequestDTO;
import com.appsmith.server.dtos.GitConnectDTO;
import com.appsmith.server.dtos.GitPullDTO;
import com.appsmith.server.dtos.ResponseDTO;
import com.appsmith.server.git.autocommit.AutoCommitService;
import com.appsmith.server.git.central.CentralGitService;
import com.appsmith.server.git.central.GitType;
import com.appsmith.server.git.utils.GitProfileUtils;
import com.fasterxml.jackson.annotation.JsonView;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.BooleanUtils;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseStatus;
import reactor.core.publisher.Mono;

import java.util.List;

@Slf4j
@RequestMapping(Url.GIT_APPLICATION_URL)
@RequiredArgsConstructor
public class GitApplicationControllerCE {

protected final CentralGitService centralGitService;
protected final GitProfileUtils gitProfileUtils;
protected final AutoCommitService autoCommitService;

protected static final ArtifactType ARTIFACT_TYPE = ArtifactType.APPLICATION;
protected static final GitType GIT_TYPE = GitType.FILE_SYSTEM;

@JsonView({Views.Metadata.class})
@GetMapping("/{baseApplicationId}/metadata")
public Mono<ResponseDTO<GitArtifactMetadata>> getGitMetadata(@PathVariable String baseApplicationId) {
return centralGitService
.getGitArtifactMetadata(baseApplicationId, ARTIFACT_TYPE)
.map(metadata -> new ResponseDTO<>(HttpStatus.OK.value(), metadata, null));
}

@JsonView(Views.Public.class)
@PostMapping("/{applicationId}/connect")
public Mono<ResponseDTO<? extends Artifact>> connectApplicationToRemoteRepo(
@PathVariable String applicationId,
@RequestBody GitConnectDTO gitConnectDTO,
@RequestHeader("Origin") String originHeader) {
return centralGitService
.connectArtifactToGit(applicationId, gitConnectDTO, originHeader, ARTIFACT_TYPE, GIT_TYPE)
.map(application -> new ResponseDTO<>(HttpStatus.OK.value(), application, null));
}

@JsonView(Views.Public.class)
@PostMapping("/{branchedApplicationId}/commit")
@ResponseStatus(HttpStatus.CREATED)
public Mono<ResponseDTO<String>> commit(
@RequestBody CommitDTO commitDTO, @PathVariable String branchedApplicationId) {
log.info("Going to commit branchedApplicationId {}", branchedApplicationId);
return centralGitService
.commitArtifact(commitDTO, branchedApplicationId, ARTIFACT_TYPE, GIT_TYPE)
.map(result -> new ResponseDTO<>(HttpStatus.CREATED.value(), result, null));
}

@JsonView(Views.Public.class)
@PostMapping("/{referencedApplicationId}/create-ref")
@ResponseStatus(HttpStatus.CREATED)
public Mono<ResponseDTO<? extends Artifact>> createReference(
@PathVariable String referencedApplicationId,
@RequestHeader(name = FieldName.BRANCH_NAME, required = false) String srcBranch,
@RequestBody GitRefDTO gitRefDTO) {
log.info(
"Going to create a reference from referencedApplicationId {}, srcBranch {}",
referencedApplicationId,
srcBranch);
return centralGitService
.createReference(referencedApplicationId, gitRefDTO, ArtifactType.APPLICATION, GIT_TYPE)
.map(result -> new ResponseDTO<>(HttpStatus.CREATED.value(), result, null));
}

@JsonView(Views.Public.class)
@PostMapping("/{referencedApplicationId}/checkout-ref")
public Mono<ResponseDTO<? extends Artifact>> checkoutReference(
@PathVariable String referencedApplicationId, @RequestBody GitRefDTO gitRefDTO) {
return centralGitService
.checkoutReference(referencedApplicationId, gitRefDTO, true, ARTIFACT_TYPE, GIT_TYPE)
.map(result -> new ResponseDTO<>(HttpStatus.OK.value(), result, null));
}

@JsonView(Views.Public.class)
@PostMapping("/{branchedApplicationId}/disconnect")
public Mono<ResponseDTO<? extends Artifact>> disconnectFromRemote(@PathVariable String branchedApplicationId) {
log.info("Going to remove the remoteUrl for application {}", branchedApplicationId);
return centralGitService
.detachRemote(branchedApplicationId, ARTIFACT_TYPE, GIT_TYPE)
.map(result -> new ResponseDTO<>(HttpStatus.OK.value(), result, null));
}

@JsonView(Views.Public.class)
@GetMapping("/{branchedApplicationId}/pull")
public Mono<ResponseDTO<GitPullDTO>> pull(@PathVariable String branchedApplicationId) {
log.info("Going to pull the latest for branchedApplicationId {}", branchedApplicationId);
return centralGitService
.pullArtifact(branchedApplicationId, ARTIFACT_TYPE, GIT_TYPE)
.map(result -> new ResponseDTO<>(HttpStatus.OK.value(), result, null));
}

@JsonView(Views.Public.class)
@GetMapping("/{branchedApplicationId}/status")
public Mono<ResponseDTO<GitStatusDTO>> getStatus(
@PathVariable String branchedApplicationId,
@RequestParam(required = false, defaultValue = "true") Boolean compareRemote) {
log.info("Going to get status for branchedApplicationId {}", branchedApplicationId);
return centralGitService
.getStatus(branchedApplicationId, compareRemote, ARTIFACT_TYPE, GIT_TYPE)
.map(result -> new ResponseDTO<>(HttpStatus.OK.value(), result, null));
}

@JsonView(Views.Public.class)
@GetMapping("/{referencedApplicationId}/fetch/remote")
public Mono<ResponseDTO<String>> fetchRemoteChanges(
@PathVariable String referencedApplicationId,
@RequestHeader(required = false, defaultValue = "branch") RefType refType) {
log.info("Going to compare with remote for default referencedApplicationId {}", referencedApplicationId);
return centralGitService
.fetchRemoteChanges(referencedApplicationId, true, ARTIFACT_TYPE, GIT_TYPE, refType)
.map(result -> new ResponseDTO<>(HttpStatus.OK.value(), result, null));
}

@JsonView(Views.Public.class)
@DeleteMapping("/{baseArtifactId}/ref")
public Mono<ResponseDTO<? extends Artifact>> deleteBranch(
@PathVariable String baseArtifactId, @RequestBody GitRefDTO gitRefDTO) {
log.info("Going to delete ref {} for baseApplicationId {}", gitRefDTO.getRefName(), baseArtifactId);
return centralGitService
.deleteGitReference(baseArtifactId, gitRefDTO, ARTIFACT_TYPE, GIT_TYPE)
.map(application -> new ResponseDTO<>(HttpStatus.OK.value(), application, null));
}

@JsonView(Views.Public.class)
@PutMapping("/{branchedApplicationId}/discard")
public Mono<ResponseDTO<? extends Artifact>> discardChanges(@PathVariable String branchedApplicationId) {
log.info("Going to discard changes for branchedApplicationId {}", branchedApplicationId);
return centralGitService
.discardChanges(branchedApplicationId, ARTIFACT_TYPE, GIT_TYPE)
.map(result -> new ResponseDTO<>((HttpStatus.OK.value()), result, null));
}

@JsonView(Views.Public.class)
@PostMapping("/{baseArtifactId}/branch/protected")
public Mono<ResponseDTO<List<String>>> updateProtectedBranches(
@PathVariable String baseArtifactId,
@RequestBody @Valid BranchProtectionRequestDTO branchProtectionRequestDTO) {
return centralGitService
.updateProtectedBranches(baseArtifactId, branchProtectionRequestDTO.getBranchNames(), ARTIFACT_TYPE)
.map(data -> new ResponseDTO<>(HttpStatus.OK.value(), data, null));
}

@JsonView(Views.Public.class)
@GetMapping("/{baseArtifactId}/branch/protected")
public Mono<ResponseDTO<List<String>>> getProtectedBranches(@PathVariable String baseArtifactId) {
return centralGitService
.getProtectedBranches(baseArtifactId, ARTIFACT_TYPE)
.map(list -> new ResponseDTO<>(HttpStatus.OK.value(), list, null));
}

@JsonView(Views.Public.class)
@PostMapping("/{branchedApplicationId}/auto-commit")
public Mono<ResponseDTO<AutoCommitResponseDTO>> autoCommitApplication(@PathVariable String branchedApplicationId) {
return autoCommitService
.autoCommitApplication(branchedApplicationId)
.map(data -> new ResponseDTO<>(HttpStatus.OK.value(), data, null));
}

@JsonView(Views.Public.class)
@GetMapping("/{baseApplicationId}/auto-commit/progress")
public Mono<ResponseDTO<AutoCommitResponseDTO>> getAutoCommitProgress(
@PathVariable String baseApplicationId,
@RequestHeader(name = FieldName.BRANCH_NAME, required = false) String branchName) {
return centralGitService
.getAutoCommitProgress(baseApplicationId, branchName, ARTIFACT_TYPE)
.map(data -> new ResponseDTO<>(HttpStatus.OK.value(), data, null));
}

@JsonView(Views.Public.class)
@PatchMapping("/{baseArtifactId}/auto-commit/toggle")
public Mono<ResponseDTO<Boolean>> toggleAutoCommitEnabled(@PathVariable String baseArtifactId) {
return centralGitService
.toggleAutoCommitEnabled(baseArtifactId, ARTIFACT_TYPE)
.map(data -> new ResponseDTO<>(HttpStatus.OK.value(), data, null));
}

@JsonView(Views.Public.class)
@GetMapping("/{branchedApplicationId}/branches")
public Mono<ResponseDTO<List<GitBranchDTO>>> branch(
@PathVariable String branchedApplicationId,
@RequestParam(required = false, defaultValue = "false") Boolean pruneBranches) {
log.debug("Going to get branch list for application {}", branchedApplicationId);
return centralGitService
.listBranchForArtifact(
branchedApplicationId, BooleanUtils.isTrue(pruneBranches), ARTIFACT_TYPE, GIT_TYPE)
.map(result -> new ResponseDTO<>(HttpStatus.OK.value(), result, null));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package com.appsmith.server.git.controllers;

import com.appsmith.server.constants.Url;
import com.appsmith.server.git.central.CentralGitService;
import com.appsmith.server.git.utils.GitProfileUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Slf4j
@RestController
@RequestMapping(Url.GIT_ARTIFACT_URL)
public class GitArtifactController extends GitArtifactControllerCE {

public GitArtifactController(CentralGitService centralGitService, GitProfileUtils gitProfileUtils) {
super(centralGitService, gitProfileUtils);
}
}
Loading

0 comments on commit bd116cd

Please sign in to comment.