Skip to content
This repository has been archived by the owner on Jul 23, 2024. It is now read-only.

Commit

Permalink
Feat: add git prebuilt-tasks
Browse files Browse the repository at this point in the history
This commit addressed a new way to clone and archive git repositories
inside Parodos.

The main objective for these tasks is to implement work on top of
Move2kube.

Signed-off-by: Eloy Coto <eloy.coto@acalustra.com>
  • Loading branch information
eloycoto committed May 4, 2023
1 parent 039c1c4 commit 40786b4
Show file tree
Hide file tree
Showing 6 changed files with 495 additions and 0 deletions.
36 changes: 36 additions & 0 deletions prebuilt-tasks/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
<jira-rest-client.version>5.2.4</jira-rest-client.version>
<attlasian-fugue.version>2.6.1</attlasian-fugue.version>
<org.json.version>20230227</org.json.version>
<jgit-version>6.5.0.202303070854-r</jgit-version>
</properties>

<repositories>
Expand Down Expand Up @@ -86,5 +87,40 @@
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
</dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<version>${jgit-version}</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.eclipse.jgit/org.eclipse.jgit.ssh.apache -->
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.ssh.apache</artifactId>
<version>${jgit-version}</version>
</dependency>

<!-- https://mvnrepository.com/artifact/org.eclipse.jgit/org.eclipse.jgit.gpg.bc -->
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.gpg.bc</artifactId>
<version>${jgit-version}</version>
</dependency>

<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit.archive</artifactId>
<version>${jgit-version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package com.redhat.parodos.tasks.git;

import com.google.common.io.Files;
import com.redhat.parodos.workflow.parameter.WorkParameter;
import com.redhat.parodos.workflow.parameter.WorkParameterType;
import com.redhat.parodos.workflow.task.BaseWorkFlowTask;
import com.redhat.parodos.workflows.work.DefaultWorkReport;
import com.redhat.parodos.workflows.work.WorkContext;
import com.redhat.parodos.workflows.work.WorkReport;
import com.redhat.parodos.workflows.work.WorkStatus;
import lombok.AllArgsConstructor;
import lombok.NonNull;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.eclipse.jgit.api.ArchiveCommand;
import org.eclipse.jgit.archive.ZipFormat;

import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.io.FileOutputStream;

@Slf4j
@AllArgsConstructor
public class GitArchive extends BaseWorkFlowTask {

@Autowired
private GitUtils gitUtils;

@Override
public @NonNull List<WorkParameter> getWorkFlowTaskParameters() {
return List.of(WorkParameter.builder().key(gitUtils.getGitRepoPath()).type(WorkParameterType.TEXT)
.optional(true).description("path where the git repo is located").build());
}

@Override
public WorkReport execute(WorkContext workContext) {
String path = gitUtils.getRepoPath(workContext);
if (path == null || path == "") {
return new DefaultWorkReport(WorkStatus.FAILED, workContext,
new Exception("The path parameter cannot be null or empty"));
}

Repository repo = getRepo(path);
if (repo == null) {
return new DefaultWorkReport(WorkStatus.FAILED, workContext, new Exception("No repository at " + path));
}

try {
var archivePath = archive(repo);
workContext.put(gitUtils.getContextArchivePath(), archivePath.toAbsolutePath().toString());
}
catch (Exception e) {
return new DefaultWorkReport(WorkStatus.FAILED, workContext,
new Exception("Cannot archive the repository:" + e));
}
finally {
repo.close();
}

return new DefaultWorkReport(WorkStatus.COMPLETED, workContext, null);
}

private Repository getRepo(String path) {
Path gitDir = Paths.get(path);
try {
Repository repository = new FileRepositoryBuilder().setGitDir(gitDir.toFile()).build();
return repository;
}
catch (Exception e) {
log.warn("Cannot clone repository for path: '" + path + "' with error: ", e);
return null;
}
}

private Path archive(Repository repo) throws Exception {

// Create a Git instance
Git git = new Git(repo);
ArchiveCommand.registerFormat("zip", new ZipFormat());

// Create a ZipFormat instance
String tmpdir = Files.createTempDir().getAbsolutePath();
Path zipFile = Paths.get(tmpdir + "/output.zip");

try {
FileOutputStream out = new FileOutputStream(zipFile.toAbsolutePath().toString());
git.archive().setTree(repo.resolve("HEAD")).setFormat("zip").setOutputStream(out).call();
}
finally {
git.close();
}
return zipFile;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
package com.redhat.parodos.tasks.git;

import com.google.common.io.Files;
import com.redhat.parodos.tasks.jira.JiraTask;
import com.redhat.parodos.workflow.exception.MissingParameterException;
import com.redhat.parodos.workflow.parameter.WorkParameter;
import com.redhat.parodos.workflow.parameter.WorkParameterType;
import com.redhat.parodos.workflow.task.BaseWorkFlowTask;
import com.redhat.parodos.workflows.work.DefaultWorkReport;
import com.redhat.parodos.workflows.work.WorkContext;
import com.redhat.parodos.workflows.work.WorkReport;
import com.redhat.parodos.workflows.work.WorkStatus;

import static com.redhat.parodos.workflow.context.WorkContextDelegate.getOptionalValueFromRequestParams;
import static com.redhat.parodos.workflow.context.WorkContextDelegate.getRequiredValueFromRequestParams;

import lombok.AllArgsConstructor;
import lombok.NonNull;

import java.io.File;
import java.util.List;

import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.api.errors.InvalidRemoteException;
import org.eclipse.jgit.api.errors.TransportException;
import org.springframework.beans.factory.annotation.Autowired;

@AllArgsConstructor
public class GitClone extends BaseWorkFlowTask {

@Autowired
private GitUtils gitUtils;

@Override
public @NonNull List<WorkParameter> getWorkFlowTaskParameters() {
return List.of(
WorkParameter.builder().key(gitUtils.getUri()).type(WorkParameterType.TEXT).optional(false)
.description("Url to clone from").build(),
WorkParameter.builder().key(gitUtils.getBranch()).type(WorkParameterType.TEXT).optional(true)
.description("Branch to clone from, default main").build(),
WorkParameter.builder().key("credentials").type(WorkParameterType.TEXT).optional(false)
.description("Git credential").build());
}

@Override
public WorkReport execute(WorkContext workContext) {
String gitUri = "";
String destination = "";
String gitBranch = "";

try {
gitUri = getRequiredValueFromRequestParams(workContext, gitUtils.getUri());
gitBranch = getOptionalValueFromRequestParams(workContext, gitUtils.getBranch(), "main");
destination = cloneRepo(gitUri, gitBranch);
}
catch (MissingParameterException e) {
return new DefaultWorkReport(WorkStatus.FAILED, workContext, e);
}
catch (TransportException e) {
return new DefaultWorkReport(WorkStatus.FAILED, workContext,
new Exception("cannot connect to the repository server"));
}
catch (InvalidRemoteException e) {
return new DefaultWorkReport(WorkStatus.FAILED, workContext,
new Exception("Remote repository " + gitUri + " is not available"));
}
catch (GitAPIException e) {
return new DefaultWorkReport(WorkStatus.FAILED, workContext, new Exception("cannot clone repository"));
}

workContext.put(gitUtils.getContextUri(), gitUri);
workContext.put(gitUtils.getContextDestination(), destination);
workContext.put(gitUtils.getContextBranch(), gitBranch);
return new DefaultWorkReport(WorkStatus.COMPLETED, workContext, null);
}

private String cloneRepo(String gitUri, String gitBranch)
throws InvalidRemoteException, TransportException, GitAPIException {
String tmpdir = Files.createTempDir().getAbsolutePath();
Git.cloneRepository().setURI(gitUri).setBranch("refs/heads/" + gitBranch).setDirectory(new File(tmpdir)).call();
return tmpdir;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package com.redhat.parodos.tasks.git;

import com.redhat.parodos.workflows.work.WorkContext;
import lombok.Getter;

import static com.redhat.parodos.workflow.context.WorkContextDelegate.getOptionalValueFromRequestParams;

public class GitUtils {

@Getter
static final String gitRepoPath = "path";

@Getter
static final String uri = "uri";

@Getter
static final String branch = "branch";

@Getter
static final String ContextUri = "gitUri";

@Getter
static final String ContextBranch = "gitBranch";

@Getter
static final String contextDestination = "gitDestination";

@Getter
static final String contextArchivePath = "gitArchivePath";

public String getRepoPath(WorkContext workContext) {
var dest = workContext.get(contextDestination);
if (dest == null) {
return getOptionalValueFromRequestParams(workContext, this.gitRepoPath, "");
}
return getOptionalValueFromRequestParams(workContext, gitRepoPath, dest.toString());
}

}
Loading

0 comments on commit 40786b4

Please sign in to comment.