From 710d79fff8a6b9535d54977787006e3aaacabcbd Mon Sep 17 00:00:00 2001 From: Andrea Lamparelli Date: Wed, 4 Jan 2023 15:05:54 +0100 Subject: [PATCH] feat(open-pr): allow open pull requests backporting * [ISSUE-18] allow open pull requests backporting --- .husky/pre-commit | 2 +- build/src/service/git/git-cli.js | 115 --- build/src/service/git/git-service-factory.js | 39 - build/src/service/git/git-service.js | 2 - build/src/service/git/git.types.js | 7 - build/src/service/git/github/github-mapper.js | 29 - .../src/service/git/github/github-service.js | 69 -- .../src/service/git/github/octokit-factory.js | 24 - .../service/logger/console-logger-service.js | 27 - .../service/logger/logger-service-factory.js | 18 - build/src/service/logger/logger-service.js | 2 - build/src/service/logger/logger.js | 15 - .../service/git/github/github-service.test.js | 37 - build/test/support/moctokit/moctokit-data.js | 899 ----------------- .../test/support/moctokit/moctokit-support.js | 63 -- dist/cli/index.js | 32 +- dist/gha/index.js | 32 +- src/service/configs/configs-parser.ts | 19 +- .../configs/pullrequest/pr-configs-parser.ts | 1 + src/service/git/git-cli.ts | 1 + src/service/git/git.types.ts | 4 +- src/service/git/github/github-mapper.ts | 5 +- src/service/runner/runner.ts | 7 +- .../pullrequest/pr-configs-parser.test.ts | 53 +- test/service/runner/cli-runner.test.ts | 100 +- test/service/runner/gha-runner.test.ts | 50 +- test/support/moctokit/moctokit-data.ts | 910 +++++++++++++++++- test/support/moctokit/moctokit-support.ts | 28 +- 28 files changed, 1203 insertions(+), 1387 deletions(-) delete mode 100644 build/src/service/git/git-cli.js delete mode 100644 build/src/service/git/git-service-factory.js delete mode 100644 build/src/service/git/git-service.js delete mode 100644 build/src/service/git/git.types.js delete mode 100644 build/src/service/git/github/github-mapper.js delete mode 100644 build/src/service/git/github/github-service.js delete mode 100644 build/src/service/git/github/octokit-factory.js delete mode 100644 build/src/service/logger/console-logger-service.js delete mode 100644 build/src/service/logger/logger-service-factory.js delete mode 100644 build/src/service/logger/logger-service.js delete mode 100644 build/src/service/logger/logger.js delete mode 100644 build/test/service/git/github/github-service.test.js delete mode 100644 build/test/support/moctokit/moctokit-data.js delete mode 100644 build/test/support/moctokit/moctokit-support.js diff --git a/.husky/pre-commit b/.husky/pre-commit index 9f3420b..4c2576f 100755 --- a/.husky/pre-commit +++ b/.husky/pre-commit @@ -1,4 +1,4 @@ #!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" -npm run lint && npm run build && git add dist +npm run lint && npm run build && git add dist && rm -rf build diff --git a/build/src/service/git/git-cli.js b/build/src/service/git/git-cli.js deleted file mode 100644 index ebf7eeb..0000000 --- a/build/src/service/git/git-cli.js +++ /dev/null @@ -1,115 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const logger_service_factory_1 = __importDefault(require("../../service/logger/logger-service-factory")); -const simple_git_1 = __importDefault(require("simple-git")); -const fs_1 = __importDefault(require("fs")); -/** - * Command line git commands executor service - */ -class GitCLIService { - 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 - * directory or the provided one - * @param cwd [optional] current working directory - * @returns {SimpleGit} - */ - git(cwd) { - const gitConfig = { ...(cwd ? { baseDir: cwd } : {}) }; - 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 - * @returns {Promise} - */ - async version(cwd) { - const rawOutput = await this.git(cwd).raw("version"); - const match = rawOutput.match(/(\d+\.\d+(\.\d+)?)/); - return match ? match[1] : undefined; - } - /** - * Clone a git repository - * @param from url or path from which the repository should be cloned from - * @param to location at which the repository should be cloned at - * @param branch branch which should be cloned - */ - async clone(from, to, branch) { - this.logger.info(`Cloning repository ${from} to ${to}.`); - if (!fs_1.default.existsSync(to)) { - 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`); - } - } - /** - * Create a new branch starting from the current one and checkout in it - * @param cwd repository in which createBranch should be performed - * @param newBranch new branch name - */ - async createLocalBranch(cwd, newBranch) { - this.logger.info(`Creating branch ${newBranch}.`); - await this.git(cwd).checkoutLocalBranch(newBranch); - } - /** - * Add a new remote to the current repository - * @param cwd repository in which addRemote should be performed - * @param remote remote git link - * @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, this.remoteWithAuth(remote)); - } - /** - * Git fetch from a particular branch - * @param cwd repository in which fetch should be performed - * @param branch fetch from the given branch - * @param remote [optional] the remote to fetch, by default origin - */ - async fetch(cwd, branch, remote = "origin") { - await this.git(cwd).fetch(remote, branch, ["--quiet"]); - } - /** - * Get cherry-pick a specific sha - * @param cwd repository in which the sha should be cherry picked to - * @param sha commit sha - */ - async cherryPick(cwd, 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 - * @param cwd repository in which the push should be performed - * @param branch branch to be pushed - * @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}.`); - const options = ["--quiet"]; - if (force) { - options.push("--force-with-lease"); - } - await this.git(cwd).push(remote, branch, options); - } -} -exports.default = GitCLIService; diff --git a/build/src/service/git/git-service-factory.js b/build/src/service/git/git-service-factory.js deleted file mode 100644 index e359f2d..0000000 --- a/build/src/service/git/git-service-factory.js +++ /dev/null @@ -1,39 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": 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 - */ -class GitServiceFactory { - static getService() { - if (!GitServiceFactory.instance) { - throw new Error("You must call `init` method first!"); - } - return GitServiceFactory.instance; - } - /** - * Initialize the singleton git management service - * @param type git management service type - * @param auth authentication, like github token - */ - static init(type, auth) { - if (GitServiceFactory.instance) { - GitServiceFactory.logger.warn("Git service already initialized!"); - return; - } - switch (type) { - case git_types_1.GitServiceType.GITHUB: - GitServiceFactory.instance = new github_service_1.default(auth); - break; - default: - throw new Error(`Invalid git service type received: ${type}`); - } - } -} -exports.default = GitServiceFactory; -GitServiceFactory.logger = logger_service_factory_1.default.getLogger(); diff --git a/build/src/service/git/git-service.js b/build/src/service/git/git-service.js deleted file mode 100644 index c8ad2e5..0000000 --- a/build/src/service/git/git-service.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/build/src/service/git/git.types.js b/build/src/service/git/git.types.js deleted file mode 100644 index cc62d84..0000000 --- a/build/src/service/git/git.types.js +++ /dev/null @@ -1,7 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.GitServiceType = void 0; -var GitServiceType; -(function (GitServiceType) { - GitServiceType["GITHUB"] = "github"; -})(GitServiceType = exports.GitServiceType || (exports.GitServiceType = {})); diff --git a/build/src/service/git/github/github-mapper.js b/build/src/service/git/github/github-mapper.js deleted file mode 100644 index 917c45e..0000000 --- a/build/src/service/git/github/github-mapper.js +++ /dev/null @@ -1,29 +0,0 @@ -"use strict"; -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 ?? "", - 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: { - 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] - }; - } -} -exports.default = GitHubMapper; diff --git a/build/src/service/git/github/github-service.js b/build/src/service/git/github/github-service.js deleted file mode 100644 index e8d82ee..0000000 --- a/build/src/service/git/github/github-service.js +++ /dev/null @@ -1,69 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": 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, - pull_number: prNumber - }); - 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 - 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; diff --git a/build/src/service/git/github/octokit-factory.js b/build/src/service/git/github/octokit-factory.js deleted file mode 100644 index 1ba999e..0000000 --- a/build/src/service/git/github/octokit-factory.js +++ /dev/null @@ -1,24 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const logger_service_factory_1 = __importDefault(require("../../../service/logger/logger-service-factory")); -const rest_1 = require("@octokit/rest"); -/** - * Singleton factory class for {Octokit} instance - */ -class OctokitFactory { - static getOctokit(token) { - if (!OctokitFactory.octokit) { - OctokitFactory.logger.info("Creating octokit instance."); - OctokitFactory.octokit = new rest_1.Octokit({ - auth: token, - userAgent: "lampajr/backporting" - }); - } - return OctokitFactory.octokit; - } -} -exports.default = OctokitFactory; -OctokitFactory.logger = logger_service_factory_1.default.getLogger(); diff --git a/build/src/service/logger/console-logger-service.js b/build/src/service/logger/console-logger-service.js deleted file mode 100644 index 87e913b..0000000 --- a/build/src/service/logger/console-logger-service.js +++ /dev/null @@ -1,27 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const logger_1 = __importDefault(require("../../service/logger/logger")); -class ConsoleLoggerService { - constructor() { - this.logger = new logger_1.default(); - } - trace(message) { - this.logger.log("[TRACE]", message); - } - debug(message) { - this.logger.log("[DEBUG]", message); - } - info(message) { - this.logger.log("[INFO]", message); - } - warn(message) { - this.logger.log("[WARN]", message); - } - error(message) { - this.logger.log("[ERROR]", message); - } -} -exports.default = ConsoleLoggerService; diff --git a/build/src/service/logger/logger-service-factory.js b/build/src/service/logger/logger-service-factory.js deleted file mode 100644 index 3256000..0000000 --- a/build/src/service/logger/logger-service-factory.js +++ /dev/null @@ -1,18 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const console_logger_service_1 = __importDefault(require("../../service/logger/console-logger-service")); -/** - * Singleton factory class - */ -class LoggerServiceFactory { - static getLogger() { - if (!LoggerServiceFactory.instance) { - LoggerServiceFactory.instance = new console_logger_service_1.default(); - } - return LoggerServiceFactory.instance; - } -} -exports.default = LoggerServiceFactory; diff --git a/build/src/service/logger/logger-service.js b/build/src/service/logger/logger-service.js deleted file mode 100644 index c8ad2e5..0000000 --- a/build/src/service/logger/logger-service.js +++ /dev/null @@ -1,2 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); diff --git a/build/src/service/logger/logger.js b/build/src/service/logger/logger.js deleted file mode 100644 index 08bc7ca..0000000 --- a/build/src/service/logger/logger.js +++ /dev/null @@ -1,15 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -/** - * Common logger class based on the console.log functionality - */ -class Logger { - log(prefix, ...str) { - // eslint-disable-next-line no-console - console.log.apply(console, [prefix, ...str]); - } - emptyLine() { - this.log("", ""); - } -} -exports.default = Logger; diff --git a/build/test/service/git/github/github-service.test.js b/build/test/service/git/github/github-service.test.js deleted file mode 100644 index 4c24802..0000000 --- a/build/test/service/git/github/github-service.test.js +++ /dev/null @@ -1,37 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -const git_service_factory_1 = __importDefault(require("../../../../src/service/git/git-service-factory")); -const git_types_1 = require("../../../../src/service/git/git.types"); -const moctokit_data_1 = require("../../../support/moctokit/moctokit-data"); -const moctokit_support_1 = require("../../../support/moctokit/moctokit-support"); -describe("github service", () => { - let gitService; - beforeAll(() => { - // init git service - git_service_factory_1.default.init(git_types_1.GitServiceType.GITHUB, "whatever"); - }); - beforeEach(() => { - // mock github api calls - (0, moctokit_support_1.setupMoctokit)(); - gitService = git_service_factory_1.default.getService(); - }); - test("get pull request: success", async () => { - const res = await gitService.getPullRequest(moctokit_data_1.targetOwner, moctokit_data_1.repo, moctokit_data_1.mergedPullRequestFixture.number); - expect(res.sourceRepo).toEqual({ - owner: "fork", - project: "reponame", - cloneUrl: "https://github.com/fork/reponame.git" - }); - expect(res.targetRepo).toEqual({ - owner: "owner", - project: "reponame", - cloneUrl: "https://github.com/owner/reponame.git" - }); - expect(res.title).toBe("PR Title"); - expect(res.commits.length).toBe(1); - expect(res.commits).toEqual(["28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"]); - }); -}); diff --git a/build/test/support/moctokit/moctokit-data.js b/build/test/support/moctokit/moctokit-data.js deleted file mode 100644 index 836ecb4..0000000 --- a/build/test/support/moctokit/moctokit-data.js +++ /dev/null @@ -1,899 +0,0 @@ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.notMergedPullRequestFixture = exports.mergedPullRequestFixture = exports.notFoundPullRequestNumber = exports.repo = exports.sourceOwner = exports.targetOwner = void 0; -exports.targetOwner = "owner"; -exports.sourceOwner = "fork"; -exports.repo = "reponame"; -exports.notFoundPullRequestNumber = 1; -exports.mergedPullRequestFixture = { - "url": "https://api.github.com/repos/owner/reponame/pulls/2368", - "id": 1137188271, - "node_id": "PR_kwDOABTq6s5DyB2v", - "html_url": "https://github.com/owner/reponame/pull/2368", - "diff_url": "https://github.com/owner/reponame/pull/2368.diff", - "patch_url": "https://github.com/owner/reponame/pull/2368.patch", - "issue_url": "https://api.github.com/repos/owner/reponame/issues/2368", - "number": 2368, - "state": "closed", - "locked": false, - "title": "PR Title", - "user": { - "login": "gh-user", - "id": 11995863, - "node_id": "MDQ6VXNlcjExOTk1ODYz", - "avatar_url": "https://avatars.githubusercontent.com/u/11995863?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/gh-user", - "html_url": "https://github.com/gh-user", - "followers_url": "https://api.github.com/users/gh-user/followers", - "following_url": "https://api.github.com/users/gh-user/following{/other_user}", - "gists_url": "https://api.github.com/users/gh-user/gists{/gist_id}", - "starred_url": "https://api.github.com/users/gh-user/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/gh-user/subscriptions", - "organizations_url": "https://api.github.com/users/gh-user/orgs", - "repos_url": "https://api.github.com/users/gh-user/repos", - "events_url": "https://api.github.com/users/gh-user/events{/privacy}", - "received_events_url": "https://api.github.com/users/gh-user/received_events", - "type": "User", - "site_admin": false - }, - "body": "Please review and merge", - "created_at": "2022-11-28T08:43:09Z", - "updated_at": "2022-11-28T10:11:53Z", - "closed_at": "2022-11-28T10:11:52Z", - "merged_at": "2022-11-28T10:11:52Z", - "merge_commit_sha": "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", - "assignee": null, - "assignees": [], - "requested_reviewers": [ - { - "login": "requested-gh-user", - "id": 1422582, - "node_id": "MDQ6VXNlcjE0MjI1ODI=", - "avatar_url": "https://avatars.githubusercontent.com/u/1422582?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/requested-gh-user", - "html_url": "https://github.com/requested-gh-user", - "followers_url": "https://api.github.com/users/requested-gh-user/followers", - "following_url": "https://api.github.com/users/requested-gh-user/following{/other_user}", - "gists_url": "https://api.github.com/users/requested-gh-user/gists{/gist_id}", - "starred_url": "https://api.github.com/users/requested-gh-user/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/requested-gh-user/subscriptions", - "organizations_url": "https://api.github.com/users/requested-gh-user/orgs", - "repos_url": "https://api.github.com/users/requested-gh-user/repos", - "events_url": "https://api.github.com/users/requested-gh-user/events{/privacy}", - "received_events_url": "https://api.github.com/users/requested-gh-user/received_events", - "type": "User", - "site_admin": false - }, - { - "login": "gh-user", - "id": 1422582, - "node_id": "MDQ6VXNlcjE0MjI1ODI=", - "avatar_url": "https://avatars.githubusercontent.com/u/1422582?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/gh-user", - "html_url": "https://github.com/gh-user", - "followers_url": "https://api.github.com/users/gh-user/followers", - "following_url": "https://api.github.com/users/gh-user/following{/other_user}", - "gists_url": "https://api.github.com/users/gh-user/gists{/gist_id}", - "starred_url": "https://api.github.com/users/gh-user/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/gh-user/subscriptions", - "organizations_url": "https://api.github.com/users/gh-user/orgs", - "repos_url": "https://api.github.com/users/gh-user/repos", - "events_url": "https://api.github.com/users/gh-user/events{/privacy}", - "received_events_url": "https://api.github.com/users/gh-user/received_events", - "type": "User", - "site_admin": false - } - ], - "requested_teams": [], - "labels": [], - "milestone": null, - "draft": false, - "commits_url": "https://api.github.com/repos/owner/reponame/pulls/2368/commits", - "review_comments_url": "https://api.github.com/repos/owner/reponame/pulls/2368/comments", - "review_comment_url": "https://api.github.com/repos/owner/reponame/pulls/comments{/number}", - "comments_url": "https://api.github.com/repos/owner/reponame/issues/2368/comments", - "statuses_url": "https://api.github.com/repos/owner/reponame/statuses/91748965051fae1330ad58d15cf694e103267c87", - "head": { - "label": "kiegroup:bump-8.31.x-drools-8.31.0.Final", - "ref": "bump-8.31.x-drools-8.31.0.Final", - "sha": "91748965051fae1330ad58d15cf694e103267c87", - "user": { - "login": "kiegroup", - "id": 517980, - "node_id": "MDEyOk9yZ2FuaXphdGlvbjUxNzk4MA==", - "avatar_url": "https://avatars.githubusercontent.com/u/517980?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/kiegroup", - "html_url": "https://github.com/kiegroup", - "followers_url": "https://api.github.com/users/kiegroup/followers", - "following_url": "https://api.github.com/users/kiegroup/following{/other_user}", - "gists_url": "https://api.github.com/users/kiegroup/gists{/gist_id}", - "starred_url": "https://api.github.com/users/kiegroup/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/kiegroup/subscriptions", - "organizations_url": "https://api.github.com/users/kiegroup/orgs", - "repos_url": "https://api.github.com/users/kiegroup/repos", - "events_url": "https://api.github.com/users/kiegroup/events{/privacy}", - "received_events_url": "https://api.github.com/users/kiegroup/received_events", - "type": "Organization", - "site_admin": false - }, - "repo": { - "id": 1370858, - "node_id": "MDEwOlJlcG9zaXRvcnkxMzcwODU4", - "name": "reponame", - "full_name": "fork/reponame", - "private": false, - "owner": { - "login": "kiegroup", - "id": 517980, - "node_id": "MDEyOk9yZ2FuaXphdGlvbjUxNzk4MA==", - "avatar_url": "https://avatars.githubusercontent.com/u/517980?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/kiegroup", - "html_url": "https://github.com/kiegroup", - "followers_url": "https://api.github.com/users/kiegroup/followers", - "following_url": "https://api.github.com/users/kiegroup/following{/other_user}", - "gists_url": "https://api.github.com/users/kiegroup/gists{/gist_id}", - "starred_url": "https://api.github.com/users/kiegroup/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/kiegroup/subscriptions", - "organizations_url": "https://api.github.com/users/kiegroup/orgs", - "repos_url": "https://api.github.com/users/kiegroup/repos", - "events_url": "https://api.github.com/users/kiegroup/events{/privacy}", - "received_events_url": "https://api.github.com/users/kiegroup/received_events", - "type": "Organization", - "site_admin": false - }, - "html_url": "https://github.com/fork/reponame", - "description": "AI constraint solver in Java to optimize the vehicle routing problem, employee rostering, task assignment, maintenance scheduling, conference scheduling and other planning problems.", - "fork": false, - "url": "https://api.github.com/repos/fork/reponame", - "forks_url": "https://api.github.com/repos/fork/reponame/forks", - "keys_url": "https://api.github.com/repos/fork/reponame/keys{/key_id}", - "collaborators_url": "https://api.github.com/repos/fork/reponame/collaborators{/collaborator}", - "teams_url": "https://api.github.com/repos/fork/reponame/teams", - "hooks_url": "https://api.github.com/repos/fork/reponame/hooks", - "issue_events_url": "https://api.github.com/repos/fork/reponame/issues/events{/number}", - "events_url": "https://api.github.com/repos/fork/reponame/events", - "assignees_url": "https://api.github.com/repos/fork/reponame/assignees{/user}", - "branches_url": "https://api.github.com/repos/fork/reponame/branches{/branch}", - "tags_url": "https://api.github.com/repos/fork/reponame/tags", - "blobs_url": "https://api.github.com/repos/fork/reponame/git/blobs{/sha}", - "git_tags_url": "https://api.github.com/repos/fork/reponame/git/tags{/sha}", - "git_refs_url": "https://api.github.com/repos/fork/reponame/git/refs{/sha}", - "trees_url": "https://api.github.com/repos/fork/reponame/git/trees{/sha}", - "statuses_url": "https://api.github.com/repos/fork/reponame/statuses/{sha}", - "languages_url": "https://api.github.com/repos/fork/reponame/languages", - "stargazers_url": "https://api.github.com/repos/fork/reponame/stargazers", - "contributors_url": "https://api.github.com/repos/fork/reponame/contributors", - "subscribers_url": "https://api.github.com/repos/fork/reponame/subscribers", - "subscription_url": "https://api.github.com/repos/fork/reponame/subscription", - "commits_url": "https://api.github.com/repos/fork/reponame/commits{/sha}", - "git_commits_url": "https://api.github.com/repos/fork/reponame/git/commits{/sha}", - "comments_url": "https://api.github.com/repos/fork/reponame/comments{/number}", - "issue_comment_url": "https://api.github.com/repos/fork/reponame/issues/comments{/number}", - "contents_url": "https://api.github.com/repos/fork/reponame/contents/{+path}", - "compare_url": "https://api.github.com/repos/fork/reponame/compare/{base}...{head}", - "merges_url": "https://api.github.com/repos/fork/reponame/merges", - "archive_url": "https://api.github.com/repos/fork/reponame/{archive_format}{/ref}", - "downloads_url": "https://api.github.com/repos/fork/reponame/downloads", - "issues_url": "https://api.github.com/repos/fork/reponame/issues{/number}", - "pulls_url": "https://api.github.com/repos/fork/reponame/pulls{/number}", - "milestones_url": "https://api.github.com/repos/fork/reponame/milestones{/number}", - "notifications_url": "https://api.github.com/repos/fork/reponame/notifications{?since,all,participating}", - "labels_url": "https://api.github.com/repos/fork/reponame/labels{/name}", - "releases_url": "https://api.github.com/repos/fork/reponame/releases{/id}", - "deployments_url": "https://api.github.com/repos/fork/reponame/deployments", - "created_at": "2011-02-15T19:38:23Z", - "updated_at": "2022-11-28T05:01:47Z", - "pushed_at": "2022-11-28T10:50:51Z", - "git_url": "git://github.com/fork/reponame.git", - "ssh_url": "git@github.com:fork/reponame.git", - "clone_url": "https://github.com/fork/reponame.git", - "svn_url": "https://github.com/fork/reponame", - "homepage": "https://www.reponame.org", - "size": 238339, - "stargazers_count": 2811, - "watchers_count": 2811, - "language": "Java", - "has_issues": false, - "has_projects": false, - "has_downloads": true, - "has_wiki": false, - "has_pages": false, - "has_discussions": false, - "forks_count": 878, - "mirror_url": null, - "archived": false, - "disabled": false, - "open_issues_count": 30, - "license": { - "key": "apache-2.0", - "name": "Apache License 2.0", - "spdx_id": "Apache-2.0", - "url": "https://api.github.com/licenses/apache-2.0", - "node_id": "MDc6TGljZW5zZTI=" - }, - "allow_forking": true, - "is_template": false, - "web_commit_signoff_required": false, - "topics": [ - "artificial-intelligence", - "branch-and-bound", - "constraint-programming", - "constraint-satisfaction-problem", - "constraint-solver", - "constraints", - "employee-rostering", - "java", - "local-search", - "mathematical-optimization", - "metaheuristics", - "optimization", - "rostering", - "scheduling", - "simulated-annealing", - "solver", - "tabu-search", - "traveling-salesman", - "traveling-salesman-problem", - "vehicle-routing-problem" - ], - "visibility": "public", - "forks": 878, - "open_issues": 30, - "watchers": 2811, - "default_branch": "main" - } - }, - "base": { - "label": "kiegroup:8.31.x", - "ref": "8.31.x", - "sha": "8cfc286765cb01c84a1d62c65519fa8032bfecbd", - "user": { - "login": "kiegroup", - "id": 517980, - "node_id": "MDEyOk9yZ2FuaXphdGlvbjUxNzk4MA==", - "avatar_url": "https://avatars.githubusercontent.com/u/517980?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/kiegroup", - "html_url": "https://github.com/kiegroup", - "followers_url": "https://api.github.com/users/kiegroup/followers", - "following_url": "https://api.github.com/users/kiegroup/following{/other_user}", - "gists_url": "https://api.github.com/users/kiegroup/gists{/gist_id}", - "starred_url": "https://api.github.com/users/kiegroup/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/kiegroup/subscriptions", - "organizations_url": "https://api.github.com/users/kiegroup/orgs", - "repos_url": "https://api.github.com/users/kiegroup/repos", - "events_url": "https://api.github.com/users/kiegroup/events{/privacy}", - "received_events_url": "https://api.github.com/users/kiegroup/received_events", - "type": "Organization", - "site_admin": false - }, - "repo": { - "id": 1370858, - "node_id": "MDEwOlJlcG9zaXRvcnkxMzcwODU4", - "name": "reponame", - "full_name": "owner/reponame", - "private": false, - "owner": { - "login": "kiegroup", - "id": 517980, - "node_id": "MDEyOk9yZ2FuaXphdGlvbjUxNzk4MA==", - "avatar_url": "https://avatars.githubusercontent.com/u/517980?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/kiegroup", - "html_url": "https://github.com/kiegroup", - "followers_url": "https://api.github.com/users/kiegroup/followers", - "following_url": "https://api.github.com/users/kiegroup/following{/other_user}", - "gists_url": "https://api.github.com/users/kiegroup/gists{/gist_id}", - "starred_url": "https://api.github.com/users/kiegroup/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/kiegroup/subscriptions", - "organizations_url": "https://api.github.com/users/kiegroup/orgs", - "repos_url": "https://api.github.com/users/kiegroup/repos", - "events_url": "https://api.github.com/users/kiegroup/events{/privacy}", - "received_events_url": "https://api.github.com/users/kiegroup/received_events", - "type": "Organization", - "site_admin": false - }, - "html_url": "https://github.com/owner/reponame", - "description": "AI constraint solver in Java to optimize the vehicle routing problem, employee rostering, task assignment, maintenance scheduling, conference scheduling and other planning problems.", - "fork": false, - "url": "https://api.github.com/repos/owner/reponame", - "forks_url": "https://api.github.com/repos/owner/reponame/forks", - "keys_url": "https://api.github.com/repos/owner/reponame/keys{/key_id}", - "collaborators_url": "https://api.github.com/repos/owner/reponame/collaborators{/collaborator}", - "teams_url": "https://api.github.com/repos/owner/reponame/teams", - "hooks_url": "https://api.github.com/repos/owner/reponame/hooks", - "issue_events_url": "https://api.github.com/repos/owner/reponame/issues/events{/number}", - "events_url": "https://api.github.com/repos/owner/reponame/events", - "assignees_url": "https://api.github.com/repos/owner/reponame/assignees{/user}", - "branches_url": "https://api.github.com/repos/owner/reponame/branches{/branch}", - "tags_url": "https://api.github.com/repos/owner/reponame/tags", - "blobs_url": "https://api.github.com/repos/owner/reponame/git/blobs{/sha}", - "git_tags_url": "https://api.github.com/repos/owner/reponame/git/tags{/sha}", - "git_refs_url": "https://api.github.com/repos/owner/reponame/git/refs{/sha}", - "trees_url": "https://api.github.com/repos/owner/reponame/git/trees{/sha}", - "statuses_url": "https://api.github.com/repos/owner/reponame/statuses/{sha}", - "languages_url": "https://api.github.com/repos/owner/reponame/languages", - "stargazers_url": "https://api.github.com/repos/owner/reponame/stargazers", - "contributors_url": "https://api.github.com/repos/owner/reponame/contributors", - "subscribers_url": "https://api.github.com/repos/owner/reponame/subscribers", - "subscription_url": "https://api.github.com/repos/owner/reponame/subscription", - "commits_url": "https://api.github.com/repos/owner/reponame/commits{/sha}", - "git_commits_url": "https://api.github.com/repos/owner/reponame/git/commits{/sha}", - "comments_url": "https://api.github.com/repos/owner/reponame/comments{/number}", - "issue_comment_url": "https://api.github.com/repos/owner/reponame/issues/comments{/number}", - "contents_url": "https://api.github.com/repos/owner/reponame/contents/{+path}", - "compare_url": "https://api.github.com/repos/owner/reponame/compare/{base}...{head}", - "merges_url": "https://api.github.com/repos/owner/reponame/merges", - "archive_url": "https://api.github.com/repos/owner/reponame/{archive_format}{/ref}", - "downloads_url": "https://api.github.com/repos/owner/reponame/downloads", - "issues_url": "https://api.github.com/repos/owner/reponame/issues{/number}", - "pulls_url": "https://api.github.com/repos/owner/reponame/pulls{/number}", - "milestones_url": "https://api.github.com/repos/owner/reponame/milestones{/number}", - "notifications_url": "https://api.github.com/repos/owner/reponame/notifications{?since,all,participating}", - "labels_url": "https://api.github.com/repos/owner/reponame/labels{/name}", - "releases_url": "https://api.github.com/repos/owner/reponame/releases{/id}", - "deployments_url": "https://api.github.com/repos/owner/reponame/deployments", - "created_at": "2011-02-15T19:38:23Z", - "updated_at": "2022-11-28T05:01:47Z", - "pushed_at": "2022-11-28T10:50:51Z", - "git_url": "git://github.com/owner/reponame.git", - "ssh_url": "git@github.com:owner/reponame.git", - "clone_url": "https://github.com/owner/reponame.git", - "svn_url": "https://github.com/owner/reponame", - "homepage": "https://www.reponame.org", - "size": 238339, - "stargazers_count": 2811, - "watchers_count": 2811, - "language": "Java", - "has_issues": false, - "has_projects": false, - "has_downloads": true, - "has_wiki": false, - "has_pages": false, - "has_discussions": false, - "forks_count": 878, - "mirror_url": null, - "archived": false, - "disabled": false, - "open_issues_count": 30, - "license": { - "key": "apache-2.0", - "name": "Apache License 2.0", - "spdx_id": "Apache-2.0", - "url": "https://api.github.com/licenses/apache-2.0", - "node_id": "MDc6TGljZW5zZTI=" - }, - "allow_forking": true, - "is_template": false, - "web_commit_signoff_required": false, - "topics": [ - "artificial-intelligence", - "branch-and-bound", - "constraint-programming", - "constraint-satisfaction-problem", - "constraint-solver", - "constraints", - "employee-rostering", - "java", - "local-search", - "mathematical-optimization", - "metaheuristics", - "optimization", - "rostering", - "scheduling", - "simulated-annealing", - "solver", - "tabu-search", - "traveling-salesman", - "traveling-salesman-problem", - "vehicle-routing-problem" - ], - "visibility": "public", - "forks": 878, - "open_issues": 30, - "watchers": 2811, - "default_branch": "main" - } - }, - "_links": { - "self": { - "href": "https://api.github.com/repos/owner/reponame/pulls/2368" - }, - "html": { - "href": "https://github.com/owner/reponame/pull/2368" - }, - "issue": { - "href": "https://api.github.com/repos/owner/reponame/issues/2368" - }, - "comments": { - "href": "https://api.github.com/repos/owner/reponame/issues/2368/comments" - }, - "review_comments": { - "href": "https://api.github.com/repos/owner/reponame/pulls/2368/comments" - }, - "review_comment": { - "href": "https://api.github.com/repos/owner/reponame/pulls/comments{/number}" - }, - "commits": { - "href": "https://api.github.com/repos/owner/reponame/pulls/2368/commits" - }, - "statuses": { - "href": "https://api.github.com/repos/owner/reponame/statuses/91748965051fae1330ad58d15cf694e103267c87" - } - }, - "author_association": "CONTRIBUTOR", - "auto_merge": null, - "active_lock_reason": null, - "merged": true, - "mergeable": null, - "rebaseable": null, - "mergeable_state": "unknown", - "merged_by": { - "login": "that-s-a-user", - "id": 17157711, - "node_id": "MDQ6VXNlcjE3MTU3NzEx", - "avatar_url": "https://avatars.githubusercontent.com/u/17157711?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/that-s-a-user", - "html_url": "https://github.com/that-s-a-user", - "followers_url": "https://api.github.com/users/that-s-a-user/followers", - "following_url": "https://api.github.com/users/that-s-a-user/following{/other_user}", - "gists_url": "https://api.github.com/users/that-s-a-user/gists{/gist_id}", - "starred_url": "https://api.github.com/users/that-s-a-user/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/that-s-a-user/subscriptions", - "organizations_url": "https://api.github.com/users/that-s-a-user/orgs", - "repos_url": "https://api.github.com/users/that-s-a-user/repos", - "events_url": "https://api.github.com/users/that-s-a-user/events{/privacy}", - "received_events_url": "https://api.github.com/users/that-s-a-user/received_events", - "type": "User", - "site_admin": false - }, - "comments": 0, - "review_comments": 0, - "maintainer_can_modify": false, - "commits": 2, - "additions": 2, - "deletions": 2, - "changed_files": 2 -}; -exports.notMergedPullRequestFixture = { - "url": "https://api.github.com/repos/owner/reponame/pulls/4444", - "id": 1137188271, - "node_id": "PR_kwDOABTq6s5DyB2v", - "html_url": "https://github.com/owner/reponame/pull/4444", - "diff_url": "https://github.com/owner/reponame/pull/4444.diff", - "patch_url": "https://github.com/owner/reponame/pull/4444.patch", - "issue_url": "https://api.github.com/repos/owner/reponame/issues/4444", - "number": 4444, - "state": "closed", - "locked": false, - "title": "PR Title", - "user": { - "login": "gh-user", - "id": 11995863, - "node_id": "MDQ6VXNlcjExOTk1ODYz", - "avatar_url": "https://avatars.githubusercontent.com/u/11995863?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/gh-user", - "html_url": "https://github.com/gh-user", - "followers_url": "https://api.github.com/users/gh-user/followers", - "following_url": "https://api.github.com/users/gh-user/following{/other_user}", - "gists_url": "https://api.github.com/users/gh-user/gists{/gist_id}", - "starred_url": "https://api.github.com/users/gh-user/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/gh-user/subscriptions", - "organizations_url": "https://api.github.com/users/gh-user/orgs", - "repos_url": "https://api.github.com/users/gh-user/repos", - "events_url": "https://api.github.com/users/gh-user/events{/privacy}", - "received_events_url": "https://api.github.com/users/gh-user/received_events", - "type": "User", - "site_admin": false - }, - "body": "Please review and merge", - "created_at": "2022-11-28T08:43:09Z", - "updated_at": "2022-11-28T10:11:53Z", - "closed_at": "2022-11-28T10:11:52Z", - "merged_at": "2022-11-28T10:11:52Z", - "merge_commit_sha": "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", - "assignee": null, - "assignees": [], - "requested_reviewers": [ - { - "login": "gh-user", - "id": 1422582, - "node_id": "MDQ6VXNlcjE0MjI1ODI=", - "avatar_url": "https://avatars.githubusercontent.com/u/1422582?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/gh-user", - "html_url": "https://github.com/gh-user", - "followers_url": "https://api.github.com/users/gh-user/followers", - "following_url": "https://api.github.com/users/gh-user/following{/other_user}", - "gists_url": "https://api.github.com/users/gh-user/gists{/gist_id}", - "starred_url": "https://api.github.com/users/gh-user/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/gh-user/subscriptions", - "organizations_url": "https://api.github.com/users/gh-user/orgs", - "repos_url": "https://api.github.com/users/gh-user/repos", - "events_url": "https://api.github.com/users/gh-user/events{/privacy}", - "received_events_url": "https://api.github.com/users/gh-user/received_events", - "type": "User", - "site_admin": false - } - ], - "requested_teams": [], - "labels": [], - "milestone": null, - "draft": false, - "commits_url": "https://api.github.com/repos/owner/reponame/pulls/4444/commits", - "review_comments_url": "https://api.github.com/repos/owner/reponame/pulls/4444/comments", - "review_comment_url": "https://api.github.com/repos/owner/reponame/pulls/comments{/number}", - "comments_url": "https://api.github.com/repos/owner/reponame/issues/4444/comments", - "statuses_url": "https://api.github.com/repos/owner/reponame/statuses/91748965051fae1330ad58d15cf694e103267c87", - "head": { - "label": "kiegroup:bump-8.31.x-drools-8.31.0.Final", - "ref": "bump-8.31.x-drools-8.31.0.Final", - "sha": "91748965051fae1330ad58d15cf694e103267c87", - "user": { - "login": "kiegroup", - "id": 517980, - "node_id": "MDEyOk9yZ2FuaXphdGlvbjUxNzk4MA==", - "avatar_url": "https://avatars.githubusercontent.com/u/517980?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/kiegroup", - "html_url": "https://github.com/kiegroup", - "followers_url": "https://api.github.com/users/kiegroup/followers", - "following_url": "https://api.github.com/users/kiegroup/following{/other_user}", - "gists_url": "https://api.github.com/users/kiegroup/gists{/gist_id}", - "starred_url": "https://api.github.com/users/kiegroup/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/kiegroup/subscriptions", - "organizations_url": "https://api.github.com/users/kiegroup/orgs", - "repos_url": "https://api.github.com/users/kiegroup/repos", - "events_url": "https://api.github.com/users/kiegroup/events{/privacy}", - "received_events_url": "https://api.github.com/users/kiegroup/received_events", - "type": "Organization", - "site_admin": false - }, - "repo": { - "id": 1370858, - "node_id": "MDEwOlJlcG9zaXRvcnkxMzcwODU4", - "name": "reponame", - "full_name": "fork/reponame", - "private": false, - "owner": { - "login": "kiegroup", - "id": 517980, - "node_id": "MDEyOk9yZ2FuaXphdGlvbjUxNzk4MA==", - "avatar_url": "https://avatars.githubusercontent.com/u/517980?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/kiegroup", - "html_url": "https://github.com/kiegroup", - "followers_url": "https://api.github.com/users/kiegroup/followers", - "following_url": "https://api.github.com/users/kiegroup/following{/other_user}", - "gists_url": "https://api.github.com/users/kiegroup/gists{/gist_id}", - "starred_url": "https://api.github.com/users/kiegroup/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/kiegroup/subscriptions", - "organizations_url": "https://api.github.com/users/kiegroup/orgs", - "repos_url": "https://api.github.com/users/kiegroup/repos", - "events_url": "https://api.github.com/users/kiegroup/events{/privacy}", - "received_events_url": "https://api.github.com/users/kiegroup/received_events", - "type": "Organization", - "site_admin": false - }, - "html_url": "https://github.com/fork/reponame", - "description": "AI constraint solver in Java to optimize the vehicle routing problem, employee rostering, task assignment, maintenance scheduling, conference scheduling and other planning problems.", - "fork": false, - "url": "https://api.github.com/repos/fork/reponame", - "forks_url": "https://api.github.com/repos/fork/reponame/forks", - "keys_url": "https://api.github.com/repos/fork/reponame/keys{/key_id}", - "collaborators_url": "https://api.github.com/repos/fork/reponame/collaborators{/collaborator}", - "teams_url": "https://api.github.com/repos/fork/reponame/teams", - "hooks_url": "https://api.github.com/repos/fork/reponame/hooks", - "issue_events_url": "https://api.github.com/repos/fork/reponame/issues/events{/number}", - "events_url": "https://api.github.com/repos/fork/reponame/events", - "assignees_url": "https://api.github.com/repos/fork/reponame/assignees{/user}", - "branches_url": "https://api.github.com/repos/fork/reponame/branches{/branch}", - "tags_url": "https://api.github.com/repos/fork/reponame/tags", - "blobs_url": "https://api.github.com/repos/fork/reponame/git/blobs{/sha}", - "git_tags_url": "https://api.github.com/repos/fork/reponame/git/tags{/sha}", - "git_refs_url": "https://api.github.com/repos/fork/reponame/git/refs{/sha}", - "trees_url": "https://api.github.com/repos/fork/reponame/git/trees{/sha}", - "statuses_url": "https://api.github.com/repos/fork/reponame/statuses/{sha}", - "languages_url": "https://api.github.com/repos/fork/reponame/languages", - "stargazers_url": "https://api.github.com/repos/fork/reponame/stargazers", - "contributors_url": "https://api.github.com/repos/fork/reponame/contributors", - "subscribers_url": "https://api.github.com/repos/fork/reponame/subscribers", - "subscription_url": "https://api.github.com/repos/fork/reponame/subscription", - "commits_url": "https://api.github.com/repos/fork/reponame/commits{/sha}", - "git_commits_url": "https://api.github.com/repos/fork/reponame/git/commits{/sha}", - "comments_url": "https://api.github.com/repos/fork/reponame/comments{/number}", - "issue_comment_url": "https://api.github.com/repos/fork/reponame/issues/comments{/number}", - "contents_url": "https://api.github.com/repos/fork/reponame/contents/{+path}", - "compare_url": "https://api.github.com/repos/fork/reponame/compare/{base}...{head}", - "merges_url": "https://api.github.com/repos/fork/reponame/merges", - "archive_url": "https://api.github.com/repos/fork/reponame/{archive_format}{/ref}", - "downloads_url": "https://api.github.com/repos/fork/reponame/downloads", - "issues_url": "https://api.github.com/repos/fork/reponame/issues{/number}", - "pulls_url": "https://api.github.com/repos/fork/reponame/pulls{/number}", - "milestones_url": "https://api.github.com/repos/fork/reponame/milestones{/number}", - "notifications_url": "https://api.github.com/repos/fork/reponame/notifications{?since,all,participating}", - "labels_url": "https://api.github.com/repos/fork/reponame/labels{/name}", - "releases_url": "https://api.github.com/repos/fork/reponame/releases{/id}", - "deployments_url": "https://api.github.com/repos/fork/reponame/deployments", - "created_at": "2011-02-15T19:38:23Z", - "updated_at": "2022-11-28T05:01:47Z", - "pushed_at": "2022-11-28T10:50:51Z", - "git_url": "git://github.com/fork/reponame.git", - "ssh_url": "git@github.com:fork/reponame.git", - "clone_url": "https://github.com/fork/reponame.git", - "svn_url": "https://github.com/fork/reponame", - "homepage": "https://www.reponame.org", - "size": 238339, - "stargazers_count": 2811, - "watchers_count": 2811, - "language": "Java", - "has_issues": false, - "has_projects": false, - "has_downloads": true, - "has_wiki": false, - "has_pages": false, - "has_discussions": false, - "forks_count": 878, - "mirror_url": null, - "archived": false, - "disabled": false, - "open_issues_count": 30, - "license": { - "key": "apache-2.0", - "name": "Apache License 2.0", - "spdx_id": "Apache-2.0", - "url": "https://api.github.com/licenses/apache-2.0", - "node_id": "MDc6TGljZW5zZTI=" - }, - "allow_forking": true, - "is_template": false, - "web_commit_signoff_required": false, - "topics": [ - "artificial-intelligence", - "branch-and-bound", - "constraint-programming", - "constraint-satisfaction-problem", - "constraint-solver", - "constraints", - "employee-rostering", - "java", - "local-search", - "mathematical-optimization", - "metaheuristics", - "optimization", - "rostering", - "scheduling", - "simulated-annealing", - "solver", - "tabu-search", - "traveling-salesman", - "traveling-salesman-problem", - "vehicle-routing-problem" - ], - "visibility": "public", - "forks": 878, - "open_issues": 30, - "watchers": 2811, - "default_branch": "main" - } - }, - "base": { - "label": "kiegroup:8.31.x", - "ref": "8.31.x", - "sha": "8cfc286765cb01c84a1d62c65519fa8032bfecbd", - "user": { - "login": "kiegroup", - "id": 517980, - "node_id": "MDEyOk9yZ2FuaXphdGlvbjUxNzk4MA==", - "avatar_url": "https://avatars.githubusercontent.com/u/517980?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/kiegroup", - "html_url": "https://github.com/kiegroup", - "followers_url": "https://api.github.com/users/kiegroup/followers", - "following_url": "https://api.github.com/users/kiegroup/following{/other_user}", - "gists_url": "https://api.github.com/users/kiegroup/gists{/gist_id}", - "starred_url": "https://api.github.com/users/kiegroup/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/kiegroup/subscriptions", - "organizations_url": "https://api.github.com/users/kiegroup/orgs", - "repos_url": "https://api.github.com/users/kiegroup/repos", - "events_url": "https://api.github.com/users/kiegroup/events{/privacy}", - "received_events_url": "https://api.github.com/users/kiegroup/received_events", - "type": "Organization", - "site_admin": false - }, - "repo": { - "id": 1370858, - "node_id": "MDEwOlJlcG9zaXRvcnkxMzcwODU4", - "name": "reponame", - "full_name": "owner/reponame", - "private": false, - "owner": { - "login": "kiegroup", - "id": 517980, - "node_id": "MDEyOk9yZ2FuaXphdGlvbjUxNzk4MA==", - "avatar_url": "https://avatars.githubusercontent.com/u/517980?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/kiegroup", - "html_url": "https://github.com/kiegroup", - "followers_url": "https://api.github.com/users/kiegroup/followers", - "following_url": "https://api.github.com/users/kiegroup/following{/other_user}", - "gists_url": "https://api.github.com/users/kiegroup/gists{/gist_id}", - "starred_url": "https://api.github.com/users/kiegroup/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/kiegroup/subscriptions", - "organizations_url": "https://api.github.com/users/kiegroup/orgs", - "repos_url": "https://api.github.com/users/kiegroup/repos", - "events_url": "https://api.github.com/users/kiegroup/events{/privacy}", - "received_events_url": "https://api.github.com/users/kiegroup/received_events", - "type": "Organization", - "site_admin": false - }, - "html_url": "https://github.com/owner/reponame", - "description": "AI constraint solver in Java to optimize the vehicle routing problem, employee rostering, task assignment, maintenance scheduling, conference scheduling and other planning problems.", - "fork": false, - "url": "https://api.github.com/repos/owner/reponame", - "forks_url": "https://api.github.com/repos/owner/reponame/forks", - "keys_url": "https://api.github.com/repos/owner/reponame/keys{/key_id}", - "collaborators_url": "https://api.github.com/repos/owner/reponame/collaborators{/collaborator}", - "teams_url": "https://api.github.com/repos/owner/reponame/teams", - "hooks_url": "https://api.github.com/repos/owner/reponame/hooks", - "issue_events_url": "https://api.github.com/repos/owner/reponame/issues/events{/number}", - "events_url": "https://api.github.com/repos/owner/reponame/events", - "assignees_url": "https://api.github.com/repos/owner/reponame/assignees{/user}", - "branches_url": "https://api.github.com/repos/owner/reponame/branches{/branch}", - "tags_url": "https://api.github.com/repos/owner/reponame/tags", - "blobs_url": "https://api.github.com/repos/owner/reponame/git/blobs{/sha}", - "git_tags_url": "https://api.github.com/repos/owner/reponame/git/tags{/sha}", - "git_refs_url": "https://api.github.com/repos/owner/reponame/git/refs{/sha}", - "trees_url": "https://api.github.com/repos/owner/reponame/git/trees{/sha}", - "statuses_url": "https://api.github.com/repos/owner/reponame/statuses/{sha}", - "languages_url": "https://api.github.com/repos/owner/reponame/languages", - "stargazers_url": "https://api.github.com/repos/owner/reponame/stargazers", - "contributors_url": "https://api.github.com/repos/owner/reponame/contributors", - "subscribers_url": "https://api.github.com/repos/owner/reponame/subscribers", - "subscription_url": "https://api.github.com/repos/owner/reponame/subscription", - "commits_url": "https://api.github.com/repos/owner/reponame/commits{/sha}", - "git_commits_url": "https://api.github.com/repos/owner/reponame/git/commits{/sha}", - "comments_url": "https://api.github.com/repos/owner/reponame/comments{/number}", - "issue_comment_url": "https://api.github.com/repos/owner/reponame/issues/comments{/number}", - "contents_url": "https://api.github.com/repos/owner/reponame/contents/{+path}", - "compare_url": "https://api.github.com/repos/owner/reponame/compare/{base}...{head}", - "merges_url": "https://api.github.com/repos/owner/reponame/merges", - "archive_url": "https://api.github.com/repos/owner/reponame/{archive_format}{/ref}", - "downloads_url": "https://api.github.com/repos/owner/reponame/downloads", - "issues_url": "https://api.github.com/repos/owner/reponame/issues{/number}", - "pulls_url": "https://api.github.com/repos/owner/reponame/pulls{/number}", - "milestones_url": "https://api.github.com/repos/owner/reponame/milestones{/number}", - "notifications_url": "https://api.github.com/repos/owner/reponame/notifications{?since,all,participating}", - "labels_url": "https://api.github.com/repos/owner/reponame/labels{/name}", - "releases_url": "https://api.github.com/repos/owner/reponame/releases{/id}", - "deployments_url": "https://api.github.com/repos/owner/reponame/deployments", - "created_at": "2011-02-15T19:38:23Z", - "updated_at": "2022-11-28T05:01:47Z", - "pushed_at": "2022-11-28T10:50:51Z", - "git_url": "git://github.com/owner/reponame.git", - "ssh_url": "git@github.com:owner/reponame.git", - "clone_url": "https://github.com/owner/reponame.git", - "svn_url": "https://github.com/owner/reponame", - "homepage": "https://www.reponame.org", - "size": 238339, - "stargazers_count": 2811, - "watchers_count": 2811, - "language": "Java", - "has_issues": false, - "has_projects": false, - "has_downloads": true, - "has_wiki": false, - "has_pages": false, - "has_discussions": false, - "forks_count": 878, - "mirror_url": null, - "archived": false, - "disabled": false, - "open_issues_count": 30, - "license": { - "key": "apache-2.0", - "name": "Apache License 2.0", - "spdx_id": "Apache-2.0", - "url": "https://api.github.com/licenses/apache-2.0", - "node_id": "MDc6TGljZW5zZTI=" - }, - "allow_forking": true, - "is_template": false, - "web_commit_signoff_required": false, - "topics": [ - "artificial-intelligence", - "branch-and-bound", - "constraint-programming", - "constraint-satisfaction-problem", - "constraint-solver", - "constraints", - "employee-rostering", - "java", - "local-search", - "mathematical-optimization", - "metaheuristics", - "optimization", - "rostering", - "scheduling", - "simulated-annealing", - "solver", - "tabu-search", - "traveling-salesman", - "traveling-salesman-problem", - "vehicle-routing-problem" - ], - "visibility": "public", - "forks": 878, - "open_issues": 30, - "watchers": 2811, - "default_branch": "main" - } - }, - "_links": { - "self": { - "href": "https://api.github.com/repos/owner/reponame/pulls/4444" - }, - "html": { - "href": "https://github.com/owner/reponame/pull/4444" - }, - "issue": { - "href": "https://api.github.com/repos/owner/reponame/issues/4444" - }, - "comments": { - "href": "https://api.github.com/repos/owner/reponame/issues/4444/comments" - }, - "review_comments": { - "href": "https://api.github.com/repos/owner/reponame/pulls/4444/comments" - }, - "review_comment": { - "href": "https://api.github.com/repos/owner/reponame/pulls/comments{/number}" - }, - "commits": { - "href": "https://api.github.com/repos/owner/reponame/pulls/4444/commits" - }, - "statuses": { - "href": "https://api.github.com/repos/owner/reponame/statuses/91748965051fae1330ad58d15cf694e103267c87" - } - }, - "author_association": "CONTRIBUTOR", - "auto_merge": null, - "active_lock_reason": null, - "merged": null, - "mergeable": null, - "rebaseable": null, - "mergeable_state": "unknown", - "merged_by": { - "login": "that-s-a-user", - "id": 17157711, - "node_id": "MDQ6VXNlcjE3MTU3NzEx", - "avatar_url": "https://avatars.githubusercontent.com/u/17157711?v=4", - "gravatar_id": "", - "url": "https://api.github.com/users/that-s-a-user", - "html_url": "https://github.com/that-s-a-user", - "followers_url": "https://api.github.com/users/that-s-a-user/followers", - "following_url": "https://api.github.com/users/that-s-a-user/following{/other_user}", - "gists_url": "https://api.github.com/users/that-s-a-user/gists{/gist_id}", - "starred_url": "https://api.github.com/users/that-s-a-user/starred{/owner}{/repo}", - "subscriptions_url": "https://api.github.com/users/that-s-a-user/subscriptions", - "organizations_url": "https://api.github.com/users/that-s-a-user/orgs", - "repos_url": "https://api.github.com/users/that-s-a-user/repos", - "events_url": "https://api.github.com/users/that-s-a-user/events{/privacy}", - "received_events_url": "https://api.github.com/users/that-s-a-user/received_events", - "type": "User", - "site_admin": false - }, - "comments": 0, - "review_comments": 0, - "maintainer_can_modify": false, - "commits": 2, - "additions": 2, - "deletions": 2, - "changed_files": 2 -}; diff --git a/build/test/support/moctokit/moctokit-support.js b/build/test/support/moctokit/moctokit-support.js deleted file mode 100644 index 9330baa..0000000 --- a/build/test/support/moctokit/moctokit-support.js +++ /dev/null @@ -1,63 +0,0 @@ -"use strict"; -var __importDefault = (this && this.__importDefault) || function (mod) { - return (mod && mod.__esModule) ? mod : { "default": mod }; -}; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.setupMoctokit = void 0; -const logger_service_factory_1 = __importDefault(require("../../../src/service/logger/logger-service-factory")); -const mock_github_1 = require("@kie/mock-github"); -const moctokit_data_1 = require("./moctokit-data"); -const logger = logger_service_factory_1.default.getLogger(); -const setupMoctokit = () => { - logger.debug("Setting up moctokit."); - const mock = new mock_github_1.Moctokit(); - // setup the mock requests here - // valid requests - mock.rest.pulls - .get({ - owner: moctokit_data_1.targetOwner, - repo: moctokit_data_1.repo, - pull_number: moctokit_data_1.mergedPullRequestFixture.number - }) - .reply({ - status: 200, - data: moctokit_data_1.mergedPullRequestFixture - }); - mock.rest.pulls - .get({ - owner: moctokit_data_1.targetOwner, - repo: moctokit_data_1.repo, - pull_number: moctokit_data_1.notMergedPullRequestFixture.number - }) - .reply({ - status: 200, - data: moctokit_data_1.notMergedPullRequestFixture - }); - mock.rest.pulls - .create() - .reply({ - status: 201, - data: moctokit_data_1.mergedPullRequestFixture - }); - mock.rest.pulls - .requestReviewers() - .reply({ - status: 201, - data: moctokit_data_1.mergedPullRequestFixture - }); - // invalid requests - mock.rest.pulls - .get({ - owner: moctokit_data_1.targetOwner, - repo: moctokit_data_1.repo, - pull_number: moctokit_data_1.notFoundPullRequestNumber - }) - .reply({ - status: 404, - data: { - message: "Not found" - } - }); - return mock; -}; -exports.setupMoctokit = setupMoctokit; diff --git a/dist/cli/index.js b/dist/cli/index.js index 387b97c..6dcae35 100755 --- a/dist/cli/index.js +++ b/dist/cli/index.js @@ -60,21 +60,33 @@ exports["default"] = CLIArgsParser; /***/ }), /***/ 5799: -/***/ ((__unused_webpack_module, exports) => { +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; Object.defineProperty(exports, "__esModule", ({ value: true })); +const logger_service_factory_1 = __importDefault(__nccwpck_require__(8936)); /** * Abstract configuration parser class in charge to parse * Args and produces a common Configs object */ class ConfigsParser { + constructor() { + this.logger = logger_service_factory_1.default.getLogger(); + } async parseAndValidate(args) { const configs = await this.parse(args); // apply validation, throw errors if something is wrong - if (configs.originalPullRequest.state == "open" || !configs.originalPullRequest.merged) { - throw new Error("Provided pull request is not merged!"); + // if pr is opened check if the there exists one single commit + if (configs.originalPullRequest.state == "open") { + this.logger.warn("Trying to backport an open pull request!"); + } + // if PR is closed and not merged log a warning + if (configs.originalPullRequest.state == "closed" && !configs.originalPullRequest.merged) { + throw new Error("Provided pull request is closed and not merged!"); } return Promise.resolve(configs); } @@ -136,6 +148,7 @@ class PullRequestConfigsParser extends configs_parser_1.default { reviewers: [...new Set(reviewers)], targetRepo: originalPullRequest.targetRepo, sourceRepo: originalPullRequest.targetRepo, + nCommits: 0, commits: [] // TODO needed? }; } @@ -237,6 +250,7 @@ class GitCLIService { * @param remote [optional] the remote to fetch, by default origin */ async fetch(cwd, branch, remote = "origin") { + this.logger.info(`Fetching ${remote} ${branch}.`); await this.git(cwd).fetch(remote, branch, ["--quiet"]); } /** @@ -339,6 +353,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); class GitHubMapper { mapPullRequest(pr) { return { + number: pr.number, author: pr.user.login, url: pr.url, htmlUrl: pr.html_url, @@ -358,7 +373,9 @@ class GitHubMapper { project: pr.base.repo.full_name.split("/")[1], cloneUrl: pr.base.repo.clone_url }, - commits: [pr.merge_commit_sha] + nCommits: pr.commits, + // if pr is open use latest commit sha otherwise use merge_commit_sha + commits: pr.state === "open" ? [pr.head.sha] : [pr.merge_commit_sha] }; } } @@ -634,8 +651,11 @@ class Runner { // 5. create new branch from target one and checkout const backportBranch = `bp-${configs.targetBranch}-${originalPR.commits.join("-")}`; await git.createLocalBranch(configs.folder, backportBranch); - // 6. add new remote if source != target and fetch source repo - // Skip this, we assume the PR has been already merged + // 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); diff --git a/dist/gha/index.js b/dist/gha/index.js index 1f8992e..8f22edd 100755 --- a/dist/gha/index.js +++ b/dist/gha/index.js @@ -46,21 +46,33 @@ exports["default"] = GHAArgsParser; /***/ }), /***/ 5799: -/***/ ((__unused_webpack_module, exports) => { +/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) { "use strict"; +var __importDefault = (this && this.__importDefault) || function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; +}; Object.defineProperty(exports, "__esModule", ({ value: true })); +const logger_service_factory_1 = __importDefault(__nccwpck_require__(8936)); /** * Abstract configuration parser class in charge to parse * Args and produces a common Configs object */ class ConfigsParser { + constructor() { + this.logger = logger_service_factory_1.default.getLogger(); + } async parseAndValidate(args) { const configs = await this.parse(args); // apply validation, throw errors if something is wrong - if (configs.originalPullRequest.state == "open" || !configs.originalPullRequest.merged) { - throw new Error("Provided pull request is not merged!"); + // if pr is opened check if the there exists one single commit + if (configs.originalPullRequest.state == "open") { + this.logger.warn("Trying to backport an open pull request!"); + } + // if PR is closed and not merged log a warning + if (configs.originalPullRequest.state == "closed" && !configs.originalPullRequest.merged) { + throw new Error("Provided pull request is closed and not merged!"); } return Promise.resolve(configs); } @@ -122,6 +134,7 @@ class PullRequestConfigsParser extends configs_parser_1.default { reviewers: [...new Set(reviewers)], targetRepo: originalPullRequest.targetRepo, sourceRepo: originalPullRequest.targetRepo, + nCommits: 0, commits: [] // TODO needed? }; } @@ -223,6 +236,7 @@ class GitCLIService { * @param remote [optional] the remote to fetch, by default origin */ async fetch(cwd, branch, remote = "origin") { + this.logger.info(`Fetching ${remote} ${branch}.`); await this.git(cwd).fetch(remote, branch, ["--quiet"]); } /** @@ -325,6 +339,7 @@ Object.defineProperty(exports, "__esModule", ({ value: true })); class GitHubMapper { mapPullRequest(pr) { return { + number: pr.number, author: pr.user.login, url: pr.url, htmlUrl: pr.html_url, @@ -344,7 +359,9 @@ class GitHubMapper { project: pr.base.repo.full_name.split("/")[1], cloneUrl: pr.base.repo.clone_url }, - commits: [pr.merge_commit_sha] + nCommits: pr.commits, + // if pr is open use latest commit sha otherwise use merge_commit_sha + commits: pr.state === "open" ? [pr.head.sha] : [pr.merge_commit_sha] }; } } @@ -620,8 +637,11 @@ class Runner { // 5. create new branch from target one and checkout const backportBranch = `bp-${configs.targetBranch}-${originalPR.commits.join("-")}`; await git.createLocalBranch(configs.folder, backportBranch); - // 6. add new remote if source != target and fetch source repo - // Skip this, we assume the PR has been already merged + // 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); diff --git a/src/service/configs/configs-parser.ts b/src/service/configs/configs-parser.ts index 4fb60cf..0b30f08 100644 --- a/src/service/configs/configs-parser.ts +++ b/src/service/configs/configs-parser.ts @@ -1,11 +1,19 @@ import { Args } from "@bp/service/args/args.types"; import { Configs } from "@bp/service/configs/configs.types"; +import LoggerService from "../logger/logger-service"; +import LoggerServiceFactory from "../logger/logger-service-factory"; /** * Abstract configuration parser class in charge to parse * Args and produces a common Configs object */ export default abstract class ConfigsParser { + + private readonly logger: LoggerService; + + constructor() { + this.logger = LoggerServiceFactory.getLogger(); + } abstract parse(args: Args): Promise; @@ -13,8 +21,15 @@ import { Configs } from "@bp/service/configs/configs.types"; const configs: Configs = await this.parse(args); // apply validation, throw errors if something is wrong - if (configs.originalPullRequest.state == "open" || !configs.originalPullRequest.merged) { - throw new Error("Provided pull request is not merged!"); + + // if pr is opened check if the there exists one single commit + if (configs.originalPullRequest.state == "open") { + this.logger.warn("Trying to backport an open pull request!"); + } + + // if PR is closed and not merged log a warning + if (configs.originalPullRequest.state == "closed" && !configs.originalPullRequest.merged) { + throw new Error("Provided pull request is closed and not merged!"); } return Promise.resolve(configs); diff --git a/src/service/configs/pullrequest/pr-configs-parser.ts b/src/service/configs/pullrequest/pr-configs-parser.ts index c3abfee..baade07 100644 --- a/src/service/configs/pullrequest/pr-configs-parser.ts +++ b/src/service/configs/pullrequest/pr-configs-parser.ts @@ -54,6 +54,7 @@ export default class PullRequestConfigsParser extends ConfigsParser { reviewers: [...new Set(reviewers)], targetRepo: originalPullRequest.targetRepo, sourceRepo: originalPullRequest.targetRepo, + nCommits: 0, // TODO: needed? commits: [] // TODO needed? }; } diff --git a/src/service/git/git-cli.ts b/src/service/git/git-cli.ts index 1df5a31..8c3b628 100644 --- a/src/service/git/git-cli.ts +++ b/src/service/git/git-cli.ts @@ -95,6 +95,7 @@ export default class GitCLIService { * @param remote [optional] the remote to fetch, by default origin */ async fetch(cwd: string, branch: string, remote = "origin"): Promise { + this.logger.info(`Fetching ${remote} ${branch}.`); await this.git(cwd).fetch(remote, branch, ["--quiet"]); } diff --git a/src/service/git/git.types.ts b/src/service/git/git.types.ts index 35f926d..5a515df 100644 --- a/src/service/git/git.types.ts +++ b/src/service/git/git.types.ts @@ -1,4 +1,5 @@ export interface GitPullRequest { + number?: number, author: string, url?: string, htmlUrl?: string, @@ -10,7 +11,8 @@ export interface GitPullRequest { reviewers: string[], targetRepo: GitRepository, sourceRepo: GitRepository, - commits: string[] + nCommits: number, // number of commits in the pr + commits: string[] // merge commit or last one } export interface GitRepository { diff --git a/src/service/git/github/github-mapper.ts b/src/service/git/github/github-mapper.ts index 315e7e0..8b519aa 100644 --- a/src/service/git/github/github-mapper.ts +++ b/src/service/git/github/github-mapper.ts @@ -5,6 +5,7 @@ export default class GitHubMapper { mapPullRequest(pr: PullRequest): GitPullRequest { return { + number: pr.number, author: pr.user.login, url: pr.url, htmlUrl: pr.html_url, @@ -24,7 +25,9 @@ export default class GitHubMapper { project: pr.base.repo.full_name.split("/")[1], cloneUrl: pr.base.repo.clone_url }, - commits: [pr.merge_commit_sha as string] + nCommits: pr.commits, + // if pr is open use latest commit sha otherwise use merge_commit_sha + commits: pr.state === "open" ? [pr.head.sha] : [pr.merge_commit_sha as string] }; } } \ No newline at end of file diff --git a/src/service/runner/runner.ts b/src/service/runner/runner.ts index 8b5971d..f242af5 100644 --- a/src/service/runner/runner.ts +++ b/src/service/runner/runner.ts @@ -89,8 +89,11 @@ export default class Runner { const backportBranch = `bp-${configs.targetBranch}-${originalPR.commits.join("-")}`; await git.createLocalBranch(configs.folder, backportBranch); - // 6. add new remote if source != target and fetch source repo - // Skip this, we assume the PR has been already merged + // 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) { diff --git a/test/service/configs/pullrequest/pr-configs-parser.test.ts b/test/service/configs/pullrequest/pr-configs-parser.test.ts index 3ade285..f01cd58 100644 --- a/test/service/configs/pullrequest/pr-configs-parser.test.ts +++ b/test/service/configs/pullrequest/pr-configs-parser.test.ts @@ -4,11 +4,12 @@ import PullRequestConfigsParser from "@bp/service/configs/pullrequest/pr-configs import GitServiceFactory from "@bp/service/git/git-service-factory"; import { GitServiceType } from "@bp/service/git/git.types"; import { setupMoctokit } from "../../../support/moctokit/moctokit-support"; -import { mergedPullRequestFixture, notMergedPullRequestFixture, repo, targetOwner } from "../../../support/moctokit/moctokit-data"; +import { mergedPullRequestFixture, openPullRequestFixture, notMergedPullRequestFixture, repo, targetOwner } from "../../../support/moctokit/moctokit-data"; describe("pull request config parser", () => { const mergedPRUrl = `https://github.com/${targetOwner}/${repo}/pull/${mergedPullRequestFixture.number}`; + const openPRUrl = `https://github.com/${targetOwner}/${repo}/pull/${openPullRequestFixture.number}`; const notMergedPRUrl = `https://github.com/${targetOwner}/${repo}/pull/${notMergedPullRequestFixture.number}`; let parser: PullRequestConfigsParser; @@ -27,7 +28,7 @@ describe("pull request config parser", () => { jest.clearAllMocks(); }); - test("parse configs from pull request [default]", async () => { + test("parse configs from pull request", async () => { const args: Args = { dryRun: false, auth: "", @@ -43,6 +44,7 @@ describe("pull request config parser", () => { expect(configs.targetBranch).toEqual("prod"); expect(configs.folder).toEqual(process.cwd() + "/bp"); expect(configs.originalPullRequest).toEqual({ + number: 2368, author: "gh-user", url: "https://api.github.com/repos/owner/reponame/pulls/2368", htmlUrl: "https://github.com/owner/reponame/pull/2368", @@ -62,6 +64,7 @@ describe("pull request config parser", () => { project: "reponame", cloneUrl: "https://github.com/fork/reponame.git" }, + nCommits: 2, commits: ["28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"] }); expect(configs.backportPullRequest).toEqual({ @@ -81,6 +84,7 @@ describe("pull request config parser", () => { project: "reponame", cloneUrl: "https://github.com/owner/reponame.git" }, + nCommits: 0, commits: [] }); }); @@ -119,7 +123,48 @@ describe("pull request config parser", () => { expect(configs.author).toEqual("another-user"); }); - test("not merged pull request", async () => { + test("still open pull request", async () => { + const args: Args = { + dryRun: true, + auth: "whatever", + pullRequest: openPRUrl, + targetBranch: "prod" + }; + + const configs: Configs = await parser.parseAndValidate(args); + + expect(configs.dryRun).toEqual(true); + expect(configs.auth).toEqual("whatever"); + expect(configs.targetBranch).toEqual("prod"); + expect(configs.author).toEqual("gh-user"); + expect(configs.originalPullRequest).toEqual({ + number: 4444, + author: "gh-user", + url: "https://api.github.com/repos/owner/reponame/pulls/4444", + htmlUrl: "https://github.com/owner/reponame/pull/4444", + state: "open", + merged: false, + mergedBy: "that-s-a-user", + title: "PR Title", + body: "Please review and merge", + reviewers: ["gh-user"], + targetRepo: { + owner: "owner", + project: "reponame", + cloneUrl: "https://github.com/owner/reponame.git" + }, + sourceRepo: { + owner: "fork", + project: "reponame", + cloneUrl: "https://github.com/fork/reponame.git" + }, + nCommits: 2, + // taken from head.sha + commits: ["91748965051fae1330ad58d15cf694e103267c87"] + }); + }); + + test("closed pull request", async () => { const args: Args = { dryRun: true, auth: "whatever", @@ -127,6 +172,6 @@ describe("pull request config parser", () => { targetBranch: "prod" }; - expect(async () => await parser.parseAndValidate(args)).rejects.toThrow("Provided pull request is not merged!"); + expect(async () => await parser.parseAndValidate(args)).rejects.toThrow("Provided pull request is closed and not merged!"); }); }); \ No newline at end of file diff --git a/test/service/runner/cli-runner.test.ts b/test/service/runner/cli-runner.test.ts index 498d3ea..5a54803 100644 --- a/test/service/runner/cli-runner.test.ts +++ b/test/service/runner/cli-runner.test.ts @@ -29,7 +29,7 @@ afterEach(() => { resetProcessArgs(); }); -describe("pull request runner test", () => { +describe("cli runner", () => { test("with dry run", async () => { addProcessArgs([ "-d", @@ -49,7 +49,8 @@ describe("pull request runner test", () => { expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1); expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"); - expect(GitCLIService.prototype.addRemote).toBeCalledTimes(0); + expect(GitCLIService.prototype.fetch).toBeCalledTimes(1); + expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "pull/2368/head:pr/2368"); expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1); expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"); @@ -77,7 +78,8 @@ describe("pull request runner test", () => { expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1); expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"); - expect(GitCLIService.prototype.addRemote).toBeCalledTimes(0); + expect(GitCLIService.prototype.fetch).toBeCalledTimes(1); + expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "pull/2368/head:pr/2368"); expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1); expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"); @@ -107,7 +109,8 @@ describe("pull request runner test", () => { expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1); expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"); - expect(GitCLIService.prototype.addRemote).toBeCalledTimes(0); + expect(GitCLIService.prototype.fetch).toBeCalledTimes(1); + expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "pull/2368/head:pr/2368"); expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1); expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"); @@ -140,7 +143,8 @@ describe("pull request runner test", () => { expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1); expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"); - expect(GitCLIService.prototype.addRemote).toBeCalledTimes(0); + expect(GitCLIService.prototype.fetch).toBeCalledTimes(1); + expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "pull/2368/head:pr/2368"); expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1); expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"); @@ -167,7 +171,8 @@ describe("pull request runner test", () => { expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1); expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"); - expect(GitCLIService.prototype.addRemote).toBeCalledTimes(0); + expect(GitCLIService.prototype.fetch).toBeCalledTimes(1); + expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "pull/2368/head:pr/2368"); expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1); expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"); @@ -188,7 +193,57 @@ describe("pull request runner test", () => { ); }); - test("not merged pull request", async () => { + test("same owner", async () => { + addProcessArgs([ + "-tb", + "target", + "-pr", + "https://github.com/owner/reponame/pull/8632" + ]); + + await runner.execute(); + + const cwd = process.cwd() + "/bp"; + + expect(GitCLIService.prototype.clone).toBeCalledTimes(1); + expect(GitCLIService.prototype.clone).toBeCalledWith("https://github.com/owner/reponame.git", cwd, "target"); + + expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1); + expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"); + + expect(GitCLIService.prototype.fetch).toBeCalledTimes(0); + + expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1); + expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"); + + expect(GitCLIService.prototype.push).toBeCalledTimes(1); + expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"); + + expect(GitHubService.prototype.createPullRequest).toBeCalledTimes(1); + expect(GitHubService.prototype.createPullRequest).toBeCalledWith({ + owner: "owner", + repo: "reponame", + head: "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", + base: "target", + title: "[target] PR Title", + body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/8632"), + reviewers: ["gh-user", "that-s-a-user"] + } + ); + }); + + test("closed and not merged pull request", async () => { + addProcessArgs([ + "-tb", + "target", + "-pr", + "https://github.com/owner/reponame/pull/6666" + ]); + + expect(async () => await runner.execute()).rejects.toThrow("Provided pull request is closed and not merged!"); + }); + + test("open pull request", async () => { addProcessArgs([ "-tb", "target", @@ -196,6 +251,35 @@ describe("pull request runner test", () => { "https://github.com/owner/reponame/pull/4444" ]); - expect(async () => await runner.execute()).rejects.toThrow("Provided pull request is not merged!"); + await runner.execute(); + + const cwd = process.cwd() + "/bp"; + + expect(GitCLIService.prototype.clone).toBeCalledTimes(1); + expect(GitCLIService.prototype.clone).toBeCalledWith("https://github.com/owner/reponame.git", cwd, "target"); + + expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1); + expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-91748965051fae1330ad58d15cf694e103267c87"); + + expect(GitCLIService.prototype.fetch).toBeCalledTimes(1); + expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "pull/4444/head:pr/4444"); + + expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1); + expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "91748965051fae1330ad58d15cf694e103267c87"); + + expect(GitCLIService.prototype.push).toBeCalledTimes(1); + expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-91748965051fae1330ad58d15cf694e103267c87"); + + expect(GitHubService.prototype.createPullRequest).toBeCalledTimes(1); + expect(GitHubService.prototype.createPullRequest).toBeCalledWith({ + owner: "owner", + repo: "reponame", + head: "bp-target-91748965051fae1330ad58d15cf694e103267c87", + base: "target", + title: "[target] PR Title", + body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/4444"), + reviewers: ["gh-user", "that-s-a-user"] + } + ); }); }); \ No newline at end of file diff --git a/test/service/runner/gha-runner.test.ts b/test/service/runner/gha-runner.test.ts index fca39a4..678a1cc 100644 --- a/test/service/runner/gha-runner.test.ts +++ b/test/service/runner/gha-runner.test.ts @@ -26,7 +26,7 @@ afterEach(() => { jest.clearAllMocks(); }); -describe("pull request runner test", () => { +describe("gha runner", () => { test("with dry run", async () => { spyGetInput({ "dry-run": "true", @@ -44,7 +44,8 @@ describe("pull request runner test", () => { expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1); expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"); - expect(GitCLIService.prototype.addRemote).toBeCalledTimes(0); + expect(GitCLIService.prototype.fetch).toBeCalledTimes(1); + expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "pull/2368/head:pr/2368"); expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1); expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"); @@ -69,7 +70,8 @@ describe("pull request runner test", () => { expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1); expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"); - expect(GitCLIService.prototype.addRemote).toBeCalledTimes(0); + expect(GitCLIService.prototype.fetch).toBeCalledTimes(1); + expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "pull/2368/head:pr/2368"); expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1); expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"); @@ -90,12 +92,50 @@ describe("pull request runner test", () => { ); }); - test("not merged pull request", async () => { + test("closed and not merged pull request", async () => { + spyGetInput({ + "target-branch": "target", + "pull-request": "https://github.com/owner/reponame/pull/6666" + }); + + expect(async () => await runner.execute()).rejects.toThrow("Provided pull request is closed and not merged!"); + }); + + test("open pull request", async () => { spyGetInput({ "target-branch": "target", "pull-request": "https://github.com/owner/reponame/pull/4444" }); - expect(async () => await runner.execute()).rejects.toThrow("Provided pull request is not merged!"); + await runner.execute(); + + const cwd = process.cwd() + "/bp"; + + expect(GitCLIService.prototype.clone).toBeCalledTimes(1); + expect(GitCLIService.prototype.clone).toBeCalledWith("https://github.com/owner/reponame.git", cwd, "target"); + + expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1); + expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-91748965051fae1330ad58d15cf694e103267c87"); + + expect(GitCLIService.prototype.fetch).toBeCalledTimes(1); + expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "pull/4444/head:pr/4444"); + + expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1); + expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "91748965051fae1330ad58d15cf694e103267c87"); + + expect(GitCLIService.prototype.push).toBeCalledTimes(1); + expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-91748965051fae1330ad58d15cf694e103267c87"); + + expect(GitHubService.prototype.createPullRequest).toBeCalledTimes(1); + expect(GitHubService.prototype.createPullRequest).toBeCalledWith({ + owner: "owner", + repo: "reponame", + head: "bp-target-91748965051fae1330ad58d15cf694e103267c87", + base: "target", + title: "[target] PR Title", + body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/4444"), + reviewers: ["gh-user", "that-s-a-user"] + } + ); }); }); \ No newline at end of file diff --git a/test/support/moctokit/moctokit-data.ts b/test/support/moctokit/moctokit-data.ts index c118e5c..9f242b3 100644 --- a/test/support/moctokit/moctokit-data.ts +++ b/test/support/moctokit/moctokit-data.ts @@ -466,7 +466,7 @@ export const mergedPullRequestFixture = { "changed_files": 2 }; -export const notMergedPullRequestFixture = { +export const openPullRequestFixture = { "url": "https://api.github.com/repos/owner/reponame/pulls/4444", "id": 1137188271, "node_id": "PR_kwDOABTq6s5DyB2v", @@ -475,7 +475,7 @@ export const notMergedPullRequestFixture = { "patch_url": "https://github.com/owner/reponame/pull/4444.patch", "issue_url": "https://api.github.com/repos/owner/reponame/issues/4444", "number": 4444, - "state": "closed", + "state": "open", "locked": false, "title": "PR Title", "user": { @@ -907,4 +907,910 @@ export const notMergedPullRequestFixture = { "additions": 2, "deletions": 2, "changed_files": 2 +}; + +export const notMergedPullRequestFixture = { + "url": "https://api.github.com/repos/owner/reponame/pulls/6666", + "id": 1137188271, + "node_id": "PR_kwDOABTq6s5DyB2v", + "html_url": "https://github.com/owner/reponame/pull/6666", + "diff_url": "https://github.com/owner/reponame/pull/6666.diff", + "patch_url": "https://github.com/owner/reponame/pull/6666.patch", + "issue_url": "https://api.github.com/repos/owner/reponame/issues/6666", + "number": 6666, + "state": "closed", + "locked": false, + "title": "PR Title", + "user": { + "login": "gh-user", + "id": 11995863, + "node_id": "MDQ6VXNlcjExOTk1ODYz", + "avatar_url": "https://avatars.githubusercontent.com/u/11995863?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/gh-user", + "html_url": "https://github.com/gh-user", + "followers_url": "https://api.github.com/users/gh-user/followers", + "following_url": "https://api.github.com/users/gh-user/following{/other_user}", + "gists_url": "https://api.github.com/users/gh-user/gists{/gist_id}", + "starred_url": "https://api.github.com/users/gh-user/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/gh-user/subscriptions", + "organizations_url": "https://api.github.com/users/gh-user/orgs", + "repos_url": "https://api.github.com/users/gh-user/repos", + "events_url": "https://api.github.com/users/gh-user/events{/privacy}", + "received_events_url": "https://api.github.com/users/gh-user/received_events", + "type": "User", + "site_admin": false + }, + "body": "Please review and merge", + "created_at": "2022-11-28T08:43:09Z", + "updated_at": "2022-11-28T10:11:53Z", + "closed_at": "2022-11-28T10:11:52Z", + "merged_at": "2022-11-28T10:11:52Z", + "merge_commit_sha": "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", + "assignee": null, + "assignees": [ + + ], + "requested_reviewers": [ + { + "login": "gh-user", + "id": 1422582, + "node_id": "MDQ6VXNlcjE0MjI1ODI=", + "avatar_url": "https://avatars.githubusercontent.com/u/1422582?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/gh-user", + "html_url": "https://github.com/gh-user", + "followers_url": "https://api.github.com/users/gh-user/followers", + "following_url": "https://api.github.com/users/gh-user/following{/other_user}", + "gists_url": "https://api.github.com/users/gh-user/gists{/gist_id}", + "starred_url": "https://api.github.com/users/gh-user/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/gh-user/subscriptions", + "organizations_url": "https://api.github.com/users/gh-user/orgs", + "repos_url": "https://api.github.com/users/gh-user/repos", + "events_url": "https://api.github.com/users/gh-user/events{/privacy}", + "received_events_url": "https://api.github.com/users/gh-user/received_events", + "type": "User", + "site_admin": false + } + ], + "requested_teams": [ + + ], + "labels": [ + + ], + "milestone": null, + "draft": false, + "commits_url": "https://api.github.com/repos/owner/reponame/pulls/6666/commits", + "review_comments_url": "https://api.github.com/repos/owner/reponame/pulls/6666/comments", + "review_comment_url": "https://api.github.com/repos/owner/reponame/pulls/comments{/number}", + "comments_url": "https://api.github.com/repos/owner/reponame/issues/6666/comments", + "statuses_url": "https://api.github.com/repos/owner/reponame/statuses/91748965051fae1330ad58d15cf694e103267c87", + "head": { + "label": "kiegroup:bump-8.31.x-drools-8.31.0.Final", + "ref": "bump-8.31.x-drools-8.31.0.Final", + "sha": "91748965051fae1330ad58d15cf694e103267c87", + "user": { + "login": "kiegroup", + "id": 517980, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjUxNzk4MA==", + "avatar_url": "https://avatars.githubusercontent.com/u/517980?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/kiegroup", + "html_url": "https://github.com/kiegroup", + "followers_url": "https://api.github.com/users/kiegroup/followers", + "following_url": "https://api.github.com/users/kiegroup/following{/other_user}", + "gists_url": "https://api.github.com/users/kiegroup/gists{/gist_id}", + "starred_url": "https://api.github.com/users/kiegroup/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/kiegroup/subscriptions", + "organizations_url": "https://api.github.com/users/kiegroup/orgs", + "repos_url": "https://api.github.com/users/kiegroup/repos", + "events_url": "https://api.github.com/users/kiegroup/events{/privacy}", + "received_events_url": "https://api.github.com/users/kiegroup/received_events", + "type": "Organization", + "site_admin": false + }, + "repo": { + "id": 1370858, + "node_id": "MDEwOlJlcG9zaXRvcnkxMzcwODU4", + "name": "reponame", + "full_name": "fork/reponame", + "private": false, + "owner": { + "login": "kiegroup", + "id": 517980, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjUxNzk4MA==", + "avatar_url": "https://avatars.githubusercontent.com/u/517980?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/kiegroup", + "html_url": "https://github.com/kiegroup", + "followers_url": "https://api.github.com/users/kiegroup/followers", + "following_url": "https://api.github.com/users/kiegroup/following{/other_user}", + "gists_url": "https://api.github.com/users/kiegroup/gists{/gist_id}", + "starred_url": "https://api.github.com/users/kiegroup/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/kiegroup/subscriptions", + "organizations_url": "https://api.github.com/users/kiegroup/orgs", + "repos_url": "https://api.github.com/users/kiegroup/repos", + "events_url": "https://api.github.com/users/kiegroup/events{/privacy}", + "received_events_url": "https://api.github.com/users/kiegroup/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/fork/reponame", + "description": "AI constraint solver in Java to optimize the vehicle routing problem, employee rostering, task assignment, maintenance scheduling, conference scheduling and other planning problems.", + "fork": false, + "url": "https://api.github.com/repos/fork/reponame", + "forks_url": "https://api.github.com/repos/fork/reponame/forks", + "keys_url": "https://api.github.com/repos/fork/reponame/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/fork/reponame/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/fork/reponame/teams", + "hooks_url": "https://api.github.com/repos/fork/reponame/hooks", + "issue_events_url": "https://api.github.com/repos/fork/reponame/issues/events{/number}", + "events_url": "https://api.github.com/repos/fork/reponame/events", + "assignees_url": "https://api.github.com/repos/fork/reponame/assignees{/user}", + "branches_url": "https://api.github.com/repos/fork/reponame/branches{/branch}", + "tags_url": "https://api.github.com/repos/fork/reponame/tags", + "blobs_url": "https://api.github.com/repos/fork/reponame/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/fork/reponame/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/fork/reponame/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/fork/reponame/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/fork/reponame/statuses/{sha}", + "languages_url": "https://api.github.com/repos/fork/reponame/languages", + "stargazers_url": "https://api.github.com/repos/fork/reponame/stargazers", + "contributors_url": "https://api.github.com/repos/fork/reponame/contributors", + "subscribers_url": "https://api.github.com/repos/fork/reponame/subscribers", + "subscription_url": "https://api.github.com/repos/fork/reponame/subscription", + "commits_url": "https://api.github.com/repos/fork/reponame/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/fork/reponame/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/fork/reponame/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/fork/reponame/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/fork/reponame/contents/{+path}", + "compare_url": "https://api.github.com/repos/fork/reponame/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/fork/reponame/merges", + "archive_url": "https://api.github.com/repos/fork/reponame/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/fork/reponame/downloads", + "issues_url": "https://api.github.com/repos/fork/reponame/issues{/number}", + "pulls_url": "https://api.github.com/repos/fork/reponame/pulls{/number}", + "milestones_url": "https://api.github.com/repos/fork/reponame/milestones{/number}", + "notifications_url": "https://api.github.com/repos/fork/reponame/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/fork/reponame/labels{/name}", + "releases_url": "https://api.github.com/repos/fork/reponame/releases{/id}", + "deployments_url": "https://api.github.com/repos/fork/reponame/deployments", + "created_at": "2011-02-15T19:38:23Z", + "updated_at": "2022-11-28T05:01:47Z", + "pushed_at": "2022-11-28T10:50:51Z", + "git_url": "git://github.com/fork/reponame.git", + "ssh_url": "git@github.com:fork/reponame.git", + "clone_url": "https://github.com/fork/reponame.git", + "svn_url": "https://github.com/fork/reponame", + "homepage": "https://www.reponame.org", + "size": 238339, + "stargazers_count": 2811, + "watchers_count": 2811, + "language": "Java", + "has_issues": false, + "has_projects": false, + "has_downloads": true, + "has_wiki": false, + "has_pages": false, + "has_discussions": false, + "forks_count": 878, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 30, + "license": { + "key": "apache-2.0", + "name": "Apache License 2.0", + "spdx_id": "Apache-2.0", + "url": "https://api.github.com/licenses/apache-2.0", + "node_id": "MDc6TGljZW5zZTI=" + }, + "allow_forking": true, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [ + "artificial-intelligence", + "branch-and-bound", + "constraint-programming", + "constraint-satisfaction-problem", + "constraint-solver", + "constraints", + "employee-rostering", + "java", + "local-search", + "mathematical-optimization", + "metaheuristics", + "optimization", + "rostering", + "scheduling", + "simulated-annealing", + "solver", + "tabu-search", + "traveling-salesman", + "traveling-salesman-problem", + "vehicle-routing-problem" + ], + "visibility": "public", + "forks": 878, + "open_issues": 30, + "watchers": 2811, + "default_branch": "main" + } + }, + "base": { + "label": "kiegroup:8.31.x", + "ref": "8.31.x", + "sha": "8cfc286765cb01c84a1d62c65519fa8032bfecbd", + "user": { + "login": "kiegroup", + "id": 517980, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjUxNzk4MA==", + "avatar_url": "https://avatars.githubusercontent.com/u/517980?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/kiegroup", + "html_url": "https://github.com/kiegroup", + "followers_url": "https://api.github.com/users/kiegroup/followers", + "following_url": "https://api.github.com/users/kiegroup/following{/other_user}", + "gists_url": "https://api.github.com/users/kiegroup/gists{/gist_id}", + "starred_url": "https://api.github.com/users/kiegroup/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/kiegroup/subscriptions", + "organizations_url": "https://api.github.com/users/kiegroup/orgs", + "repos_url": "https://api.github.com/users/kiegroup/repos", + "events_url": "https://api.github.com/users/kiegroup/events{/privacy}", + "received_events_url": "https://api.github.com/users/kiegroup/received_events", + "type": "Organization", + "site_admin": false + }, + "repo": { + "id": 1370858, + "node_id": "MDEwOlJlcG9zaXRvcnkxMzcwODU4", + "name": "reponame", + "full_name": "owner/reponame", + "private": false, + "owner": { + "login": "kiegroup", + "id": 517980, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjUxNzk4MA==", + "avatar_url": "https://avatars.githubusercontent.com/u/517980?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/kiegroup", + "html_url": "https://github.com/kiegroup", + "followers_url": "https://api.github.com/users/kiegroup/followers", + "following_url": "https://api.github.com/users/kiegroup/following{/other_user}", + "gists_url": "https://api.github.com/users/kiegroup/gists{/gist_id}", + "starred_url": "https://api.github.com/users/kiegroup/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/kiegroup/subscriptions", + "organizations_url": "https://api.github.com/users/kiegroup/orgs", + "repos_url": "https://api.github.com/users/kiegroup/repos", + "events_url": "https://api.github.com/users/kiegroup/events{/privacy}", + "received_events_url": "https://api.github.com/users/kiegroup/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/owner/reponame", + "description": "AI constraint solver in Java to optimize the vehicle routing problem, employee rostering, task assignment, maintenance scheduling, conference scheduling and other planning problems.", + "fork": false, + "url": "https://api.github.com/repos/owner/reponame", + "forks_url": "https://api.github.com/repos/owner/reponame/forks", + "keys_url": "https://api.github.com/repos/owner/reponame/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/owner/reponame/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/owner/reponame/teams", + "hooks_url": "https://api.github.com/repos/owner/reponame/hooks", + "issue_events_url": "https://api.github.com/repos/owner/reponame/issues/events{/number}", + "events_url": "https://api.github.com/repos/owner/reponame/events", + "assignees_url": "https://api.github.com/repos/owner/reponame/assignees{/user}", + "branches_url": "https://api.github.com/repos/owner/reponame/branches{/branch}", + "tags_url": "https://api.github.com/repos/owner/reponame/tags", + "blobs_url": "https://api.github.com/repos/owner/reponame/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/owner/reponame/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/owner/reponame/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/owner/reponame/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/owner/reponame/statuses/{sha}", + "languages_url": "https://api.github.com/repos/owner/reponame/languages", + "stargazers_url": "https://api.github.com/repos/owner/reponame/stargazers", + "contributors_url": "https://api.github.com/repos/owner/reponame/contributors", + "subscribers_url": "https://api.github.com/repos/owner/reponame/subscribers", + "subscription_url": "https://api.github.com/repos/owner/reponame/subscription", + "commits_url": "https://api.github.com/repos/owner/reponame/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/owner/reponame/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/owner/reponame/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/owner/reponame/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/owner/reponame/contents/{+path}", + "compare_url": "https://api.github.com/repos/owner/reponame/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/owner/reponame/merges", + "archive_url": "https://api.github.com/repos/owner/reponame/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/owner/reponame/downloads", + "issues_url": "https://api.github.com/repos/owner/reponame/issues{/number}", + "pulls_url": "https://api.github.com/repos/owner/reponame/pulls{/number}", + "milestones_url": "https://api.github.com/repos/owner/reponame/milestones{/number}", + "notifications_url": "https://api.github.com/repos/owner/reponame/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/owner/reponame/labels{/name}", + "releases_url": "https://api.github.com/repos/owner/reponame/releases{/id}", + "deployments_url": "https://api.github.com/repos/owner/reponame/deployments", + "created_at": "2011-02-15T19:38:23Z", + "updated_at": "2022-11-28T05:01:47Z", + "pushed_at": "2022-11-28T10:50:51Z", + "git_url": "git://github.com/owner/reponame.git", + "ssh_url": "git@github.com:owner/reponame.git", + "clone_url": "https://github.com/owner/reponame.git", + "svn_url": "https://github.com/owner/reponame", + "homepage": "https://www.reponame.org", + "size": 238339, + "stargazers_count": 2811, + "watchers_count": 2811, + "language": "Java", + "has_issues": false, + "has_projects": false, + "has_downloads": true, + "has_wiki": false, + "has_pages": false, + "has_discussions": false, + "forks_count": 878, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 30, + "license": { + "key": "apache-2.0", + "name": "Apache License 2.0", + "spdx_id": "Apache-2.0", + "url": "https://api.github.com/licenses/apache-2.0", + "node_id": "MDc6TGljZW5zZTI=" + }, + "allow_forking": true, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [ + "artificial-intelligence", + "branch-and-bound", + "constraint-programming", + "constraint-satisfaction-problem", + "constraint-solver", + "constraints", + "employee-rostering", + "java", + "local-search", + "mathematical-optimization", + "metaheuristics", + "optimization", + "rostering", + "scheduling", + "simulated-annealing", + "solver", + "tabu-search", + "traveling-salesman", + "traveling-salesman-problem", + "vehicle-routing-problem" + ], + "visibility": "public", + "forks": 878, + "open_issues": 30, + "watchers": 2811, + "default_branch": "main" + } + }, + "_links": { + "self": { + "href": "https://api.github.com/repos/owner/reponame/pulls/6666" + }, + "html": { + "href": "https://github.com/owner/reponame/pull/6666" + }, + "issue": { + "href": "https://api.github.com/repos/owner/reponame/issues/6666" + }, + "comments": { + "href": "https://api.github.com/repos/owner/reponame/issues/6666/comments" + }, + "review_comments": { + "href": "https://api.github.com/repos/owner/reponame/pulls/6666/comments" + }, + "review_comment": { + "href": "https://api.github.com/repos/owner/reponame/pulls/comments{/number}" + }, + "commits": { + "href": "https://api.github.com/repos/owner/reponame/pulls/6666/commits" + }, + "statuses": { + "href": "https://api.github.com/repos/owner/reponame/statuses/91748965051fae1330ad58d15cf694e103267c87" + } + }, + "author_association": "CONTRIBUTOR", + "auto_merge": null, + "active_lock_reason": null, + "merged": null, + "mergeable": null, + "rebaseable": null, + "mergeable_state": "unknown", + "merged_by": { + "login": "that-s-a-user", + "id": 17157711, + "node_id": "MDQ6VXNlcjE3MTU3NzEx", + "avatar_url": "https://avatars.githubusercontent.com/u/17157711?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/that-s-a-user", + "html_url": "https://github.com/that-s-a-user", + "followers_url": "https://api.github.com/users/that-s-a-user/followers", + "following_url": "https://api.github.com/users/that-s-a-user/following{/other_user}", + "gists_url": "https://api.github.com/users/that-s-a-user/gists{/gist_id}", + "starred_url": "https://api.github.com/users/that-s-a-user/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/that-s-a-user/subscriptions", + "organizations_url": "https://api.github.com/users/that-s-a-user/orgs", + "repos_url": "https://api.github.com/users/that-s-a-user/repos", + "events_url": "https://api.github.com/users/that-s-a-user/events{/privacy}", + "received_events_url": "https://api.github.com/users/that-s-a-user/received_events", + "type": "User", + "site_admin": false + }, + "comments": 0, + "review_comments": 0, + "maintainer_can_modify": false, + "commits": 2, + "additions": 2, + "deletions": 2, + "changed_files": 2 +}; + +export const sameOwnerPullRequestFixture = { + "url": "https://api.github.com/repos/owner/reponame/pulls/8632", + "id": 1137188271, + "node_id": "PR_kwDOABTq6s5DyB2v", + "html_url": "https://github.com/owner/reponame/pull/8632", + "diff_url": "https://github.com/owner/reponame/pull/8632.diff", + "patch_url": "https://github.com/owner/reponame/pull/8632.patch", + "issue_url": "https://api.github.com/repos/owner/reponame/issues/8632", + "number": 8632, + "state": "closed", + "locked": false, + "title": "PR Title", + "user": { + "login": "gh-user", + "id": 11995863, + "node_id": "MDQ6VXNlcjExOTk1ODYz", + "avatar_url": "https://avatars.githubusercontent.com/u/11995863?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/gh-user", + "html_url": "https://github.com/gh-user", + "followers_url": "https://api.github.com/users/gh-user/followers", + "following_url": "https://api.github.com/users/gh-user/following{/other_user}", + "gists_url": "https://api.github.com/users/gh-user/gists{/gist_id}", + "starred_url": "https://api.github.com/users/gh-user/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/gh-user/subscriptions", + "organizations_url": "https://api.github.com/users/gh-user/orgs", + "repos_url": "https://api.github.com/users/gh-user/repos", + "events_url": "https://api.github.com/users/gh-user/events{/privacy}", + "received_events_url": "https://api.github.com/users/gh-user/received_events", + "type": "User", + "site_admin": false + }, + "body": "Please review and merge", + "created_at": "2022-11-28T08:43:09Z", + "updated_at": "2022-11-28T10:11:53Z", + "closed_at": "2022-11-28T10:11:52Z", + "merged_at": "2022-11-28T10:11:52Z", + "merge_commit_sha": "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc", + "assignee": null, + "assignees": [ + + ], + "requested_reviewers": [ + { + "login": "requested-gh-user", + "id": 1422582, + "node_id": "MDQ6VXNlcjE0MjI1ODI=", + "avatar_url": "https://avatars.githubusercontent.com/u/1422582?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/requested-gh-user", + "html_url": "https://github.com/requested-gh-user", + "followers_url": "https://api.github.com/users/requested-gh-user/followers", + "following_url": "https://api.github.com/users/requested-gh-user/following{/other_user}", + "gists_url": "https://api.github.com/users/requested-gh-user/gists{/gist_id}", + "starred_url": "https://api.github.com/users/requested-gh-user/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/requested-gh-user/subscriptions", + "organizations_url": "https://api.github.com/users/requested-gh-user/orgs", + "repos_url": "https://api.github.com/users/requested-gh-user/repos", + "events_url": "https://api.github.com/users/requested-gh-user/events{/privacy}", + "received_events_url": "https://api.github.com/users/requested-gh-user/received_events", + "type": "User", + "site_admin": false + }, + { + "login": "gh-user", + "id": 1422582, + "node_id": "MDQ6VXNlcjE0MjI1ODI=", + "avatar_url": "https://avatars.githubusercontent.com/u/1422582?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/gh-user", + "html_url": "https://github.com/gh-user", + "followers_url": "https://api.github.com/users/gh-user/followers", + "following_url": "https://api.github.com/users/gh-user/following{/other_user}", + "gists_url": "https://api.github.com/users/gh-user/gists{/gist_id}", + "starred_url": "https://api.github.com/users/gh-user/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/gh-user/subscriptions", + "organizations_url": "https://api.github.com/users/gh-user/orgs", + "repos_url": "https://api.github.com/users/gh-user/repos", + "events_url": "https://api.github.com/users/gh-user/events{/privacy}", + "received_events_url": "https://api.github.com/users/gh-user/received_events", + "type": "User", + "site_admin": false + } + ], + "requested_teams": [ + + ], + "labels": [ + + ], + "milestone": null, + "draft": false, + "commits_url": "https://api.github.com/repos/owner/reponame/pulls/8632/commits", + "review_comments_url": "https://api.github.com/repos/owner/reponame/pulls/8632/comments", + "review_comment_url": "https://api.github.com/repos/owner/reponame/pulls/comments{/number}", + "comments_url": "https://api.github.com/repos/owner/reponame/issues/8632/comments", + "statuses_url": "https://api.github.com/repos/owner/reponame/statuses/91748965051fae1330ad58d15cf694e103267c87", + "head": { + "label": "kiegroup:bump-8.31.x-drools-8.31.0.Final", + "ref": "bump-8.31.x-drools-8.31.0.Final", + "sha": "91748965051fae1330ad58d15cf694e103267c87", + "user": { + "login": "kiegroup", + "id": 517980, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjUxNzk4MA==", + "avatar_url": "https://avatars.githubusercontent.com/u/517980?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/kiegroup", + "html_url": "https://github.com/kiegroup", + "followers_url": "https://api.github.com/users/kiegroup/followers", + "following_url": "https://api.github.com/users/kiegroup/following{/other_user}", + "gists_url": "https://api.github.com/users/kiegroup/gists{/gist_id}", + "starred_url": "https://api.github.com/users/kiegroup/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/kiegroup/subscriptions", + "organizations_url": "https://api.github.com/users/kiegroup/orgs", + "repos_url": "https://api.github.com/users/kiegroup/repos", + "events_url": "https://api.github.com/users/kiegroup/events{/privacy}", + "received_events_url": "https://api.github.com/users/kiegroup/received_events", + "type": "Organization", + "site_admin": false + }, + "repo": { + "id": 1370858, + "node_id": "MDEwOlJlcG9zaXRvcnkxMzcwODU4", + "name": "reponame", + "full_name": "owner/reponame", + "private": false, + "owner": { + "login": "kiegroup", + "id": 517980, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjUxNzk4MA==", + "avatar_url": "https://avatars.githubusercontent.com/u/517980?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/kiegroup", + "html_url": "https://github.com/kiegroup", + "followers_url": "https://api.github.com/users/kiegroup/followers", + "following_url": "https://api.github.com/users/kiegroup/following{/other_user}", + "gists_url": "https://api.github.com/users/kiegroup/gists{/gist_id}", + "starred_url": "https://api.github.com/users/kiegroup/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/kiegroup/subscriptions", + "organizations_url": "https://api.github.com/users/kiegroup/orgs", + "repos_url": "https://api.github.com/users/kiegroup/repos", + "events_url": "https://api.github.com/users/kiegroup/events{/privacy}", + "received_events_url": "https://api.github.com/users/kiegroup/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/owner/reponame", + "description": "AI constraint solver in Java to optimize the vehicle routing problem, employee rostering, task assignment, maintenance scheduling, conference scheduling and other planning problems.", + "fork": false, + "url": "https://api.github.com/repos/owner/reponame", + "forks_url": "https://api.github.com/repos/owner/reponame/forks", + "keys_url": "https://api.github.com/repos/owner/reponame/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/owner/reponame/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/owner/reponame/teams", + "hooks_url": "https://api.github.com/repos/owner/reponame/hooks", + "issue_events_url": "https://api.github.com/repos/owner/reponame/issues/events{/number}", + "events_url": "https://api.github.com/repos/owner/reponame/events", + "assignees_url": "https://api.github.com/repos/owner/reponame/assignees{/user}", + "branches_url": "https://api.github.com/repos/owner/reponame/branches{/branch}", + "tags_url": "https://api.github.com/repos/owner/reponame/tags", + "blobs_url": "https://api.github.com/repos/owner/reponame/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/owner/reponame/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/owner/reponame/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/owner/reponame/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/owner/reponame/statuses/{sha}", + "languages_url": "https://api.github.com/repos/owner/reponame/languages", + "stargazers_url": "https://api.github.com/repos/owner/reponame/stargazers", + "contributors_url": "https://api.github.com/repos/owner/reponame/contributors", + "subscribers_url": "https://api.github.com/repos/owner/reponame/subscribers", + "subscription_url": "https://api.github.com/repos/owner/reponame/subscription", + "commits_url": "https://api.github.com/repos/owner/reponame/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/owner/reponame/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/owner/reponame/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/owner/reponame/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/owner/reponame/contents/{+path}", + "compare_url": "https://api.github.com/repos/owner/reponame/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/owner/reponame/merges", + "archive_url": "https://api.github.com/repos/owner/reponame/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/owner/reponame/downloads", + "issues_url": "https://api.github.com/repos/owner/reponame/issues{/number}", + "pulls_url": "https://api.github.com/repos/owner/reponame/pulls{/number}", + "milestones_url": "https://api.github.com/repos/owner/reponame/milestones{/number}", + "notifications_url": "https://api.github.com/repos/owner/reponame/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/owner/reponame/labels{/name}", + "releases_url": "https://api.github.com/repos/owner/reponame/releases{/id}", + "deployments_url": "https://api.github.com/repos/owner/reponame/deployments", + "created_at": "2011-02-15T19:38:23Z", + "updated_at": "2022-11-28T05:01:47Z", + "pushed_at": "2022-11-28T10:50:51Z", + "git_url": "git://github.com/owner/reponame.git", + "ssh_url": "git@github.com:owner/reponame.git", + "clone_url": "https://github.com/owner/reponame.git", + "svn_url": "https://github.com/owner/reponame", + "homepage": "https://www.reponame.org", + "size": 238339, + "stargazers_count": 2811, + "watchers_count": 2811, + "language": "Java", + "has_issues": false, + "has_projects": false, + "has_downloads": true, + "has_wiki": false, + "has_pages": false, + "has_discussions": false, + "forks_count": 878, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 30, + "license": { + "key": "apache-2.0", + "name": "Apache License 2.0", + "spdx_id": "Apache-2.0", + "url": "https://api.github.com/licenses/apache-2.0", + "node_id": "MDc6TGljZW5zZTI=" + }, + "allow_forking": true, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [ + "artificial-intelligence", + "branch-and-bound", + "constraint-programming", + "constraint-satisfaction-problem", + "constraint-solver", + "constraints", + "employee-rostering", + "java", + "local-search", + "mathematical-optimization", + "metaheuristics", + "optimization", + "rostering", + "scheduling", + "simulated-annealing", + "solver", + "tabu-search", + "traveling-salesman", + "traveling-salesman-problem", + "vehicle-routing-problem" + ], + "visibility": "public", + "forks": 878, + "open_issues": 30, + "watchers": 2811, + "default_branch": "main" + } + }, + "base": { + "label": "kiegroup:8.31.x", + "ref": "8.31.x", + "sha": "8cfc286765cb01c84a1d62c65519fa8032bfecbd", + "user": { + "login": "kiegroup", + "id": 517980, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjUxNzk4MA==", + "avatar_url": "https://avatars.githubusercontent.com/u/517980?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/kiegroup", + "html_url": "https://github.com/kiegroup", + "followers_url": "https://api.github.com/users/kiegroup/followers", + "following_url": "https://api.github.com/users/kiegroup/following{/other_user}", + "gists_url": "https://api.github.com/users/kiegroup/gists{/gist_id}", + "starred_url": "https://api.github.com/users/kiegroup/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/kiegroup/subscriptions", + "organizations_url": "https://api.github.com/users/kiegroup/orgs", + "repos_url": "https://api.github.com/users/kiegroup/repos", + "events_url": "https://api.github.com/users/kiegroup/events{/privacy}", + "received_events_url": "https://api.github.com/users/kiegroup/received_events", + "type": "Organization", + "site_admin": false + }, + "repo": { + "id": 1370858, + "node_id": "MDEwOlJlcG9zaXRvcnkxMzcwODU4", + "name": "reponame", + "full_name": "owner/reponame", + "private": false, + "owner": { + "login": "kiegroup", + "id": 517980, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjUxNzk4MA==", + "avatar_url": "https://avatars.githubusercontent.com/u/517980?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/kiegroup", + "html_url": "https://github.com/kiegroup", + "followers_url": "https://api.github.com/users/kiegroup/followers", + "following_url": "https://api.github.com/users/kiegroup/following{/other_user}", + "gists_url": "https://api.github.com/users/kiegroup/gists{/gist_id}", + "starred_url": "https://api.github.com/users/kiegroup/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/kiegroup/subscriptions", + "organizations_url": "https://api.github.com/users/kiegroup/orgs", + "repos_url": "https://api.github.com/users/kiegroup/repos", + "events_url": "https://api.github.com/users/kiegroup/events{/privacy}", + "received_events_url": "https://api.github.com/users/kiegroup/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/owner/reponame", + "description": "AI constraint solver in Java to optimize the vehicle routing problem, employee rostering, task assignment, maintenance scheduling, conference scheduling and other planning problems.", + "fork": false, + "url": "https://api.github.com/repos/owner/reponame", + "forks_url": "https://api.github.com/repos/owner/reponame/forks", + "keys_url": "https://api.github.com/repos/owner/reponame/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/owner/reponame/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/owner/reponame/teams", + "hooks_url": "https://api.github.com/repos/owner/reponame/hooks", + "issue_events_url": "https://api.github.com/repos/owner/reponame/issues/events{/number}", + "events_url": "https://api.github.com/repos/owner/reponame/events", + "assignees_url": "https://api.github.com/repos/owner/reponame/assignees{/user}", + "branches_url": "https://api.github.com/repos/owner/reponame/branches{/branch}", + "tags_url": "https://api.github.com/repos/owner/reponame/tags", + "blobs_url": "https://api.github.com/repos/owner/reponame/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/owner/reponame/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/owner/reponame/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/owner/reponame/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/owner/reponame/statuses/{sha}", + "languages_url": "https://api.github.com/repos/owner/reponame/languages", + "stargazers_url": "https://api.github.com/repos/owner/reponame/stargazers", + "contributors_url": "https://api.github.com/repos/owner/reponame/contributors", + "subscribers_url": "https://api.github.com/repos/owner/reponame/subscribers", + "subscription_url": "https://api.github.com/repos/owner/reponame/subscription", + "commits_url": "https://api.github.com/repos/owner/reponame/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/owner/reponame/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/owner/reponame/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/owner/reponame/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/owner/reponame/contents/{+path}", + "compare_url": "https://api.github.com/repos/owner/reponame/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/owner/reponame/merges", + "archive_url": "https://api.github.com/repos/owner/reponame/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/owner/reponame/downloads", + "issues_url": "https://api.github.com/repos/owner/reponame/issues{/number}", + "pulls_url": "https://api.github.com/repos/owner/reponame/pulls{/number}", + "milestones_url": "https://api.github.com/repos/owner/reponame/milestones{/number}", + "notifications_url": "https://api.github.com/repos/owner/reponame/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/owner/reponame/labels{/name}", + "releases_url": "https://api.github.com/repos/owner/reponame/releases{/id}", + "deployments_url": "https://api.github.com/repos/owner/reponame/deployments", + "created_at": "2011-02-15T19:38:23Z", + "updated_at": "2022-11-28T05:01:47Z", + "pushed_at": "2022-11-28T10:50:51Z", + "git_url": "git://github.com/owner/reponame.git", + "ssh_url": "git@github.com:owner/reponame.git", + "clone_url": "https://github.com/owner/reponame.git", + "svn_url": "https://github.com/owner/reponame", + "homepage": "https://www.reponame.org", + "size": 238339, + "stargazers_count": 2811, + "watchers_count": 2811, + "language": "Java", + "has_issues": false, + "has_projects": false, + "has_downloads": true, + "has_wiki": false, + "has_pages": false, + "has_discussions": false, + "forks_count": 878, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 30, + "license": { + "key": "apache-2.0", + "name": "Apache License 2.0", + "spdx_id": "Apache-2.0", + "url": "https://api.github.com/licenses/apache-2.0", + "node_id": "MDc6TGljZW5zZTI=" + }, + "allow_forking": true, + "is_template": false, + "web_commit_signoff_required": false, + "topics": [ + "artificial-intelligence", + "branch-and-bound", + "constraint-programming", + "constraint-satisfaction-problem", + "constraint-solver", + "constraints", + "employee-rostering", + "java", + "local-search", + "mathematical-optimization", + "metaheuristics", + "optimization", + "rostering", + "scheduling", + "simulated-annealing", + "solver", + "tabu-search", + "traveling-salesman", + "traveling-salesman-problem", + "vehicle-routing-problem" + ], + "visibility": "public", + "forks": 878, + "open_issues": 30, + "watchers": 2811, + "default_branch": "main" + } + }, + "_links": { + "self": { + "href": "https://api.github.com/repos/owner/reponame/pulls/8632" + }, + "html": { + "href": "https://github.com/owner/reponame/pull/8632" + }, + "issue": { + "href": "https://api.github.com/repos/owner/reponame/issues/8632" + }, + "comments": { + "href": "https://api.github.com/repos/owner/reponame/issues/8632/comments" + }, + "review_comments": { + "href": "https://api.github.com/repos/owner/reponame/pulls/8632/comments" + }, + "review_comment": { + "href": "https://api.github.com/repos/owner/reponame/pulls/comments{/number}" + }, + "commits": { + "href": "https://api.github.com/repos/owner/reponame/pulls/8632/commits" + }, + "statuses": { + "href": "https://api.github.com/repos/owner/reponame/statuses/91748965051fae1330ad58d15cf694e103267c87" + } + }, + "author_association": "CONTRIBUTOR", + "auto_merge": null, + "active_lock_reason": null, + "merged": true, + "mergeable": null, + "rebaseable": null, + "mergeable_state": "unknown", + "merged_by": { + "login": "that-s-a-user", + "id": 17157711, + "node_id": "MDQ6VXNlcjE3MTU3NzEx", + "avatar_url": "https://avatars.githubusercontent.com/u/17157711?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/that-s-a-user", + "html_url": "https://github.com/that-s-a-user", + "followers_url": "https://api.github.com/users/that-s-a-user/followers", + "following_url": "https://api.github.com/users/that-s-a-user/following{/other_user}", + "gists_url": "https://api.github.com/users/that-s-a-user/gists{/gist_id}", + "starred_url": "https://api.github.com/users/that-s-a-user/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/that-s-a-user/subscriptions", + "organizations_url": "https://api.github.com/users/that-s-a-user/orgs", + "repos_url": "https://api.github.com/users/that-s-a-user/repos", + "events_url": "https://api.github.com/users/that-s-a-user/events{/privacy}", + "received_events_url": "https://api.github.com/users/that-s-a-user/received_events", + "type": "User", + "site_admin": false + }, + "comments": 0, + "review_comments": 0, + "maintainer_can_modify": false, + "commits": 2, + "additions": 2, + "deletions": 2, + "changed_files": 2 }; \ No newline at end of file diff --git a/test/support/moctokit/moctokit-support.ts b/test/support/moctokit/moctokit-support.ts index 7f58910..78be900 100644 --- a/test/support/moctokit/moctokit-support.ts +++ b/test/support/moctokit/moctokit-support.ts @@ -1,6 +1,6 @@ import LoggerServiceFactory from "@bp/service/logger/logger-service-factory"; import { Moctokit } from "@kie/mock-github"; -import { targetOwner, repo, mergedPullRequestFixture, notMergedPullRequestFixture, notFoundPullRequestNumber } from "./moctokit-data"; +import { targetOwner, repo, mergedPullRequestFixture, openPullRequestFixture, notMergedPullRequestFixture, notFoundPullRequestNumber, sameOwnerPullRequestFixture } from "./moctokit-data"; const logger = LoggerServiceFactory.getLogger(); @@ -22,18 +22,40 @@ export const setupMoctokit = (): Moctokit => { status: 200, data: mergedPullRequestFixture }); + + mock.rest.pulls + .get({ + owner: targetOwner, + repo: repo, + pull_number: sameOwnerPullRequestFixture.number + }) + .reply({ + status: 200, + data: sameOwnerPullRequestFixture + }); mock.rest.pulls .get({ owner: targetOwner, repo: repo, - pull_number: notMergedPullRequestFixture.number + pull_number: openPullRequestFixture.number }) .reply({ status: 200, - data: notMergedPullRequestFixture + data: openPullRequestFixture }); + mock.rest.pulls + .get({ + owner: targetOwner, + repo: repo, + pull_number: notMergedPullRequestFixture.number + }) + .reply({ + status: 200, + data: notMergedPullRequestFixture + }); + mock.rest.pulls .create() .reply({