feat: integrate tool with gitlab service (#39)

* feat: integrate tool with gitlab service

Fix https://github.com/lampajr/backporting/issues/30
This commit is contained in:
Andrea Lamparelli 2023-07-02 00:05:17 +02:00 committed by GitHub
parent 8a007941d1
commit 107f5e52d6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
35 changed files with 17821 additions and 1553 deletions

View file

@ -1,12 +1,12 @@
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, openPullRequestFixture, notMergedPullRequestFixture, repo, targetOwner } from "../../../support/moctokit/moctokit-data";
import GitClientFactory from "@bp/service/git/git-client-factory";
import { GitClientType } from "@bp/service/git/git.types";
import { mockGitHubClient } from "../../../support/mock/git-client-mock-support";
import { mergedPullRequestFixture, openPullRequestFixture, notMergedPullRequestFixture, repo, targetOwner } from "../../../support/mock/github-data";
describe("pull request config parser", () => {
describe("github pull request config parser", () => {
const mergedPRUrl = `https://github.com/${targetOwner}/${repo}/pull/${mergedPullRequestFixture.number}`;
const openPRUrl = `https://github.com/${targetOwner}/${repo}/pull/${openPullRequestFixture.number}`;
@ -15,11 +15,12 @@ describe("pull request config parser", () => {
let parser: PullRequestConfigsParser;
beforeAll(() => {
GitServiceFactory.getOrCreate(GitServiceType.GITHUB, "whatever");
GitClientFactory.reset();
GitClientFactory.getOrCreate(GitClientType.GITHUB, "whatever", "http://localhost/api/v3");
});
beforeEach(() => {
setupMoctokit();
mockGitHubClient("http://localhost/api/v3");
parser = new PullRequestConfigsParser();
});
@ -124,30 +125,6 @@ describe("pull request config parser", () => {
});
});
test("override author", async () => {
const args: Args = {
dryRun: true,
auth: "whatever",
pullRequest: mergedPRUrl,
targetBranch: "prod",
gitUser: "GitHub",
gitEmail: "noreply@github.com",
reviewers: [],
assignees: [],
inheritReviewers: true,
};
const configs: Configs = await parser.parseAndValidate(args);
expect(configs.dryRun).toEqual(true);
expect(configs.auth).toEqual("whatever");
expect(configs.targetBranch).toEqual("prod");
expect(configs.git).toEqual({
user: "GitHub",
email: "noreply@github.com"
});
});
test("still open pull request", async () => {
const args: Args = {
dryRun: true,
@ -177,7 +154,7 @@ describe("pull request config parser", () => {
htmlUrl: "https://github.com/owner/reponame/pull/4444",
state: "open",
merged: false,
mergedBy: "that-s-a-user",
mergedBy: undefined,
title: "PR Title",
body: "Please review and merge",
reviewers: ["gh-user"],

View file

@ -0,0 +1,420 @@
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 GitClientFactory from "@bp/service/git/git-client-factory";
import { GitClientType } from "@bp/service/git/git.types";
import { getAxiosMocked } from "../../../support/mock/git-client-mock-support";
import { CLOSED_NOT_MERGED_MR, MERGED_SQUASHED_MR, OPEN_MR } from "../../../support/mock/gitlab-data";
jest.mock("axios", () => {
return {
create: jest.fn(() => ({
get: getAxiosMocked,
})),
};
});
describe("gitlab merge request config parser", () => {
const mergedPRUrl = `https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/${MERGED_SQUASHED_MR.iid}`;
const openPRUrl = `https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/${OPEN_MR.iid}`;
const notMergedPRUrl = `https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/${CLOSED_NOT_MERGED_MR.iid}`;
let parser: PullRequestConfigsParser;
beforeAll(() => {
GitClientFactory.reset();
GitClientFactory.getOrCreate(GitClientType.GITLAB, "whatever", "my.gitlab.host.com");
});
beforeEach(() => {
parser = new PullRequestConfigsParser();
});
afterEach(() => {
jest.clearAllMocks();
});
test("parse configs from merge request", async () => {
const args: Args = {
dryRun: false,
auth: "",
pullRequest: mergedPRUrl,
targetBranch: "prod",
gitUser: "GitLab",
gitEmail: "noreply@gitlab.com",
reviewers: [],
assignees: [],
inheritReviewers: true,
};
const configs: Configs = await parser.parseAndValidate(args);
expect(configs.dryRun).toEqual(false);
expect(configs.git).toEqual({
user: "GitLab",
email: "noreply@gitlab.com"
});
expect(configs.auth).toEqual("");
expect(configs.targetBranch).toEqual("prod");
expect(configs.folder).toEqual(process.cwd() + "/bp");
expect(configs.originalPullRequest).toEqual({
number: 1,
author: "superuser",
url: "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1",
htmlUrl: "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1",
state: "merged",
merged: true,
mergedBy: "superuser",
title: "Update test.txt",
body: "This is the body",
reviewers: ["superuser1", "superuser2"],
assignees: ["superuser"],
targetRepo: {
owner: "superuser",
project: "backporting-example",
cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
},
sourceRepo: {
owner: "superuser",
project: "backporting-example",
cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
},
nCommits: 1,
commits: ["ebb1eca696c42fd067658bd9b5267709f78ef38e"]
});
expect(configs.backportPullRequest).toEqual({
author: "GitLab",
url: undefined,
htmlUrl: undefined,
title: "[prod] Update test.txt",
body: "**Backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1\r\n\r\nThis is the body",
reviewers: ["superuser"],
assignees: [],
targetRepo: {
owner: "superuser",
project: "backporting-example",
cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
},
sourceRepo: {
owner: "superuser",
project: "backporting-example",
cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
},
bpBranchName: undefined,
});
});
test("override folder", async () => {
const args: Args = {
dryRun: true,
auth: "whatever",
pullRequest: mergedPRUrl,
targetBranch: "prod",
folder: "/tmp/test",
gitUser: "GitLab",
gitEmail: "noreply@gitlab.com",
reviewers: [],
assignees: [],
inheritReviewers: true,
};
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");
expect(configs.git).toEqual({
user: "GitLab",
email: "noreply@gitlab.com"
});
});
test("still open pull request", async () => {
const args: Args = {
dryRun: true,
auth: "whatever",
pullRequest: openPRUrl,
targetBranch: "prod",
gitUser: "GitLab",
gitEmail: "noreply@gitlab.com",
reviewers: [],
assignees: [],
inheritReviewers: true,
};
const configs: Configs = await parser.parseAndValidate(args);
expect(configs.dryRun).toEqual(true);
expect(configs.auth).toEqual("whatever");
expect(configs.targetBranch).toEqual("prod");
expect(configs.git).toEqual({
user: "GitLab",
email: "noreply@gitlab.com"
});
expect(configs.originalPullRequest).toEqual({
number: 2,
author: "superuser",
url: "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/2",
htmlUrl: "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/2",
state: "open",
merged: false,
mergedBy: undefined,
title: "Update test.txt opened",
body: "Still opened mr body",
reviewers: ["superuser"],
assignees: ["superuser"],
targetRepo: {
owner: "superuser",
project: "backporting-example",
cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
},
sourceRepo: {
owner: "superuser",
project: "backporting-example",
cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
},
bpBranchName: undefined,
nCommits: 1,
// taken from mr.sha
commits: ["9e15674ebd48e05c6e428a1fa31dbb60a778d644"]
});
});
test("closed pull request", async () => {
const args: Args = {
dryRun: true,
auth: "whatever",
pullRequest: notMergedPRUrl,
targetBranch: "prod",
gitUser: "GitLab",
gitEmail: "noreply@gitlab.com",
reviewers: [],
assignees: [],
inheritReviewers: true,
};
expect(async () => await parser.parseAndValidate(args)).rejects.toThrow("Provided pull request is closed and not merged!");
});
test("override backport pr data inherting reviewers", async () => {
const args: Args = {
dryRun: false,
auth: "",
pullRequest: mergedPRUrl,
targetBranch: "prod",
gitUser: "Me",
gitEmail: "me@email.com",
title: "New Title",
body: "New Body",
bodyPrefix: "New Body Prefix -",
reviewers: [],
assignees: [],
inheritReviewers: true,
};
const configs: Configs = await parser.parseAndValidate(args);
expect(configs.dryRun).toEqual(false);
expect(configs.git).toEqual({
user: "Me",
email: "me@email.com"
});
expect(configs.auth).toEqual("");
expect(configs.targetBranch).toEqual("prod");
expect(configs.folder).toEqual(process.cwd() + "/bp");
expect(configs.originalPullRequest).toEqual({
number: 1,
author: "superuser",
url: "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1",
htmlUrl: "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1",
state: "merged",
merged: true,
mergedBy: "superuser",
title: "Update test.txt",
body: "This is the body",
reviewers: ["superuser1", "superuser2"],
assignees: ["superuser"],
targetRepo: {
owner: "superuser",
project: "backporting-example",
cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
},
sourceRepo: {
owner: "superuser",
project: "backporting-example",
cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
},
nCommits: 1,
commits: ["ebb1eca696c42fd067658bd9b5267709f78ef38e"]
});
expect(configs.backportPullRequest).toEqual({
author: "Me",
url: undefined,
htmlUrl: undefined,
title: "New Title",
body: "New Body Prefix -New Body",
reviewers: ["superuser"],
assignees: [],
targetRepo: {
owner: "superuser",
project: "backporting-example",
cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
},
sourceRepo: {
owner: "superuser",
project: "backporting-example",
cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
},
bpBranchName: undefined,
});
});
test("override backport pr reviewers and assignees", async () => {
const args: Args = {
dryRun: false,
auth: "",
pullRequest: mergedPRUrl,
targetBranch: "prod",
gitUser: "Me",
gitEmail: "me@email.com",
title: "New Title",
body: "New Body",
bodyPrefix: "New Body Prefix -",
reviewers: ["user1", "user2"],
assignees: ["user3", "user4"],
inheritReviewers: true, // not taken into account
};
const configs: Configs = await parser.parseAndValidate(args);
expect(configs.dryRun).toEqual(false);
expect(configs.git).toEqual({
user: "Me",
email: "me@email.com"
});
expect(configs.auth).toEqual("");
expect(configs.targetBranch).toEqual("prod");
expect(configs.folder).toEqual(process.cwd() + "/bp");
expect(configs.originalPullRequest).toEqual({
number: 1,
author: "superuser",
url: "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1",
htmlUrl: "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1",
state: "merged",
merged: true,
mergedBy: "superuser",
title: "Update test.txt",
body: "This is the body",
reviewers: ["superuser1", "superuser2"],
assignees: ["superuser"],
targetRepo: {
owner: "superuser",
project: "backporting-example",
cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
},
sourceRepo: {
owner: "superuser",
project: "backporting-example",
cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
},
nCommits: 1,
commits: ["ebb1eca696c42fd067658bd9b5267709f78ef38e"]
});
expect(configs.backportPullRequest).toEqual({
author: "Me",
url: undefined,
htmlUrl: undefined,
title: "New Title",
body: "New Body Prefix -New Body",
reviewers: ["user1", "user2"],
assignees: ["user3", "user4"],
targetRepo: {
owner: "superuser",
project: "backporting-example",
cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
},
sourceRepo: {
owner: "superuser",
project: "backporting-example",
cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
},
bpBranchName: undefined,
});
});
test("override backport pr empty reviewers", async () => {
const args: Args = {
dryRun: false,
auth: "",
pullRequest: mergedPRUrl,
targetBranch: "prod",
gitUser: "Me",
gitEmail: "me@email.com",
title: "New Title",
body: "New Body",
bodyPrefix: "New Body Prefix -",
reviewers: [],
assignees: ["user3", "user4"],
inheritReviewers: false,
};
const configs: Configs = await parser.parseAndValidate(args);
expect(configs.dryRun).toEqual(false);
expect(configs.git).toEqual({
user: "Me",
email: "me@email.com"
});
expect(configs.auth).toEqual("");
expect(configs.targetBranch).toEqual("prod");
expect(configs.folder).toEqual(process.cwd() + "/bp");
expect(configs.originalPullRequest).toEqual({
number: 1,
author: "superuser",
url: "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1",
htmlUrl: "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1",
state: "merged",
merged: true,
mergedBy: "superuser",
title: "Update test.txt",
body: "This is the body",
reviewers: ["superuser1", "superuser2"],
assignees: ["superuser"],
targetRepo: {
owner: "superuser",
project: "backporting-example",
cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
},
sourceRepo: {
owner: "superuser",
project: "backporting-example",
cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
},
nCommits: 1,
commits: ["ebb1eca696c42fd067658bd9b5267709f78ef38e"]
});
expect(configs.backportPullRequest).toEqual({
author: "Me",
url: undefined,
htmlUrl: undefined,
title: "New Title",
body: "New Body Prefix -New Body",
reviewers: [],
assignees: ["user3", "user4"],
targetRepo: {
owner: "superuser",
project: "backporting-example",
cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
},
sourceRepo: {
owner: "superuser",
project: "backporting-example",
cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
},
bpBranchName: undefined,
});
});
});

View file

@ -0,0 +1,34 @@
import GitClientFactory from "@bp/service/git/git-client-factory";
import { GitClientType } from "@bp/service/git/git.types";
import GitHubClient from "@bp/service/git/github/github-client";
import GitLabClient from "@bp/service/git/gitlab/gitlab-client";
describe("git client factory test", () => {
beforeEach(() => {
// reset git service
GitClientFactory.reset();
});
test("correctly create github client", () => {
const client = GitClientFactory.getOrCreate(GitClientType.GITHUB, "auth", "apiurl");
expect(client).toBeInstanceOf(GitHubClient);
});
test("correctly create gitlab client", () => {
const client = GitClientFactory.getOrCreate(GitClientType.GITLAB, "auth", "apiurl");
expect(client).toBeInstanceOf(GitLabClient);
});
test("check get service github", () => {
const create = GitClientFactory.getOrCreate(GitClientType.GITHUB, "auth", "apiurl");
const get = GitClientFactory.getClient();
expect(create).toStrictEqual(get);
});
test("check get service gitlab", () => {
const create = GitClientFactory.getOrCreate(GitClientType.GITLAB, "auth", "apiurl");
const get = GitClientFactory.getClient();
expect(create).toStrictEqual(get);
});
});

View file

@ -0,0 +1,37 @@
import { inferGitApiUrl, inferGitClient } from "@bp/service/git/git-util";
import { GitClientType } from "@bp/service/git/git.types";
describe("check git utilities", () => {
test("check infer gitlab api", ()=> {
expect(inferGitApiUrl("https://my.gitlab.awesome.com/superuser/backporting-example/-/merge_requests/4")).toStrictEqual("https://my.gitlab.awesome.com/api/v4");
});
test("check infer gitlab api with different version", ()=> {
expect(inferGitApiUrl("http://my.gitlab.awesome.com/superuser/backporting-example/-/merge_requests/4", "v2")).toStrictEqual("http://my.gitlab.awesome.com/api/v2");
});
test("check infer github api", ()=> {
expect(inferGitApiUrl("https://github.com/superuser/backporting-example/pull/4")).toStrictEqual("https://api.github.com");
});
test("check infer custom github api", ()=> {
expect(inferGitApiUrl("http://github.acme-inc.com/superuser/backporting-example/pull/4")).toStrictEqual("http://github.acme-inc.com/api/v4");
});
test("check infer custom github api with different version", ()=> {
expect(inferGitApiUrl("http://github.acme-inc.com/superuser/backporting-example/pull/4", "v3")).toStrictEqual("http://github.acme-inc.com/api/v3");
});
test("check infer github client", ()=> {
expect(inferGitClient("https://github.com/superuser/backporting-example/-/merge_requests/4")).toStrictEqual(GitClientType.GITHUB);
});
test("check infer gitlab client", ()=> {
expect(inferGitClient("https://my.gitlab.awesome.com/superuser/backporting-example/-/merge_requests/4")).toStrictEqual(GitClientType.GITLAB);
});
test("Not recognized git client type", ()=> {
expect(() => inferGitClient("https://not.recognized/superuser/backporting-example/-/merge_requests/4")).toThrowError("Remote git service not recognized from pr url: https://not.recognized/superuser/backporting-example/-/merge_requests/4");
});
});

View file

@ -1,27 +1,28 @@
import GitServiceFactory from "@bp/service/git/git-service-factory";
import { GitPullRequest, GitServiceType } from "@bp/service/git/git.types";
import GitHubService from "@bp/service/git/github/github-service";
import { mergedPullRequestFixture, repo, targetOwner } from "../../../support/moctokit/moctokit-data";
import { setupMoctokit } from "../../../support/moctokit/moctokit-support";
import GitClientFactory from "@bp/service/git/git-client-factory";
import { GitPullRequest, GitClientType } from "@bp/service/git/git.types";
import GitHubClient from "@bp/service/git/github/github-client";
import { mergedPullRequestFixture, repo, targetOwner } from "../../../support/mock/github-data";
import { mockGitHubClient } from "../../../support/mock/git-client-mock-support";
describe("github service", () => {
let gitService: GitHubService;
let gitClient: GitHubClient;
beforeAll(() => {
// init git service
GitServiceFactory.getOrCreate(GitServiceType.GITHUB, "whatever");
GitClientFactory.reset();
GitClientFactory.getOrCreate(GitClientType.GITHUB, "whatever", "http://localhost/api/v3");
});
beforeEach(() => {
// mock github api calls
setupMoctokit();
mockGitHubClient("http://localhost/api/v3");
gitService = GitServiceFactory.getService() as GitHubService;
gitClient = GitClientFactory.getClient() as GitHubClient;
});
test("get pull request: success", async () => {
const res: GitPullRequest = await gitService.getPullRequest(targetOwner, repo, mergedPullRequestFixture.number);
const res: GitPullRequest = await gitClient.getPullRequest(targetOwner, repo, mergedPullRequestFixture.number);
expect(res.sourceRepo).toEqual({
owner: "fork",
project: "reponame",

View file

@ -0,0 +1,249 @@
import GitClientFactory from "@bp/service/git/git-client-factory";
import { NEW_GITLAB_MR_ID, SECOND_NEW_GITLAB_MR_ID, getAxiosMocked, postAxiosMocked, putAxiosMocked } from "../../../support/mock/git-client-mock-support";
import { BackportPullRequest, GitClientType, GitPullRequest } from "@bp/service/git/git.types";
import GitLabClient from "@bp/service/git/gitlab/gitlab-client";
import axios from "axios";
jest.mock("axios");
const axiosSpy = axios.create as jest.Mock;
let axiosInstanceSpy: {[key: string]: jest.Func};
function setupAxiosSpy() {
const getSpy = jest.fn(getAxiosMocked);
const postSpy = jest.fn(postAxiosMocked);
const putSpy = jest.fn(putAxiosMocked);
const axiosInstance = {
get: getSpy,
post: postSpy,
put: putSpy,
};
axiosSpy.mockImplementation(() => (axiosInstance));
return axiosInstance;
}
describe("github service", () => {
let gitClient: GitLabClient;
beforeEach(() => {
axiosInstanceSpy = setupAxiosSpy();
GitClientFactory.reset();
gitClient = GitClientFactory.getOrCreate(GitClientType.GITLAB, "whatever", "apiUrl") as GitLabClient;
});
afterEach(() => {
jest.clearAllMocks();
});
test("get merged pull request", async () => {
const res: GitPullRequest = await gitClient.getPullRequest("superuser", "backporting-example", 1);
// check content
expect(res.sourceRepo).toEqual({
owner: "superuser",
project: "backporting-example",
cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
});
expect(res.targetRepo).toEqual({
owner: "superuser",
project: "backporting-example",
cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
});
expect(res.title).toBe("Update test.txt");
expect(res.commits!.length).toBe(1);
expect(res.commits).toEqual(["ebb1eca696c42fd067658bd9b5267709f78ef38e"]);
// check axios invocation
expect(axiosInstanceSpy.get).toBeCalledTimes(3); // merge request and 2 repos
expect(axiosInstanceSpy.get).toBeCalledWith("/projects/superuser%2Fbackporting-example/merge_requests/1");
expect(axiosInstanceSpy.get).toBeCalledWith("/projects/76316");
expect(axiosInstanceSpy.get).toBeCalledWith("/projects/76316");
});
test("get open pull request", async () => {
const res: GitPullRequest = await gitClient.getPullRequest("superuser", "backporting-example", 2);
expect(res.sourceRepo).toEqual({
owner: "superuser",
project: "backporting-example",
cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
});
expect(res.targetRepo).toEqual({
owner: "superuser",
project: "backporting-example",
cloneUrl: "https://my.gitlab.host.com/superuser/backporting-example.git"
});
expect(res.title).toBe("Update test.txt opened");
expect(res.commits!.length).toBe(1);
expect(res.commits).toEqual(["9e15674ebd48e05c6e428a1fa31dbb60a778d644"]);
// check axios invocation
expect(axiosInstanceSpy.get).toBeCalledTimes(3); // merge request and 2 repos
expect(axiosInstanceSpy.get).toBeCalledWith("/projects/superuser%2Fbackporting-example/merge_requests/2");
expect(axiosInstanceSpy.get).toBeCalledWith("/projects/76316");
expect(axiosInstanceSpy.get).toBeCalledWith("/projects/76316");
});
test("create backport pull request without reviewers and assignees", async () => {
const backport: BackportPullRequest = {
title: "Backport Title",
body: "Backport Body",
owner: "superuser",
repo: "backporting-example",
base: "old/branch",
head: "bp-branch",
reviewers: [],
assignees: [],
};
const url: string = await gitClient.createPullRequest(backport);
expect(url).toStrictEqual("https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/" + NEW_GITLAB_MR_ID);
// check axios invocation
expect(axiosInstanceSpy.post).toBeCalledTimes(1);
expect(axiosInstanceSpy.post).toBeCalledWith("/projects/superuser%2Fbackporting-example/merge_requests", expect.objectContaining({
source_branch: "bp-branch",
target_branch: "old/branch",
title: "Backport Title",
description: "Backport Body",
reviewer_ids: [],
assignee_ids: [],
}));
expect(axiosInstanceSpy.get).toBeCalledTimes(0); // no reviewers nor assignees
expect(axiosInstanceSpy.put).toBeCalledTimes(0); // no reviewers nor assignees
});
test("create backport pull request with reviewers", async () => {
const backport: BackportPullRequest = {
title: "Backport Title",
body: "Backport Body",
owner: "superuser",
repo: "backporting-example",
base: "old/branch",
head: "bp-branch",
reviewers: ["superuser", "invalid"],
assignees: [],
};
const url: string = await gitClient.createPullRequest(backport);
expect(url).toStrictEqual("https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/" + NEW_GITLAB_MR_ID);
// check axios invocation
expect(axiosInstanceSpy.post).toBeCalledTimes(1);
expect(axiosInstanceSpy.post).toBeCalledWith("/projects/superuser%2Fbackporting-example/merge_requests", expect.objectContaining({
source_branch: "bp-branch",
target_branch: "old/branch",
title: "Backport Title",
description: "Backport Body",
reviewer_ids: [],
assignee_ids: [],
}));
expect(axiosInstanceSpy.get).toBeCalledTimes(2); // just reviewers, one invalid
expect(axiosInstanceSpy.get).toBeCalledWith("/users?username=superuser");
expect(axiosInstanceSpy.get).toBeCalledWith("/users?username=invalid");
expect(axiosInstanceSpy.put).toBeCalledTimes(1); // just reviewers
expect(axiosInstanceSpy.put).toBeCalledWith("/projects/superuser%2Fbackporting-example/merge_requests/" + NEW_GITLAB_MR_ID, {
reviewer_ids: [14041],
});
});
test("create backport pull request with assignees", async () => {
const backport: BackportPullRequest = {
title: "Backport Title",
body: "Backport Body",
owner: "superuser",
repo: "backporting-example",
base: "old/branch",
head: "bp-branch",
reviewers: [],
assignees: ["superuser", "invalid"],
};
const url: string = await gitClient.createPullRequest(backport);
expect(url).toStrictEqual("https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/" + NEW_GITLAB_MR_ID);
// check axios invocation
expect(axiosInstanceSpy.post).toBeCalledTimes(1);
expect(axiosInstanceSpy.post).toBeCalledWith("/projects/superuser%2Fbackporting-example/merge_requests", expect.objectContaining({
source_branch: "bp-branch",
target_branch: "old/branch",
title: "Backport Title",
description: "Backport Body",
reviewer_ids: [],
assignee_ids: [],
}));
expect(axiosInstanceSpy.get).toBeCalledTimes(2); // just assignees, one invalid
expect(axiosInstanceSpy.get).toBeCalledWith("/users?username=superuser");
expect(axiosInstanceSpy.get).toBeCalledWith("/users?username=invalid");
expect(axiosInstanceSpy.put).toBeCalledTimes(1); // just assignees
expect(axiosInstanceSpy.put).toBeCalledWith("/projects/superuser%2Fbackporting-example/merge_requests/" + NEW_GITLAB_MR_ID, {
assignee_ids: [14041],
});
});
test("create backport pull request with failure assigning reviewers", async () => {
const backport: BackportPullRequest = {
title: "Backport Title",
body: "Backport Body",
owner: "superuser",
repo: "backporting-example",
base: "old/branch",
head: "bp-branch-2",
reviewers: ["superuser", "invalid"],
assignees: [],
};
const url: string = await gitClient.createPullRequest(backport);
expect(url).toStrictEqual("https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/" + SECOND_NEW_GITLAB_MR_ID);
// check axios invocation
expect(axiosInstanceSpy.post).toBeCalledTimes(1);
expect(axiosInstanceSpy.post).toBeCalledWith("/projects/superuser%2Fbackporting-example/merge_requests", expect.objectContaining({
source_branch: "bp-branch-2",
target_branch: "old/branch",
title: "Backport Title",
description: "Backport Body",
reviewer_ids: [],
assignee_ids: [],
}));
expect(axiosInstanceSpy.get).toBeCalledTimes(2); // just reviewers, one invalid
expect(axiosInstanceSpy.get).toBeCalledWith("/users?username=superuser");
expect(axiosInstanceSpy.get).toBeCalledWith("/users?username=invalid");
expect(axiosInstanceSpy.put).toBeCalledTimes(1); // just reviewers
expect(axiosInstanceSpy.put).toBeCalledWith("/projects/superuser%2Fbackporting-example/merge_requests/" + SECOND_NEW_GITLAB_MR_ID, {
reviewer_ids: [14041],
});
});
test("create backport pull request with failure assigning assignees", async () => {
const backport: BackportPullRequest = {
title: "Backport Title",
body: "Backport Body",
owner: "superuser",
repo: "backporting-example",
base: "old/branch",
head: "bp-branch-2",
reviewers: [],
assignees: ["superuser", "invalid"],
};
const url: string = await gitClient.createPullRequest(backport);
expect(url).toStrictEqual("https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/" + SECOND_NEW_GITLAB_MR_ID);
// check axios invocation
expect(axiosInstanceSpy.post).toBeCalledTimes(1);
expect(axiosInstanceSpy.post).toBeCalledWith("/projects/superuser%2Fbackporting-example/merge_requests", expect.objectContaining({
source_branch: "bp-branch-2",
target_branch: "old/branch",
title: "Backport Title",
description: "Backport Body",
reviewer_ids: [],
assignee_ids: [],
}));
expect(axiosInstanceSpy.get).toBeCalledTimes(2); // just assignees, one invalid
expect(axiosInstanceSpy.get).toBeCalledWith("/users?username=superuser");
expect(axiosInstanceSpy.get).toBeCalledWith("/users?username=invalid");
expect(axiosInstanceSpy.put).toBeCalledTimes(1); // just assignees
expect(axiosInstanceSpy.put).toBeCalledWith("/projects/superuser%2Fbackporting-example/merge_requests/" + SECOND_NEW_GITLAB_MR_ID, {
assignee_ids: [14041],
});
});
});

View file

@ -1,19 +1,19 @@
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 GitHubClient from "@bp/service/git/github/github-client";
import CLIArgsParser from "@bp/service/args/cli/cli-args-parser";
import { addProcessArgs, resetProcessArgs } from "../../support/utils";
import { setupMoctokit } from "../../support/moctokit/moctokit-support";
import { mockGitHubClient } from "../../support/mock/git-client-mock-support";
jest.mock("@bp/service/git/git-cli");
jest.spyOn(GitHubService.prototype, "createPullRequest");
jest.spyOn(GitHubClient.prototype, "createPullRequest");
let parser: ArgsParser;
let runner: Runner;
beforeEach(() => {
setupMoctokit();
mockGitHubClient();
// create CLI arguments parser
parser = new CLIArgsParser();
@ -30,6 +30,7 @@ afterEach(() => {
});
describe("cli runner", () => {
test("with dry run", async () => {
addProcessArgs([
"-d",
@ -56,7 +57,7 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
expect(GitCLIService.prototype.push).toBeCalledTimes(0);
expect(GitHubService.prototype.createPullRequest).toBeCalledTimes(0);
expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(0);
});
test("overriding author", async () => {
@ -85,7 +86,7 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
expect(GitCLIService.prototype.push).toBeCalledTimes(0);
expect(GitHubService.prototype.createPullRequest).toBeCalledTimes(0);
expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(0);
});
test("with relative folder", async () => {
@ -119,7 +120,7 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.addRemote).toBeCalledTimes(0);
expect(GitCLIService.prototype.push).toBeCalledTimes(0);
expect(GitHubService.prototype.createPullRequest).toBeCalledTimes(0);
expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(0);
});
test("with absolute folder", async () => {
@ -150,7 +151,7 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
expect(GitCLIService.prototype.push).toBeCalledTimes(0);
expect(GitHubService.prototype.createPullRequest).toBeCalledTimes(0);
expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(0);
});
test("without dry run", async () => {
@ -180,8 +181,8 @@ describe("cli runner", () => {
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({
expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
owner: "owner",
repo: "reponame",
head: "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc",
@ -220,8 +221,8 @@ describe("cli runner", () => {
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({
expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
owner: "owner",
repo: "reponame",
head: "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc",
@ -272,15 +273,15 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-91748965051fae1330ad58d15cf694e103267c87");
expect(GitHubService.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitHubService.prototype.createPullRequest).toBeCalledWith({
expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
owner: "owner",
repo: "reponame",
head: "bp-target-91748965051fae1330ad58d15cf694e103267c87",
base: "target",
title: "[target] PR Title",
body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/4444"),
reviewers: ["gh-user", "that-s-a-user"],
reviewers: ["gh-user"],
assignees: [],
}
);
@ -325,8 +326,8 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp_branch_name");
expect(GitHubService.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitHubService.prototype.createPullRequest).toBeCalledWith({
expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
owner: "owner",
repo: "reponame",
head: "bp_branch_name",
@ -377,8 +378,8 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp_branch_name");
expect(GitHubService.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitHubService.prototype.createPullRequest).toBeCalledWith({
expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
owner: "owner",
repo: "reponame",
head: "bp_branch_name",

View file

@ -0,0 +1,309 @@
import ArgsParser from "@bp/service/args/args-parser";
import Runner from "@bp/service/runner/runner";
import GitCLIService from "@bp/service/git/git-cli";
import GitLabClient from "@bp/service/git/gitlab/gitlab-client";
import CLIArgsParser from "@bp/service/args/cli/cli-args-parser";
import { addProcessArgs, resetProcessArgs } from "../../support/utils";
import { getAxiosMocked } from "../../support/mock/git-client-mock-support";
jest.mock("axios", () => {
return {
create: () => ({
get: getAxiosMocked,
post: () => ({
data: {
iid: 1, // FIXME: I am not testing this atm
}
}),
put: jest.fn(),
}),
};
});
jest.mock("@bp/service/git/git-cli");
jest.spyOn(GitLabClient.prototype, "createPullRequest");
let parser: ArgsParser;
let runner: Runner;
beforeEach(() => {
// create CLI arguments parser
parser = new CLIArgsParser();
// create runner
runner = new Runner(parser);
});
afterEach(() => {
jest.clearAllMocks();
// reset process.env variables
resetProcessArgs();
});
describe("cli runner", () => {
test("with dry run", async () => {
addProcessArgs([
"-d",
"-tb",
"target",
"-pr",
"https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/2"
]);
await runner.execute();
const cwd = process.cwd() + "/bp";
expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-9e15674ebd48e05c6e428a1fa31dbb60a778d644");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(1);
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "merge-requests/2/head:pr/2");
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "9e15674ebd48e05c6e428a1fa31dbb60a778d644");
expect(GitCLIService.prototype.push).toBeCalledTimes(0);
expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(0);
});
test("dry run with relative folder", async () => {
addProcessArgs([
"-d",
"-tb",
"target",
"-pr",
"https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/2",
"-f",
"folder"
]);
await runner.execute();
const cwd = process.cwd() + "/folder";
expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-9e15674ebd48e05c6e428a1fa31dbb60a778d644");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(1);
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "merge-requests/2/head:pr/2");
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "9e15674ebd48e05c6e428a1fa31dbb60a778d644");
expect(GitCLIService.prototype.addRemote).toBeCalledTimes(0);
expect(GitCLIService.prototype.addRemote).toBeCalledTimes(0);
expect(GitCLIService.prototype.push).toBeCalledTimes(0);
expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(0);
});
test("without dry run", async () => {
addProcessArgs([
"-tb",
"target",
"-pr",
"https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/2"
]);
await runner.execute();
const cwd = process.cwd() + "/bp";
expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-9e15674ebd48e05c6e428a1fa31dbb60a778d644");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(1);
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "merge-requests/2/head:pr/2");
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "9e15674ebd48e05c6e428a1fa31dbb60a778d644");
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-9e15674ebd48e05c6e428a1fa31dbb60a778d644");
expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitLabClient.prototype.createPullRequest).toBeCalledWith({
owner: "superuser",
repo: "backporting-example",
head: "bp-target-9e15674ebd48e05c6e428a1fa31dbb60a778d644",
base: "target",
title: "[target] Update test.txt opened",
body: expect.stringContaining("**Backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/2"),
reviewers: ["superuser"],
assignees: [],
}
);
});
test("closed and not merged pull request", async () => {
addProcessArgs([
"-tb",
"target",
"-pr",
"https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/3"
]);
expect(async () => await runner.execute()).rejects.toThrow("Provided pull request is closed and not merged!");
});
test("merged pull request", async () => {
addProcessArgs([
"-tb",
"target",
"-pr",
"https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1"
]);
await runner.execute();
const cwd = process.cwd() + "/bp";
expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-ebb1eca696c42fd067658bd9b5267709f78ef38e");
// 0 occurrences as the mr is already merged and the owner is the same for
// both source and target repositories
expect(GitCLIService.prototype.fetch).toBeCalledTimes(0);
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "ebb1eca696c42fd067658bd9b5267709f78ef38e");
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-ebb1eca696c42fd067658bd9b5267709f78ef38e");
expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitLabClient.prototype.createPullRequest).toBeCalledWith({
owner: "superuser",
repo: "backporting-example",
head: "bp-target-ebb1eca696c42fd067658bd9b5267709f78ef38e",
base: "target",
title: "[target] Update test.txt",
body: expect.stringContaining("**Backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1"),
reviewers: ["superuser"],
assignees: [],
}
);
});
test("override backporting pr data", async () => {
addProcessArgs([
"-tb",
"target",
"-pr",
"https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/2",
"--title",
"New Title",
"--body",
"New Body",
"--body-prefix",
"New Body Prefix - ",
"--bp-branch-name",
"bp_branch_name",
"--reviewers",
"user1,user2",
"--assignees",
"user3,user4"
]);
await runner.execute();
const cwd = process.cwd() + "/bp";
expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp_branch_name");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(1);
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "merge-requests/2/head:pr/2");
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "9e15674ebd48e05c6e428a1fa31dbb60a778d644");
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp_branch_name");
expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitLabClient.prototype.createPullRequest).toBeCalledWith({
owner: "superuser",
repo: "backporting-example",
head: "bp_branch_name",
base: "target",
title: "New Title",
body: "New Body Prefix - New Body",
reviewers: ["user1", "user2"],
assignees: ["user3", "user4"],
}
);
});
test("set empty reviewers", async () => {
addProcessArgs([
"-tb",
"target",
"-pr",
"https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/2",
"--title",
"New Title",
"--body",
"New Body",
"--body-prefix",
"New Body Prefix - ",
"--bp-branch-name",
"bp_branch_name",
"--no-inherit-reviewers",
"--assignees",
"user3,user4",
]);
await runner.execute();
const cwd = process.cwd() + "/bp";
expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp_branch_name");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(1);
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "merge-requests/2/head:pr/2");
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "9e15674ebd48e05c6e428a1fa31dbb60a778d644");
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp_branch_name");
expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitLabClient.prototype.createPullRequest).toBeCalledWith({
owner: "superuser",
repo: "backporting-example",
head: "bp_branch_name",
base: "target",
title: "New Title",
body: "New Body Prefix - New Body",
reviewers: [],
assignees: ["user3", "user4"],
}
);
});
});

View file

@ -1,19 +1,19 @@
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 GitHubClient from "@bp/service/git/github/github-client";
import GHAArgsParser from "@bp/service/args/gha/gha-args-parser";
import { spyGetInput } from "../../support/utils";
import { setupMoctokit } from "../../support/moctokit/moctokit-support";
import { mockGitHubClient } from "../../support/mock/git-client-mock-support";
jest.mock("@bp/service/git/git-cli");
jest.spyOn(GitHubService.prototype, "createPullRequest");
jest.spyOn(GitHubClient.prototype, "createPullRequest");
let parser: ArgsParser;
let runner: Runner;
beforeEach(() => {
setupMoctokit();
mockGitHubClient();
// create GHA arguments parser
parser = new GHAArgsParser();
@ -51,7 +51,7 @@ describe("gha runner", () => {
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc");
expect(GitCLIService.prototype.push).toBeCalledTimes(0);
expect(GitHubService.prototype.createPullRequest).toBeCalledTimes(0);
expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(0);
});
test("without dry run", async () => {
@ -79,8 +79,8 @@ describe("gha runner", () => {
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({
expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
owner: "owner",
repo: "reponame",
head: "bp-target-28f63db774185f4ec4b57cd9aaeb12dbfb4c9ecc",
@ -127,15 +127,15 @@ describe("gha runner", () => {
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-91748965051fae1330ad58d15cf694e103267c87");
expect(GitHubService.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitHubService.prototype.createPullRequest).toBeCalledWith({
expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
owner: "owner",
repo: "reponame",
head: "bp-target-91748965051fae1330ad58d15cf694e103267c87",
base: "target",
title: "[target] PR Title",
body: expect.stringContaining("**Backport:** https://github.com/owner/reponame/pull/4444"),
reviewers: ["gh-user", "that-s-a-user"],
reviewers: ["gh-user"],
assignees: [],
}
);
@ -172,8 +172,8 @@ describe("gha runner", () => {
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp_branch_name");
expect(GitHubService.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitHubService.prototype.createPullRequest).toBeCalledWith({
expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
owner: "owner",
repo: "reponame",
head: "bp_branch_name",
@ -218,8 +218,8 @@ describe("gha runner", () => {
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp_branch_name");
expect(GitHubService.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitHubService.prototype.createPullRequest).toBeCalledWith({
expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
owner: "owner",
repo: "reponame",
head: "bp_branch_name",

View file

@ -0,0 +1,245 @@
import ArgsParser from "@bp/service/args/args-parser";
import Runner from "@bp/service/runner/runner";
import GitCLIService from "@bp/service/git/git-cli";
import GitLabClient from "@bp/service/git/gitlab/gitlab-client";
import GHAArgsParser from "@bp/service/args/gha/gha-args-parser";
import { spyGetInput } from "../../support/utils";
import { getAxiosMocked } from "../../support/mock/git-client-mock-support";
jest.mock("axios", () => {
return {
create: () => ({
get: getAxiosMocked,
post: () => ({
data: {
iid: 1, // FIXME: I am not testing this atm
}
}),
put: jest.fn(),
}),
};
});
jest.mock("@bp/service/git/git-cli");
jest.spyOn(GitLabClient.prototype, "createPullRequest");
let parser: ArgsParser;
let runner: Runner;
beforeEach(() => {
// create GHA arguments parser
parser = new GHAArgsParser();
// create runner
runner = new Runner(parser);
});
afterEach(() => {
jest.clearAllMocks();
});
describe("gha runner", () => {
test("with dry run", async () => {
spyGetInput({
"dry-run": "true",
"target-branch": "target",
"pull-request": "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/2"
});
await runner.execute();
const cwd = process.cwd() + "/bp";
expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-9e15674ebd48e05c6e428a1fa31dbb60a778d644");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(1);
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "merge-requests/2/head:pr/2");
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "9e15674ebd48e05c6e428a1fa31dbb60a778d644");
expect(GitCLIService.prototype.push).toBeCalledTimes(0);
expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(0);
});
test("without dry run", async () => {
spyGetInput({
"target-branch": "target",
"pull-request": "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/2"
});
await runner.execute();
const cwd = process.cwd() + "/bp";
expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-9e15674ebd48e05c6e428a1fa31dbb60a778d644");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(1);
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "merge-requests/2/head:pr/2");
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "9e15674ebd48e05c6e428a1fa31dbb60a778d644");
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-9e15674ebd48e05c6e428a1fa31dbb60a778d644");
expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitLabClient.prototype.createPullRequest).toBeCalledWith({
owner: "superuser",
repo: "backporting-example",
head: "bp-target-9e15674ebd48e05c6e428a1fa31dbb60a778d644",
base: "target",
title: "[target] Update test.txt opened",
body: expect.stringContaining("**Backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/2"),
reviewers: ["superuser"],
assignees: [],
}
);
});
test("closed and not merged pull request", async () => {
spyGetInput({
"target-branch": "target",
"pull-request": "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/3"
});
expect(async () => await runner.execute()).rejects.toThrow("Provided pull request is closed and not merged!");
});
test("merged pull request", async () => {
spyGetInput({
"target-branch": "target",
"pull-request": "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1"
});
await runner.execute();
const cwd = process.cwd() + "/bp";
expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-ebb1eca696c42fd067658bd9b5267709f78ef38e");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(0);
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "ebb1eca696c42fd067658bd9b5267709f78ef38e");
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-ebb1eca696c42fd067658bd9b5267709f78ef38e");
expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitLabClient.prototype.createPullRequest).toBeCalledWith({
owner: "superuser",
repo: "backporting-example",
head: "bp-target-ebb1eca696c42fd067658bd9b5267709f78ef38e",
base: "target",
title: "[target] Update test.txt",
body: expect.stringContaining("**Backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1"),
reviewers: ["superuser"],
assignees: [],
}
);
});
test("override backporting pr data", async () => {
spyGetInput({
"target-branch": "target",
"pull-request": "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/2",
"title": "New Title",
"body": "New Body",
"body-prefix": "New Body Prefix - ",
"bp-branch-name": "bp_branch_name",
"reviewers": "user1, user2",
"assignees": "user3, user4",
});
await runner.execute();
const cwd = process.cwd() + "/bp";
expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp_branch_name");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(1);
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "merge-requests/2/head:pr/2");
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "9e15674ebd48e05c6e428a1fa31dbb60a778d644");
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp_branch_name");
expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitLabClient.prototype.createPullRequest).toBeCalledWith({
owner: "superuser",
repo: "backporting-example",
head: "bp_branch_name",
base: "target",
title: "New Title",
body: "New Body Prefix - New Body",
reviewers: ["user1", "user2"],
assignees: ["user3", "user4"],
}
);
});
test("set empty reviewers", async () => {
spyGetInput({
"target-branch": "target",
"pull-request": "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/2",
"title": "New Title",
"body": "New Body",
"body-prefix": "New Body Prefix - ",
"bp-branch-name": "bp_branch_name",
"reviewers": "",
"assignees": "user3, user4",
"no-inherit-reviewers": "true",
});
await runner.execute();
const cwd = process.cwd() + "/bp";
expect(GitCLIService.prototype.clone).toBeCalledTimes(1);
expect(GitCLIService.prototype.clone).toBeCalledWith("https://my.gitlab.host.com/superuser/backporting-example.git", cwd, "target");
expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp_branch_name");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(1);
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "merge-requests/2/head:pr/2");
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "9e15674ebd48e05c6e428a1fa31dbb60a778d644");
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp_branch_name");
expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitLabClient.prototype.createPullRequest).toBeCalledWith({
owner: "superuser",
repo: "backporting-example",
head: "bp_branch_name",
base: "target",
title: "New Title",
body: "New Body Prefix - New Body",
reviewers: [],
assignees: ["user3", "user4"],
}
);
});
});

View file

@ -0,0 +1,168 @@
import LoggerServiceFactory from "@bp/service/logger/logger-service-factory";
import { Moctokit } from "@kie/mock-github";
import { targetOwner, repo, mergedPullRequestFixture, openPullRequestFixture, notMergedPullRequestFixture, notFoundPullRequestNumber, sameOwnerPullRequestFixture } from "./github-data";
import { CLOSED_NOT_MERGED_MR, MERGED_SQUASHED_MR, OPEN_MR, PROJECT_EXAMPLE, SUPERUSER} from "./gitlab-data";
const logger = LoggerServiceFactory.getLogger();
// AXIOS
export const getAxiosMocked = (url: string) => {
let data = undefined;
// gitlab
if (url.endsWith("merge_requests/1")) {
data = MERGED_SQUASHED_MR;
} else if (url.endsWith("merge_requests/2")) {
data = OPEN_MR;
} else if (url.endsWith("merge_requests/3")) {
data = CLOSED_NOT_MERGED_MR;
} else if (url.endsWith("projects/76316")) {
data = PROJECT_EXAMPLE;
} else if (url.endsWith("users?username=superuser")) {
data = [SUPERUSER];
}
return {
data,
status: data ? 200 : 404,
};
};
export const NEW_GITLAB_MR_ID = 999;
export const SECOND_NEW_GITLAB_MR_ID = 1000;
export const postAxiosMocked = (_url: string, data?: {source_branch: string,}) => {
let responseData = undefined;
// gitlab
if (data?.source_branch === "bp-branch") {
responseData = {
// we do not need the whole response
iid: NEW_GITLAB_MR_ID,
web_url: "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/" + NEW_GITLAB_MR_ID
};
} if (data?.source_branch === "bp-branch-2") {
responseData = {
// we do not need the whole response
iid: SECOND_NEW_GITLAB_MR_ID,
web_url: "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/" + SECOND_NEW_GITLAB_MR_ID
};
}
return {
data: responseData,
status: responseData ? 200 : 404,
};
};
export const putAxiosMocked = (url: string, _data?: unknown) => {
const responseData = undefined;
// gitlab
if (url.endsWith(`merge_requests/${NEW_GITLAB_MR_ID}`)) {
return {
data: {
iid: NEW_GITLAB_MR_ID,
},
status: responseData ? 200 : 404,
};
}
throw new Error("Error updating merge request: " + url);
};
// GITHUB - OCTOKIT
export const mockGitHubClient = (apiUrl = "https://api.github.com"): Moctokit => {
logger.debug("Setting up moctokit.");
const mock = new Moctokit(apiUrl);
// setup the mock requests here
// valid requests
mock.rest.pulls
.get({
owner: targetOwner,
repo: repo,
pull_number: mergedPullRequestFixture.number
})
.reply({
status: 200,
data: mergedPullRequestFixture
});
mock.rest.pulls
.get({
owner: targetOwner,
repo: repo,
pull_number: sameOwnerPullRequestFixture.number
})
.reply({
status: 200,
data: sameOwnerPullRequestFixture
});
mock.rest.pulls
.get({
owner: targetOwner,
repo: repo,
pull_number: openPullRequestFixture.number
})
.reply({
status: 200,
data: openPullRequestFixture
});
mock.rest.pulls
.get({
owner: targetOwner,
repo: repo,
pull_number: notMergedPullRequestFixture.number
})
.reply({
status: 200,
data: notMergedPullRequestFixture
});
mock.rest.pulls
.create()
.reply({
status: 201,
data: mergedPullRequestFixture
});
mock.rest.pulls
.requestReviewers()
.reply({
status: 201,
data: mergedPullRequestFixture
});
mock.rest.issues
.addAssignees()
.reply({
status: 201,
data: {}
});
// invalid requests
mock.rest.pulls
.get({
owner: targetOwner,
repo: repo,
pull_number: notFoundPullRequestNumber
})
.reply({
status: 404,
data: {
message: "Not found"
}
});
return mock;
};

View file

@ -880,26 +880,7 @@ export const openPullRequestFixture = {
"mergeable": null,
"rebaseable": null,
"mergeable_state": "unknown",
"merged_by": {
"login": "that-s-a-user",
"id": 17157711,
"node_id": "MDQ6VXNlcjE3MTU3NzEx",
"avatar_url": "https://avatars.githubusercontent.com/u/17157711?v=4",
"gravatar_id": "",
"url": "https://api.github.com/users/that-s-a-user",
"html_url": "https://github.com/that-s-a-user",
"followers_url": "https://api.github.com/users/that-s-a-user/followers",
"following_url": "https://api.github.com/users/that-s-a-user/following{/other_user}",
"gists_url": "https://api.github.com/users/that-s-a-user/gists{/gist_id}",
"starred_url": "https://api.github.com/users/that-s-a-user/starred{/owner}{/repo}",
"subscriptions_url": "https://api.github.com/users/that-s-a-user/subscriptions",
"organizations_url": "https://api.github.com/users/that-s-a-user/orgs",
"repos_url": "https://api.github.com/users/that-s-a-user/repos",
"events_url": "https://api.github.com/users/that-s-a-user/events{/privacy}",
"received_events_url": "https://api.github.com/users/that-s-a-user/received_events",
"type": "User",
"site_admin": false
},
"merged_by": {},
"comments": 0,
"review_comments": 0,
"maintainer_can_modify": false,

View file

@ -0,0 +1,539 @@
// <host>/api/v4/projects/superuser%2Fbackporting-example/merge_requests/1
// <host>/api/v4/projects/76316
export const PROJECT_EXAMPLE = {
"id":76316,
"description":null,
"name":"Backporting Example",
"name_with_namespace":"Super User / Backporting Example",
"path":"backporting-example",
"path_with_namespace":"superuser/backporting-example",
"created_at":"2023-06-23T13:45:15.121Z",
"default_branch":"main",
"tag_list":[
],
"topics":[
],
"ssh_url_to_repo":"git@my.gitlab.host.com:superuser/backporting-example.git",
"http_url_to_repo":"https://my.gitlab.host.com/superuser/backporting-example.git",
"web_url":"https://my.gitlab.host.com/superuser/backporting-example",
"readme_url":"https://my.gitlab.host.com/superuser/backporting-example/-/blob/main/README.md",
"forks_count":0,
"avatar_url":null,
"star_count":0,
"last_activity_at":"2023-06-28T14:05:42.596Z",
"namespace":{
"id":70747,
"name":"Super User",
"path":"superuser",
"kind":"user",
"full_path":"superuser",
"parent_id":null,
"avatar_url":"/uploads/-/system/user/avatar/14041/avatar.png",
"web_url":"https://my.gitlab.host.com/superuser"
},
"_links":{
"self":"https://my.gitlab.host.com/api/v4/projects/76316",
"issues":"https://my.gitlab.host.com/api/v4/projects/76316/issues",
"merge_requests":"https://my.gitlab.host.com/api/v4/projects/76316/merge_requests",
"repo_branches":"https://my.gitlab.host.com/api/v4/projects/76316/repository/branches",
"labels":"https://my.gitlab.host.com/api/v4/projects/76316/labels",
"events":"https://my.gitlab.host.com/api/v4/projects/76316/events",
"members":"https://my.gitlab.host.com/api/v4/projects/76316/members",
"cluster_agents":"https://my.gitlab.host.com/api/v4/projects/76316/cluster_agents"
},
"packages_enabled":true,
"empty_repo":false,
"archived":false,
"visibility":"private",
"owner":{
"id":14041,
"username":"superuser",
"name":"Super User",
"state":"active",
"avatar_url":"https://my.gitlab.host.com/uploads/-/system/user/avatar/14041/avatar.png",
"web_url":"https://my.gitlab.host.com/superuser"
},
"resolve_outdated_diff_discussions":false,
"container_expiration_policy":{
"cadence":"1d",
"enabled":false,
"keep_n":10,
"older_than":"90d",
"name_regex":".*",
"name_regex_keep":null,
"next_run_at":"2023-06-24T13:45:15.167Z"
},
"issues_enabled":true,
"merge_requests_enabled":true,
"wiki_enabled":true,
"jobs_enabled":true,
"snippets_enabled":true,
"container_registry_enabled":true,
"service_desk_enabled":false,
"service_desk_address":null,
"can_create_merge_request_in":true,
"issues_access_level":"enabled",
"repository_access_level":"enabled",
"merge_requests_access_level":"enabled",
"forking_access_level":"enabled",
"wiki_access_level":"enabled",
"builds_access_level":"enabled",
"snippets_access_level":"enabled",
"pages_access_level":"private",
"analytics_access_level":"enabled",
"container_registry_access_level":"enabled",
"security_and_compliance_access_level":"private",
"releases_access_level":"enabled",
"environments_access_level":"enabled",
"feature_flags_access_level":"enabled",
"infrastructure_access_level":"enabled",
"monitor_access_level":"enabled",
"emails_disabled":null,
"shared_runners_enabled":true,
"lfs_enabled":true,
"creator_id":14041,
"import_url":null,
"import_type":null,
"import_status":"none",
"import_error":null,
"open_issues_count":0,
"description_html":"",
"updated_at":"2023-06-28T14:05:42.596Z",
"ci_default_git_depth":20,
"ci_forward_deployment_enabled":true,
"ci_job_token_scope_enabled":false,
"ci_separated_caches":true,
"ci_allow_fork_pipelines_to_run_in_parent_project":true,
"build_git_strategy":"fetch",
"keep_latest_artifact":true,
"restrict_user_defined_variables":false,
"runners_token":"GR13489419z7QQ54AUgJaNMFD5asU",
"runner_token_expiration_interval":null,
"group_runners_enabled":true,
"auto_cancel_pending_pipelines":"enabled",
"build_timeout":3600,
"auto_devops_enabled":false,
"auto_devops_deploy_strategy":"continuous",
"ci_config_path":"",
"public_jobs":true,
"shared_with_groups":[
],
"only_allow_merge_if_pipeline_succeeds":false,
"allow_merge_on_skipped_pipeline":null,
"request_access_enabled":true,
"only_allow_merge_if_all_discussions_are_resolved":false,
"remove_source_branch_after_merge":true,
"printing_merge_request_link_enabled":true,
"merge_method":"merge",
"squash_option":"default_off",
"enforce_auth_checks_on_uploads":true,
"suggestion_commit_message":null,
"merge_commit_template":null,
"squash_commit_template":null,
"issue_branch_template":null,
"autoclose_referenced_issues":true,
"approvals_before_merge":0,
"mirror":false,
"external_authorization_classification_label":null,
"marked_for_deletion_at":null,
"marked_for_deletion_on":null,
"requirements_enabled":false,
"requirements_access_level":"enabled",
"security_and_compliance_enabled":true,
"compliance_frameworks":[
],
"issues_template":null,
"merge_requests_template":null,
"merge_pipelines_enabled":false,
"merge_trains_enabled":false,
"allow_pipeline_trigger_approve_deployment":false,
"permissions":{
"project_access":{
"access_level":50,
"notification_level":3
},
"group_access":null
}
};
export const MERGED_SQUASHED_MR = {
"id":807106,
"iid":1,
"project_id":76316,
"title":"Update test.txt",
"description":"This is the body",
"state":"merged",
"created_at":"2023-06-28T14:32:40.943Z",
"updated_at":"2023-06-28T14:37:12.108Z",
"merged_by":{
"id":14041,
"username":"superuser",
"name":"Super User",
"state":"active",
"avatar_url":"https://my.gitlab.host.com/uploads/-/system/user/avatar/14041/avatar.png",
"web_url":"https://my.gitlab.host.com/superuser"
},
"merge_user":{
"id":14041,
"username":"superuser",
"name":"Super User",
"state":"active",
"avatar_url":"https://my.gitlab.host.com/uploads/-/system/user/avatar/14041/avatar.png",
"web_url":"https://my.gitlab.host.com/superuser"
},
"merged_at":"2023-06-28T14:37:11.667Z",
"closed_by":null,
"closed_at":null,
"target_branch":"main",
"source_branch":"feature",
"user_notes_count":0,
"upvotes":0,
"downvotes":0,
"author":{
"id":14041,
"username":"superuser",
"name":"Super User",
"state":"active",
"avatar_url":"https://my.gitlab.host.com/uploads/-/system/user/avatar/14041/avatar.png",
"web_url":"https://my.gitlab.host.com/superuser"
},
"assignees":[
{
"id":14041,
"username":"superuser",
"name":"Super User",
"state":"active",
"avatar_url":"https://my.gitlab.host.com/uploads/-/system/user/avatar/14041/avatar.png",
"web_url":"https://my.gitlab.host.com/superuser"
}
],
"assignee":{
"id":14041,
"username":"superuser",
"name":"Super User",
"state":"active",
"avatar_url":"https://my.gitlab.host.com/uploads/-/system/user/avatar/14041/avatar.png",
"web_url":"https://my.gitlab.host.com/superuser"
},
"reviewers":[
{
"id":1404188,
"username":"superuser1",
"name":"Super User",
"state":"active",
"avatar_url":"https://my.gitlab.host.com/uploads/-/system/user/avatar/14041/avatar.png",
"web_url":"https://my.gitlab.host.com/superuser"
},
{
"id":1404199,
"username":"superuser2",
"name":"Super User",
"state":"active",
"avatar_url":"https://my.gitlab.host.com/uploads/-/system/user/avatar/14041/avatar.png",
"web_url":"https://my.gitlab.host.com/superuser"
}
],
"source_project_id":76316,
"target_project_id":76316,
"labels":[
],
"draft":false,
"work_in_progress":false,
"milestone":null,
"merge_when_pipeline_succeeds":false,
"merge_status":"can_be_merged",
"detailed_merge_status":"not_open",
"sha":"9e15674ebd48e05c6e428a1fa31dbb60a778d644",
"merge_commit_sha":"4d369c3e9a8d1d5b7e56c892a8ab2a7666583ac3",
"squash_commit_sha":"ebb1eca696c42fd067658bd9b5267709f78ef38e",
"discussion_locked":null,
"should_remove_source_branch":true,
"force_remove_source_branch":true,
"reference":"!2",
"references":{
"short":"!2",
"relative":"!2",
"full":"superuser/backporting-example!2"
},
"web_url":"https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/1",
"time_stats":{
"time_estimate":0,
"total_time_spent":0,
"human_time_estimate":null,
"human_total_time_spent":null
},
"squash":true,
"squash_on_merge":true,
"task_completion_status":{
"count":0,
"completed_count":0
},
"has_conflicts":false,
"blocking_discussions_resolved":true,
"approvals_before_merge":null,
"subscribed":true,
"changes_count":"1",
"latest_build_started_at":null,
"latest_build_finished_at":null,
"first_deployed_to_production_at":null,
"pipeline":null,
"head_pipeline":null,
"diff_refs":{
"base_sha":"2c553a0c4c133a51806badce5fa4842b7253cb3b",
"head_sha":"9e15674ebd48e05c6e428a1fa31dbb60a778d644",
"start_sha":"2c553a0c4c133a51806badce5fa4842b7253cb3b"
},
"merge_error":null,
"first_contribution":false,
"user":{
"can_merge":true
}
};
export const OPEN_MR = {
"id":807106,
"iid":2,
"project_id":76316,
"title":"Update test.txt opened",
"description":"Still opened mr body",
"state":"opened",
"created_at":"2023-06-28T14:32:40.943Z",
"updated_at":"2023-06-28T14:35:56.433Z",
"merged_by":null,
"merge_user":null,
"merged_at":null,
"closed_by":null,
"closed_at":null,
"target_branch":"main",
"source_branch":"feature",
"user_notes_count":0,
"upvotes":0,
"downvotes":0,
"author":{
"id":14041,
"username":"superuser",
"name":"Super User",
"state":"active",
"avatar_url":"https://my.gitlab.host.com/uploads/-/system/user/avatar/14041/avatar.png",
"web_url":"https://my.gitlab.host.com/superuser"
},
"assignees":[
{
"id":14041,
"username":"superuser",
"name":"Super User",
"state":"active",
"avatar_url":"https://my.gitlab.host.com/uploads/-/system/user/avatar/14041/avatar.png",
"web_url":"https://my.gitlab.host.com/superuser"
}
],
"assignee":{
"id":14041,
"username":"superuser",
"name":"Super User",
"state":"active",
"avatar_url":"https://my.gitlab.host.com/uploads/-/system/user/avatar/14041/avatar.png",
"web_url":"https://my.gitlab.host.com/superuser"
},
"reviewers":[
{
"id":14041,
"username":"superuser",
"name":"Super User",
"state":"active",
"avatar_url":"https://my.gitlab.host.com/uploads/-/system/user/avatar/14041/avatar.png",
"web_url":"https://my.gitlab.host.com/superuser"
}
],
"source_project_id":76316,
"target_project_id":76316,
"labels":[
],
"draft":false,
"work_in_progress":false,
"milestone":null,
"merge_when_pipeline_succeeds":false,
"merge_status":"checking",
"detailed_merge_status":"checking",
"sha":"9e15674ebd48e05c6e428a1fa31dbb60a778d644",
"merge_commit_sha":null,
"squash_commit_sha":null,
"discussion_locked":null,
"should_remove_source_branch":null,
"force_remove_source_branch":true,
"reference":"!2",
"references":{
"short":"!2",
"relative":"!2",
"full":"superuser/backporting-example!2"
},
"web_url":"https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/2",
"time_stats":{
"time_estimate":0,
"total_time_spent":0,
"human_time_estimate":null,
"human_total_time_spent":null
},
"squash":false,
"squash_on_merge":false,
"task_completion_status":{
"count":0,
"completed_count":0
},
"has_conflicts":false,
"blocking_discussions_resolved":true,
"approvals_before_merge":null,
"subscribed":true,
"changes_count":"1",
"latest_build_started_at":null,
"latest_build_finished_at":null,
"first_deployed_to_production_at":null,
"pipeline":null,
"head_pipeline":null,
"diff_refs":{
"base_sha":"2c553a0c4c133a51806badce5fa4842b7253cb3b",
"head_sha":"9e15674ebd48e05c6e428a1fa31dbb60a778d644",
"start_sha":"2c553a0c4c133a51806badce5fa4842b7253cb3b"
},
"merge_error":null,
"first_contribution":false,
"user":{
"can_merge":true
}
};
export const CLOSED_NOT_MERGED_MR = {
"id":807191,
"iid":3,
"project_id":76316,
"title":"Update test.txt",
"description":"",
"state":"closed",
"created_at":"2023-06-28T15:44:50.549Z",
"updated_at":"2023-06-28T15:44:58.318Z",
"merged_by":null,
"merge_user":null,
"merged_at":null,
"closed_by":{
"id":14041,
"username":"superuser",
"name":"Super User",
"state":"active",
"avatar_url":"https://my.gitlab.host.com/uploads/-/system/user/avatar/14041/avatar.png",
"web_url":"https://my.gitlab.host.com/superuser"
},
"closed_at":"2023-06-28T15:44:58.349Z",
"target_branch":"main",
"source_branch":"closed",
"user_notes_count":0,
"upvotes":0,
"downvotes":0,
"author":{
"id":14041,
"username":"superuser",
"name":"Super User",
"state":"active",
"avatar_url":"https://my.gitlab.host.com/uploads/-/system/user/avatar/14041/avatar.png",
"web_url":"https://my.gitlab.host.com/superuser"
},
"assignees":[
{
"id":14041,
"username":"superuser",
"name":"Super User",
"state":"active",
"avatar_url":"https://my.gitlab.host.com/uploads/-/system/user/avatar/14041/avatar.png",
"web_url":"https://my.gitlab.host.com/superuser"
}
],
"assignee":{
"id":14041,
"username":"superuser",
"name":"Super User",
"state":"active",
"avatar_url":"https://my.gitlab.host.com/uploads/-/system/user/avatar/14041/avatar.png",
"web_url":"https://my.gitlab.host.com/superuser"
},
"reviewers":[
{
"id":14041,
"username":"superuser",
"name":"Super User",
"state":"active",
"avatar_url":"https://my.gitlab.host.com/uploads/-/system/user/avatar/14041/avatar.png",
"web_url":"https://my.gitlab.host.com/superuser"
}
],
"source_project_id":76316,
"target_project_id":76316,
"labels":[
],
"draft":false,
"work_in_progress":false,
"milestone":null,
"merge_when_pipeline_succeeds":false,
"merge_status":"can_be_merged",
"detailed_merge_status":"not_open",
"sha":"c8ce0ffdd372c2ed89d65f9e3f6f3681e6d16eb3",
"merge_commit_sha":null,
"squash_commit_sha":null,
"discussion_locked":null,
"should_remove_source_branch":null,
"force_remove_source_branch":true,
"reference":"!3",
"references":{
"short":"!3",
"relative":"!3",
"full":"superuser/backporting-example!3"
},
"web_url":"https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/3",
"time_stats":{
"time_estimate":0,
"total_time_spent":0,
"human_time_estimate":null,
"human_total_time_spent":null
},
"squash":false,
"squash_on_merge":false,
"task_completion_status":{
"count":0,
"completed_count":0
},
"has_conflicts":false,
"blocking_discussions_resolved":true,
"approvals_before_merge":null,
"subscribed":true,
"changes_count":"1",
"latest_build_started_at":null,
"latest_build_finished_at":null,
"first_deployed_to_production_at":null,
"pipeline":null,
"head_pipeline":null,
"diff_refs":{
"base_sha":"4d369c3e9a8d1d5b7e56c892a8ab2a7666583ac3",
"head_sha":"c8ce0ffdd372c2ed89d65f9e3f6f3681e6d16eb3",
"start_sha":"4d369c3e9a8d1d5b7e56c892a8ab2a7666583ac3"
},
"merge_error":null,
"first_contribution":false,
"user":{
"can_merge":true
}
};
export const SUPERUSER = {
"id":14041,
"username":"superuser",
"name":"Super USer",
"state":"active",
"avatar_url":"https://my.gitlab.host.com/uploads/-/system/user/avatar/14041/avatar.png",
"web_url":"https://my.gitlab.host.com/superuser"
};

View file

@ -1,89 +0,0 @@
import LoggerServiceFactory from "@bp/service/logger/logger-service-factory";
import { Moctokit } from "@kie/mock-github";
import { targetOwner, repo, mergedPullRequestFixture, openPullRequestFixture, notMergedPullRequestFixture, notFoundPullRequestNumber, sameOwnerPullRequestFixture } from "./moctokit-data";
const logger = LoggerServiceFactory.getLogger();
export const setupMoctokit = (): Moctokit => {
logger.debug("Setting up moctokit.");
const mock = new Moctokit();
// setup the mock requests here
// valid requests
mock.rest.pulls
.get({
owner: targetOwner,
repo: repo,
pull_number: mergedPullRequestFixture.number
})
.reply({
status: 200,
data: mergedPullRequestFixture
});
mock.rest.pulls
.get({
owner: targetOwner,
repo: repo,
pull_number: sameOwnerPullRequestFixture.number
})
.reply({
status: 200,
data: sameOwnerPullRequestFixture
});
mock.rest.pulls
.get({
owner: targetOwner,
repo: repo,
pull_number: openPullRequestFixture.number
})
.reply({
status: 200,
data: openPullRequestFixture
});
mock.rest.pulls
.get({
owner: targetOwner,
repo: repo,
pull_number: notMergedPullRequestFixture.number
})
.reply({
status: 200,
data: notMergedPullRequestFixture
});
mock.rest.pulls
.create()
.reply({
status: 201,
data: mergedPullRequestFixture
});
mock.rest.pulls
.requestReviewers()
.reply({
status: 201,
data: mergedPullRequestFixture
});
// invalid requests
mock.rest.pulls
.get({
owner: targetOwner,
repo: repo,
pull_number: notFoundPullRequestNumber
})
.reply({
status: 404,
data: {
message: "Not found"
}
});
return mock;
};