mirror of
https://github.com/kiegroup/git-backporting.git
synced 2025-04-24 20:32:14 +00:00
Initial BPer implementation
This commit is contained in:
parent
05d156a5b0
commit
f0d9f789fa
59 changed files with 33618 additions and 1048 deletions
|
@ -43,5 +43,9 @@
|
||||||
"error",
|
"error",
|
||||||
"as-needed"
|
"as-needed"
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"env": {
|
||||||
|
"node": true,
|
||||||
|
"es2020": true
|
||||||
}
|
}
|
||||||
}
|
}
|
9
.github/dependabot.yml
vendored
Normal file
9
.github/dependabot.yml
vendored
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
version: 2
|
||||||
|
updates:
|
||||||
|
# Enable version updates for npm
|
||||||
|
- package-ecosystem: 'npm'
|
||||||
|
# Look for `package.json` and `lock` files in the `root` directory
|
||||||
|
directory: '/'
|
||||||
|
# Check the npm registry for updates every day (weekdays)
|
||||||
|
schedule:
|
||||||
|
interval: 'daily'
|
20
.github/pull_request_template.md
vendored
Normal file
20
.github/pull_request_template.md
vendored
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
**Thank you for submitting this pull request**
|
||||||
|
|
||||||
|
fix _(please add the issue ID if it exists)_
|
||||||
|
|
||||||
|
### Referenced pull requests
|
||||||
|
|
||||||
|
<!-- Add URLs of all referenced pull requests if they exist. This is only required when making
|
||||||
|
changes that span multiple kiegroup repositories and depend on each other. -->
|
||||||
|
<!-- Example:
|
||||||
|
- https://github.com/kiegroup/droolsjbpm-build-bootstrap/pull/1234
|
||||||
|
- https://github.com/kiegroup/drools/pull/3000
|
||||||
|
- https://github.com/kiegroup/optaplanner/pull/899
|
||||||
|
- etc.
|
||||||
|
-->
|
||||||
|
|
||||||
|
### Checklist
|
||||||
|
- [ ] Documentation updated if applicable.
|
||||||
|
- [ ] Changelog updated if applicable.
|
||||||
|
|
||||||
|
> **Note:** `dist/cli/index.js` and `dist/gha/index.js` are automatically generated by git hooks and gh workflows.
|
28
.github/workflows/publish-gha.yml
vendored
Normal file
28
.github/workflows/publish-gha.yml
vendored
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
##
|
||||||
|
# Publish new action tag(s) for downstream consumption
|
||||||
|
##
|
||||||
|
name: Publish
|
||||||
|
|
||||||
|
# Manual or automatic release
|
||||||
|
on:
|
||||||
|
release:
|
||||||
|
types: [published, edited]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
publish:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
ref: ${{ github.event.release.tag_name }}
|
||||||
|
|
||||||
|
- name: Setup Node
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
|
||||||
|
# Compile dist/index.js and bundle with action.yml
|
||||||
|
# Force push major and minor tags, e.g. v1, v1.0
|
||||||
|
# See documentation: https://github.com/JasonEtco/build-and-tag-action
|
||||||
|
- uses: JasonEtco/build-and-tag-action@v2
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ github.token }}
|
24
.github/workflows/publish.yml
vendored
Normal file
24
.github/workflows/publish.yml
vendored
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
name: Publish
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
tag:
|
||||||
|
description: 'publish the package with the specified tag, default is "latest"'
|
||||||
|
required: false
|
||||||
|
default: 'latest'
|
||||||
|
type: string
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 16
|
||||||
|
registry-url: https://registry.npmjs.org/
|
||||||
|
- run: npm install
|
||||||
|
- run: npm publish --access public --tag ${{ inputs.tag }}
|
||||||
|
env:
|
||||||
|
NODE_AUTH_TOKEN: ${{secrets.NPM_TOKEN}}
|
23
.github/workflows/pull-request.yml
vendored
Normal file
23
.github/workflows/pull-request.yml
vendored
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
# This workflow will do a clean install of node dependencies, build the source code and run tests across different versions of node
|
||||||
|
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-nodejs-with-github-actions
|
||||||
|
|
||||||
|
name: Pull Request Checks
|
||||||
|
|
||||||
|
on: pull_request
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
strategy:
|
||||||
|
matrix:
|
||||||
|
node-version: [16]
|
||||||
|
os: [ubuntu-latest]
|
||||||
|
fail-fast: false
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- name: Setup Node ${{ matrix.node-version }}
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: ${{ matrix.node-version }}
|
||||||
|
- run: npm ci
|
27
.github/workflows/version.yml
vendored
Normal file
27
.github/workflows/version.yml
vendored
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
# This manual workflow will bump the project to a new version and tag it, see https://docs.npmjs.com/cli/v8/commands/npm-version#description for more details
|
||||||
|
|
||||||
|
name: Version Tag
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
inputs:
|
||||||
|
version:
|
||||||
|
description: 'version to bump [<newversion> | major | minor | patch | premajor | preminor | prepatch | prerelease | from-git]'
|
||||||
|
required: false
|
||||||
|
default: 'minor'
|
||||||
|
type: string
|
||||||
|
message:
|
||||||
|
description: 'version commit message to be used'
|
||||||
|
required: false
|
||||||
|
default: 'Bumping to version %s'
|
||||||
|
type: string
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
- uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 16
|
||||||
|
- run: npm version ${{ inputs.version }} -m "${{ inputs.message }}"
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -8,4 +8,5 @@ coverage/
|
||||||
test-report.xml
|
test-report.xml
|
||||||
.idea/
|
.idea/
|
||||||
.vscode/
|
.vscode/
|
||||||
dist/
|
build/
|
||||||
|
# dist/
|
|
@ -1,4 +1,4 @@
|
||||||
#!/usr/bin/env sh
|
#!/usr/bin/env sh
|
||||||
. "$(dirname -- "$0")/_/husky.sh"
|
. "$(dirname -- "$0")/_/husky.sh"
|
||||||
|
|
||||||
npm run lint && npm run build && git add build
|
npm run lint && npm run build && git add dist
|
||||||
|
|
25
action.yml
Normal file
25
action.yml
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
name: "Backporting GitHub Action"
|
||||||
|
description: "GitHub action providing an automated way to backport pull requests from one branch to another"
|
||||||
|
inputs:
|
||||||
|
dry-run:
|
||||||
|
description: "If enabled the tool does not create any pull request nor push anything remotely."
|
||||||
|
required: false
|
||||||
|
default: "false"
|
||||||
|
auth:
|
||||||
|
description: "GITHUB_TOKEN or a `repo` scoped Personal Access Token (PAT)."
|
||||||
|
default: ${{ github.token }}
|
||||||
|
required: false
|
||||||
|
pull-request:
|
||||||
|
description: "URL of the pull request to backport, e.g., https://github.com/lampajr/backporting/pull/1."
|
||||||
|
required: true
|
||||||
|
target-branch:
|
||||||
|
description: "Branch where the pull request must be backported to."
|
||||||
|
required: true
|
||||||
|
|
||||||
|
runs:
|
||||||
|
using: node16
|
||||||
|
main: dist/gha/index.js
|
||||||
|
|
||||||
|
branding:
|
||||||
|
icon: 'git-merge'
|
||||||
|
color: 'blue'
|
|
@ -1,102 +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() {
|
|
||||||
this.logger = logger_service_factory_1.default.getLogger();
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* 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", "Github").addConfig("user.email", "noreply@github.com");
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Return the git version
|
|
||||||
* @returns {Promise<string | undefined>}
|
|
||||||
*/
|
|
||||||
async version() {
|
|
||||||
const rawOutput = await this.git().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}..`);
|
|
||||||
if (!fs_1.default.existsSync(to)) {
|
|
||||||
await this.git().clone(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, 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", "--strategy=recursive", "-X", "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;
|
|
|
@ -1,36 +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"));
|
|
||||||
/**
|
|
||||||
* 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) {
|
|
||||||
throw new Error("Git service already initialized!");
|
|
||||||
}
|
|
||||||
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;
|
|
|
@ -1,2 +0,0 @@
|
||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
@ -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 = {}));
|
|
|
@ -1,18 +0,0 @@
|
||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
class GitHubMapper {
|
|
||||||
mapPullRequest(pr) {
|
|
||||||
return {
|
|
||||||
url: pr.url,
|
|
||||||
title: pr.title,
|
|
||||||
body: pr.body,
|
|
||||||
patchUrl: pr.patch_url,
|
|
||||||
state: pr.state,
|
|
||||||
reviewers: pr.requested_reviewers.filter(r => "login" in r).map((r => r?.login)),
|
|
||||||
sourceRepo: pr.head.repo.full_name,
|
|
||||||
targetRepo: pr.base.repo.full_name,
|
|
||||||
commits: [pr.merge_commit_sha]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.default = GitHubMapper;
|
|
|
@ -1,30 +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"));
|
|
||||||
class GitHubService {
|
|
||||||
constructor(token) {
|
|
||||||
this.octokit = octokit_factory_1.default.getOctokit(token);
|
|
||||||
this.mapper = new github_mapper_1.default();
|
|
||||||
}
|
|
||||||
// READ
|
|
||||||
async getPullRequest(owner, repo, prNumber) {
|
|
||||||
const { data } = await this.octokit.rest.pulls.get({
|
|
||||||
owner: owner,
|
|
||||||
repo: repo,
|
|
||||||
pull_number: prNumber
|
|
||||||
});
|
|
||||||
return this.mapper.mapPullRequest(data);
|
|
||||||
}
|
|
||||||
// WRITE
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
||||||
createPullRequest(owner, repo, head, base, title, body, reviewers) {
|
|
||||||
// throw new Error("Method not implemented.");
|
|
||||||
// TODO implement
|
|
||||||
return Promise.resolve();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
exports.default = GitHubService;
|
|
|
@ -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();
|
|
|
@ -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;
|
|
|
@ -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;
|
|
|
@ -1,2 +0,0 @@
|
||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
@ -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;
|
|
|
@ -1,29 +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.pullRequestNumber);
|
|
||||||
expect(res.sourceRepo).toBe("fork/reponame");
|
|
||||||
expect(res.targetRepo).toBe("owner/reponame");
|
|
||||||
expect(res.title).toBe("PR Title");
|
|
||||||
expect(res.commits.length).toBe(1);
|
|
||||||
expect(res.commits).toEqual(["28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"]);
|
|
||||||
});
|
|
||||||
});
|
|
|
@ -1,445 +0,0 @@
|
||||||
"use strict";
|
|
||||||
Object.defineProperty(exports, "__esModule", { value: true });
|
|
||||||
exports.validPR = exports.commitRef = exports.invalidPullRequestNumber = exports.pullRequestNumber = exports.repo = exports.sourceOwner = exports.targetOwner = void 0;
|
|
||||||
exports.targetOwner = "owner";
|
|
||||||
exports.sourceOwner = "fork";
|
|
||||||
exports.repo = "reponame";
|
|
||||||
exports.pullRequestNumber = 2368;
|
|
||||||
exports.invalidPullRequestNumber = 1;
|
|
||||||
exports.commitRef = "91748965051fae1330ad58d15cf694e103267c87";
|
|
||||||
exports.validPR = {
|
|
||||||
"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": "kie-ci",
|
|
||||||
"id": 11995863,
|
|
||||||
"node_id": "MDQ6VXNlcjExOTk1ODYz",
|
|
||||||
"avatar_url": "https://avatars.githubusercontent.com/u/11995863?v=4",
|
|
||||||
"gravatar_id": "",
|
|
||||||
"url": "https://api.github.com/users/kie-ci",
|
|
||||||
"html_url": "https://github.com/kie-ci",
|
|
||||||
"followers_url": "https://api.github.com/users/kie-ci/followers",
|
|
||||||
"following_url": "https://api.github.com/users/kie-ci/following{/other_user}",
|
|
||||||
"gists_url": "https://api.github.com/users/kie-ci/gists{/gist_id}",
|
|
||||||
"starred_url": "https://api.github.com/users/kie-ci/starred{/owner}{/repo}",
|
|
||||||
"subscriptions_url": "https://api.github.com/users/kie-ci/subscriptions",
|
|
||||||
"organizations_url": "https://api.github.com/users/kie-ci/orgs",
|
|
||||||
"repos_url": "https://api.github.com/users/kie-ci/repos",
|
|
||||||
"events_url": "https://api.github.com/users/kie-ci/events{/privacy}",
|
|
||||||
"received_events_url": "https://api.github.com/users/kie-ci/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": "ghuser",
|
|
||||||
"id": 1422582,
|
|
||||||
"node_id": "MDQ6VXNlcjE0MjI1ODI=",
|
|
||||||
"avatar_url": "https://avatars.githubusercontent.com/u/1422582?v=4",
|
|
||||||
"gravatar_id": "",
|
|
||||||
"url": "https://api.github.com/users/ghuser",
|
|
||||||
"html_url": "https://github.com/ghuser",
|
|
||||||
"followers_url": "https://api.github.com/users/ghuser/followers",
|
|
||||||
"following_url": "https://api.github.com/users/ghuser/following{/other_user}",
|
|
||||||
"gists_url": "https://api.github.com/users/ghuser/gists{/gist_id}",
|
|
||||||
"starred_url": "https://api.github.com/users/ghuser/starred{/owner}{/repo}",
|
|
||||||
"subscriptions_url": "https://api.github.com/users/ghuser/subscriptions",
|
|
||||||
"organizations_url": "https://api.github.com/users/ghuser/orgs",
|
|
||||||
"repos_url": "https://api.github.com/users/ghuser/repos",
|
|
||||||
"events_url": "https://api.github.com/users/ghuser/events{/privacy}",
|
|
||||||
"received_events_url": "https://api.github.com/users/ghuser/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": "optaplanner",
|
|
||||||
"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.optaplanner.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": "optaplanner",
|
|
||||||
"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.optaplanner.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": "radtriste",
|
|
||||||
"id": 17157711,
|
|
||||||
"node_id": "MDQ6VXNlcjE3MTU3NzEx",
|
|
||||||
"avatar_url": "https://avatars.githubusercontent.com/u/17157711?v=4",
|
|
||||||
"gravatar_id": "",
|
|
||||||
"url": "https://api.github.com/users/radtriste",
|
|
||||||
"html_url": "https://github.com/radtriste",
|
|
||||||
"followers_url": "https://api.github.com/users/radtriste/followers",
|
|
||||||
"following_url": "https://api.github.com/users/radtriste/following{/other_user}",
|
|
||||||
"gists_url": "https://api.github.com/users/radtriste/gists{/gist_id}",
|
|
||||||
"starred_url": "https://api.github.com/users/radtriste/starred{/owner}{/repo}",
|
|
||||||
"subscriptions_url": "https://api.github.com/users/radtriste/subscriptions",
|
|
||||||
"organizations_url": "https://api.github.com/users/radtriste/orgs",
|
|
||||||
"repos_url": "https://api.github.com/users/radtriste/repos",
|
|
||||||
"events_url": "https://api.github.com/users/radtriste/events{/privacy}",
|
|
||||||
"received_events_url": "https://api.github.com/users/radtriste/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
|
|
||||||
};
|
|
|
@ -1,47 +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.pullRequestNumber
|
|
||||||
})
|
|
||||||
.reply({
|
|
||||||
status: 200,
|
|
||||||
data: moctokit_data_1.validPR
|
|
||||||
});
|
|
||||||
mock.rest.pulls
|
|
||||||
.create()
|
|
||||||
.reply({
|
|
||||||
status: 201,
|
|
||||||
data: moctokit_data_1.validPR
|
|
||||||
});
|
|
||||||
// invalid requests
|
|
||||||
mock.rest.pulls
|
|
||||||
.get({
|
|
||||||
owner: moctokit_data_1.targetOwner,
|
|
||||||
repo: moctokit_data_1.repo,
|
|
||||||
pull_number: moctokit_data_1.invalidPullRequestNumber
|
|
||||||
})
|
|
||||||
.reply({
|
|
||||||
status: 404,
|
|
||||||
data: {
|
|
||||||
message: "Not found"
|
|
||||||
}
|
|
||||||
});
|
|
||||||
return mock;
|
|
||||||
};
|
|
||||||
exports.setupMoctokit = setupMoctokit;
|
|
16112
dist/cli/index.js
vendored
Executable file
16112
dist/cli/index.js
vendored
Executable file
File diff suppressed because one or more lines are too long
15542
dist/gha/index.js
vendored
Executable file
15542
dist/gha/index.js
vendored
Executable file
File diff suppressed because one or more lines are too long
|
@ -6,11 +6,11 @@ const jestConfig: Config.InitialOptions = {
|
||||||
"^.+\\.tsx?$": "ts-jest",
|
"^.+\\.tsx?$": "ts-jest",
|
||||||
},
|
},
|
||||||
moduleNameMapper: {
|
moduleNameMapper: {
|
||||||
"^@gb/(.*)$": "<rootDir>/src/$1",
|
"^@bp/(.*)$": "<rootDir>/src/$1",
|
||||||
},
|
},
|
||||||
clearMocks: true,
|
clearMocks: true,
|
||||||
resetMocks: true,
|
resetMocks: true,
|
||||||
modulePathIgnorePatterns: ["<rootDir>/dist/"],
|
modulePathIgnorePatterns: ["<rootDir>/build/", "<rootDir>/dist/"],
|
||||||
coveragePathIgnorePatterns: ["<rootDir>/node_modules/", "<rootDir>/test/", "<rootDir>/build/", "<rootDir>/dist/"]
|
coveragePathIgnorePatterns: ["<rootDir>/node_modules/", "<rootDir>/test/", "<rootDir>/build/", "<rootDir>/dist/"]
|
||||||
};
|
};
|
||||||
export default jestConfig;
|
export default jestConfig;
|
||||||
|
|
166
package-lock.json
generated
166
package-lock.json
generated
|
@ -1,18 +1,15 @@
|
||||||
{
|
{
|
||||||
"name": "@lampajr/backporting",
|
"name": "@lampajr/bper",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "@lampajr/backporting",
|
"name": "@lampajr/bper",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/artifact": "^1.1.0",
|
"@actions/core": "^1.10.0",
|
||||||
"@actions/core": "^1.8.2",
|
|
||||||
"@actions/exec": "^1.1.1",
|
|
||||||
"@actions/glob": "^0.3.0",
|
|
||||||
"@octokit/rest": "^19.0.5",
|
"@octokit/rest": "^19.0.5",
|
||||||
"@octokit/types": "^8.0.0",
|
"@octokit/types": "^8.0.0",
|
||||||
"@octokit/webhooks-types": "^6.7.0",
|
"@octokit/webhooks-types": "^6.7.0",
|
||||||
|
@ -21,7 +18,7 @@
|
||||||
"simple-git": "^3.15.1"
|
"simple-git": "^3.15.1"
|
||||||
},
|
},
|
||||||
"bin": {
|
"bin": {
|
||||||
"backporting": "build/src/bin/main.js"
|
"bper": "build/src/bin/cli.js"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@kie/mock-github": "^0.1.1",
|
"@kie/mock-github": "^0.1.1",
|
||||||
|
@ -30,6 +27,7 @@
|
||||||
"@types/node": "^17.0.41",
|
"@types/node": "^17.0.41",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.45.1",
|
"@typescript-eslint/eslint-plugin": "^5.45.1",
|
||||||
"@typescript-eslint/parser": "^5.45.1",
|
"@typescript-eslint/parser": "^5.45.1",
|
||||||
|
"@vercel/ncc": "^0.34.0",
|
||||||
"eslint": "^8.29.0",
|
"eslint": "^8.29.0",
|
||||||
"husky": "^8.0.2",
|
"husky": "^8.0.2",
|
||||||
"jest": "^29.3.1",
|
"jest": "^29.3.1",
|
||||||
|
@ -41,17 +39,6 @@
|
||||||
"typescript": "^4.9.3"
|
"typescript": "^4.9.3"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@actions/artifact": {
|
|
||||||
"version": "1.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@actions/artifact/-/artifact-1.1.0.tgz",
|
|
||||||
"integrity": "sha512-shO+w/BAnzRnFhfsgUao8sxjByAMqDdfvek2LLKeCueBKXoTrAcp7U/hs9Fdx+z9g7Q0mbIrmHAzAAww4HK1bQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"@actions/core": "^1.2.6",
|
|
||||||
"@actions/http-client": "^2.0.1",
|
|
||||||
"tmp": "^0.2.1",
|
|
||||||
"tmp-promise": "^3.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@actions/core": {
|
"node_modules/@actions/core": {
|
||||||
"version": "1.10.0",
|
"version": "1.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.0.tgz",
|
||||||
|
@ -61,23 +48,6 @@
|
||||||
"uuid": "^8.3.2"
|
"uuid": "^8.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@actions/exec": {
|
|
||||||
"version": "1.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.1.1.tgz",
|
|
||||||
"integrity": "sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==",
|
|
||||||
"dependencies": {
|
|
||||||
"@actions/io": "^1.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@actions/glob": {
|
|
||||||
"version": "0.3.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@actions/glob/-/glob-0.3.0.tgz",
|
|
||||||
"integrity": "sha512-tJP1ZhF87fd6LBnaXWlahkyvdgvsLl7WnreW1EZaC8JWjpMXmzqWzQVe/IEYslrkT9ymibVrKyJN4UMD7uQM2w==",
|
|
||||||
"dependencies": {
|
|
||||||
"@actions/core": "^1.2.6",
|
|
||||||
"minimatch": "^3.0.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@actions/http-client": {
|
"node_modules/@actions/http-client": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
|
||||||
|
@ -86,11 +56,6 @@
|
||||||
"tunnel": "^0.0.6"
|
"tunnel": "^0.0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@actions/io": {
|
|
||||||
"version": "1.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.2.tgz",
|
|
||||||
"integrity": "sha512-d+RwPlMp+2qmBfeLYPLXuSRykDIFEwdTA0MMxzS9kh4kvP1ftrc/9fzy6pX6qAjthdXruHQ6/6kjT/DNo5ALuw=="
|
|
||||||
},
|
|
||||||
"node_modules/@ampproject/remapping": {
|
"node_modules/@ampproject/remapping": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
|
||||||
|
@ -2238,6 +2203,15 @@
|
||||||
"url": "https://opencollective.com/typescript-eslint"
|
"url": "https://opencollective.com/typescript-eslint"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@vercel/ncc": {
|
||||||
|
"version": "0.34.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.34.0.tgz",
|
||||||
|
"integrity": "sha512-G9h5ZLBJ/V57Ou9vz5hI8pda/YQX5HQszCs3AmIus3XzsmRn/0Ptic5otD3xVST8QLKk7AMk7AqpsyQGN7MZ9A==",
|
||||||
|
"dev": true,
|
||||||
|
"bin": {
|
||||||
|
"ncc": "dist/ncc/cli.js"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/accepts": {
|
"node_modules/accepts": {
|
||||||
"version": "1.3.8",
|
"version": "1.3.8",
|
||||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
|
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
|
||||||
|
@ -2482,7 +2456,8 @@
|
||||||
"node_modules/balanced-match": {
|
"node_modules/balanced-match": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/before-after-hook": {
|
"node_modules/before-after-hook": {
|
||||||
"version": "2.2.3",
|
"version": "2.2.3",
|
||||||
|
@ -2541,6 +2516,7 @@
|
||||||
"version": "1.1.11",
|
"version": "1.1.11",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||||
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"balanced-match": "^1.0.0",
|
"balanced-match": "^1.0.0",
|
||||||
"concat-map": "0.0.1"
|
"concat-map": "0.0.1"
|
||||||
|
@ -2807,7 +2783,8 @@
|
||||||
"node_modules/concat-map": {
|
"node_modules/concat-map": {
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
|
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/content-disposition": {
|
"node_modules/content-disposition": {
|
||||||
"version": "0.5.4",
|
"version": "0.5.4",
|
||||||
|
@ -3601,7 +3578,8 @@
|
||||||
"node_modules/fs.realpath": {
|
"node_modules/fs.realpath": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
|
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/function-bind": {
|
"node_modules/function-bind": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
|
@ -3666,6 +3644,7 @@
|
||||||
"version": "7.2.3",
|
"version": "7.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
|
||||||
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
|
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
|
||||||
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"fs.realpath": "^1.0.0",
|
"fs.realpath": "^1.0.0",
|
||||||
"inflight": "^1.0.4",
|
"inflight": "^1.0.4",
|
||||||
|
@ -3887,6 +3866,7 @@
|
||||||
"version": "1.0.6",
|
"version": "1.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||||
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
|
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
|
||||||
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"once": "^1.3.0",
|
"once": "^1.3.0",
|
||||||
"wrappy": "1"
|
"wrappy": "1"
|
||||||
|
@ -3895,7 +3875,8 @@
|
||||||
"node_modules/inherits": {
|
"node_modules/inherits": {
|
||||||
"version": "2.0.4",
|
"version": "2.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/ipaddr.js": {
|
"node_modules/ipaddr.js": {
|
||||||
"version": "1.9.1",
|
"version": "1.9.1",
|
||||||
|
@ -5697,6 +5678,7 @@
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||||
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"brace-expansion": "^1.1.7"
|
"brace-expansion": "^1.1.7"
|
||||||
},
|
},
|
||||||
|
@ -5971,6 +5953,7 @@
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||||
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
|
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
|
||||||
|
"dev": true,
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
|
@ -6380,6 +6363,7 @@
|
||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
||||||
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
|
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
|
||||||
|
"dev": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"glob": "^7.1.3"
|
"glob": "^7.1.3"
|
||||||
},
|
},
|
||||||
|
@ -6758,25 +6742,6 @@
|
||||||
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
|
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/tmp": {
|
|
||||||
"version": "0.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
|
|
||||||
"integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"rimraf": "^3.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=8.17.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/tmp-promise": {
|
|
||||||
"version": "3.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz",
|
|
||||||
"integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==",
|
|
||||||
"dependencies": {
|
|
||||||
"tmp": "^0.2.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/tmpl": {
|
"node_modules/tmpl": {
|
||||||
"version": "1.0.5",
|
"version": "1.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
|
||||||
|
@ -7320,17 +7285,6 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/artifact": {
|
|
||||||
"version": "1.1.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@actions/artifact/-/artifact-1.1.0.tgz",
|
|
||||||
"integrity": "sha512-shO+w/BAnzRnFhfsgUao8sxjByAMqDdfvek2LLKeCueBKXoTrAcp7U/hs9Fdx+z9g7Q0mbIrmHAzAAww4HK1bQ==",
|
|
||||||
"requires": {
|
|
||||||
"@actions/core": "^1.2.6",
|
|
||||||
"@actions/http-client": "^2.0.1",
|
|
||||||
"tmp": "^0.2.1",
|
|
||||||
"tmp-promise": "^3.0.2"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@actions/core": {
|
"@actions/core": {
|
||||||
"version": "1.10.0",
|
"version": "1.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/@actions/core/-/core-1.10.0.tgz",
|
||||||
|
@ -7340,23 +7294,6 @@
|
||||||
"uuid": "^8.3.2"
|
"uuid": "^8.3.2"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@actions/exec": {
|
|
||||||
"version": "1.1.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/@actions/exec/-/exec-1.1.1.tgz",
|
|
||||||
"integrity": "sha512-+sCcHHbVdk93a0XT19ECtO/gIXoxvdsgQLzb2fE2/5sIZmWQuluYyjPQtrtTHdU1YzTZ7bAPN4sITq2xi1679w==",
|
|
||||||
"requires": {
|
|
||||||
"@actions/io": "^1.0.1"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@actions/glob": {
|
|
||||||
"version": "0.3.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@actions/glob/-/glob-0.3.0.tgz",
|
|
||||||
"integrity": "sha512-tJP1ZhF87fd6LBnaXWlahkyvdgvsLl7WnreW1EZaC8JWjpMXmzqWzQVe/IEYslrkT9ymibVrKyJN4UMD7uQM2w==",
|
|
||||||
"requires": {
|
|
||||||
"@actions/core": "^1.2.6",
|
|
||||||
"minimatch": "^3.0.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"@actions/http-client": {
|
"@actions/http-client": {
|
||||||
"version": "2.0.1",
|
"version": "2.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/@actions/http-client/-/http-client-2.0.1.tgz",
|
||||||
|
@ -7365,11 +7302,6 @@
|
||||||
"tunnel": "^0.0.6"
|
"tunnel": "^0.0.6"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"@actions/io": {
|
|
||||||
"version": "1.1.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/@actions/io/-/io-1.1.2.tgz",
|
|
||||||
"integrity": "sha512-d+RwPlMp+2qmBfeLYPLXuSRykDIFEwdTA0MMxzS9kh4kvP1ftrc/9fzy6pX6qAjthdXruHQ6/6kjT/DNo5ALuw=="
|
|
||||||
},
|
|
||||||
"@ampproject/remapping": {
|
"@ampproject/remapping": {
|
||||||
"version": "2.2.0",
|
"version": "2.2.0",
|
||||||
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
|
"resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.2.0.tgz",
|
||||||
|
@ -9042,6 +8974,12 @@
|
||||||
"eslint-visitor-keys": "^3.3.0"
|
"eslint-visitor-keys": "^3.3.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"@vercel/ncc": {
|
||||||
|
"version": "0.34.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vercel/ncc/-/ncc-0.34.0.tgz",
|
||||||
|
"integrity": "sha512-G9h5ZLBJ/V57Ou9vz5hI8pda/YQX5HQszCs3AmIus3XzsmRn/0Ptic5otD3xVST8QLKk7AMk7AqpsyQGN7MZ9A==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
"accepts": {
|
"accepts": {
|
||||||
"version": "1.3.8",
|
"version": "1.3.8",
|
||||||
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
|
"resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz",
|
||||||
|
@ -9222,7 +9160,8 @@
|
||||||
"balanced-match": {
|
"balanced-match": {
|
||||||
"version": "1.0.2",
|
"version": "1.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"before-after-hook": {
|
"before-after-hook": {
|
||||||
"version": "2.2.3",
|
"version": "2.2.3",
|
||||||
|
@ -9276,6 +9215,7 @@
|
||||||
"version": "1.1.11",
|
"version": "1.1.11",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||||
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"balanced-match": "^1.0.0",
|
"balanced-match": "^1.0.0",
|
||||||
"concat-map": "0.0.1"
|
"concat-map": "0.0.1"
|
||||||
|
@ -9461,7 +9401,8 @@
|
||||||
"concat-map": {
|
"concat-map": {
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
|
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"content-disposition": {
|
"content-disposition": {
|
||||||
"version": "0.5.4",
|
"version": "0.5.4",
|
||||||
|
@ -10087,7 +10028,8 @@
|
||||||
"fs.realpath": {
|
"fs.realpath": {
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
|
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"function-bind": {
|
"function-bind": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
|
@ -10134,6 +10076,7 @@
|
||||||
"version": "7.2.3",
|
"version": "7.2.3",
|
||||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
|
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
|
||||||
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
|
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
|
||||||
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"fs.realpath": "^1.0.0",
|
"fs.realpath": "^1.0.0",
|
||||||
"inflight": "^1.0.4",
|
"inflight": "^1.0.4",
|
||||||
|
@ -10283,6 +10226,7 @@
|
||||||
"version": "1.0.6",
|
"version": "1.0.6",
|
||||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||||
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
|
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
|
||||||
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"once": "^1.3.0",
|
"once": "^1.3.0",
|
||||||
"wrappy": "1"
|
"wrappy": "1"
|
||||||
|
@ -10291,7 +10235,8 @@
|
||||||
"inherits": {
|
"inherits": {
|
||||||
"version": "2.0.4",
|
"version": "2.0.4",
|
||||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
|
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"ipaddr.js": {
|
"ipaddr.js": {
|
||||||
"version": "1.9.1",
|
"version": "1.9.1",
|
||||||
|
@ -11689,6 +11634,7 @@
|
||||||
"version": "3.1.2",
|
"version": "3.1.2",
|
||||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||||
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"brace-expansion": "^1.1.7"
|
"brace-expansion": "^1.1.7"
|
||||||
}
|
}
|
||||||
|
@ -11881,7 +11827,8 @@
|
||||||
"path-is-absolute": {
|
"path-is-absolute": {
|
||||||
"version": "1.0.1",
|
"version": "1.0.1",
|
||||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||||
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="
|
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
|
||||||
|
"dev": true
|
||||||
},
|
},
|
||||||
"path-key": {
|
"path-key": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
|
@ -12171,6 +12118,7 @@
|
||||||
"version": "3.0.2",
|
"version": "3.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
||||||
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
|
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
|
||||||
|
"dev": true,
|
||||||
"requires": {
|
"requires": {
|
||||||
"glob": "^7.1.3"
|
"glob": "^7.1.3"
|
||||||
}
|
}
|
||||||
|
@ -12448,22 +12396,6 @@
|
||||||
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
|
"integrity": "sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==",
|
||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"tmp": {
|
|
||||||
"version": "0.2.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/tmp/-/tmp-0.2.1.tgz",
|
|
||||||
"integrity": "sha512-76SUhtfqR2Ijn+xllcI5P1oyannHNHByD80W1q447gU3mp9G9PSpGdWmjUOHRDPiHYacIk66W7ubDTuPF3BEtQ==",
|
|
||||||
"requires": {
|
|
||||||
"rimraf": "^3.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"tmp-promise": {
|
|
||||||
"version": "3.0.3",
|
|
||||||
"resolved": "https://registry.npmjs.org/tmp-promise/-/tmp-promise-3.0.3.tgz",
|
|
||||||
"integrity": "sha512-RwM7MoPojPxsOBYnyd2hy0bxtIlVrihNs9pj5SUvY8Zz1sQcQG2tG1hSr8PDxfgEB8RNKDhqbIlroIarSNDNsQ==",
|
|
||||||
"requires": {
|
|
||||||
"tmp": "^0.2.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"tmpl": {
|
"tmpl": {
|
||||||
"version": "1.0.5",
|
"version": "1.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz",
|
||||||
|
|
29
package.json
29
package.json
|
@ -1,28 +1,33 @@
|
||||||
{
|
{
|
||||||
"name": "@lampajr/backporting",
|
"name": "@lampajr/bper",
|
||||||
"version": "0.0.1",
|
"version": "0.0.1",
|
||||||
"description": "Tool to execute automatic git backporting.",
|
"description": "BPer is a tool to execute automatic git backporting.",
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"private": false,
|
"private": false,
|
||||||
"main": "./build/src/bin/main.js",
|
"main": "./dist/gha/index.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
"backporting": "./build/src/bin/main.js"
|
"bper": "./dist/cli/index.js"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"build/"
|
"dist/cli/index.js"
|
||||||
],
|
],
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"prepare": "husky install",
|
"prepare": "husky install",
|
||||||
"clean": "rm -rf ./build",
|
"clean": "rm -rf ./build ./dist",
|
||||||
"compile": "tsc -p tsconfig.json && tsc-alias -p tsconfig.json",
|
"compile": "tsc -p tsconfig.json && tsc-alias -p tsconfig.json",
|
||||||
"build": "npm run clean && npm run compile",
|
"package": "npm run package:cli && npm run package:gha",
|
||||||
"package": "ncc build --source-map --license licenses.txt",
|
"package:cli": "ncc build ./build/src/bin/cli.js -o dist/cli",
|
||||||
|
"package:gha": "ncc build ./build/src/bin/gha.js -o dist/gha",
|
||||||
|
"build": "npm run clean && npm run compile && npm run package",
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
"test:report": "npm test -- --coverage --testResultsProcessor=jest-sonar-reporter",
|
"test:report": "npm test -- --coverage --testResultsProcessor=jest-sonar-reporter",
|
||||||
"lint": "eslint . --ext .ts",
|
"lint": "eslint . --ext .ts",
|
||||||
"lint:fix": "npm run lint -- --fix",
|
"lint:fix": "npm run lint -- --fix",
|
||||||
"ts-node": "ts-node"
|
"ts-node": "ts-node",
|
||||||
|
"preversion": "npm test",
|
||||||
|
"version": "npm run build && git add -A dist",
|
||||||
|
"postversion": "git push && git push --tags"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -45,6 +50,7 @@
|
||||||
"@types/node": "^17.0.41",
|
"@types/node": "^17.0.41",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.45.1",
|
"@typescript-eslint/eslint-plugin": "^5.45.1",
|
||||||
"@typescript-eslint/parser": "^5.45.1",
|
"@typescript-eslint/parser": "^5.45.1",
|
||||||
|
"@vercel/ncc": "^0.34.0",
|
||||||
"eslint": "^8.29.0",
|
"eslint": "^8.29.0",
|
||||||
"husky": "^8.0.2",
|
"husky": "^8.0.2",
|
||||||
"jest": "^29.3.1",
|
"jest": "^29.3.1",
|
||||||
|
@ -56,10 +62,7 @@
|
||||||
"typescript": "^4.9.3"
|
"typescript": "^4.9.3"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@actions/artifact": "^1.1.0",
|
"@actions/core": "^1.10.0",
|
||||||
"@actions/core": "^1.8.2",
|
|
||||||
"@actions/exec": "^1.1.1",
|
|
||||||
"@actions/glob": "^0.3.0",
|
|
||||||
"@octokit/rest": "^19.0.5",
|
"@octokit/rest": "^19.0.5",
|
||||||
"@octokit/types": "^8.0.0",
|
"@octokit/types": "^8.0.0",
|
||||||
"@octokit/webhooks-types": "^6.7.0",
|
"@octokit/webhooks-types": "^6.7.0",
|
||||||
|
|
12
src/bin/cli.ts
Normal file
12
src/bin/cli.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
import CLIArgsParser from "@bp/service/args/cli/cli-args-parser";
|
||||||
|
import Runner from "@bp/service/runner/runner";
|
||||||
|
|
||||||
|
// create CLI arguments parser
|
||||||
|
const parser = new CLIArgsParser();
|
||||||
|
|
||||||
|
// create runner
|
||||||
|
const runner = new Runner(parser);
|
||||||
|
|
||||||
|
runner.run();
|
12
src/bin/gha.ts
Normal file
12
src/bin/gha.ts
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
import GHAArgsParser from "@bp/service/args/gha/gha-args-parser";
|
||||||
|
import Runner from "@bp/service/runner/runner";
|
||||||
|
|
||||||
|
// create CLI arguments parser
|
||||||
|
const parser = new GHAArgsParser();
|
||||||
|
|
||||||
|
// create runner
|
||||||
|
const runner = new Runner(parser);
|
||||||
|
|
||||||
|
runner.run();
|
10
src/service/args/args-parser.ts
Normal file
10
src/service/args/args-parser.ts
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
import { Args } from "@bp/service/args/args.types";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract arguments parser interface in charge to parse inputs and
|
||||||
|
* produce a common Args object
|
||||||
|
*/
|
||||||
|
export default interface ArgsParser {
|
||||||
|
|
||||||
|
parse(): Args;
|
||||||
|
}
|
11
src/service/args/args.types.ts
Normal file
11
src/service/args/args.types.ts
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
/**
|
||||||
|
* Input arguments
|
||||||
|
*/
|
||||||
|
export interface Args {
|
||||||
|
dryRun: boolean, // if enabled do not push anything remotely
|
||||||
|
auth: string, // git service auth, like github token
|
||||||
|
targetBranch: string, // branch on the target repo where the change should be backported to
|
||||||
|
pullRequest: string, // url of the pull request to backport
|
||||||
|
folder?: string, // local folder where the repositories should be cloned
|
||||||
|
author?: string, // backport pr author, default taken from pr
|
||||||
|
}
|
49
src/service/args/cli/cli-args-parser.ts
Normal file
49
src/service/args/cli/cli-args-parser.ts
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
import ArgsParser from "@bp/service/args/args-parser";
|
||||||
|
import { Args } from "@bp/service/args/args.types";
|
||||||
|
import { Command } from "commander";
|
||||||
|
import { env } from "process";
|
||||||
|
|
||||||
|
interface PkgInfo {
|
||||||
|
name: string;
|
||||||
|
version: string;
|
||||||
|
description: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default class CLIArgsParser implements ArgsParser {
|
||||||
|
|
||||||
|
private pkg: PkgInfo;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
this.pkg = {
|
||||||
|
name: env.npm_package_name ?? "backporting",
|
||||||
|
version: env.npm_package_version ?? "0.0.0",
|
||||||
|
description: env.npm_package_description ?? ""
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private getCommand(): Command {
|
||||||
|
return new Command(this.pkg.name)
|
||||||
|
.version(this.pkg.version)
|
||||||
|
.description(this.pkg.description)
|
||||||
|
.requiredOption("-tb, --target-branch <branch>", "branch where changes must be backported to.")
|
||||||
|
.requiredOption("-pr, --pull-request <pr url>", "pull request url, e.g., https://github.com/lampajr/backporting/pull/1.")
|
||||||
|
.option("-d, --dry-run", "if enabled the tool does not create any pull request nor push anything remotely", false)
|
||||||
|
.option("-a, --auth <auth>", "git service authentication string, e.g., github token.", "")
|
||||||
|
.option("-f, --folder <folder>", "local folder where the repo will be checked out, e.g., /tmp/folder.", undefined);
|
||||||
|
}
|
||||||
|
|
||||||
|
parse(): Args {
|
||||||
|
const opts = this.getCommand()
|
||||||
|
.parse()
|
||||||
|
.opts();
|
||||||
|
|
||||||
|
return {
|
||||||
|
dryRun: opts.dryRun,
|
||||||
|
auth: opts.auth,
|
||||||
|
pullRequest: opts.pullRequest,
|
||||||
|
targetBranch: opts.targetBranch,
|
||||||
|
folder: opts.folder
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
17
src/service/args/gha/gha-args-parser.ts
Normal file
17
src/service/args/gha/gha-args-parser.ts
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
import ArgsParser from "@bp/service/args/args-parser";
|
||||||
|
import { Args } from "@bp/service/args/args.types";
|
||||||
|
import { getInput } from "@actions/core";
|
||||||
|
|
||||||
|
export default class GHAArgsParser implements ArgsParser {
|
||||||
|
|
||||||
|
parse(): Args {
|
||||||
|
return {
|
||||||
|
dryRun: getInput("dry-run") === "true",
|
||||||
|
auth: getInput("auth") ? getInput("auth") : "",
|
||||||
|
pullRequest: getInput("pull-request"),
|
||||||
|
targetBranch: getInput("target-branch"),
|
||||||
|
folder: getInput("folder") !== "" ? getInput("folder") : undefined
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
22
src/service/configs/configs-parser.ts
Normal file
22
src/service/configs/configs-parser.ts
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
import { Args } from "@bp/service/args/args.types";
|
||||||
|
import { Configs } from "@bp/service/configs/configs.types";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abstract configuration parser class in charge to parse
|
||||||
|
* Args and produces a common Configs object
|
||||||
|
*/
|
||||||
|
export default abstract class ConfigsParser {
|
||||||
|
|
||||||
|
abstract parse(args: Args): Promise<Configs>;
|
||||||
|
|
||||||
|
async parseAndValidate(args: Args): Promise<Configs> {
|
||||||
|
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!");
|
||||||
|
}
|
||||||
|
|
||||||
|
return Promise.resolve(configs);
|
||||||
|
}
|
||||||
|
}
|
17
src/service/configs/configs.types.ts
Normal file
17
src/service/configs/configs.types.ts
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
|
||||||
|
|
||||||
|
import { GitPullRequest } from "@bp/service/git/git.types";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Internal configuration object
|
||||||
|
*/
|
||||||
|
export interface Configs {
|
||||||
|
dryRun: boolean,
|
||||||
|
auth: string,
|
||||||
|
author: string, // author of the backport pr
|
||||||
|
folder: string,
|
||||||
|
targetBranch: string,
|
||||||
|
originalPullRequest: GitPullRequest,
|
||||||
|
backportPullRequest: GitPullRequest
|
||||||
|
}
|
||||||
|
|
60
src/service/configs/pullrequest/pr-configs-parser.ts
Normal file
60
src/service/configs/pullrequest/pr-configs-parser.ts
Normal file
|
@ -0,0 +1,60 @@
|
||||||
|
import { Args } from "@bp/service/args/args.types";
|
||||||
|
import ConfigsParser from "@bp/service/configs/configs-parser";
|
||||||
|
import { Configs } from "@bp/service/configs/configs.types";
|
||||||
|
import GitService from "@bp/service/git/git-service";
|
||||||
|
import GitServiceFactory from "@bp/service/git/git-service-factory";
|
||||||
|
import { GitPullRequest } from "@bp/service/git/git.types";
|
||||||
|
|
||||||
|
export default class PullRequestConfigsParser extends ConfigsParser {
|
||||||
|
|
||||||
|
private gitService: GitService;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
this.gitService = GitServiceFactory.getService();
|
||||||
|
}
|
||||||
|
|
||||||
|
public async parse(args: Args): Promise<Configs> {
|
||||||
|
const pr: GitPullRequest = await this.gitService.getPullRequestFromUrl(args.pullRequest);
|
||||||
|
const folder: string = args.folder ?? this.getDefaultFolder();
|
||||||
|
|
||||||
|
return {
|
||||||
|
dryRun: args.dryRun,
|
||||||
|
auth: args.auth,
|
||||||
|
author: args.author ?? pr.author,
|
||||||
|
folder: `${folder.startsWith("/") ? "" : process.cwd() + "/"}${args.folder ?? this.getDefaultFolder()}`,
|
||||||
|
targetBranch: args.targetBranch,
|
||||||
|
originalPullRequest: pr,
|
||||||
|
backportPullRequest: this.getDefaultBackportPullRequest(pr, args.targetBranch)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private getDefaultFolder() {
|
||||||
|
return "bp";
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a default backport pull request starting from the target branch and
|
||||||
|
* the original pr to be backported
|
||||||
|
* @param originalPullRequest original pull request
|
||||||
|
* @param targetBranch target branch where the backport should be applied
|
||||||
|
* @returns {GitPullRequest}
|
||||||
|
*/
|
||||||
|
private getDefaultBackportPullRequest(originalPullRequest: GitPullRequest, targetBranch: string): GitPullRequest {
|
||||||
|
const reviewers = [];
|
||||||
|
reviewers.push(originalPullRequest.author);
|
||||||
|
if (originalPullRequest.mergedBy) {
|
||||||
|
reviewers.push(originalPullRequest.mergedBy);
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
author: originalPullRequest.author,
|
||||||
|
title: `[${targetBranch}] ${originalPullRequest.title}`,
|
||||||
|
body: `**Backport:** ${originalPullRequest.htmlUrl}\r\n\r\n${originalPullRequest.body}\r\n\r\nPowered by [BPer](https://github.com/lampajr/backporting).`,
|
||||||
|
reviewers: [...new Set(reviewers)],
|
||||||
|
targetRepo: originalPullRequest.targetRepo,
|
||||||
|
sourceRepo: originalPullRequest.targetRepo,
|
||||||
|
commits: [] // TODO needed?
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
import LoggerService from "@gb/service/logger/logger-service";
|
import LoggerService from "@bp/service/logger/logger-service";
|
||||||
import LoggerServiceFactory from "@gb/service/logger/logger-service-factory";
|
import LoggerServiceFactory from "@bp/service/logger/logger-service-factory";
|
||||||
import simpleGit, { SimpleGit } from "simple-git";
|
import simpleGit, { SimpleGit } from "simple-git";
|
||||||
import fs from "fs";
|
import fs from "fs";
|
||||||
|
|
||||||
|
@ -9,9 +9,13 @@ import fs from "fs";
|
||||||
export default class GitCLIService {
|
export default class GitCLIService {
|
||||||
|
|
||||||
private readonly logger: LoggerService;
|
private readonly logger: LoggerService;
|
||||||
|
private readonly auth: string;
|
||||||
|
private readonly author: string;
|
||||||
|
|
||||||
constructor() {
|
constructor(auth: string, author: string) {
|
||||||
this.logger = LoggerServiceFactory.getLogger();
|
this.logger = LoggerServiceFactory.getLogger();
|
||||||
|
this.auth = auth;
|
||||||
|
this.author = author;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -22,7 +26,20 @@ export default class GitCLIService {
|
||||||
*/
|
*/
|
||||||
private git(cwd?: string): SimpleGit {
|
private git(cwd?: string): SimpleGit {
|
||||||
const gitConfig = { ...(cwd ? { baseDir: cwd } : {})};
|
const gitConfig = { ...(cwd ? { baseDir: cwd } : {})};
|
||||||
return simpleGit(gitConfig).addConfig("user.name", "Github").addConfig("user.email", "noreply@github.com");
|
return simpleGit(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
|
||||||
|
*/
|
||||||
|
private remoteWithAuth(remoteURL: string): string {
|
||||||
|
if (this.auth && this.author) {
|
||||||
|
return remoteURL.replace("://", `://${this.author}:${this.auth}@`);
|
||||||
|
}
|
||||||
|
|
||||||
|
// return remote as it is
|
||||||
|
return remoteURL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -42,9 +59,9 @@ export default class GitCLIService {
|
||||||
* @param branch branch which should be cloned
|
* @param branch branch which should be cloned
|
||||||
*/
|
*/
|
||||||
async clone(from: string, to: string, branch: string): Promise<void> {
|
async clone(from: string, to: string, branch: string): Promise<void> {
|
||||||
this.logger.info(`Cloning repository ${from}..`);
|
this.logger.info(`Cloning repository ${from} to ${to}.`);
|
||||||
if (!fs.existsSync(to)) {
|
if (!fs.existsSync(to)) {
|
||||||
await this.git().clone(from, to, ["--quiet", "--shallow-submodules", "--no-tags", "--branch", branch]);
|
await simpleGit().clone(this.remoteWithAuth(from), to, ["--quiet", "--shallow-submodules", "--no-tags", "--branch", branch]);
|
||||||
} else {
|
} else {
|
||||||
this.logger.warn(`Folder ${to} already exist. Won't clone`);
|
this.logger.warn(`Folder ${to} already exist. Won't clone`);
|
||||||
}
|
}
|
||||||
|
@ -56,7 +73,7 @@ export default class GitCLIService {
|
||||||
* @param newBranch new branch name
|
* @param newBranch new branch name
|
||||||
*/
|
*/
|
||||||
async createLocalBranch(cwd: string, newBranch: string): Promise<void> {
|
async createLocalBranch(cwd: string, newBranch: string): Promise<void> {
|
||||||
this.logger.info(`Creating branch ${newBranch}..`);
|
this.logger.info(`Creating branch ${newBranch}.`);
|
||||||
await this.git(cwd).checkoutLocalBranch(newBranch);
|
await this.git(cwd).checkoutLocalBranch(newBranch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,8 +84,8 @@ export default class GitCLIService {
|
||||||
* @param remoteName [optional] name of the remote, by default 'fork' is used
|
* @param remoteName [optional] name of the remote, by default 'fork' is used
|
||||||
*/
|
*/
|
||||||
async addRemote(cwd: string, remote: string, remoteName = "fork"): Promise<void> {
|
async addRemote(cwd: string, remote: string, remoteName = "fork"): Promise<void> {
|
||||||
this.logger.info(`Adding new remote ${remote}..`);
|
this.logger.info(`Adding new remote ${remote}.`);
|
||||||
await this.git(cwd).addRemote(remoteName, remote);
|
await this.git(cwd).addRemote(remoteName, this.remoteWithAuth(remote));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -87,8 +104,8 @@ export default class GitCLIService {
|
||||||
* @param sha commit sha
|
* @param sha commit sha
|
||||||
*/
|
*/
|
||||||
async cherryPick(cwd: string, sha: string): Promise<void> {
|
async cherryPick(cwd: string, sha: string): Promise<void> {
|
||||||
this.logger.info(`Cherry picking ${sha}..`);
|
this.logger.info(`Cherry picking ${sha}.`);
|
||||||
await this.git(cwd).raw(["cherry-pick", "--strategy=recursive", "-X", "theirs", sha]);
|
await this.git(cwd).raw(["cherry-pick", "-m", "1", "--strategy=recursive", "--strategy-option=theirs", sha]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -98,7 +115,7 @@ export default class GitCLIService {
|
||||||
* @param remote [optional] remote to which the branch should be pushed to, by default 'origin'
|
* @param remote [optional] remote to which the branch should be pushed to, by default 'origin'
|
||||||
*/
|
*/
|
||||||
async push(cwd: string, branch: string, remote = "origin", force = false): Promise<void> {
|
async push(cwd: string, branch: string, remote = "origin", force = false): Promise<void> {
|
||||||
this.logger.info(`Pushing ${branch} to ${remote}..`);
|
this.logger.info(`Pushing ${branch} to ${remote}.`);
|
||||||
|
|
||||||
const options = ["--quiet"];
|
const options = ["--quiet"];
|
||||||
if (force) {
|
if (force) {
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
import GitService from "@gb/service/git/git-service";
|
import GitService from "@bp/service/git/git-service";
|
||||||
import { GitServiceType } from "@gb/service/git/git.types";
|
import { GitServiceType } from "@bp/service/git/git.types";
|
||||||
import GitHubService from "@gb/service/git/github/github-service";
|
import GitHubService from "@bp/service/git/github/github-service";
|
||||||
|
import LoggerService from "@bp/service/logger/logger-service";
|
||||||
|
import LoggerServiceFactory from "@bp/service/logger/logger-service-factory";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Singleton git service factory class
|
* Singleton git service factory class
|
||||||
*/
|
*/
|
||||||
export default class GitServiceFactory {
|
export default class GitServiceFactory {
|
||||||
|
|
||||||
|
private static logger: LoggerService = LoggerServiceFactory.getLogger();
|
||||||
private static instance?: GitService;
|
private static instance?: GitService;
|
||||||
|
|
||||||
public static getService(): GitService {
|
public static getService(): GitService {
|
||||||
|
@ -25,7 +28,8 @@ export default class GitServiceFactory {
|
||||||
public static init(type: GitServiceType, auth: string): void {
|
public static init(type: GitServiceType, auth: string): void {
|
||||||
|
|
||||||
if (GitServiceFactory.instance) {
|
if (GitServiceFactory.instance) {
|
||||||
throw new Error("Git service already initialized!");
|
GitServiceFactory.logger.warn("Git service already initialized!");
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(type) {
|
switch(type) {
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { GitPullRequest } from "@gb/service/git/git.types";
|
import { BackportPullRequest, GitPullRequest } from "@bp/service/git/git.types";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Git management service interface, which provides a common API for interacting
|
* Git management service interface, which provides a common API for interacting
|
||||||
|
@ -17,17 +17,18 @@ import { GitPullRequest } from "@gb/service/git/git.types";
|
||||||
*/
|
*/
|
||||||
getPullRequest(owner: string, repo: string, prNumber: number): Promise<GitPullRequest>;
|
getPullRequest(owner: string, repo: string, prNumber: number): Promise<GitPullRequest>;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get a pull request object from the underneath git service
|
||||||
|
* @param prUrl pull request html url
|
||||||
|
* @returns {Promise<PullRequest>}
|
||||||
|
*/
|
||||||
|
getPullRequestFromUrl(prUrl: string): Promise<GitPullRequest>;
|
||||||
|
|
||||||
// WRITE
|
// WRITE
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new pull request on the underneath git service
|
* Create a new pull request on the underneath git service
|
||||||
* @param owner repository's owner
|
* @param backport backport pull request data
|
||||||
* @param repo repository's name
|
|
||||||
* @param head name of the source branch
|
|
||||||
* @param base name of the target branch
|
|
||||||
* @param title pr title
|
|
||||||
* @param body pr body
|
|
||||||
* @param reviewers pr list of reviewers
|
|
||||||
*/
|
*/
|
||||||
createPullRequest(owner: string, repo: string, head: string, base: string, title: string, body: string, reviewers: string[]): Promise<void>;
|
createPullRequest(backport: BackportPullRequest): Promise<void>;
|
||||||
}
|
}
|
|
@ -1,15 +1,34 @@
|
||||||
export interface GitPullRequest {
|
export interface GitPullRequest {
|
||||||
url: string,
|
author: string,
|
||||||
patchUrl: string,
|
url?: string,
|
||||||
state: string,
|
htmlUrl?: string,
|
||||||
|
state?: "open" | "closed",
|
||||||
|
merged?: boolean,
|
||||||
|
mergedBy?: string,
|
||||||
title: string,
|
title: string,
|
||||||
body: string,
|
body: string,
|
||||||
reviewers: string[],
|
reviewers: string[],
|
||||||
targetRepo: string,
|
targetRepo: GitRepository,
|
||||||
sourceRepo: string,
|
sourceRepo: GitRepository,
|
||||||
commits: string[]
|
commits: string[]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface GitRepository {
|
||||||
|
owner: string,
|
||||||
|
project: string,
|
||||||
|
cloneUrl: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface BackportPullRequest {
|
||||||
|
owner: string, // repository's owner
|
||||||
|
repo: string, // repository's name
|
||||||
|
head: string, // name of the source branch
|
||||||
|
base: string, // name of the target branch
|
||||||
|
title: string, // pr title
|
||||||
|
body: string, // pr body
|
||||||
|
reviewers: string[] // pr list of reviewers
|
||||||
|
}
|
||||||
|
|
||||||
export enum GitServiceType {
|
export enum GitServiceType {
|
||||||
GITHUB = "github"
|
GITHUB = "github"
|
||||||
}
|
}
|
|
@ -1,19 +1,30 @@
|
||||||
import { GitPullRequest } from "@gb/service/git/git.types";
|
import { GitPullRequest } from "@bp/service/git/git.types";
|
||||||
import { PullRequest, User } from "@octokit/webhooks-types";
|
import { PullRequest, User } from "@octokit/webhooks-types";
|
||||||
|
|
||||||
export default class GitHubMapper {
|
export default class GitHubMapper {
|
||||||
|
|
||||||
mapPullRequest(pr: PullRequest): GitPullRequest {
|
mapPullRequest(pr: PullRequest): GitPullRequest {
|
||||||
return {
|
return {
|
||||||
|
author: pr.user.login,
|
||||||
url: pr.url,
|
url: pr.url,
|
||||||
|
htmlUrl: pr.html_url,
|
||||||
title: pr.title,
|
title: pr.title,
|
||||||
body: pr.body,
|
body: pr.body ?? "",
|
||||||
patchUrl: pr.patch_url,
|
|
||||||
state: pr.state,
|
state: pr.state,
|
||||||
|
merged: pr.merged ?? false,
|
||||||
|
mergedBy: pr.merged_by?.login,
|
||||||
reviewers: pr.requested_reviewers.filter(r => "login" in r).map((r => (r as User)?.login)),
|
reviewers: pr.requested_reviewers.filter(r => "login" in r).map((r => (r as User)?.login)),
|
||||||
sourceRepo: pr.head.repo.full_name,
|
sourceRepo: {
|
||||||
targetRepo: pr.base.repo.full_name,
|
owner: pr.head.repo.full_name.split("/")[0],
|
||||||
commits: [pr.merge_commit_sha]
|
project: pr.head.repo.full_name.split("/")[1],
|
||||||
} as GitPullRequest;
|
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 as string]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,16 +1,20 @@
|
||||||
import GitService from "@gb/service/git/git-service";
|
import GitService from "@bp/service/git/git-service";
|
||||||
import { GitPullRequest } from "@gb/service/git/git.types";
|
import { BackportPullRequest, GitPullRequest } from "@bp/service/git/git.types";
|
||||||
import GitHubMapper from "@gb/service/git/github/github-mapper";
|
import GitHubMapper from "@bp/service/git/github/github-mapper";
|
||||||
import OctokitFactory from "@gb/service/git/github/octokit-factory";
|
import OctokitFactory from "@bp/service/git/github/octokit-factory";
|
||||||
|
import LoggerService from "@bp/service/logger/logger-service";
|
||||||
|
import LoggerServiceFactory from "@bp/service/logger/logger-service-factory";
|
||||||
import { Octokit } from "@octokit/rest";
|
import { Octokit } from "@octokit/rest";
|
||||||
import { PullRequest } from "@octokit/webhooks-types";
|
import { PullRequest } from "@octokit/webhooks-types";
|
||||||
|
|
||||||
export default class GitHubService implements GitService {
|
export default class GitHubService implements GitService {
|
||||||
|
|
||||||
|
private logger: LoggerService;
|
||||||
private octokit: Octokit;
|
private octokit: Octokit;
|
||||||
private mapper: GitHubMapper;
|
private mapper: GitHubMapper;
|
||||||
|
|
||||||
constructor(token: string) {
|
constructor(token: string) {
|
||||||
|
this.logger = LoggerServiceFactory.getLogger();
|
||||||
this.octokit = OctokitFactory.getOctokit(token);
|
this.octokit = OctokitFactory.getOctokit(token);
|
||||||
this.mapper = new GitHubMapper();
|
this.mapper = new GitHubMapper();
|
||||||
}
|
}
|
||||||
|
@ -18,6 +22,7 @@ export default class GitHubService implements GitService {
|
||||||
// READ
|
// READ
|
||||||
|
|
||||||
async getPullRequest(owner: string, repo: string, prNumber: number): Promise<GitPullRequest> {
|
async getPullRequest(owner: string, repo: string, prNumber: number): Promise<GitPullRequest> {
|
||||||
|
this.logger.info(`Getting pull request ${owner}/${repo}/${prNumber}.`);
|
||||||
const { data } = await this.octokit.rest.pulls.get({
|
const { data } = await this.octokit.rest.pulls.get({
|
||||||
owner: owner,
|
owner: owner,
|
||||||
repo: repo,
|
repo: repo,
|
||||||
|
@ -27,12 +32,52 @@ export default class GitHubService implements GitService {
|
||||||
return this.mapper.mapPullRequest(data as PullRequest);
|
return this.mapper.mapPullRequest(data as PullRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getPullRequestFromUrl(prUrl: string): Promise<GitPullRequest> {
|
||||||
|
const {owner, project} = this.getRepositoryFromPrUrl(prUrl);
|
||||||
|
return this.getPullRequest(owner, project, parseInt(prUrl.substring(prUrl.lastIndexOf("/") + 1, prUrl.length)));
|
||||||
|
}
|
||||||
|
|
||||||
// WRITE
|
// WRITE
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
async createPullRequest(backport: BackportPullRequest): Promise<void> {
|
||||||
createPullRequest(owner: string, repo: string, head: string, base: string, title: string, body: string, reviewers: string[]): Promise<void> {
|
this.logger.info(`Creating pull request ${backport.head} -> ${backport.base}.`);
|
||||||
// throw new Error("Method not implemented.");
|
this.logger.info(`${JSON.stringify(backport, null, 2)}`);
|
||||||
// TODO implement
|
|
||||||
return Promise.resolve();
|
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 as PullRequest).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}}
|
||||||
|
*/
|
||||||
|
private getRepositoryFromPrUrl(prUrl: string): {owner: string, project: string} {
|
||||||
|
const elems: string[] = prUrl.split("/");
|
||||||
|
return {
|
||||||
|
owner: elems[elems.length - 4],
|
||||||
|
project: elems[elems.length - 3]
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
import LoggerService from "@gb/service/logger/logger-service";
|
import LoggerService from "@bp/service/logger/logger-service";
|
||||||
import LoggerServiceFactory from "@gb/service/logger/logger-service-factory";
|
import LoggerServiceFactory from "@bp/service/logger/logger-service-factory";
|
||||||
import { Octokit } from "@octokit/rest";
|
import { Octokit } from "@octokit/rest";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -12,7 +12,7 @@ export default class OctokitFactory {
|
||||||
|
|
||||||
public static getOctokit(token: string): Octokit {
|
public static getOctokit(token: string): Octokit {
|
||||||
if (!OctokitFactory.octokit) {
|
if (!OctokitFactory.octokit) {
|
||||||
OctokitFactory.logger.info("Creating octokit instance..");
|
OctokitFactory.logger.info("Creating octokit instance.");
|
||||||
OctokitFactory.octokit = new Octokit({
|
OctokitFactory.octokit = new Octokit({
|
||||||
auth: token,
|
auth: token,
|
||||||
userAgent: "lampajr/backporting"
|
userAgent: "lampajr/backporting"
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import Logger from "@gb/service/logger/logger";
|
import Logger from "@bp/service/logger/logger";
|
||||||
import LoggerService from "@gb/service/logger/logger-service";
|
import LoggerService from "@bp/service/logger/logger-service";
|
||||||
|
|
||||||
export default class ConsoleLoggerService implements LoggerService {
|
export default class ConsoleLoggerService implements LoggerService {
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import ConsoleLoggerService from "@gb/service/logger/console-logger-service";
|
import ConsoleLoggerService from "@bp/service/logger/console-logger-service";
|
||||||
import LoggerService from "@gb/service/logger/logger-service";
|
import LoggerService from "@bp/service/logger/logger-service";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Singleton factory class
|
* Singleton factory class
|
||||||
|
|
123
src/service/runner/runner.ts
Normal file
123
src/service/runner/runner.ts
Normal file
|
@ -0,0 +1,123 @@
|
||||||
|
import ArgsParser from "@bp/service/args/args-parser";
|
||||||
|
import { Args } from "@bp/service/args/args.types";
|
||||||
|
import { Configs } from "@bp/service/configs/configs.types";
|
||||||
|
import PullRequestConfigsParser from "@bp/service/configs/pullrequest/pr-configs-parser";
|
||||||
|
import GitCLIService from "@bp/service/git/git-cli";
|
||||||
|
import GitService from "@bp/service/git/git-service";
|
||||||
|
import GitServiceFactory from "@bp/service/git/git-service-factory";
|
||||||
|
import { BackportPullRequest, GitPullRequest, GitServiceType } from "@bp/service/git/git.types";
|
||||||
|
import LoggerService from "@bp/service/logger/logger-service";
|
||||||
|
import LoggerServiceFactory from "@bp/service/logger/logger-service-factory";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Main runner implementation, it implements the core logic flow
|
||||||
|
*/
|
||||||
|
export default class Runner {
|
||||||
|
|
||||||
|
private logger: LoggerService;
|
||||||
|
private argsParser: ArgsParser;
|
||||||
|
|
||||||
|
constructor(parser: ArgsParser) {
|
||||||
|
this.logger = LoggerServiceFactory.getLogger();
|
||||||
|
this.argsParser = parser;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Infer the remote GIT service to interact with based on the provided
|
||||||
|
* pull request URL
|
||||||
|
* @param prUrl provided pull request URL
|
||||||
|
* @returns {GitServiceType}
|
||||||
|
*/
|
||||||
|
private inferRemoteGitService(prUrl: string): GitServiceType {
|
||||||
|
const stdPrUrl = prUrl.toLowerCase().trim();
|
||||||
|
|
||||||
|
if (stdPrUrl.includes(GitServiceType.GITHUB.toString())) {
|
||||||
|
return GitServiceType.GITHUB;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error(`Remote GIT service not recognixed from PR url: ${prUrl}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entry point invoked by the command line or gha
|
||||||
|
*/
|
||||||
|
async run(): Promise<void> {
|
||||||
|
this.logger.info("Starting process.");
|
||||||
|
|
||||||
|
try {
|
||||||
|
await this.execute();
|
||||||
|
|
||||||
|
this.logger.info("Process succeeded!");
|
||||||
|
process.exit(0);
|
||||||
|
|
||||||
|
} catch (error) {
|
||||||
|
this.logger.error(`${error}`);
|
||||||
|
|
||||||
|
this.logger.info("Process failed!");
|
||||||
|
process.exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Core logic
|
||||||
|
*/
|
||||||
|
async execute(): Promise<void>{
|
||||||
|
|
||||||
|
// 1. parse args
|
||||||
|
const args: Args = this.argsParser.parse();
|
||||||
|
|
||||||
|
if (args.dryRun) {
|
||||||
|
this.logger.warn("Dry run enabled!");
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2. init git service
|
||||||
|
GitServiceFactory.init(this.inferRemoteGitService(args.pullRequest), args.auth);
|
||||||
|
const gitApi: GitService = GitServiceFactory.getService();
|
||||||
|
|
||||||
|
// 3. parse configs
|
||||||
|
const configs: Configs = await new PullRequestConfigsParser().parseAndValidate(args);
|
||||||
|
const originalPR: GitPullRequest = configs.originalPullRequest;
|
||||||
|
const backportPR: GitPullRequest = configs.backportPullRequest;
|
||||||
|
|
||||||
|
// start local git operations
|
||||||
|
const git: GitCLIService = new GitCLIService(configs.auth, configs.author);
|
||||||
|
|
||||||
|
// 4. clone the repository
|
||||||
|
await git.clone(configs.originalPullRequest.targetRepo.cloneUrl, configs.folder, configs.targetBranch);
|
||||||
|
|
||||||
|
// 5. create new branch from target one and checkout
|
||||||
|
const backportBranch = `bp-${configs.targetBranch}-${originalPR.commits.join("-")}`;
|
||||||
|
await git.createLocalBranch(configs.folder, backportBranch);
|
||||||
|
|
||||||
|
// 6. add new remote if source != target and fetch source repo
|
||||||
|
// Skip this, we assume the PR has been already merged
|
||||||
|
|
||||||
|
// 7. apply all changes to the new branch
|
||||||
|
for (const sha of originalPR.commits) {
|
||||||
|
await git.cherryPick(configs.folder, sha);
|
||||||
|
}
|
||||||
|
|
||||||
|
const backport: BackportPullRequest = {
|
||||||
|
owner: originalPR.targetRepo.owner,
|
||||||
|
repo: originalPR.targetRepo.project,
|
||||||
|
head: backportBranch,
|
||||||
|
base: configs.targetBranch,
|
||||||
|
title: backportPR.title,
|
||||||
|
body: backportPR.body,
|
||||||
|
reviewers: backportPR.reviewers
|
||||||
|
};
|
||||||
|
|
||||||
|
if (!configs.dryRun) {
|
||||||
|
// 8. push the new branch to origin
|
||||||
|
await git.push(configs.folder, backportBranch);
|
||||||
|
|
||||||
|
// 9. create pull request new branch -> target branch (using octokit)
|
||||||
|
await gitApi.createPullRequest(backport);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this.logger.warn("Pull request creation and remote push skipped!");
|
||||||
|
this.logger.info(`${JSON.stringify(backport, null, 2)}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
90
test/service/args/cli/cli-args-parser.test.ts
Normal file
90
test/service/args/cli/cli-args-parser.test.ts
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
import { Args } from "@bp/service/args/args.types";
|
||||||
|
import CLIArgsParser from "@bp/service/args/cli/cli-args-parser";
|
||||||
|
import { addProcessArgs, resetProcessArgs } from "../../../support/utils";
|
||||||
|
|
||||||
|
describe("cli args parser", () => {
|
||||||
|
let parser: CLIArgsParser;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
// create a fresh new instance every time
|
||||||
|
parser = new CLIArgsParser();
|
||||||
|
|
||||||
|
// reset process.env variables
|
||||||
|
resetProcessArgs();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("valid execution [default, short]", () => {
|
||||||
|
addProcessArgs([
|
||||||
|
"-tb",
|
||||||
|
"target",
|
||||||
|
"-pr",
|
||||||
|
"https://localhost/whatever/pulls/1"
|
||||||
|
]);
|
||||||
|
|
||||||
|
const args: Args = parser.parse();
|
||||||
|
expect(args.dryRun).toEqual(false);
|
||||||
|
expect(args.auth).toEqual("");
|
||||||
|
expect(args.author).toEqual(undefined);
|
||||||
|
expect(args.folder).toEqual(undefined);
|
||||||
|
expect(args.targetBranch).toEqual("target");
|
||||||
|
expect(args.pullRequest).toEqual("https://localhost/whatever/pulls/1");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("valid execution [default, long]", () => {
|
||||||
|
addProcessArgs([
|
||||||
|
"--target-branch",
|
||||||
|
"target",
|
||||||
|
"--pull-request",
|
||||||
|
"https://localhost/whatever/pulls/1"
|
||||||
|
]);
|
||||||
|
|
||||||
|
const args: Args = parser.parse();
|
||||||
|
expect(args.dryRun).toEqual(false);
|
||||||
|
expect(args.auth).toEqual("");
|
||||||
|
expect(args.author).toEqual(undefined);
|
||||||
|
expect(args.folder).toEqual(undefined);
|
||||||
|
expect(args.targetBranch).toEqual("target");
|
||||||
|
expect(args.pullRequest).toEqual("https://localhost/whatever/pulls/1");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("valid execution [override, short]", () => {
|
||||||
|
addProcessArgs([
|
||||||
|
"-d",
|
||||||
|
"-a",
|
||||||
|
"bearer-token",
|
||||||
|
"-tb",
|
||||||
|
"target",
|
||||||
|
"-pr",
|
||||||
|
"https://localhost/whatever/pulls/1"
|
||||||
|
]);
|
||||||
|
|
||||||
|
const args: Args = parser.parse();
|
||||||
|
expect(args.dryRun).toEqual(true);
|
||||||
|
expect(args.auth).toEqual("bearer-token");
|
||||||
|
expect(args.author).toEqual(undefined);
|
||||||
|
expect(args.folder).toEqual(undefined);
|
||||||
|
expect(args.targetBranch).toEqual("target");
|
||||||
|
expect(args.pullRequest).toEqual("https://localhost/whatever/pulls/1");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("valid execution [override, long]", () => {
|
||||||
|
addProcessArgs([
|
||||||
|
"--dry-run",
|
||||||
|
"--auth",
|
||||||
|
"bearer-token",
|
||||||
|
"--target-branch",
|
||||||
|
"target",
|
||||||
|
"--pull-request",
|
||||||
|
"https://localhost/whatever/pulls/1"
|
||||||
|
]);
|
||||||
|
|
||||||
|
const args: Args = parser.parse();
|
||||||
|
expect(args.dryRun).toEqual(true);
|
||||||
|
expect(args.auth).toEqual("bearer-token");
|
||||||
|
expect(args.author).toEqual(undefined);
|
||||||
|
expect(args.folder).toEqual(undefined);
|
||||||
|
expect(args.targetBranch).toEqual("target");
|
||||||
|
expect(args.pullRequest).toEqual("https://localhost/whatever/pulls/1");
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
50
test/service/args/gha/gha-args-parser.test.ts
Normal file
50
test/service/args/gha/gha-args-parser.test.ts
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
import { Args } from "@bp/service/args/args.types";
|
||||||
|
import GHAArgsParser from "@bp/service/args/gha/gha-args-parser";
|
||||||
|
import { spyGetInput } from "../../../support/utils";
|
||||||
|
|
||||||
|
describe("gha args parser", () => {
|
||||||
|
let parser: GHAArgsParser;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
// create a fresh new instance every time
|
||||||
|
parser = new GHAArgsParser();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
test("valid execution [default]", () => {
|
||||||
|
spyGetInput({
|
||||||
|
"target-branch": "target",
|
||||||
|
"pull-request": "https://localhost/whatever/pulls/1"
|
||||||
|
});
|
||||||
|
|
||||||
|
const args: Args = parser.parse();
|
||||||
|
expect(args.dryRun).toEqual(false);
|
||||||
|
expect(args.auth).toEqual("");
|
||||||
|
expect(args.author).toEqual(undefined);
|
||||||
|
expect(args.folder).toEqual(undefined);
|
||||||
|
expect(args.targetBranch).toEqual("target");
|
||||||
|
expect(args.pullRequest).toEqual("https://localhost/whatever/pulls/1");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("valid execution [override]", () => {
|
||||||
|
spyGetInput({
|
||||||
|
"dry-run": "true",
|
||||||
|
"auth": "bearer-token",
|
||||||
|
"target-branch": "target",
|
||||||
|
"pull-request": "https://localhost/whatever/pulls/1"
|
||||||
|
});
|
||||||
|
|
||||||
|
const args: Args = parser.parse();
|
||||||
|
expect(args.dryRun).toEqual(true);
|
||||||
|
expect(args.auth).toEqual("bearer-token");
|
||||||
|
expect(args.author).toEqual(undefined);
|
||||||
|
expect(args.folder).toEqual(undefined);
|
||||||
|
expect(args.targetBranch).toEqual("target");
|
||||||
|
expect(args.pullRequest).toEqual("https://localhost/whatever/pulls/1");
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
132
test/service/configs/pullrequest/pr-configs-parser.test.ts
Normal file
132
test/service/configs/pullrequest/pr-configs-parser.test.ts
Normal file
|
@ -0,0 +1,132 @@
|
||||||
|
import { Args } from "@bp/service/args/args.types";
|
||||||
|
import { Configs } from "@bp/service/configs/configs.types";
|
||||||
|
import PullRequestConfigsParser from "@bp/service/configs/pullrequest/pr-configs-parser";
|
||||||
|
import 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";
|
||||||
|
|
||||||
|
describe("pull request config parser", () => {
|
||||||
|
|
||||||
|
const mergedPRUrl = `https://github.com/${targetOwner}/${repo}/pull/${mergedPullRequestFixture.number}`;
|
||||||
|
const notMergedPRUrl = `https://github.com/${targetOwner}/${repo}/pull/${notMergedPullRequestFixture.number}`;
|
||||||
|
|
||||||
|
let parser: PullRequestConfigsParser;
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
GitServiceFactory.init(GitServiceType.GITHUB, "whatever");
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
setupMoctokit();
|
||||||
|
|
||||||
|
parser = new PullRequestConfigsParser();
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("parse configs from pull request [default]", async () => {
|
||||||
|
const args: Args = {
|
||||||
|
dryRun: false,
|
||||||
|
auth: "",
|
||||||
|
pullRequest: mergedPRUrl,
|
||||||
|
targetBranch: "prod"
|
||||||
|
};
|
||||||
|
|
||||||
|
const configs: Configs = await parser.parseAndValidate(args);
|
||||||
|
|
||||||
|
expect(configs.dryRun).toEqual(false);
|
||||||
|
expect(configs.author).toEqual("gh-user");
|
||||||
|
expect(configs.auth).toEqual("");
|
||||||
|
expect(configs.targetBranch).toEqual("prod");
|
||||||
|
expect(configs.folder).toEqual(process.cwd() + "/bp");
|
||||||
|
expect(configs.originalPullRequest).toEqual({
|
||||||
|
author: "gh-user",
|
||||||
|
url: "https://api.github.com/repos/owner/reponame/pulls/2368",
|
||||||
|
htmlUrl: "https://github.com/owner/reponame/pull/2368",
|
||||||
|
state: "closed",
|
||||||
|
merged: true,
|
||||||
|
mergedBy: "that-s-a-user",
|
||||||
|
title: "PR Title",
|
||||||
|
body: "Please review and merge",
|
||||||
|
reviewers: ["requested-gh-user", "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"
|
||||||
|
},
|
||||||
|
commits: ["28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"]
|
||||||
|
});
|
||||||
|
expect(configs.backportPullRequest).toEqual({
|
||||||
|
author: "gh-user",
|
||||||
|
url: undefined,
|
||||||
|
htmlUrl: undefined,
|
||||||
|
title: "[prod] PR Title",
|
||||||
|
body: "**Backport:** https://github.com/owner/reponame/pull/2368\r\n\r\nPlease review and merge\r\n\r\nPowered by [BPer](https://github.com/lampajr/backporting).",
|
||||||
|
reviewers: ["gh-user", "that-s-a-user"],
|
||||||
|
targetRepo: {
|
||||||
|
owner: "owner",
|
||||||
|
project: "reponame",
|
||||||
|
cloneUrl: "https://github.com/owner/reponame.git"
|
||||||
|
},
|
||||||
|
sourceRepo: {
|
||||||
|
owner: "owner",
|
||||||
|
project: "reponame",
|
||||||
|
cloneUrl: "https://github.com/owner/reponame.git"
|
||||||
|
},
|
||||||
|
commits: []
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test("override folder", async () => {
|
||||||
|
const args: Args = {
|
||||||
|
dryRun: true,
|
||||||
|
auth: "whatever",
|
||||||
|
pullRequest: mergedPRUrl,
|
||||||
|
targetBranch: "prod",
|
||||||
|
folder: "/tmp/test"
|
||||||
|
};
|
||||||
|
|
||||||
|
const configs: Configs = await parser.parseAndValidate(args);
|
||||||
|
|
||||||
|
expect(configs.dryRun).toEqual(true);
|
||||||
|
expect(configs.auth).toEqual("whatever");
|
||||||
|
expect(configs.targetBranch).toEqual("prod");
|
||||||
|
expect(configs.folder).toEqual("/tmp/test");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("override author", async () => {
|
||||||
|
const args: Args = {
|
||||||
|
dryRun: true,
|
||||||
|
auth: "whatever",
|
||||||
|
pullRequest: mergedPRUrl,
|
||||||
|
targetBranch: "prod",
|
||||||
|
author: "another-user"
|
||||||
|
};
|
||||||
|
|
||||||
|
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("another-user");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("not merged pull request", async () => {
|
||||||
|
const args: Args = {
|
||||||
|
dryRun: true,
|
||||||
|
auth: "whatever",
|
||||||
|
pullRequest: notMergedPRUrl,
|
||||||
|
targetBranch: "prod"
|
||||||
|
};
|
||||||
|
|
||||||
|
expect(async () => await parser.parseAndValidate(args)).rejects.toThrow("Provided pull request is not merged!");
|
||||||
|
});
|
||||||
|
});
|
114
test/service/git/git-cli.test.ts
Normal file
114
test/service/git/git-cli.test.ts
Normal file
|
@ -0,0 +1,114 @@
|
||||||
|
import GitCLIService from "@bp/service/git/git-cli";
|
||||||
|
import { FileState, GitActionTypes, MockGithub } from "@kie/mock-github";
|
||||||
|
import { spawnSync } from "child_process";
|
||||||
|
import { assert } from "console";
|
||||||
|
import path from "path";
|
||||||
|
import fs from "fs";
|
||||||
|
|
||||||
|
let git: GitCLIService;
|
||||||
|
let cwd: string;
|
||||||
|
let currentBranch: string;
|
||||||
|
let pushedBranches: string[];
|
||||||
|
let localBranches: string[];
|
||||||
|
let files: FileState[];
|
||||||
|
|
||||||
|
const mockGithub = new MockGithub(
|
||||||
|
{
|
||||||
|
repo: {
|
||||||
|
repoA: {
|
||||||
|
pushedBranches: ["sbranch", "tbranch"],
|
||||||
|
localBranches: ["lbranch"],
|
||||||
|
currentBranch: "main",
|
||||||
|
history: [
|
||||||
|
{
|
||||||
|
action: GitActionTypes.PUSH,
|
||||||
|
branch: "main",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: GitActionTypes.PUSH,
|
||||||
|
branch: "sbranch",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
action: GitActionTypes.PUSH,
|
||||||
|
branch: "tbranch",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
path.join(__dirname, "setup-cli")
|
||||||
|
);
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
//setup
|
||||||
|
await mockGithub.setup();
|
||||||
|
cwd = mockGithub.repo.getPath("repoA")!;
|
||||||
|
currentBranch = mockGithub.repo.getBranchState("repoA")!.currentBranch;
|
||||||
|
pushedBranches = mockGithub.repo.getBranchState("repoA")!.pushedBranches;
|
||||||
|
localBranches = mockGithub.repo.getBranchState("repoA")!.localBranches;
|
||||||
|
files = (await mockGithub.repo.getFileSystemState("repoA"))!;
|
||||||
|
|
||||||
|
//make sure the setup is correct to run this test suite
|
||||||
|
assert(
|
||||||
|
pushedBranches.length > 1,
|
||||||
|
"your configuration must have a repository with pushed branches other than main"
|
||||||
|
);
|
||||||
|
assert(
|
||||||
|
localBranches.length > 0,
|
||||||
|
"your configuration must have a repository with local branches i.e. not pushed branches"
|
||||||
|
);
|
||||||
|
assert(
|
||||||
|
files.length > 0,
|
||||||
|
"your configuration needs at least 1 file committed to some branch which is not the current branch"
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
await mockGithub.teardown();
|
||||||
|
});
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
// create a fresh instance of git before each test
|
||||||
|
git = new GitCLIService("", "author");
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("git cli service", () => {
|
||||||
|
test("version", async () => {
|
||||||
|
const result = await git.version();
|
||||||
|
const actualVersion = spawnSync("git", ["version"]).stdout.toString();
|
||||||
|
const match = actualVersion.match(/(\d+\.\d+(\.\d+)?)/);
|
||||||
|
if (match) {
|
||||||
|
expect(result).toEqual(match[1]);
|
||||||
|
} else {
|
||||||
|
expect(result).toBe(undefined);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
test("fetch", async () => {
|
||||||
|
await expect(git.fetch(cwd, currentBranch)).resolves.not.toThrowError();
|
||||||
|
});
|
||||||
|
|
||||||
|
test("local branch", async () => {
|
||||||
|
await expect(git.createLocalBranch(cwd, "new-local-branch")).resolves.not.toThrowError();
|
||||||
|
|
||||||
|
// use rev-parse to double check the current branch is the new one
|
||||||
|
const output = spawnSync("git", ["rev-parse", "--abbrev-ref", "HEAD"], { cwd }).stdout.toString().trim();
|
||||||
|
expect(output).toEqual("new-local-branch");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("push local branch", async () => {
|
||||||
|
const expressionToTest = "GIT_CHERRY_SHOULD_NOT_INCLUDE_THIS_MSG";
|
||||||
|
// create file to push
|
||||||
|
fs.writeFileSync(path.join(cwd, "test-push"), "testing git push");
|
||||||
|
|
||||||
|
// add and commit the file
|
||||||
|
spawnSync("git", ["add", "."], { cwd });
|
||||||
|
spawnSync("git", ["commit", "-m", expressionToTest], { cwd });
|
||||||
|
|
||||||
|
await git.push(cwd, currentBranch, "origin", false);
|
||||||
|
|
||||||
|
// use git cherry to verify this commit was pushed
|
||||||
|
const output = spawnSync("git", ["cherry", "-v"], { cwd }).stdout.toString();
|
||||||
|
expect(output.includes(expressionToTest)).toBe(false);
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,7 +1,7 @@
|
||||||
import GitServiceFactory from "@gb/service/git/git-service-factory";
|
import GitServiceFactory from "@bp/service/git/git-service-factory";
|
||||||
import { GitPullRequest, GitServiceType } from "@gb/service/git/git.types";
|
import { GitPullRequest, GitServiceType } from "@bp/service/git/git.types";
|
||||||
import GitHubService from "@gb/service/git/github/github-service";
|
import GitHubService from "@bp/service/git/github/github-service";
|
||||||
import { pullRequestNumber, repo, targetOwner } from "../../../support/moctokit/moctokit-data";
|
import { mergedPullRequestFixture, repo, targetOwner } from "../../../support/moctokit/moctokit-data";
|
||||||
import { setupMoctokit } from "../../../support/moctokit/moctokit-support";
|
import { setupMoctokit } from "../../../support/moctokit/moctokit-support";
|
||||||
|
|
||||||
describe("github service", () => {
|
describe("github service", () => {
|
||||||
|
@ -21,9 +21,17 @@ describe("github service", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test("get pull request: success", async () => {
|
test("get pull request: success", async () => {
|
||||||
const res: GitPullRequest = await gitService.getPullRequest(targetOwner, repo, pullRequestNumber);
|
const res: GitPullRequest = await gitService.getPullRequest(targetOwner, repo, mergedPullRequestFixture.number);
|
||||||
expect(res.sourceRepo).toBe("fork/reponame");
|
expect(res.sourceRepo).toEqual({
|
||||||
expect(res.targetRepo).toBe("owner/reponame");
|
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.title).toBe("PR Title");
|
||||||
expect(res.commits.length).toBe(1);
|
expect(res.commits.length).toBe(1);
|
||||||
expect(res.commits).toEqual(["28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"]);
|
expect(res.commits).toEqual(["28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc"]);
|
||||||
|
|
201
test/service/runner/cli-runner.test.ts
Normal file
201
test/service/runner/cli-runner.test.ts
Normal file
|
@ -0,0 +1,201 @@
|
||||||
|
import ArgsParser from "@bp/service/args/args-parser";
|
||||||
|
import Runner from "@bp/service/runner/runner";
|
||||||
|
import GitCLIService from "@bp/service/git/git-cli";
|
||||||
|
import GitHubService from "@bp/service/git/github/github-service";
|
||||||
|
import CLIArgsParser from "@bp/service/args/cli/cli-args-parser";
|
||||||
|
import { addProcessArgs, resetProcessArgs } from "../../support/utils";
|
||||||
|
import { setupMoctokit } from "../../support/moctokit/moctokit-support";
|
||||||
|
|
||||||
|
jest.mock("@bp/service/git/git-cli");
|
||||||
|
jest.spyOn(GitHubService.prototype, "createPullRequest");
|
||||||
|
|
||||||
|
let parser: ArgsParser;
|
||||||
|
let runner: Runner;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
setupMoctokit();
|
||||||
|
|
||||||
|
// create CLI arguments parser
|
||||||
|
parser = new CLIArgsParser();
|
||||||
|
|
||||||
|
// create runner
|
||||||
|
runner = new Runner(parser);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
|
||||||
|
// reset process.env variables
|
||||||
|
resetProcessArgs();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("pull request runner test", () => {
|
||||||
|
test("with dry run", async () => {
|
||||||
|
addProcessArgs([
|
||||||
|
"-d",
|
||||||
|
"-tb",
|
||||||
|
"target",
|
||||||
|
"-pr",
|
||||||
|
"https://github.com/owner/reponame/pull/2368"
|
||||||
|
]);
|
||||||
|
|
||||||
|
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.addRemote).toBeCalledTimes(0);
|
||||||
|
|
||||||
|
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
|
||||||
|
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
|
||||||
|
|
||||||
|
expect(GitCLIService.prototype.push).toBeCalledTimes(0);
|
||||||
|
expect(GitHubService.prototype.createPullRequest).toBeCalledTimes(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("overriding author", async () => {
|
||||||
|
addProcessArgs([
|
||||||
|
"-d",
|
||||||
|
"-tb",
|
||||||
|
"target",
|
||||||
|
"-pr",
|
||||||
|
"https://github.com/owner/reponame/pull/2368"
|
||||||
|
]);
|
||||||
|
|
||||||
|
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.addRemote).toBeCalledTimes(0);
|
||||||
|
|
||||||
|
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
|
||||||
|
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
|
||||||
|
|
||||||
|
expect(GitCLIService.prototype.push).toBeCalledTimes(0);
|
||||||
|
expect(GitHubService.prototype.createPullRequest).toBeCalledTimes(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("with relative folder", async () => {
|
||||||
|
addProcessArgs([
|
||||||
|
"-d",
|
||||||
|
"-tb",
|
||||||
|
"target",
|
||||||
|
"-pr",
|
||||||
|
"https://github.com/owner/reponame/pull/2368",
|
||||||
|
"-f",
|
||||||
|
"folder"
|
||||||
|
]);
|
||||||
|
|
||||||
|
await runner.execute();
|
||||||
|
|
||||||
|
const cwd = process.cwd() + "/folder";
|
||||||
|
|
||||||
|
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.addRemote).toBeCalledTimes(0);
|
||||||
|
|
||||||
|
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
|
||||||
|
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
|
||||||
|
|
||||||
|
expect(GitCLIService.prototype.addRemote).toBeCalledTimes(0);
|
||||||
|
expect(GitCLIService.prototype.addRemote).toBeCalledTimes(0);
|
||||||
|
|
||||||
|
expect(GitCLIService.prototype.push).toBeCalledTimes(0);
|
||||||
|
expect(GitHubService.prototype.createPullRequest).toBeCalledTimes(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("with absolute folder", async () => {
|
||||||
|
addProcessArgs([
|
||||||
|
"-d",
|
||||||
|
"-tb",
|
||||||
|
"target",
|
||||||
|
"-pr",
|
||||||
|
"https://github.com/owner/reponame/pull/2368",
|
||||||
|
"-f",
|
||||||
|
"/tmp/folder"
|
||||||
|
]);
|
||||||
|
|
||||||
|
await runner.execute();
|
||||||
|
|
||||||
|
const cwd = "/tmp/folder";
|
||||||
|
|
||||||
|
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.addRemote).toBeCalledTimes(0);
|
||||||
|
|
||||||
|
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
|
||||||
|
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
|
||||||
|
|
||||||
|
expect(GitCLIService.prototype.push).toBeCalledTimes(0);
|
||||||
|
expect(GitHubService.prototype.createPullRequest).toBeCalledTimes(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("without dry run", async () => {
|
||||||
|
addProcessArgs([
|
||||||
|
"-tb",
|
||||||
|
"target",
|
||||||
|
"-pr",
|
||||||
|
"https://github.com/owner/reponame/pull/2368"
|
||||||
|
]);
|
||||||
|
|
||||||
|
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.addRemote).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/2368"),
|
||||||
|
reviewers: ["gh-user", "that-s-a-user"]
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("not merged pull request", async () => {
|
||||||
|
addProcessArgs([
|
||||||
|
"-tb",
|
||||||
|
"target",
|
||||||
|
"-pr",
|
||||||
|
"https://github.com/owner/reponame/pull/4444"
|
||||||
|
]);
|
||||||
|
|
||||||
|
expect(async () => await runner.execute()).rejects.toThrow("Provided pull request is not merged!");
|
||||||
|
});
|
||||||
|
});
|
101
test/service/runner/gha-runner.test.ts
Normal file
101
test/service/runner/gha-runner.test.ts
Normal file
|
@ -0,0 +1,101 @@
|
||||||
|
import ArgsParser from "@bp/service/args/args-parser";
|
||||||
|
import Runner from "@bp/service/runner/runner";
|
||||||
|
import GitCLIService from "@bp/service/git/git-cli";
|
||||||
|
import GitHubService from "@bp/service/git/github/github-service";
|
||||||
|
import GHAArgsParser from "@bp/service/args/gha/gha-args-parser";
|
||||||
|
import { spyGetInput } from "../../support/utils";
|
||||||
|
import { setupMoctokit } from "../../support/moctokit/moctokit-support";
|
||||||
|
|
||||||
|
jest.mock("@bp/service/git/git-cli");
|
||||||
|
jest.spyOn(GitHubService.prototype, "createPullRequest");
|
||||||
|
|
||||||
|
let parser: ArgsParser;
|
||||||
|
let runner: Runner;
|
||||||
|
|
||||||
|
beforeEach(() => {
|
||||||
|
setupMoctokit();
|
||||||
|
|
||||||
|
// create GHA arguments parser
|
||||||
|
parser = new GHAArgsParser();
|
||||||
|
|
||||||
|
// create runner
|
||||||
|
runner = new Runner(parser);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
jest.clearAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("pull request runner test", () => {
|
||||||
|
test("with dry run", async () => {
|
||||||
|
spyGetInput({
|
||||||
|
"dry-run": "true",
|
||||||
|
"target-branch": "target",
|
||||||
|
"pull-request": "https://github.com/owner/reponame/pull/2368"
|
||||||
|
});
|
||||||
|
|
||||||
|
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.addRemote).toBeCalledTimes(0);
|
||||||
|
|
||||||
|
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
|
||||||
|
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
|
||||||
|
|
||||||
|
expect(GitCLIService.prototype.push).toBeCalledTimes(0);
|
||||||
|
expect(GitHubService.prototype.createPullRequest).toBeCalledTimes(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("without dry run", async () => {
|
||||||
|
spyGetInput({
|
||||||
|
"target-branch": "target",
|
||||||
|
"pull-request": "https://github.com/owner/reponame/pull/2368"
|
||||||
|
});
|
||||||
|
|
||||||
|
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.addRemote).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/2368"),
|
||||||
|
reviewers: ["gh-user", "that-s-a-user"]
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("not merged 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!");
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,11 +1,9 @@
|
||||||
export const targetOwner = "owner";
|
export const targetOwner = "owner";
|
||||||
export const sourceOwner = "fork";
|
export const sourceOwner = "fork";
|
||||||
export const repo = "reponame";
|
export const repo = "reponame";
|
||||||
export const pullRequestNumber = 2368;
|
export const notFoundPullRequestNumber = 1;
|
||||||
export const invalidPullRequestNumber = 1;
|
|
||||||
export const commitRef = "91748965051fae1330ad58d15cf694e103267c87";
|
|
||||||
|
|
||||||
export const validPR = {
|
export const mergedPullRequestFixture = {
|
||||||
"url": "https://api.github.com/repos/owner/reponame/pulls/2368",
|
"url": "https://api.github.com/repos/owner/reponame/pulls/2368",
|
||||||
"id": 1137188271,
|
"id": 1137188271,
|
||||||
"node_id": "PR_kwDOABTq6s5DyB2v",
|
"node_id": "PR_kwDOABTq6s5DyB2v",
|
||||||
|
@ -18,22 +16,22 @@ export const validPR = {
|
||||||
"locked": false,
|
"locked": false,
|
||||||
"title": "PR Title",
|
"title": "PR Title",
|
||||||
"user": {
|
"user": {
|
||||||
"login": "kie-ci",
|
"login": "gh-user",
|
||||||
"id": 11995863,
|
"id": 11995863,
|
||||||
"node_id": "MDQ6VXNlcjExOTk1ODYz",
|
"node_id": "MDQ6VXNlcjExOTk1ODYz",
|
||||||
"avatar_url": "https://avatars.githubusercontent.com/u/11995863?v=4",
|
"avatar_url": "https://avatars.githubusercontent.com/u/11995863?v=4",
|
||||||
"gravatar_id": "",
|
"gravatar_id": "",
|
||||||
"url": "https://api.github.com/users/kie-ci",
|
"url": "https://api.github.com/users/gh-user",
|
||||||
"html_url": "https://github.com/kie-ci",
|
"html_url": "https://github.com/gh-user",
|
||||||
"followers_url": "https://api.github.com/users/kie-ci/followers",
|
"followers_url": "https://api.github.com/users/gh-user/followers",
|
||||||
"following_url": "https://api.github.com/users/kie-ci/following{/other_user}",
|
"following_url": "https://api.github.com/users/gh-user/following{/other_user}",
|
||||||
"gists_url": "https://api.github.com/users/kie-ci/gists{/gist_id}",
|
"gists_url": "https://api.github.com/users/gh-user/gists{/gist_id}",
|
||||||
"starred_url": "https://api.github.com/users/kie-ci/starred{/owner}{/repo}",
|
"starred_url": "https://api.github.com/users/gh-user/starred{/owner}{/repo}",
|
||||||
"subscriptions_url": "https://api.github.com/users/kie-ci/subscriptions",
|
"subscriptions_url": "https://api.github.com/users/gh-user/subscriptions",
|
||||||
"organizations_url": "https://api.github.com/users/kie-ci/orgs",
|
"organizations_url": "https://api.github.com/users/gh-user/orgs",
|
||||||
"repos_url": "https://api.github.com/users/kie-ci/repos",
|
"repos_url": "https://api.github.com/users/gh-user/repos",
|
||||||
"events_url": "https://api.github.com/users/kie-ci/events{/privacy}",
|
"events_url": "https://api.github.com/users/gh-user/events{/privacy}",
|
||||||
"received_events_url": "https://api.github.com/users/kie-ci/received_events",
|
"received_events_url": "https://api.github.com/users/gh-user/received_events",
|
||||||
"type": "User",
|
"type": "User",
|
||||||
"site_admin": false
|
"site_admin": false
|
||||||
},
|
},
|
||||||
|
@ -49,22 +47,42 @@ export const validPR = {
|
||||||
],
|
],
|
||||||
"requested_reviewers": [
|
"requested_reviewers": [
|
||||||
{
|
{
|
||||||
"login": "ghuser",
|
"login": "requested-gh-user",
|
||||||
"id": 1422582,
|
"id": 1422582,
|
||||||
"node_id": "MDQ6VXNlcjE0MjI1ODI=",
|
"node_id": "MDQ6VXNlcjE0MjI1ODI=",
|
||||||
"avatar_url": "https://avatars.githubusercontent.com/u/1422582?v=4",
|
"avatar_url": "https://avatars.githubusercontent.com/u/1422582?v=4",
|
||||||
"gravatar_id": "",
|
"gravatar_id": "",
|
||||||
"url": "https://api.github.com/users/ghuser",
|
"url": "https://api.github.com/users/requested-gh-user",
|
||||||
"html_url": "https://github.com/ghuser",
|
"html_url": "https://github.com/requested-gh-user",
|
||||||
"followers_url": "https://api.github.com/users/ghuser/followers",
|
"followers_url": "https://api.github.com/users/requested-gh-user/followers",
|
||||||
"following_url": "https://api.github.com/users/ghuser/following{/other_user}",
|
"following_url": "https://api.github.com/users/requested-gh-user/following{/other_user}",
|
||||||
"gists_url": "https://api.github.com/users/ghuser/gists{/gist_id}",
|
"gists_url": "https://api.github.com/users/requested-gh-user/gists{/gist_id}",
|
||||||
"starred_url": "https://api.github.com/users/ghuser/starred{/owner}{/repo}",
|
"starred_url": "https://api.github.com/users/requested-gh-user/starred{/owner}{/repo}",
|
||||||
"subscriptions_url": "https://api.github.com/users/ghuser/subscriptions",
|
"subscriptions_url": "https://api.github.com/users/requested-gh-user/subscriptions",
|
||||||
"organizations_url": "https://api.github.com/users/ghuser/orgs",
|
"organizations_url": "https://api.github.com/users/requested-gh-user/orgs",
|
||||||
"repos_url": "https://api.github.com/users/ghuser/repos",
|
"repos_url": "https://api.github.com/users/requested-gh-user/repos",
|
||||||
"events_url": "https://api.github.com/users/ghuser/events{/privacy}",
|
"events_url": "https://api.github.com/users/requested-gh-user/events{/privacy}",
|
||||||
"received_events_url": "https://api.github.com/users/ghuser/received_events",
|
"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",
|
"type": "User",
|
||||||
"site_admin": false
|
"site_admin": false
|
||||||
}
|
}
|
||||||
|
@ -109,7 +127,7 @@ export const validPR = {
|
||||||
"repo": {
|
"repo": {
|
||||||
"id": 1370858,
|
"id": 1370858,
|
||||||
"node_id": "MDEwOlJlcG9zaXRvcnkxMzcwODU4",
|
"node_id": "MDEwOlJlcG9zaXRvcnkxMzcwODU4",
|
||||||
"name": "optaplanner",
|
"name": "reponame",
|
||||||
"full_name": "fork/reponame",
|
"full_name": "fork/reponame",
|
||||||
"private": false,
|
"private": false,
|
||||||
"owner": {
|
"owner": {
|
||||||
|
@ -179,7 +197,7 @@ export const validPR = {
|
||||||
"ssh_url": "git@github.com:fork/reponame.git",
|
"ssh_url": "git@github.com:fork/reponame.git",
|
||||||
"clone_url": "https://github.com/fork/reponame.git",
|
"clone_url": "https://github.com/fork/reponame.git",
|
||||||
"svn_url": "https://github.com/fork/reponame",
|
"svn_url": "https://github.com/fork/reponame",
|
||||||
"homepage": "https://www.optaplanner.org",
|
"homepage": "https://www.reponame.org",
|
||||||
"size": 238339,
|
"size": 238339,
|
||||||
"stargazers_count": 2811,
|
"stargazers_count": 2811,
|
||||||
"watchers_count": 2811,
|
"watchers_count": 2811,
|
||||||
|
@ -261,7 +279,7 @@ export const validPR = {
|
||||||
"repo": {
|
"repo": {
|
||||||
"id": 1370858,
|
"id": 1370858,
|
||||||
"node_id": "MDEwOlJlcG9zaXRvcnkxMzcwODU4",
|
"node_id": "MDEwOlJlcG9zaXRvcnkxMzcwODU4",
|
||||||
"name": "optaplanner",
|
"name": "reponame",
|
||||||
"full_name": "owner/reponame",
|
"full_name": "owner/reponame",
|
||||||
"private": false,
|
"private": false,
|
||||||
"owner": {
|
"owner": {
|
||||||
|
@ -331,7 +349,7 @@ export const validPR = {
|
||||||
"ssh_url": "git@github.com:owner/reponame.git",
|
"ssh_url": "git@github.com:owner/reponame.git",
|
||||||
"clone_url": "https://github.com/owner/reponame.git",
|
"clone_url": "https://github.com/owner/reponame.git",
|
||||||
"svn_url": "https://github.com/owner/reponame",
|
"svn_url": "https://github.com/owner/reponame",
|
||||||
"homepage": "https://www.optaplanner.org",
|
"homepage": "https://www.reponame.org",
|
||||||
"size": 238339,
|
"size": 238339,
|
||||||
"stargazers_count": 2811,
|
"stargazers_count": 2811,
|
||||||
"watchers_count": 2811,
|
"watchers_count": 2811,
|
||||||
|
@ -420,22 +438,465 @@ export const validPR = {
|
||||||
"rebaseable": null,
|
"rebaseable": null,
|
||||||
"mergeable_state": "unknown",
|
"mergeable_state": "unknown",
|
||||||
"merged_by": {
|
"merged_by": {
|
||||||
"login": "radtriste",
|
"login": "that-s-a-user",
|
||||||
"id": 17157711,
|
"id": 17157711,
|
||||||
"node_id": "MDQ6VXNlcjE3MTU3NzEx",
|
"node_id": "MDQ6VXNlcjE3MTU3NzEx",
|
||||||
"avatar_url": "https://avatars.githubusercontent.com/u/17157711?v=4",
|
"avatar_url": "https://avatars.githubusercontent.com/u/17157711?v=4",
|
||||||
"gravatar_id": "",
|
"gravatar_id": "",
|
||||||
"url": "https://api.github.com/users/radtriste",
|
"url": "https://api.github.com/users/that-s-a-user",
|
||||||
"html_url": "https://github.com/radtriste",
|
"html_url": "https://github.com/that-s-a-user",
|
||||||
"followers_url": "https://api.github.com/users/radtriste/followers",
|
"followers_url": "https://api.github.com/users/that-s-a-user/followers",
|
||||||
"following_url": "https://api.github.com/users/radtriste/following{/other_user}",
|
"following_url": "https://api.github.com/users/that-s-a-user/following{/other_user}",
|
||||||
"gists_url": "https://api.github.com/users/radtriste/gists{/gist_id}",
|
"gists_url": "https://api.github.com/users/that-s-a-user/gists{/gist_id}",
|
||||||
"starred_url": "https://api.github.com/users/radtriste/starred{/owner}{/repo}",
|
"starred_url": "https://api.github.com/users/that-s-a-user/starred{/owner}{/repo}",
|
||||||
"subscriptions_url": "https://api.github.com/users/radtriste/subscriptions",
|
"subscriptions_url": "https://api.github.com/users/that-s-a-user/subscriptions",
|
||||||
"organizations_url": "https://api.github.com/users/radtriste/orgs",
|
"organizations_url": "https://api.github.com/users/that-s-a-user/orgs",
|
||||||
"repos_url": "https://api.github.com/users/radtriste/repos",
|
"repos_url": "https://api.github.com/users/that-s-a-user/repos",
|
||||||
"events_url": "https://api.github.com/users/radtriste/events{/privacy}",
|
"events_url": "https://api.github.com/users/that-s-a-user/events{/privacy}",
|
||||||
"received_events_url": "https://api.github.com/users/radtriste/received_events",
|
"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 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",
|
"type": "User",
|
||||||
"site_admin": false
|
"site_admin": false
|
||||||
},
|
},
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
import LoggerServiceFactory from "@gb/service/logger/logger-service-factory";
|
import LoggerServiceFactory from "@bp/service/logger/logger-service-factory";
|
||||||
import { Moctokit } from "@kie/mock-github";
|
import { Moctokit } from "@kie/mock-github";
|
||||||
import { targetOwner, repo, pullRequestNumber, validPR, invalidPullRequestNumber } from "./moctokit-data";
|
import { targetOwner, repo, mergedPullRequestFixture, notMergedPullRequestFixture, notFoundPullRequestNumber } from "./moctokit-data";
|
||||||
|
|
||||||
const logger = LoggerServiceFactory.getLogger();
|
const logger = LoggerServiceFactory.getLogger();
|
||||||
|
|
||||||
export const setupMoctokit = (): Moctokit => {
|
export const setupMoctokit = (): Moctokit => {
|
||||||
logger.debug("Setting up moctokit..");
|
logger.debug("Setting up moctokit.");
|
||||||
|
|
||||||
const mock = new Moctokit();
|
const mock = new Moctokit();
|
||||||
|
|
||||||
|
@ -16,18 +16,36 @@ export const setupMoctokit = (): Moctokit => {
|
||||||
.get({
|
.get({
|
||||||
owner: targetOwner,
|
owner: targetOwner,
|
||||||
repo: repo,
|
repo: repo,
|
||||||
pull_number: pullRequestNumber
|
pull_number: mergedPullRequestFixture.number
|
||||||
})
|
})
|
||||||
.reply({
|
.reply({
|
||||||
status: 200,
|
status: 200,
|
||||||
data: validPR
|
data: mergedPullRequestFixture
|
||||||
|
});
|
||||||
|
|
||||||
|
mock.rest.pulls
|
||||||
|
.get({
|
||||||
|
owner: targetOwner,
|
||||||
|
repo: repo,
|
||||||
|
pull_number: notMergedPullRequestFixture.number
|
||||||
|
})
|
||||||
|
.reply({
|
||||||
|
status: 200,
|
||||||
|
data: notMergedPullRequestFixture
|
||||||
});
|
});
|
||||||
|
|
||||||
mock.rest.pulls
|
mock.rest.pulls
|
||||||
.create()
|
.create()
|
||||||
.reply({
|
.reply({
|
||||||
status: 201,
|
status: 201,
|
||||||
data: validPR
|
data: mergedPullRequestFixture
|
||||||
|
});
|
||||||
|
|
||||||
|
mock.rest.pulls
|
||||||
|
.requestReviewers()
|
||||||
|
.reply({
|
||||||
|
status: 201,
|
||||||
|
data: mergedPullRequestFixture
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
@ -36,7 +54,7 @@ export const setupMoctokit = (): Moctokit => {
|
||||||
.get({
|
.get({
|
||||||
owner: targetOwner,
|
owner: targetOwner,
|
||||||
repo: repo,
|
repo: repo,
|
||||||
pull_number: invalidPullRequestNumber
|
pull_number: notFoundPullRequestNumber
|
||||||
})
|
})
|
||||||
.reply({
|
.reply({
|
||||||
status: 404,
|
status: 404,
|
||||||
|
|
17
test/support/utils.ts
Normal file
17
test/support/utils.ts
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
import * as core from "@actions/core";
|
||||||
|
|
||||||
|
export const addProcessArgs = (args: string[]) => {
|
||||||
|
process.argv = [...process.argv, ...args];
|
||||||
|
};
|
||||||
|
|
||||||
|
export const resetProcessArgs = () => {
|
||||||
|
process.argv = ["node", "backporting"];
|
||||||
|
};
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
export const spyGetInput = (obj: any) => {
|
||||||
|
const mock = jest.spyOn(core, "getInput");
|
||||||
|
mock.mockImplementation((name: string) : string => {
|
||||||
|
return obj[name];
|
||||||
|
});
|
||||||
|
};
|
|
@ -33,7 +33,7 @@
|
||||||
"baseUrl": "./",
|
"baseUrl": "./",
|
||||||
/* Specify the base directory to resolve non-relative module names. */
|
/* Specify the base directory to resolve non-relative module names. */
|
||||||
"paths": {
|
"paths": {
|
||||||
"@gb/*": [
|
"@bp/*": [
|
||||||
"./src/*"
|
"./src/*"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|
Loading…
Add table
Reference in a new issue