chore: git detach (#37934)
## Description > [!TIP] > _Add a TL;DR when the description is longer than 500 words or extremely technical (helps the content, marketing, and DevRel team)._ > > _Please also include relevant motivation and context. List any dependencies that are required for this change. Add links to Notion, Figma or any other documents that might be relevant to the PR._ Fixes #37439 ## Automation /ok-to-test tags="@tag.Git" ## 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** - Introduced methods for committing artifacts and managing Git operations, including `commitArtifact`, `detachRemote`, and `publishArtifactPostCommit`. - Added functionality to list branches and check repository privacy. - Enhanced error handling for Git operations, improving reliability during commits and pushes. - **Bug Fixes** - Updated parameter naming for consistency across methods, enhancing clarity. - **Documentation** - Improved JavaDoc comments for better understanding of method purposes and parameters. <!-- end of auto-generated comment: release notes by coderabbit.ai --> <!-- This is an auto-generated comment: Cypress test results --> > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: <https://github.com/appsmithorg/appsmith/actions/runs/12158276745> > Commit: f058fbe37f866ecee2cfb8fde30e4d4b62e2fd7f > <a href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=12158276745&attempt=1" target="_blank">Cypress dashboard</a>. > Tags: `@tag.Git` > Spec: > <hr>Wed, 04 Dec 2024 11:42:39 UTC <!-- end of auto-generated comment: Cypress test results -->
This commit is contained in:
parent
9c669ddcb8
commit
a64c16d98a
|
|
@ -21,4 +21,6 @@ public interface CentralGitServiceCE {
|
|||
|
||||
Mono<String> commitArtifact(
|
||||
CommitDTO commitDTO, String branchedArtifactId, ArtifactType artifactType, GitType gitType);
|
||||
|
||||
Mono<? extends Artifact> detachRemote(String branchedArtifactId, ArtifactType artifactType, GitType gitType);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package com.appsmith.server.git.central;
|
|||
|
||||
import com.appsmith.external.constants.AnalyticsEvents;
|
||||
import com.appsmith.external.git.constants.GitConstants;
|
||||
import com.appsmith.external.git.constants.GitSpan;
|
||||
import com.appsmith.external.models.Datasource;
|
||||
import com.appsmith.external.models.DatasourceStorage;
|
||||
import com.appsmith.git.dto.CommitDTO;
|
||||
|
|
@ -47,8 +48,10 @@ import org.springframework.stereotype.Service;
|
|||
import org.springframework.util.CollectionUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import reactor.core.observability.micrometer.Micrometer;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.util.function.Tuple2;
|
||||
import reactor.util.function.Tuple3;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.time.Instant;
|
||||
|
|
@ -571,7 +574,7 @@ public class CentralGitServiceCEImpl implements CentralGitServiceCE {
|
|||
return this.commitArtifact(commitDTO, artifact.getId(), artifactType, gitType)
|
||||
.onErrorResume(error ->
|
||||
// If the push fails remove all the cloned files from local repo
|
||||
this.detachRemote(baseArtifactId, artifactType)
|
||||
this.detachRemote(baseArtifactId, artifactType, gitType)
|
||||
.flatMap(isDeleted -> {
|
||||
if (error instanceof TransportException) {
|
||||
return gitAnalyticsUtils
|
||||
|
|
@ -852,13 +855,81 @@ public class CentralGitServiceCEImpl implements CentralGitServiceCE {
|
|||
}
|
||||
|
||||
/**
|
||||
* TODO: implementation quite similar to the disconnectGitRepo
|
||||
* @param baseArtifactId
|
||||
* @param artifactType
|
||||
* @return
|
||||
* Method to remove all the git metadata for the artifact and connected resources. This will remove:
|
||||
* - local repo
|
||||
* - all the branched applications present in DB except for default application
|
||||
*
|
||||
* @param branchedArtifactId : id of any branched artifact for the given repo
|
||||
* @param artifactType : type of artifact
|
||||
* @return : the base artifact after removal of git flow.
|
||||
*/
|
||||
protected Mono<? extends Artifact> detachRemote(String baseArtifactId, ArtifactType artifactType) {
|
||||
return null;
|
||||
public Mono<? extends Artifact> detachRemote(
|
||||
String branchedArtifactId, ArtifactType artifactType, GitType gitType) {
|
||||
GitHandlingService gitHandlingService = gitHandlingServiceResolver.getGitHandlingService(gitType);
|
||||
GitArtifactHelper<?> gitArtifactHelper = gitArtifactHelperResolver.getArtifactHelper(artifactType);
|
||||
AclPermission gitConnectPermission = gitArtifactHelper.getArtifactGitConnectPermission();
|
||||
|
||||
Mono<Tuple2<? extends Artifact, ? extends Artifact>> baseAndBranchedArtifactMono =
|
||||
getBaseAndBranchedArtifacts(branchedArtifactId, artifactType, gitConnectPermission);
|
||||
|
||||
Mono<? extends Artifact> disconnectMono = baseAndBranchedArtifactMono
|
||||
.flatMap(artifactTuples -> {
|
||||
Artifact baseArtifact = artifactTuples.getT1();
|
||||
|
||||
if (isBaseGitMetadataInvalid(baseArtifact.getGitArtifactMetadata(), gitType)) {
|
||||
return Mono.error(new AppsmithException(
|
||||
AppsmithError.INVALID_GIT_CONFIGURATION,
|
||||
"Please reconfigure the artifact to connect to git repo"));
|
||||
}
|
||||
|
||||
GitArtifactMetadata gitArtifactMetadata = baseArtifact.getGitArtifactMetadata();
|
||||
ArtifactJsonTransformationDTO jsonTransformationDTO = new ArtifactJsonTransformationDTO();
|
||||
jsonTransformationDTO.setRefType(RefType.BRANCH);
|
||||
jsonTransformationDTO.setWorkspaceId(baseArtifact.getWorkspaceId());
|
||||
jsonTransformationDTO.setBaseArtifactId(gitArtifactMetadata.getDefaultArtifactId());
|
||||
jsonTransformationDTO.setRepoName(gitArtifactMetadata.getRepoName());
|
||||
jsonTransformationDTO.setArtifactType(baseArtifact.getArtifactType());
|
||||
jsonTransformationDTO.setRefName(gitArtifactMetadata.getBranchName());
|
||||
|
||||
// Remove the git contents from file system
|
||||
return Mono.zip(gitHandlingService.listBranches(jsonTransformationDTO), Mono.just(baseArtifact));
|
||||
})
|
||||
.flatMap(tuple -> {
|
||||
List<String> localBranches = tuple.getT1();
|
||||
Artifact baseArtifact = tuple.getT2();
|
||||
|
||||
baseArtifact.setGitArtifactMetadata(null);
|
||||
gitArtifactHelper.resetAttributeInBaseArtifact(baseArtifact);
|
||||
|
||||
GitArtifactMetadata gitArtifactMetadata = baseArtifact.getGitArtifactMetadata();
|
||||
ArtifactJsonTransformationDTO jsonTransformationDTO = new ArtifactJsonTransformationDTO();
|
||||
jsonTransformationDTO.setRefType(RefType.BRANCH);
|
||||
jsonTransformationDTO.setWorkspaceId(baseArtifact.getWorkspaceId());
|
||||
jsonTransformationDTO.setBaseArtifactId(gitArtifactMetadata.getDefaultArtifactId());
|
||||
jsonTransformationDTO.setRepoName(gitArtifactMetadata.getRepoName());
|
||||
jsonTransformationDTO.setArtifactType(baseArtifact.getArtifactType());
|
||||
jsonTransformationDTO.setRefName(gitArtifactMetadata.getBranchName());
|
||||
|
||||
// Remove the parent application branch name from the list
|
||||
Mono<Boolean> removeRepoMono = gitHandlingService.removeRepository(jsonTransformationDTO);
|
||||
Mono<? extends Artifact> updatedArtifactMono = gitArtifactHelper.saveArtifact(baseArtifact);
|
||||
|
||||
Flux<? extends Artifact> deleteAllBranchesFlux =
|
||||
gitArtifactHelper.deleteAllBranches(branchedArtifactId, localBranches);
|
||||
|
||||
return Mono.zip(updatedArtifactMono, removeRepoMono, deleteAllBranchesFlux.collectList())
|
||||
.map(Tuple3::getT1);
|
||||
})
|
||||
.flatMap(updatedBaseArtifact -> {
|
||||
return gitArtifactHelper
|
||||
.disconnectEntitiesOfBaseArtifact(updatedBaseArtifact)
|
||||
.then(gitAnalyticsUtils.addAnalyticsForGitOperation(
|
||||
AnalyticsEvents.GIT_DISCONNECT, updatedBaseArtifact, false));
|
||||
})
|
||||
.name(GitSpan.OPS_DETACH_REMOTE)
|
||||
.tap(Micrometer.observation(observationRegistry));
|
||||
|
||||
return Mono.create(sink -> disconnectMono.subscribe(sink::success, sink::error, null, sink.currentContext()));
|
||||
}
|
||||
|
||||
private boolean isBaseGitMetadataInvalid(GitArtifactMetadata gitArtifactMetadata, GitType gitType) {
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ import com.appsmith.server.git.dtos.ArtifactJsonTransformationDTO;
|
|||
import reactor.core.publisher.Mono;
|
||||
import reactor.util.function.Tuple2;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
public interface GitHandlingServiceCE {
|
||||
|
|
@ -38,6 +39,8 @@ public interface GitHandlingServiceCE {
|
|||
|
||||
Mono<Boolean> removeRepository(ArtifactJsonTransformationDTO artifactJsonTransformationDTO);
|
||||
|
||||
Mono<List<String>> listBranches(ArtifactJsonTransformationDTO artifactJsonTransformationDTO);
|
||||
|
||||
Mono<Boolean> validateEmptyRepository(ArtifactJsonTransformationDTO artifactJsonTransformationDTO);
|
||||
|
||||
Mono<Boolean> initialiseReadMe(
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package com.appsmith.server.git.fs;
|
||||
|
||||
import com.appsmith.external.constants.AnalyticsEvents;
|
||||
import com.appsmith.external.dtos.GitBranchDTO;
|
||||
import com.appsmith.external.git.constants.GitConstants;
|
||||
import com.appsmith.external.git.constants.GitSpan;
|
||||
import com.appsmith.external.git.handler.FSGitHandler;
|
||||
|
|
@ -49,12 +50,14 @@ import org.springframework.stereotype.Service;
|
|||
import org.springframework.transaction.reactive.TransactionalOperator;
|
||||
import org.springframework.util.StringUtils;
|
||||
import reactor.core.observability.micrometer.Micrometer;
|
||||
import reactor.core.publisher.Flux;
|
||||
import reactor.core.publisher.Mono;
|
||||
import reactor.util.function.Tuple2;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Path;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
|
|
@ -248,6 +251,32 @@ public class GitFSServiceCEImpl implements GitHandlingServiceCE {
|
|||
return commonGitFileUtils.deleteLocalRepo(repoSuffix);
|
||||
}
|
||||
|
||||
/**
|
||||
* List all the local branches present in the file system
|
||||
* @param artifactJsonTransformationDTO
|
||||
* @return
|
||||
*/
|
||||
@Override
|
||||
public Mono<List<String>> listBranches(ArtifactJsonTransformationDTO artifactJsonTransformationDTO) {
|
||||
GitArtifactHelper<?> gitArtifactHelper =
|
||||
gitArtifactHelperResolver.getArtifactHelper(artifactJsonTransformationDTO.getArtifactType());
|
||||
|
||||
Path repoSuffix = gitArtifactHelper.getRepoSuffixPath(
|
||||
artifactJsonTransformationDTO.getWorkspaceId(),
|
||||
artifactJsonTransformationDTO.getBaseArtifactId(),
|
||||
artifactJsonTransformationDTO.getRepoName());
|
||||
|
||||
return fsGitHandler
|
||||
.listBranches(repoSuffix)
|
||||
.flatMapMany(Flux::fromIterable)
|
||||
.filter(gitBranchDTO -> {
|
||||
return StringUtils.hasText(gitBranchDTO.getBranchName())
|
||||
&& !gitBranchDTO.getBranchName().startsWith("origin");
|
||||
})
|
||||
.map(GitBranchDTO::getBranchName)
|
||||
.collectList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<Boolean> validateEmptyRepository(ArtifactJsonTransformationDTO artifactJsonTransformationDTO) {
|
||||
GitArtifactHelper<?> gitArtifactHelper =
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user