Compare commits

..

17 commits
v4.8.1 ... main

Author SHA1 Message Date
dependabot[bot]
8625efa217
build(deps): bump undici, @release-it/conventional-changelog and release-it (#157)
All checks were successful
main ci / ubuntu-latest - node 16 (push) Successful in 2m20s
main ci / ubuntu-latest - node 18 (push) Successful in 1m39s
main ci / ubuntu-latest - node 20 (push) Successful in 1m38s
Bumps [undici](https://github.com/nodejs/undici) to 6.21.2 and updates ancestor dependencies [undici](https://github.com/nodejs/undici), [@release-it/conventional-changelog](https://github.com/release-it/conventional-changelog) and [release-it](https://github.com/release-it/release-it). These dependencies need to be updated together.


Updates `undici` from 6.21.1 to 6.21.2
- [Release notes](https://github.com/nodejs/undici/releases)
- [Commits](https://github.com/nodejs/undici/compare/v6.21.1...v6.21.2)

Updates `@release-it/conventional-changelog` from 10.0.0 to 10.0.1
- [Release notes](https://github.com/release-it/conventional-changelog/releases)
- [Commits](https://github.com/release-it/conventional-changelog/compare/10.0.0...10.0.1)

Updates `release-it` from 18.1.2 to 19.0.2
- [Release notes](https://github.com/release-it/release-it/releases)
- [Changelog](https://github.com/release-it/release-it/blob/main/CHANGELOG.md)
- [Commits](https://github.com/release-it/release-it/compare/18.1.2...19.0.2)

---
updated-dependencies:
- dependency-name: undici
  dependency-version: 6.21.2
  dependency-type: indirect
- dependency-name: "@release-it/conventional-changelog"
  dependency-version: 10.0.1
  dependency-type: direct:development
- dependency-name: release-it
  dependency-version: 19.0.2
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-05-15 17:45:57 +02:00
github-actions[bot]
7ff4fce545
chore: release v4.8.5 (#156)
Co-authored-by: Create or Update Pull Request Action <create-or-update-pull-request@users.noreply.github.com>
2025-04-15 10:57:49 +02:00
Andrea Lamparelli
c9a7375bf9
build(deps): upgrade release-it to v18 (#153) 2025-04-15 10:42:44 +02:00
Andrea Lamparelli
d74a787035
fix(#151): fix gitlab post comments url (#152) 2025-04-14 17:48:09 +02:00
Andrea Lamparelli
3a9d367b48
build(deps): audit fix (#150) 2025-03-24 20:23:36 +01:00
github-actions[bot]
b9ed3ac959
chore: release v4.8.4 (#147)
Co-authored-by: Create or Update Pull Request Action <create-or-update-pull-request@users.noreply.github.com>
2024-11-02 13:31:20 +01:00
Andrea Lamparelli
3deee59d4c
fix: abort conflicting cherry-pick before starting new one (#146)
Signed-off-by: Andrea Lamparelli <a.lamparelli95@gmail.com>
2024-10-28 11:51:36 +01:00
Andrea Lamparelli
2b4b429356
build(deps): audit run (#143)
Signed-off-by: Andrea Lamparelli <a.lamparelli95@gmail.com>
2024-10-10 11:16:48 +02:00
dependabot[bot]
31eabaf84a
build(deps): bump cookie and express (#142)
Bumps [cookie](https://github.com/jshttp/cookie) and [express](https://github.com/expressjs/express). These dependencies needed to be updated together.

Updates `cookie` from 0.6.0 to 0.7.1
- [Release notes](https://github.com/jshttp/cookie/releases)
- [Commits](https://github.com/jshttp/cookie/compare/v0.6.0...v0.7.1)

Updates `express` from 4.21.0 to 4.21.1
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/4.21.1/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.21.0...4.21.1)

---
updated-dependencies:
- dependency-name: cookie
  dependency-type: indirect
- dependency-name: express
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-10-10 11:07:36 +02:00
github-actions[bot]
a14014e89e
chore: release v4.8.3 (#141)
Co-authored-by: Create or Update Pull Request Action <create-or-update-pull-request@users.noreply.github.com>
2024-10-10 10:58:28 +02:00
Ratchanan Srirattanamet
b4d0481c56
fix: auto-no-squash inference for GitLab (#140)
When a GitLab MR is not squashed, `squash_commit_sha` will be `null`,
not `undefined`. Update `inferSquash()` to account for this.
2024-10-07 14:40:31 +02:00
github-actions[bot]
c3daf80306
chore: release v4.8.2 (#139)
Co-authored-by: Create or Update Pull Request Action <create-or-update-pull-request@users.noreply.github.com>
2024-10-07 11:21:34 +02:00
Andrea Lamparelli
6d6592f958
ci: upgrade github actions (#138)
Signed-off-by: Andrea Lamparelli <a.lamparelli95@gmail.com>
2024-10-03 20:04:40 +02:00
Ratchanan Srirattanamet
e2d73d050c
fix: cherry-pick order on GitLab by reversing commmit list only once (#137)
GitLabClient already handle commit order reversing, so re-handle it in
Runner causes cherry-pick order on GitLab to be wrong.

Remove commit order handling from Runner, and instead handle difference
between GitHub and Codeberg inside GitHubClient.

Now, since the default of --bp-branch-name takes the commit list from
{GitHub,GitLab}Client directly, that means backporting branch name
on Codeberg will also be changed to have commits in the correct order
too (old to new, in line with GitHub and GitLab), which is IMO a nice
bonus.
2024-10-03 19:39:03 +02:00
Ratchanan Srirattanamet
1e8358bb2c
fix: handle Codeberg returning null entry in requested_reviewers (#136)
Codeberg can return null as part of requested_reviewers (presumably
because that user has been deleted). Handle that case, and also for
assignees since we're at it.
2024-10-03 19:21:14 +02:00
dependabot[bot]
fe22142b85
build(deps): bump serve-static and express (#134)
Bumps [serve-static](https://github.com/expressjs/serve-static) and [express](https://github.com/expressjs/express). These dependencies needed to be updated together.

Updates `serve-static` from 1.15.0 to 1.16.2
- [Release notes](https://github.com/expressjs/serve-static/releases)
- [Changelog](https://github.com/expressjs/serve-static/blob/v1.16.2/HISTORY.md)
- [Commits](https://github.com/expressjs/serve-static/compare/v1.15.0...v1.16.2)

Updates `express` from 4.19.2 to 4.21.0
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/4.21.0/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.19.2...4.21.0)

---
updated-dependencies:
- dependency-name: serve-static
  dependency-type: indirect
- dependency-name: express
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-09-17 16:59:26 +02:00
dependabot[bot]
26a4c5dfd2
build(deps): bump axios from 1.6.0 to 1.7.4 (#133)
Bumps [axios](https://github.com/axios/axios) from 1.6.0 to 1.7.4.
- [Release notes](https://github.com/axios/axios/releases)
- [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md)
- [Commits](https://github.com/axios/axios/compare/v1.6.0...v1.7.4)

---
updated-dependencies:
- dependency-name: axios
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2024-08-27 09:53:44 +02:00
25 changed files with 6092 additions and 7235 deletions

View file

@ -19,9 +19,9 @@ jobs:
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Setup Node ${{ matrix.node-version }}
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm ci

View file

@ -16,7 +16,7 @@ jobs:
coverage:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- uses: ArtiomTr/jest-coverage-report-action@v2
with:
test-script: npm test

View file

@ -19,11 +19,11 @@ jobs:
name: Prepare release
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: 18
- name: Git config

View file

@ -24,9 +24,9 @@ jobs:
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Setup Node ${{ matrix.node-version }}
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node-version }}
- run: npm ci

View file

@ -17,11 +17,11 @@ jobs:
name: Release package
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: 18
- name: Git config

View file

@ -1,5 +1,33 @@
# Changelog
## <small>4.8.5 (2025-04-15)</small>
* build(deps): audit fix (#150) ([3a9d367](https://github.com/kiegroup/git-backporting/commit/3a9d367)), closes [#150](https://github.com/kiegroup/git-backporting/issues/150)
* build(deps): upgrade release-it to v18 (#153) ([c9a7375](https://github.com/kiegroup/git-backporting/commit/c9a7375)), closes [#153](https://github.com/kiegroup/git-backporting/issues/153)
* fix(#151): fix gitlab post comments url (#152) ([d74a787](https://github.com/kiegroup/git-backporting/commit/d74a787)), closes [#152](https://github.com/kiegroup/git-backporting/issues/152)
## [4.8.4](https://github.com/kiegroup/git-backporting/compare/v4.8.3...v4.8.4) (2024-11-02)
### Bug Fixes
* abort conflicting cherry-pick before starting new one ([#146](https://github.com/kiegroup/git-backporting/issues/146)) ([3deee59](https://github.com/kiegroup/git-backporting/commit/3deee59d4c3b726ae131b5974af4618dd5e7d1d2))
## [4.8.3](https://github.com/kiegroup/git-backporting/compare/v4.8.2...v4.8.3) (2024-10-10)
### Bug Fixes
* auto-no-squash inference for GitLab ([#140](https://github.com/kiegroup/git-backporting/issues/140)) ([b4d0481](https://github.com/kiegroup/git-backporting/commit/b4d0481c5649115367f1ae0724d12d55b6b86e10))
## [4.8.2](https://github.com/kiegroup/git-backporting/compare/v4.8.1...v4.8.2) (2024-10-07)
### Bug Fixes
* cherry-pick order on GitLab by reversing commmit list only once ([#137](https://github.com/kiegroup/git-backporting/issues/137)) ([e2d73d0](https://github.com/kiegroup/git-backporting/commit/e2d73d050c8387c0858877ac3c56c565bacaf4f9))
* handle Codeberg returning null entry in requested_reviewers ([#136](https://github.com/kiegroup/git-backporting/issues/136)) ([1e8358b](https://github.com/kiegroup/git-backporting/commit/1e8358bb2c461c56cf86e82bec4d71284866b13b))
## [4.8.1](https://github.com/kiegroup/git-backporting/compare/v4.8.0...v4.8.1) (2024-07-16)
@ -181,4 +209,4 @@ Project moved under @kiegroup organization.
### Features
* backport still open pull requests ([b3936e0](https://github.com/kiegroup/git-backporting/commit/b3936e019a19976281c5e2582904264e974b8b42))
* pull request backporting ([b3936e0](https://github.com/kiegroup/git-backporting/commit/b3936e019a19976281c5e2582904264e974b8b42))
* pull request backporting ([b3936e0](https://github.com/kiegroup/git-backporting/commit/b3936e019a19976281c5e2582904264e974b8b42))

1760
dist/cli/index.js vendored

File diff suppressed because it is too large Load diff

1750
dist/gha/index.js vendored

File diff suppressed because it is too large Load diff

View file

@ -35,7 +35,7 @@ jobs:
fail-fast: true
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Backporting

2
mise.toml Normal file
View file

@ -0,0 +1,2 @@
[tools]
node = "20"

9429
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
{
"name": "@kie/git-backporting",
"version": "4.8.1",
"version": "4.8.5",
"description": "Git backporting is a tool to execute automatic pull request git backporting.",
"author": "",
"license": "MIT",
@ -55,7 +55,7 @@
"@gitbeaker/rest": "^39.1.0",
"@kie/mock-github": "^1.1.0",
"@octokit/webhooks-types": "^6.8.0",
"@release-it/conventional-changelog": "^7.0.0",
"@release-it/conventional-changelog": "^10.0.0",
"@types/fs-extra": "^9.0.13",
"@types/jest": "^29.2.4",
"@types/node": "^18.11.17",
@ -66,7 +66,7 @@
"husky": "^8.0.2",
"jest": "^29.0.0",
"jest-sonar-reporter": "^2.0.0",
"release-it": "^16.1.3",
"release-it": "^19.0.2",
"semver": "^7.3.8",
"ts-jest": "^29.0.0",
"ts-node": "^10.8.1",

View file

@ -68,6 +68,15 @@ export default class GitCLIService {
}
this.logger.info(`Folder ${to} already exist. Won't clone`);
// ensure the working tree is properly reset - no stale changes
// from previous (failed) backport
const ongoingCherryPick = await this.anyConflict(to);
if (ongoingCherryPick) {
this.logger.warn("Found previously failed cherry-pick, aborting it");
await this.git(to).raw(["cherry-pick", "--abort"]);
}
// checkout to the proper branch
this.logger.info(`Checking out branch ${branch}`);
await this.git(to).checkout(branch);
@ -131,6 +140,21 @@ export default class GitCLIService {
}
}
/**
* Check whether there are some conflicts in the current working directory
* which means there is an ongoing cherry-pick that did not complete successfully
* @param cwd repository in which the check should be performed
* @return true if there is some conflict, false otherwise
*/
async anyConflict(cwd: string): Promise<boolean> {
const status = await this.git(cwd).status();
if (status.conflicted.length > 0) {
this.logger.debug(`Found conflicts in branch ${status.current}`);
return true;
}
return false;
}
/**
* Push a branch to a remote
* @param cwd repository in which the push should be performed

View file

@ -45,17 +45,17 @@ export const inferGitApiUrl = (prUrl: string, apiVersion = "v4"): string => {
/**
* Infer the value of the squash option
* @param open true if the pull/merge request is still open
* @param squash_commit undefined if the pull/merge request was merged, the sha of the squashed commit if it was squashed
* @param squash_commit undefined or null if the pull/merge request was merged, the sha of the squashed commit if it was squashed
* @returns true if a single commit must be cherry-picked, false if all merged commits must be cherry-picked
*/
export const inferSquash = (open: boolean, squash_commit: string | undefined): boolean => {
export const inferSquash = (open: boolean, squash_commit: string | undefined | null): boolean => {
const logger = LoggerServiceFactory.getLogger();
if (open) {
logger.debug("cherry-pick all commits because they have not been merged (or squashed) in the base branch yet");
return false;
} else {
if (squash_commit !== undefined) {
if (squash_commit) {
logger.debug(`cherry-pick the squashed commit ${squash_commit}`);
return true;
} else {

View file

@ -73,6 +73,11 @@ export default class GitHubClient implements GitClient {
});
commits.push(...data.map(c => c.sha));
if (this.isForCodeberg) {
// For some reason, even though Codeberg advertises API compatibility
// with GitHub, it returns commits in reversed order.
commits.reverse();
}
} catch(error) {
throw new Error(`Failed to retrieve commits for pull request n. ${prNumber}`);
}

View file

@ -24,8 +24,8 @@ export default class GitHubMapper implements GitResponseMapper<PullRequest, "ope
state: this.mapGitState(pr.state), // TODO fix using custom mapper
merged: pr.merged ?? false,
mergedBy: pr.merged_by?.login,
reviewers: pr.requested_reviewers?.filter(r => "login" in r).map((r => (r as User)?.login)) ?? [],
assignees: pr.assignees?.filter(r => "login" in r).map(r => r.login) ?? [],
reviewers: pr.requested_reviewers?.filter(r => r && "login" in r).map((r => (r as User)?.login)) ?? [],
assignees: pr.assignees?.filter(r => r && "login" in r).map(r => r.login) ?? [],
labels: pr.labels?.map(l => l.name) ?? [],
sourceRepo: await this.mapSourceRepo(pr),
targetRepo: await this.mapTargetRepo(pr),

View file

@ -48,7 +48,9 @@ export default class GitLabClient implements GitClient {
// example: <host>/api/v4/projects/<namespace>%2Fbackporting-example/merge_requests/1
async getPullRequest(namespace: string, repo: string, mrNumber: number, squash: boolean | undefined): Promise<GitPullRequest> {
const projectId = this.getProjectId(namespace, repo);
const { data } = await this.client.get(`/projects/${projectId}/merge_requests/${mrNumber}`);
const url = `/projects/${projectId}/merge_requests/${mrNumber}`;
this.logger.debug(`Fetching pull request ${url}`);
const { data } = await this.client.get(`${url}`);
if (squash === undefined) {
squash = inferSquash(data.state === "opened", data.squash_commit_sha);
@ -169,7 +171,7 @@ export default class GitLabClient implements GitClient {
const { namespace, project, id } = this.extractMergeRequestData(mrUrl);
const projectId = this.getProjectId(namespace, project);
const { data } = await this.client.post(`/projects/${projectId}/issues/${id}/notes`, {
const { data } = await this.client.post(`/projects/${projectId}/merge_requests/${id}/notes`, {
body: comment,
});

View file

@ -152,14 +152,6 @@ export default class Runner {
// 7. apply all changes to the new branch
this.logger.debug("Cherry picking commits..");
// Commits might be ordered in different ways based on the git service, e.g., considering top to bottom
// GITHUB --> oldest to newest
// CODEBERG --> newest to oldest
// GITLAB --> newest to oldest
if (git.gitClientType === GitClientType.CODEBERG || git.gitClientType === GitClientType.GITLAB) {
// reverse the order as we always need to process from older to newest
originalPR.commits.reverse();
}
for (const sha of originalPR.commits) {
await git.gitCli.cherryPick(configs.folder, sha, configs.mergeStrategy, configs.mergeStrategyOption, configs.cherryPickOptions);
}

View file

@ -59,5 +59,6 @@ describe("check git utilities", () => {
expect(inferSquash(true, undefined)).toStrictEqual(false);
expect(inferSquash(false, "SHA")).toStrictEqual(true);
expect(inferSquash(false, undefined)).toStrictEqual(false);
expect(inferSquash(false, null)).toStrictEqual(false);
});
});

View file

@ -370,7 +370,7 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.clone).toBeCalledWith("https://codeberg.org/owner/reponame.git", cwd, "target");
expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-0404fb9-11da4e3");
expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-11da4e3-0404fb9");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(1);
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "pull/4444/head:pr/4444");
@ -380,13 +380,13 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "11da4e38aa3e577ffde6d546f1c52e53b04d3151", undefined, undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-0404fb9-11da4e3");
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-11da4e3-0404fb9");
expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
owner: "owner",
repo: "reponame",
head: "bp-target-0404fb9-11da4e3",
head: "bp-target-11da4e3-0404fb9",
base: "target",
title: "[target] PR Title",
body: "**Backport:** https://codeberg.org/owner/reponame/pulls/4444\r\n\r\nPlease review and merge",
@ -728,7 +728,7 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.clone).toBeCalledWith("https://codeberg.org/owner/reponame.git", cwd, "target");
expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-0404fb9-11da4e3");
expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-11da4e3-0404fb9");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(0);
@ -737,13 +737,13 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "11da4e38aa3e577ffde6d546f1c52e53b04d3151", undefined, undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-0404fb9-11da4e3");
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-11da4e3-0404fb9");
expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
owner: "owner",
repo: "reponame",
head: "bp-target-0404fb9-11da4e3",
head: "bp-target-11da4e3-0404fb9",
base: "target",
title: "[target] PR Title",
body: "**Backport:** https://codeberg.org/owner/reponame/pulls/8632\r\n\r\nPlease review and merge",
@ -834,7 +834,7 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.clone).toBeCalledWith("https://codeberg.org/owner/reponame.git", cwd, "target");
expect(GitCLIService.prototype.createLocalBranch).toBeCalledTimes(1);
expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-0404fb9-11da4e3");
expect(GitCLIService.prototype.createLocalBranch).toBeCalledWith(cwd, "bp-target-11da4e3-0404fb9");
expect(GitCLIService.prototype.fetch).toBeCalledTimes(0);
@ -843,13 +843,13 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "11da4e38aa3e577ffde6d546f1c52e53b04d3151", "ort", "find-renames", undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-0404fb9-11da4e3");
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-11da4e3-0404fb9");
expect(GitHubClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitHubClient.prototype.createPullRequest).toBeCalledWith({
owner: "owner",
repo: "reponame",
head: "bp-target-0404fb9-11da4e3",
head: "bp-target-11da4e3-0404fb9",
base: "target",
title: "[target] PR Title",
body: "**Backport:** https://codeberg.org/owner/reponame/pulls/8632\r\n\r\nPlease review and merge",

View file

@ -582,8 +582,8 @@ describe("cli runner", () => {
expect(GitCLIService.prototype.fetch).toBeCalledWith(cwd, "merge-requests/2/head:pr/2");
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(2);
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "e4dd336a4a20f394df6665994df382fb1d193a11", undefined, undefined, undefined);
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "974519f65c9e0ed65277cd71026657a09fca05e7", undefined, undefined, undefined);
expect(GitCLIService.prototype.cherryPick).toHaveBeenNthCalledWith(1, cwd, "e4dd336a4a20f394df6665994df382fb1d193a11", undefined, undefined, undefined);
expect(GitCLIService.prototype.cherryPick).toHaveBeenNthCalledWith(2, cwd, "974519f65c9e0ed65277cd71026657a09fca05e7", undefined, undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-e4dd336-974519f");
@ -604,6 +604,50 @@ describe("cli runner", () => {
);
});
test("merged MR with --auto-no-squash", async () => {
addProcessArgs([
"-tb",
"target",
"-pr",
"https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/5",
"--auto-no-squash",
]);
await runner.execute();
const cwd = process.cwd() + "/bp";
expect(GitClientFactory.getOrCreate).toBeCalledTimes(1);
expect(GitClientFactory.getOrCreate).toBeCalledWith(GitClientType.GITLAB, undefined, "https://my.gitlab.host.com/api/v4");
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-e4dd336");
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "e4dd336a4a20f394df6665994df382fb1d193a11", undefined, undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-e4dd336");
expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitLabClient.prototype.createPullRequest).toBeCalledWith({
owner: "superuser",
repo: "backporting-example",
head: "bp-target-e4dd336",
base: "target",
title: "[target] Update test.txt",
body: expect.stringContaining("**Backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/5"),
reviewers: ["superuser"],
assignees: [],
labels: [],
comments: [],
}
);
});
test("auth using GITLAB_TOKEN takes precedence over GIT_TOKEN env variable", async () => {
process.env[AuthTokenId.GIT_TOKEN] = "mygittoken";
process.env[AuthTokenId.GITLAB_TOKEN] = "mygitlabtoken";

View file

@ -519,4 +519,46 @@ describe("gha runner", () => {
}
);
});
test("merged MR with auto-no-squash", async () => {
spyGetInput({
"target-branch": "target",
"pull-request": "https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/5",
"auto-no-squash": "true",
});
await runner.execute();
const cwd = process.cwd() + "/bp";
expect(GitClientFactory.getOrCreate).toBeCalledTimes(1);
expect(GitClientFactory.getOrCreate).toBeCalledWith(GitClientType.GITLAB, undefined, "https://my.gitlab.host.com/api/v4");
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-e4dd336");
expect(GitCLIService.prototype.cherryPick).toBeCalledTimes(1);
expect(GitCLIService.prototype.cherryPick).toBeCalledWith(cwd, "e4dd336a4a20f394df6665994df382fb1d193a11", undefined, undefined, undefined);
expect(GitCLIService.prototype.push).toBeCalledTimes(1);
expect(GitCLIService.prototype.push).toBeCalledWith(cwd, "bp-target-e4dd336");
expect(GitLabClient.prototype.createPullRequest).toBeCalledTimes(1);
expect(GitLabClient.prototype.createPullRequest).toBeCalledWith({
owner: "superuser",
repo: "backporting-example",
head: "bp-target-e4dd336",
base: "target",
title: "[target] Update test.txt",
body: expect.stringContaining("**Backport:** https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/5"),
reviewers: ["superuser"],
assignees: [],
labels: [],
comments: [],
}
);
});
});

View file

@ -87,7 +87,9 @@ export const CB_MERGED_PR_FIXTURE = {
"received_events_url": "https://codeberg.org/api/v1/users/gh-user/received_events",
"type": "User",
"site_admin": false
}
},
// Sometimes Codeberg returns null as part of requested_reviewers.
null,
],
"requested_teams": [

View file

@ -1,7 +1,7 @@
import LoggerServiceFactory from "@bp/service/logger/logger-service-factory";
import { Moctokit } from "@kie/mock-github";
import { TARGET_OWNER, REPO, MERGED_PR_FIXTURE, OPEN_PR_FIXTURE, NOT_MERGED_PR_FIXTURE, NOT_FOUND_PR_NUMBER, MULT_COMMITS_PR_FIXTURE, MULT_COMMITS_PR_COMMITS, NEW_PR_URL, NEW_PR_NUMBER, GITHUB_GET_COMMIT } from "./github-data";
import { CLOSED_NOT_MERGED_MR, MERGED_SQUASHED_MR, NESTED_NAMESPACE_MR, OPEN_MR, OPEN_PR_COMMITS, PROJECT_EXAMPLE, NESTED_PROJECT_EXAMPLE, SUPERUSER, MERGED_SQUASHED_MR_COMMITS } from "./gitlab-data";
import { CLOSED_NOT_MERGED_MR, MERGED_SQUASHED_MR, NESTED_NAMESPACE_MR, OPEN_MR, OPEN_PR_COMMITS, PROJECT_EXAMPLE, NESTED_PROJECT_EXAMPLE, SUPERUSER, MERGED_SQUASHED_MR_COMMITS, MERGED_NOT_SQUASHED_MR, MERGED_NOT_SQUASHED_MR_COMMITS } from "./gitlab-data";
import { CB_TARGET_OWNER, CB_REPO, CB_MERGED_PR_FIXTURE, CB_OPEN_PR_FIXTURE, CB_NOT_MERGED_PR_FIXTURE, CB_NOT_FOUND_PR_NUMBER, CB_MULT_COMMITS_PR_FIXTURE, CB_MULT_COMMITS_PR_COMMITS, CB_NEW_PR_URL, CB_NEW_PR_NUMBER, CODEBERG_GET_COMMIT } from "./codeberg-data";
// high number, for each test we are not expecting
@ -25,6 +25,8 @@ export const getAxiosMocked = (url: string) => {
data = CLOSED_NOT_MERGED_MR;
} else if (url.endsWith("merge_requests/4")) {
data = NESTED_NAMESPACE_MR;
} else if (url.endsWith("merge_requests/5")) {
data = MERGED_NOT_SQUASHED_MR;
} else if (url.endsWith("projects/76316")) {
data = PROJECT_EXAMPLE;
} else if (url.endsWith("projects/1645")) {
@ -35,6 +37,8 @@ export const getAxiosMocked = (url: string) => {
data = MERGED_SQUASHED_MR_COMMITS;
} else if (url.endsWith("merge_requests/2/commits")) {
data = OPEN_PR_COMMITS;
} else if (url.endsWith("merge_requests/5/commits")) {
data = MERGED_NOT_SQUASHED_MR_COMMITS;
}
return {

View file

@ -755,6 +755,29 @@ export const OPEN_PR_COMMITS = [
}
];
export const MERGED_NOT_SQUASHED_MR_COMMITS = [
{
"id":"e4dd336a4a20f394df6665994df382fb1d193a11",
"short_id":"e4dd336a",
"created_at":"2023-06-29T09:59:10.000Z",
"parent_ids":[
],
"title":"Add new file",
"message":"Add new file",
"author_name":"Super User",
"author_email":"superuser@email.com",
"authored_date":"2023-06-29T09:59:10.000Z",
"committer_name":"Super User",
"committer_email":"superuser@email.com",
"committed_date":"2023-06-29T09:59:10.000Z",
"trailers":{
},
"web_url":"https://gitlab.com/superuser/backporting-example/-/commit/e4dd336a4a20f394df6665994df382fb1d193a11"
},
];
export const SUPERUSER = {
"id":14041,
"username":"superuser",
@ -898,3 +921,138 @@ export const NESTED_NAMESPACE_MR = {
"can_merge":true
}
};
export const MERGED_NOT_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":[
"backport-prod"
],
"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":null,
"discussion_locked":null,
"should_remove_source_branch":true,
"force_remove_source_branch":true,
"reference":"!5",
"references":{
"short":"!5",
"relative":"!5",
"full":"superuser/backporting-example!5"
},
"web_url":"https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/5",
"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
}
};