Skip to content
Snippets Groups Projects
Commit 24955fab authored by Rhys Arkins's avatar Rhys Arkins Committed by GitHub
Browse files

Support GitLab merge conflict rebasing (#335)

Closes #132 

* Add gitlab deleteBranch

* Add GitLab rebasing logic to branch worker

* Add GitLab getBranch

* Record user email during initRepo

* Add canRebase logic

* lint fix

* Add test
parent 10622a18
No related branches found
No related tags found
No related merge requests found
......@@ -10,8 +10,10 @@ module.exports = {
findFilePaths,
// Branch
branchExists,
getBranch,
getBranchPr,
getBranchStatus,
deleteBranch,
// issue
addAssignees,
addReviewers,
......@@ -81,6 +83,8 @@ async function initRepo(repoName, token, endpoint, repoLogger) {
const res = await glGot(`projects/${config.repoName}`);
config.defaultBranch = res.body.default_branch;
logger.debug(`${repoName} default branch = ${config.defaultBranch}`);
// Discover our user email
config.email = (await glGot(`user`)).body.email;
} catch (err) {
logger.error(`GitLab init error: ${JSON.stringify(err)}`);
throw err;
......@@ -122,6 +126,19 @@ async function branchExists(branchName) {
}
}
// Returns branch object
async function getBranch(branchName) {
logger.debug(`getBranch(${branchName})`);
const url = `projects/${config.repoName}/repository/branches/${branchName}`;
try {
return (await glGot(url)).body;
} catch (err) {
logger.warn(`Failed to getBranch ${branchName}`);
logger.debug(JSON.stringify(err));
return null;
}
}
// Returns the Pull Request for a branch. Null if not exists.
async function getBranchPr(branchName) {
logger.debug(`getBranchPr(${branchName})`);
......@@ -170,6 +187,12 @@ async function getBranchStatus(branchName) {
return status;
}
async function deleteBranch(branchName) {
await glGot.delete(
`projects/${config.repoName}/repository/branches/${branchName}`
);
}
// Issue
async function addAssignees(prNo, assignees) {
......@@ -259,8 +282,12 @@ async function getPr(prNo) {
logger.debug('pr cannot be merged');
pr.isUnmergeable = true;
}
// We can't rebase through GitLab API
pr.canRebase = false;
// Check if the most recent branch commit is by us
// If not then we don't allow it to be rebased, in case someone's changes would be lost
const branch = await getBranch(pr.source_branch);
if (branch && branch.commit.author_email === config.email) {
pr.canRebase = true;
}
return pr;
}
......
......@@ -41,10 +41,15 @@ async function getParentBranch(branchName, config) {
if (pr.isUnmergeable) {
logger.debug('PR is unmergeable');
if (pr.canRebase) {
// Only supported by GitHub
// Setting parentBranch back to undefined means that we'll use the default branch
logger.debug(`Branch ${branchName} is not mergeable and needs rebasing`);
return undefined;
if (config.platform === 'github') {
// Setting parentBranch back to undefined means that we'll use the default branch
logger.info(`Branch is not mergeable and needs rebasing`);
return undefined;
} else if (config.platform === 'gitlab') {
logger.info(`Deleting unmergeable branch in order to recreate/rebase`);
await config.api.deleteBranch(branchName);
return undefined;
}
}
// Don't do anything different, but warn
logger.warn(`Branch ${branchName} is not mergeable but can't be rebased`);
......
......@@ -22,8 +22,10 @@ describe('workers/branch', () => {
const branchName = 'foo';
beforeEach(() => {
config = {
platform: 'github',
api: {
branchExists: jest.fn(() => true),
deleteBranch: jest.fn(),
getBranchPr: jest.fn(),
getBranchStatus: jest.fn(),
isBranchStale: jest.fn(() => false),
......@@ -68,6 +70,17 @@ describe('workers/branch', () => {
undefined
);
});
it('returns undefined if unmergeable and can rebase (gitlab)', async () => {
config.platform = 'gitlab';
config.api.getBranchPr.mockReturnValue({
isUnmergeable: true,
canRebase: true,
});
expect(await branchWorker.getParentBranch(branchName, config)).toBe(
undefined
);
expect(config.api.deleteBranch.mock.calls.length).toBe(1);
});
it('returns branchName if automerge branch-push and not stale', async () => {
config.automergeEnabled = true;
config.automergeType = 'branch-push';
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment