mirror of
https://code.forgejo.org/actions/git-backporting.git
synced 2025-05-19 03:59:13 -04:00
feat(issue-77): handle multiple target branches (#78)
fix: https://github.com/kiegroup/git-backporting/issues/77 This enhancement allow users to backport the same change to multiple branches with one single tool invocation
This commit is contained in:
parent
c19a56a9ad
commit
5fc72e127b
25 changed files with 1774 additions and 234 deletions
|
@ -10,6 +10,12 @@ import LoggerService from "@bp/service/logger/logger-service";
|
|||
import LoggerServiceFactory from "@bp/service/logger/logger-service-factory";
|
||||
import { inferGitClient, inferGitApiUrl } from "@bp/service/git/git-util";
|
||||
|
||||
interface Git {
|
||||
gitClientType: GitClientType;
|
||||
gitClientApi: GitClient;
|
||||
gitCli: GitCLIService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Main runner implementation, it implements the core logic flow
|
||||
*/
|
||||
|
@ -62,47 +68,73 @@ export default class Runner {
|
|||
// 3. parse configs
|
||||
this.logger.debug("Parsing configs..");
|
||||
const configs: Configs = await new PullRequestConfigsParser().parseAndValidate(args);
|
||||
const originalPR: GitPullRequest = configs.originalPullRequest;
|
||||
const backportPR: BackportPullRequest = configs.backportPullRequest;
|
||||
const backportPRs: BackportPullRequest[] = configs.backportPullRequests;
|
||||
|
||||
// start local git operations
|
||||
const git: GitCLIService = new GitCLIService(configs.auth, configs.git);
|
||||
|
||||
const failures: string[] = [];
|
||||
// we need sequential backporting as they will operate on the same folder
|
||||
// avoid cloning the same repo multiple times
|
||||
for(const pr of backportPRs) {
|
||||
try {
|
||||
await this.executeBackport(configs, pr, {
|
||||
gitClientType: gitClientType,
|
||||
gitClientApi: gitApi,
|
||||
gitCli: git,
|
||||
});
|
||||
} catch(error) {
|
||||
this.logger.error(`Something went wrong backporting to ${pr.base}: ${error}`);
|
||||
failures.push(error as string);
|
||||
}
|
||||
}
|
||||
|
||||
if (failures.length > 0) {
|
||||
throw new Error(`Failure occurred during one of the backports: [${failures.join(" ; ")}]`);
|
||||
}
|
||||
}
|
||||
|
||||
async executeBackport(configs: Configs, backportPR: BackportPullRequest, git: Git): Promise<void> {
|
||||
this.logger.setContext(backportPR.base);
|
||||
|
||||
const originalPR: GitPullRequest = configs.originalPullRequest;
|
||||
|
||||
// 4. clone the repository
|
||||
this.logger.debug("Cloning repo..");
|
||||
await git.clone(configs.originalPullRequest.targetRepo.cloneUrl, configs.folder, configs.targetBranch);
|
||||
await git.gitCli.clone(configs.originalPullRequest.targetRepo.cloneUrl, configs.folder, backportPR.base);
|
||||
|
||||
// 5. create new branch from target one and checkout
|
||||
this.logger.debug("Creating local branch..");
|
||||
|
||||
await git.createLocalBranch(configs.folder, backportPR.head);
|
||||
await git.gitCli.createLocalBranch(configs.folder, backportPR.head);
|
||||
|
||||
// 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") {
|
||||
this.logger.debug("Fetching pull request remote..");
|
||||
const prefix = gitClientType === GitClientType.GITHUB ? "pull" : "merge-requests"; // default is for gitlab
|
||||
await git.fetch(configs.folder, `${prefix}/${configs.originalPullRequest.number}/head:pr/${configs.originalPullRequest.number}`);
|
||||
const prefix = git.gitClientType === GitClientType.GITHUB ? "pull" : "merge-requests"; // default is for gitlab
|
||||
await git.gitCli.fetch(configs.folder, `${prefix}/${configs.originalPullRequest.number}/head:pr/${configs.originalPullRequest.number}`);
|
||||
}
|
||||
|
||||
// 7. apply all changes to the new branch
|
||||
this.logger.debug("Cherry picking commits..");
|
||||
for (const sha of originalPR.commits!) {
|
||||
await git.cherryPick(configs.folder, sha, configs.mergeStrategy, configs.mergeStrategyOption);
|
||||
await git.gitCli.cherryPick(configs.folder, sha, configs.mergeStrategy, configs.mergeStrategyOption);
|
||||
}
|
||||
|
||||
if (!configs.dryRun) {
|
||||
// 8. push the new branch to origin
|
||||
await git.push(configs.folder, backportPR.head);
|
||||
await git.gitCli.push(configs.folder, backportPR.head);
|
||||
|
||||
// 9. create pull request new branch -> target branch (using octokit)
|
||||
const prUrl = await gitApi.createPullRequest(backportPR);
|
||||
const prUrl = await git.gitClientApi.createPullRequest(backportPR);
|
||||
this.logger.info(`Pull request created: ${prUrl}`);
|
||||
|
||||
} else {
|
||||
this.logger.warn("Pull request creation and remote push skipped");
|
||||
this.logger.info(`${JSON.stringify(backportPR, null, 2)}`);
|
||||
}
|
||||
}
|
||||
|
||||
this.logger.clearContext();
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue