mirror of
https://github.com/kiegroup/git-backporting.git
synced 2025-06-29 14:13:48 +00:00
Base implementation
This commit is contained in:
parent
05d156a5b0
commit
74703c48f3
53 changed files with 34684 additions and 392 deletions
|
@ -10,8 +10,10 @@ const fs_1 = __importDefault(require("fs"));
|
|||
* Command line git commands executor service
|
||||
*/
|
||||
class GitCLIService {
|
||||
constructor() {
|
||||
constructor(auth, author) {
|
||||
this.logger = logger_service_factory_1.default.getLogger();
|
||||
this.auth = auth;
|
||||
this.author = author;
|
||||
}
|
||||
/**
|
||||
* Return a pre-configured SimpleGit instance able to execute commands from current
|
||||
|
@ -21,7 +23,18 @@ class GitCLIService {
|
|||
*/
|
||||
git(cwd) {
|
||||
const gitConfig = { ...(cwd ? { baseDir: cwd } : {}) };
|
||||
return (0, simple_git_1.default)(gitConfig).addConfig("user.name", "Github").addConfig("user.email", "noreply@github.com");
|
||||
return (0, simple_git_1.default)(gitConfig).addConfig("user.name", this.author).addConfig("user.email", "noreply@github.com");
|
||||
}
|
||||
/**
|
||||
* Update the provided remote URL by adding the auth token if not empty
|
||||
* @param remoteURL remote link, e.g., https://github.com/lampajr/backporting-example.git
|
||||
*/
|
||||
remoteWithAuth(remoteURL) {
|
||||
if (this.auth && this.author) {
|
||||
return remoteURL.replace("://", `://${this.author}:${this.auth}@`);
|
||||
}
|
||||
// return remote as it is
|
||||
return remoteURL;
|
||||
}
|
||||
/**
|
||||
* Return the git version
|
||||
|
@ -39,9 +52,9 @@ class GitCLIService {
|
|||
* @param branch branch which should be cloned
|
||||
*/
|
||||
async clone(from, to, branch) {
|
||||
this.logger.info(`Cloning repository ${from}..`);
|
||||
this.logger.info(`Cloning repository ${from} to ${to}.`);
|
||||
if (!fs_1.default.existsSync(to)) {
|
||||
await this.git().clone(from, to, ["--quiet", "--shallow-submodules", "--no-tags", "--branch", branch]);
|
||||
await (0, simple_git_1.default)().clone(this.remoteWithAuth(from), to, ["--quiet", "--shallow-submodules", "--no-tags", "--branch", branch]);
|
||||
}
|
||||
else {
|
||||
this.logger.warn(`Folder ${to} already exist. Won't clone`);
|
||||
|
@ -53,7 +66,7 @@ class GitCLIService {
|
|||
* @param newBranch new branch name
|
||||
*/
|
||||
async createLocalBranch(cwd, newBranch) {
|
||||
this.logger.info(`Creating branch ${newBranch}..`);
|
||||
this.logger.info(`Creating branch ${newBranch}.`);
|
||||
await this.git(cwd).checkoutLocalBranch(newBranch);
|
||||
}
|
||||
/**
|
||||
|
@ -63,8 +76,8 @@ class GitCLIService {
|
|||
* @param remoteName [optional] name of the remote, by default 'fork' is used
|
||||
*/
|
||||
async addRemote(cwd, remote, remoteName = "fork") {
|
||||
this.logger.info(`Adding new remote ${remote}..`);
|
||||
await this.git(cwd).addRemote(remoteName, remote);
|
||||
this.logger.info(`Adding new remote ${remote}.`);
|
||||
await this.git(cwd).addRemote(remoteName, this.remoteWithAuth(remote));
|
||||
}
|
||||
/**
|
||||
* Git fetch from a particular branch
|
||||
|
@ -81,8 +94,8 @@ class GitCLIService {
|
|||
* @param sha commit sha
|
||||
*/
|
||||
async cherryPick(cwd, sha) {
|
||||
this.logger.info(`Cherry picking ${sha}..`);
|
||||
await this.git(cwd).raw(["cherry-pick", "--strategy=recursive", "-X", "theirs", sha]);
|
||||
this.logger.info(`Cherry picking ${sha}.`);
|
||||
await this.git(cwd).raw(["cherry-pick", "-m", "1", "--strategy=recursive", "--strategy-option=theirs", sha]);
|
||||
}
|
||||
/**
|
||||
* Push a branch to a remote
|
||||
|
@ -91,7 +104,7 @@ class GitCLIService {
|
|||
* @param remote [optional] remote to which the branch should be pushed to, by default 'origin'
|
||||
*/
|
||||
async push(cwd, branch, remote = "origin", force = false) {
|
||||
this.logger.info(`Pushing ${branch} to ${remote}..`);
|
||||
this.logger.info(`Pushing ${branch} to ${remote}.`);
|
||||
const options = ["--quiet"];
|
||||
if (force) {
|
||||
options.push("--force-with-lease");
|
||||
|
|
|
@ -5,6 +5,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const git_types_1 = require("../../service/git/git.types");
|
||||
const github_service_1 = __importDefault(require("../../service/git/github/github-service"));
|
||||
const logger_service_factory_1 = __importDefault(require("../../service/logger/logger-service-factory"));
|
||||
/**
|
||||
* Singleton git service factory class
|
||||
*/
|
||||
|
@ -22,7 +23,8 @@ class GitServiceFactory {
|
|||
*/
|
||||
static init(type, auth) {
|
||||
if (GitServiceFactory.instance) {
|
||||
throw new Error("Git service already initialized!");
|
||||
GitServiceFactory.logger.warn("Git service already initialized!");
|
||||
return;
|
||||
}
|
||||
switch (type) {
|
||||
case git_types_1.GitServiceType.GITHUB:
|
||||
|
@ -34,3 +36,4 @@ class GitServiceFactory {
|
|||
}
|
||||
}
|
||||
exports.default = GitServiceFactory;
|
||||
GitServiceFactory.logger = logger_service_factory_1.default.getLogger();
|
||||
|
|
|
@ -3,14 +3,25 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|||
class GitHubMapper {
|
||||
mapPullRequest(pr) {
|
||||
return {
|
||||
author: pr.user.login,
|
||||
url: pr.url,
|
||||
htmlUrl: pr.html_url,
|
||||
title: pr.title,
|
||||
body: pr.body,
|
||||
patchUrl: pr.patch_url,
|
||||
body: pr.body ?? "",
|
||||
state: pr.state,
|
||||
merged: pr.merged ?? false,
|
||||
mergedBy: pr.merged_by?.login,
|
||||
reviewers: pr.requested_reviewers.filter(r => "login" in r).map((r => r?.login)),
|
||||
sourceRepo: pr.head.repo.full_name,
|
||||
targetRepo: pr.base.repo.full_name,
|
||||
sourceRepo: {
|
||||
owner: pr.head.repo.full_name.split("/")[0],
|
||||
project: pr.head.repo.full_name.split("/")[1],
|
||||
cloneUrl: pr.head.repo.clone_url
|
||||
},
|
||||
targetRepo: {
|
||||
owner: pr.base.repo.full_name.split("/")[0],
|
||||
project: pr.base.repo.full_name.split("/")[1],
|
||||
cloneUrl: pr.base.repo.clone_url
|
||||
},
|
||||
commits: [pr.merge_commit_sha]
|
||||
};
|
||||
}
|
||||
|
|
|
@ -5,13 +5,16 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
const github_mapper_1 = __importDefault(require("../../../service/git/github/github-mapper"));
|
||||
const octokit_factory_1 = __importDefault(require("../../../service/git/github/octokit-factory"));
|
||||
const logger_service_factory_1 = __importDefault(require("../../../service/logger/logger-service-factory"));
|
||||
class GitHubService {
|
||||
constructor(token) {
|
||||
this.logger = logger_service_factory_1.default.getLogger();
|
||||
this.octokit = octokit_factory_1.default.getOctokit(token);
|
||||
this.mapper = new github_mapper_1.default();
|
||||
}
|
||||
// READ
|
||||
async getPullRequest(owner, repo, prNumber) {
|
||||
this.logger.info(`Getting pull request ${owner}/${repo}/${prNumber}.`);
|
||||
const { data } = await this.octokit.rest.pulls.get({
|
||||
owner: owner,
|
||||
repo: repo,
|
||||
|
@ -19,12 +22,48 @@ class GitHubService {
|
|||
});
|
||||
return this.mapper.mapPullRequest(data);
|
||||
}
|
||||
async getPullRequestFromUrl(prUrl) {
|
||||
const { owner, project } = this.getRepositoryFromPrUrl(prUrl);
|
||||
return this.getPullRequest(owner, project, parseInt(prUrl.substring(prUrl.lastIndexOf("/") + 1, prUrl.length)));
|
||||
}
|
||||
// WRITE
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
createPullRequest(owner, repo, head, base, title, body, reviewers) {
|
||||
// throw new Error("Method not implemented.");
|
||||
// TODO implement
|
||||
return Promise.resolve();
|
||||
async createPullRequest(backport) {
|
||||
this.logger.info(`Creating pull request ${backport.head} -> ${backport.base}.`);
|
||||
this.logger.info(`${JSON.stringify(backport, null, 2)}`);
|
||||
const { data } = await this.octokit.pulls.create({
|
||||
owner: backport.owner,
|
||||
repo: backport.repo,
|
||||
head: backport.head,
|
||||
base: backport.base,
|
||||
title: backport.title,
|
||||
body: backport.body
|
||||
});
|
||||
if (backport.reviewers.length > 0) {
|
||||
try {
|
||||
await this.octokit.pulls.requestReviewers({
|
||||
owner: backport.owner,
|
||||
repo: backport.repo,
|
||||
pull_number: data.number,
|
||||
reviewers: backport.reviewers
|
||||
});
|
||||
}
|
||||
catch (error) {
|
||||
this.logger.error(`Error requesting reviewers: ${error}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
// UTILS
|
||||
/**
|
||||
* Extract repository owner and project from the pull request url
|
||||
* @param prUrl pull request url
|
||||
* @returns {{owner: string, project: string}}
|
||||
*/
|
||||
getRepositoryFromPrUrl(prUrl) {
|
||||
const elems = prUrl.split("/");
|
||||
return {
|
||||
owner: elems[elems.length - 4],
|
||||
project: elems[elems.length - 3]
|
||||
};
|
||||
}
|
||||
}
|
||||
exports.default = GitHubService;
|
||||
|
|
|
@ -11,7 +11,7 @@ const rest_1 = require("@octokit/rest");
|
|||
class OctokitFactory {
|
||||
static getOctokit(token) {
|
||||
if (!OctokitFactory.octokit) {
|
||||
OctokitFactory.logger.info("Creating octokit instance..");
|
||||
OctokitFactory.logger.info("Creating octokit instance.");
|
||||
OctokitFactory.octokit = new rest_1.Octokit({
|
||||
auth: token,
|
||||
userAgent: "lampajr/backporting"
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue