mirror of
https://github.com/kiegroup/git-backporting.git
synced 2025-06-28 21:53:47 +00:00
feat: pull request backporting
feat: backport still open pull requests
This commit is contained in:
commit
b3936e019a
53 changed files with 48467 additions and 0 deletions
126
src/service/runner/runner.ts
Normal file
126
src/service/runner/runner.ts
Normal file
|
@ -0,0 +1,126 @@
|
|||
import ArgsParser from "@bp/service/args/args-parser";
|
||||
import { Args } from "@bp/service/args/args.types";
|
||||
import { Configs } from "@bp/service/configs/configs.types";
|
||||
import PullRequestConfigsParser from "@bp/service/configs/pullrequest/pr-configs-parser";
|
||||
import GitCLIService from "@bp/service/git/git-cli";
|
||||
import GitService from "@bp/service/git/git-service";
|
||||
import GitServiceFactory from "@bp/service/git/git-service-factory";
|
||||
import { BackportPullRequest, GitPullRequest, GitServiceType } from "@bp/service/git/git.types";
|
||||
import LoggerService from "@bp/service/logger/logger-service";
|
||||
import LoggerServiceFactory from "@bp/service/logger/logger-service-factory";
|
||||
|
||||
/**
|
||||
* Main runner implementation, it implements the core logic flow
|
||||
*/
|
||||
export default class Runner {
|
||||
|
||||
private logger: LoggerService;
|
||||
private argsParser: ArgsParser;
|
||||
|
||||
constructor(parser: ArgsParser) {
|
||||
this.logger = LoggerServiceFactory.getLogger();
|
||||
this.argsParser = parser;
|
||||
}
|
||||
|
||||
/**
|
||||
* Infer the remote GIT service to interact with based on the provided
|
||||
* pull request URL
|
||||
* @param prUrl provided pull request URL
|
||||
* @returns {GitServiceType}
|
||||
*/
|
||||
private inferRemoteGitService(prUrl: string): GitServiceType {
|
||||
const stdPrUrl = prUrl.toLowerCase().trim();
|
||||
|
||||
if (stdPrUrl.includes(GitServiceType.GITHUB.toString())) {
|
||||
return GitServiceType.GITHUB;
|
||||
}
|
||||
|
||||
throw new Error(`Remote GIT service not recognixed from PR url: ${prUrl}`);
|
||||
}
|
||||
|
||||
/**
|
||||
* Entry point invoked by the command line or gha
|
||||
*/
|
||||
async run(): Promise<void> {
|
||||
this.logger.info("Starting process.");
|
||||
|
||||
try {
|
||||
await this.execute();
|
||||
|
||||
this.logger.info("Process succeeded!");
|
||||
process.exit(0);
|
||||
|
||||
} catch (error) {
|
||||
this.logger.error(`${error}`);
|
||||
|
||||
this.logger.info("Process failed!");
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Core logic
|
||||
*/
|
||||
async execute(): Promise<void>{
|
||||
|
||||
// 1. parse args
|
||||
const args: Args = this.argsParser.parse();
|
||||
|
||||
if (args.dryRun) {
|
||||
this.logger.warn("Dry run enabled!");
|
||||
}
|
||||
|
||||
// 2. init git service
|
||||
GitServiceFactory.init(this.inferRemoteGitService(args.pullRequest), args.auth);
|
||||
const gitApi: GitService = GitServiceFactory.getService();
|
||||
|
||||
// 3. parse configs
|
||||
const configs: Configs = await new PullRequestConfigsParser().parseAndValidate(args);
|
||||
const originalPR: GitPullRequest = configs.originalPullRequest;
|
||||
const backportPR: GitPullRequest = configs.backportPullRequest;
|
||||
|
||||
// start local git operations
|
||||
const git: GitCLIService = new GitCLIService(configs.auth, configs.author);
|
||||
|
||||
// 4. clone the repository
|
||||
await git.clone(configs.originalPullRequest.targetRepo.cloneUrl, configs.folder, configs.targetBranch);
|
||||
|
||||
// 5. create new branch from target one and checkout
|
||||
const backportBranch = `bp-${configs.targetBranch}-${originalPR.commits.join("-")}`;
|
||||
await git.createLocalBranch(configs.folder, backportBranch);
|
||||
|
||||
// 6. fetch pull request remote if source owner != target owner or pull request still open
|
||||
if (configs.originalPullRequest.sourceRepo.owner !== configs.originalPullRequest.targetRepo.owner ||
|
||||
configs.originalPullRequest.state === "open") {
|
||||
await git.fetch(configs.folder, `pull/${configs.originalPullRequest.number}/head:pr/${configs.originalPullRequest.number}`);
|
||||
}
|
||||
|
||||
// 7. apply all changes to the new branch
|
||||
for (const sha of originalPR.commits) {
|
||||
await git.cherryPick(configs.folder, sha);
|
||||
}
|
||||
|
||||
const backport: BackportPullRequest = {
|
||||
owner: originalPR.targetRepo.owner,
|
||||
repo: originalPR.targetRepo.project,
|
||||
head: backportBranch,
|
||||
base: configs.targetBranch,
|
||||
title: backportPR.title,
|
||||
body: backportPR.body,
|
||||
reviewers: backportPR.reviewers
|
||||
};
|
||||
|
||||
if (!configs.dryRun) {
|
||||
// 8. push the new branch to origin
|
||||
await git.push(configs.folder, backportBranch);
|
||||
|
||||
// 9. create pull request new branch -> target branch (using octokit)
|
||||
await gitApi.createPullRequest(backport);
|
||||
|
||||
} else {
|
||||
this.logger.warn("Pull request creation and remote push skipped!");
|
||||
this.logger.info(`${JSON.stringify(backport, null, 2)}`);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue