gitlab-runner-gateway/src/main/java/tk/antoine_roux/wiki/service/GitService.java

76 lines
3.1 KiB
Java

package tk.antoine_roux.wiki.service;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.GitAPIException;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Service;
import tk.antoine_roux.wiki.model.internal.GitlabCI;
import tk.antoine_roux.wiki.model.request.HookEvent;
import tk.antoine_roux.wiki.model.request.secondary.Commit;
import java.io.IOException;
import java.nio.file.Files;
import java.util.Optional;
@Service
public class GitService {
public static final String GITLAB_CI_FILE_PATH = ".gitlab-ci.yml";
private static final String GITLAB_RUNNER_CLONE_PREFIX = "gitlab-runner-clone";
public final UsernamePasswordCredentialsProvider credentialsProvider;
private final ObjectMapper objectMapper;
@Autowired
public GitService(UsernamePasswordCredentialsProvider credentialsProvider, @Qualifier("YAMLObjectMapper") ObjectMapper objectMapper) {
this.credentialsProvider = credentialsProvider;
this.objectMapper = objectMapper;
}
/**
* return .gitlab-ci.yml content for {@link HookEvent}
*/
public Optional<GitlabCI> getYMLGitlabCI(HookEvent hookEvent) throws IOException, GitAPIException {
Optional<GitlabCI> optJob;
if (hookEvent.commits.isEmpty()) {
optJob = Optional.empty();
} else {
// search for head commit or take first in event's list of commit
Commit commit = hookEvent.commits.stream().filter(co -> co.id.equals(hookEvent.headCommit))
.findFirst().orElse(hookEvent.commits.get(0));
optJob = Optional.of(this.getGitlabCIContent(hookEvent.repository.cloneUrl, commit));
}
return optJob;
}
/**
* return .gitlab-ci.yml content for given commit into cloneUrl repository
*/
private GitlabCI getGitlabCIContent(String cloneURL, Commit commit) throws IOException, GitAPIException {
Git call = Git.cloneRepository()
.setURI(cloneURL)
.setCredentialsProvider(this.credentialsProvider)
.setDirectory(Files.createTempDirectory(GITLAB_RUNNER_CLONE_PREFIX).toFile())
.call();
RevWalk revWalk = new RevWalk(call.getRepository());
RevCommit revCommit = revWalk.parseCommit(ObjectId.fromString(commit.id));
try (TreeWalk walk = TreeWalk.forPath(call.getRepository(), GITLAB_CI_FILE_PATH, revCommit.getTree())) {
if (walk != null) {
byte[] bytes = call.getRepository().open(walk.getObjectId(0)).getBytes();
return this.objectMapper.readValue(bytes, GitlabCI.class);
} else {
throw new IllegalArgumentException("No path found.");
}
}
}
}