Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 15 additions & 4 deletions dist/cli/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -443,7 +443,10 @@ class PullRequestConfigsParser extends configs_parser_1.default {
let backportBranch = bpBranchNames.length > 1 ? bpBranchNames[idx] : bpBranchNames[0];
if (backportBranch === undefined || backportBranch.trim() === "") {
// for each commit takes the first 7 chars that are enough to uniquely identify them in most of the projects
const concatenatedCommits = originalPullRequest.commits.map(c => c.slice(0, 7)).join("-");
const concatenatedCommits = originalPullRequest.commits.filter(c => c).map(c => c.slice(0, 7)).join("-");
if (concatenatedCommits === "") {
throw new Error("Missing commits, stopping the backporting!");
}
backportBranch = `bp-${tb}-${concatenatedCommits}`;
}
else if (bpBranchNames.length == 1 && targetBranches.length > 1) {
Expand Down Expand Up @@ -1053,7 +1056,11 @@ class GitHubMapper {
}
getSha(pr) {
// if pr is open use latest commit sha otherwise use merge_commit_sha
return pr.state === "open" ? [pr.head.sha] : [pr.merge_commit_sha];
const sha = pr.state === "open" ? pr.head.sha : pr.merge_commit_sha;
if (!sha) {
throw new Error("Trying to backport a single squashed/merged commit that does not exist! Aborting...");
}
return [sha];
}
async mapSourceRepo(pr) {
return Promise.resolve({
Expand Down Expand Up @@ -1349,9 +1356,13 @@ class GitLabMapper {
};
}
getSha(mr) {
// if mr is merged, use merge_commit_sha otherwise use sha
// if mr is merged, use merge_commit_sha (or squash_commit_sha) otherwise use sha
// what is the difference between sha and diff_refs.head_sha?
return this.isMerged(mr) ? [mr.squash_commit_sha ? mr.squash_commit_sha : mr.merge_commit_sha] : [mr.sha];
const sha = this.isMerged(mr) ? (mr.squash_commit_sha ? mr.squash_commit_sha : mr.merge_commit_sha) : mr.sha;
if (!sha) {
throw new Error("Trying to backport a single squashed/merged commit that does not exist! Aborting...");
}
return [sha];
}
async mapSourceRepo(mr) {
const project = await this.getProject(mr.source_project_id);
Expand Down
19 changes: 15 additions & 4 deletions dist/gha/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,10 @@ class PullRequestConfigsParser extends configs_parser_1.default {
let backportBranch = bpBranchNames.length > 1 ? bpBranchNames[idx] : bpBranchNames[0];
if (backportBranch === undefined || backportBranch.trim() === "") {
// for each commit takes the first 7 chars that are enough to uniquely identify them in most of the projects
const concatenatedCommits = originalPullRequest.commits.map(c => c.slice(0, 7)).join("-");
const concatenatedCommits = originalPullRequest.commits.filter(c => c).map(c => c.slice(0, 7)).join("-");
if (concatenatedCommits === "") {
throw new Error("Missing commits, stopping the backporting!");
}
backportBranch = `bp-${tb}-${concatenatedCommits}`;
}
else if (bpBranchNames.length == 1 && targetBranches.length > 1) {
Expand Down Expand Up @@ -1018,7 +1021,11 @@ class GitHubMapper {
}
getSha(pr) {
// if pr is open use latest commit sha otherwise use merge_commit_sha
return pr.state === "open" ? [pr.head.sha] : [pr.merge_commit_sha];
const sha = pr.state === "open" ? pr.head.sha : pr.merge_commit_sha;
if (!sha) {
throw new Error("Trying to backport a single squashed/merged commit that does not exist! Aborting...");
}
return [sha];
}
async mapSourceRepo(pr) {
return Promise.resolve({
Expand Down Expand Up @@ -1314,9 +1321,13 @@ class GitLabMapper {
};
}
getSha(mr) {
// if mr is merged, use merge_commit_sha otherwise use sha
// if mr is merged, use merge_commit_sha (or squash_commit_sha) otherwise use sha
// what is the difference between sha and diff_refs.head_sha?
return this.isMerged(mr) ? [mr.squash_commit_sha ? mr.squash_commit_sha : mr.merge_commit_sha] : [mr.sha];
const sha = this.isMerged(mr) ? (mr.squash_commit_sha ? mr.squash_commit_sha : mr.merge_commit_sha) : mr.sha;
if (!sha) {
throw new Error("Trying to backport a single squashed/merged commit that does not exist! Aborting...");
}
return [sha];
}
async mapSourceRepo(mr) {
const project = await this.getProject(mr.source_project_id);
Expand Down
5 changes: 4 additions & 1 deletion src/service/configs/pullrequest/pr-configs-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -139,7 +139,10 @@
let backportBranch = bpBranchNames.length > 1 ? bpBranchNames[idx] : bpBranchNames[0];
if (backportBranch === undefined || backportBranch.trim() === "") {
// for each commit takes the first 7 chars that are enough to uniquely identify them in most of the projects
const concatenatedCommits: string = originalPullRequest.commits!.map(c => c.slice(0, 7)).join("-");
const concatenatedCommits: string = originalPullRequest.commits!.filter(c => c).map(c => c.slice(0, 7)).join("-");
if (concatenatedCommits === "") {
throw new Error("Missing commits, stopping the backporting!");

Check warning on line 144 in src/service/configs/pullrequest/pr-configs-parser.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
}

Check warning on line 145 in src/service/configs/pullrequest/pr-configs-parser.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch
backportBranch = `bp-${tb}-${concatenatedCommits}`;
} else if (bpBranchNames.length == 1 && targetBranches.length > 1) {
// multiple targets and single custom backport branch name we need to differentiate branch names
Expand Down
7 changes: 6 additions & 1 deletion src/service/git/github/github-mapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,12 @@

private getSha(pr: PullRequest) {
// if pr is open use latest commit sha otherwise use merge_commit_sha
return pr.state === "open" ? [pr.head.sha] : [pr.merge_commit_sha as string];
const sha = pr.state === "open" ? pr.head.sha : pr.merge_commit_sha as string;
if (!sha) {
throw new Error("Trying to backport a single squashed/merged commit that does not exist! Aborting...");

Check warning on line 42 in src/service/git/github/github-mapper.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🧾 Statement is not covered

Warning! Not covered statement
}

Check warning on line 43 in src/service/git/github/github-mapper.ts

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch

return [sha];
}

async mapSourceRepo(pr: PullRequest): Promise<GitRepository> {
Expand Down
10 changes: 8 additions & 2 deletions src/service/git/gitlab/gitlab-mapper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export default class GitLabMapper implements GitResponseMapper<MergeRequestSchem
}

async mapPullRequest(mr: MergeRequestSchema, commits?: string[]): Promise<GitPullRequest> {

return {
number: mr.iid,
author: mr.author.username,
Expand All @@ -47,9 +48,14 @@ export default class GitLabMapper implements GitResponseMapper<MergeRequestSchem
}

private getSha(mr: MergeRequestSchema) {
// if mr is merged, use merge_commit_sha otherwise use sha
// if mr is merged, use merge_commit_sha (or squash_commit_sha) otherwise use sha
// what is the difference between sha and diff_refs.head_sha?
return this.isMerged(mr) ? [mr.squash_commit_sha ? mr.squash_commit_sha : mr.merge_commit_sha as string] : [mr.sha];
const sha = this.isMerged(mr) ? (mr.squash_commit_sha ? mr.squash_commit_sha : mr.merge_commit_sha as string) : mr.sha;
if (!sha) {
throw new Error("Trying to backport a single squashed/merged commit that does not exist! Aborting...");
}

return [sha];
}

async mapSourceRepo(mr: MergeRequestSchema): Promise<GitRepository> {
Expand Down
11 changes: 11 additions & 0 deletions test/service/runner/cli-gitlab-runner.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -702,4 +702,15 @@ describe("cli runner", () => {

// Not interested in all subsequent calls, already tested in other test cases
});

test("throw error if missing squash commit", async () => {
addProcessArgs([
"-tb",
"target",
"-pr",
"https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/6"
]);

await expect(() => runner.execute()).rejects.toThrow("Trying to backport a single squashed/merged commit that does not exist! Aborting...");
});
});
4 changes: 3 additions & 1 deletion test/support/mock/git-client-mock-support.ts
Original file line number Diff line number Diff line change
@@ -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, MERGED_NOT_SQUASHED_MR, MERGED_NOT_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, UNDEFINED_COMMITS_MR } 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
Expand All @@ -27,6 +27,8 @@ export const getAxiosMocked = (url: string) => {
data = NESTED_NAMESPACE_MR;
} else if (url.endsWith("merge_requests/5")) {
data = MERGED_NOT_SQUASHED_MR;
} else if (url.endsWith("merge_requests/6")) {
data = UNDEFINED_COMMITS_MR;
} else if (url.endsWith("projects/76316")) {
data = PROJECT_EXAMPLE;
} else if (url.endsWith("projects/1645")) {
Expand Down
135 changes: 135 additions & 0 deletions test/support/mock/gitlab-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1055,4 +1055,139 @@ export const MERGED_NOT_SQUASHED_MR = {
"user":{
"can_merge":true
}
};

export const UNDEFINED_COMMITS_MR = {
"id":807106,
"iid":6,
"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":undefined,
"squash_commit_sha":undefined,
"discussion_locked":null,
"should_remove_source_branch":true,
"force_remove_source_branch":true,
"reference":"!2",
"references":{
"short":"!2",
"relative":"!2",
"full":"superuser/backporting-example!6"
},
"web_url":"https://my.gitlab.host.com/superuser/backporting-example/-/merge_requests/6",
"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
}
};