Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: separate automerge function in pr
- Loading branch information
Showing
6 changed files
with
201 additions
and
111 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
import { getConfig, getName, git, mocked, partial } from '../../../test/util'; | ||
import { Pr, platform as _platform } from '../../platform'; | ||
import { BranchStatus } from '../../types'; | ||
import { BranchConfig } from '../types'; | ||
import * as prAutomerge from './automerge'; | ||
|
||
jest.mock('../../util/git'); | ||
|
||
const platform = mocked(_platform); | ||
const defaultConfig = getConfig(); | ||
|
||
describe(getName(__filename), () => { | ||
describe('checkAutoMerge(pr, config)', () => { | ||
let config: BranchConfig; | ||
let pr: Pr; | ||
beforeEach(() => { | ||
config = partial<BranchConfig>({ | ||
...defaultConfig, | ||
}); | ||
pr = partial<Pr>({ | ||
canMerge: true, | ||
}); | ||
}); | ||
afterEach(() => { | ||
jest.clearAllMocks(); | ||
}); | ||
it('should not automerge if not configured', async () => { | ||
await prAutomerge.checkAutoMerge(pr, config); | ||
expect(platform.mergePr).toHaveBeenCalledTimes(0); | ||
}); | ||
it('should automerge if enabled and pr is mergeable', async () => { | ||
config.automerge = true; | ||
platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.green); | ||
platform.mergePr.mockResolvedValueOnce(true); | ||
await prAutomerge.checkAutoMerge(pr, config); | ||
expect(platform.mergePr).toHaveBeenCalledTimes(1); | ||
}); | ||
it('should automerge comment', async () => { | ||
config.automerge = true; | ||
config.automergeType = 'pr-comment'; | ||
config.automergeComment = '!merge'; | ||
platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.green); | ||
await prAutomerge.checkAutoMerge(pr, config); | ||
expect(platform.ensureCommentRemoval).toHaveBeenCalledTimes(0); | ||
expect(platform.ensureComment).toHaveBeenCalledTimes(1); | ||
}); | ||
it('should remove previous automerge comment when rebasing', async () => { | ||
config.automerge = true; | ||
config.automergeType = 'pr-comment'; | ||
config.automergeComment = '!merge'; | ||
config.rebaseRequested = true; | ||
platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.green); | ||
await prAutomerge.checkAutoMerge(pr, config); | ||
expect(platform.ensureCommentRemoval).toHaveBeenCalledTimes(1); | ||
expect(platform.ensureComment).toHaveBeenCalledTimes(1); | ||
}); | ||
it('should not automerge if enabled and pr is mergeable but cannot rebase', async () => { | ||
config.automerge = true; | ||
platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.green); | ||
git.isBranchModified.mockResolvedValueOnce(true); | ||
await prAutomerge.checkAutoMerge(pr, config); | ||
expect(platform.mergePr).toHaveBeenCalledTimes(0); | ||
}); | ||
it('should not automerge if enabled and pr is mergeable but branch status is not success', async () => { | ||
config.automerge = true; | ||
platform.getBranchStatus.mockResolvedValueOnce(BranchStatus.yellow); | ||
await prAutomerge.checkAutoMerge(pr, config); | ||
expect(platform.mergePr).toHaveBeenCalledTimes(0); | ||
}); | ||
it('should not automerge if enabled and pr is mergeable but unstable', async () => { | ||
config.automerge = true; | ||
pr.canMerge = undefined; | ||
await prAutomerge.checkAutoMerge(pr, config); | ||
expect(platform.mergePr).toHaveBeenCalledTimes(0); | ||
}); | ||
it('should not automerge if enabled and pr is unmergeable', async () => { | ||
config.automerge = true; | ||
pr.isConflicted = true; | ||
await prAutomerge.checkAutoMerge(pr, config); | ||
expect(platform.mergePr).toHaveBeenCalledTimes(0); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import { getAdminConfig } from '../../config/admin'; | ||
import { logger } from '../../logger'; | ||
import { Pr, platform } from '../../platform'; | ||
import { BranchStatus } from '../../types'; | ||
import { isBranchModified } from '../../util/git'; | ||
import { BranchConfig } from '../types'; | ||
|
||
export async function checkAutoMerge( | ||
pr: Pr, | ||
config: BranchConfig | ||
): Promise<boolean> { | ||
logger.trace({ config }, 'checkAutoMerge'); | ||
const { | ||
branchName, | ||
automerge, | ||
automergeType, | ||
automergeComment, | ||
requiredStatusChecks, | ||
rebaseRequested, | ||
} = config; | ||
logger.debug( | ||
{ automerge, automergeType, automergeComment }, | ||
`Checking #${pr.number} for automerge` | ||
); | ||
if (automerge) { | ||
logger.debug('PR is configured for automerge'); | ||
// Return if PR not ready for automerge | ||
if (pr.isConflicted) { | ||
logger.debug('PR is conflicted'); | ||
logger.debug({ pr }); | ||
return false; | ||
} | ||
if (requiredStatusChecks && pr.canMerge !== true) { | ||
logger.debug( | ||
{ canMergeReason: pr.canMergeReason }, | ||
'PR is not ready for merge' | ||
); | ||
return false; | ||
} | ||
const branchStatus = await platform.getBranchStatus( | ||
branchName, | ||
requiredStatusChecks | ||
); | ||
if (branchStatus !== BranchStatus.green) { | ||
logger.debug( | ||
`PR is not ready for merge (branch status is ${branchStatus})` | ||
); | ||
return false; | ||
} | ||
// Check if it's been touched | ||
if (await isBranchModified(branchName)) { | ||
logger.debug('PR is ready for automerge but has been modified'); | ||
return false; | ||
} | ||
if (automergeType === 'pr-comment') { | ||
logger.debug(`Applying automerge comment: ${automergeComment}`); | ||
// istanbul ignore if | ||
if (getAdminConfig().dryRun) { | ||
logger.info( | ||
`DRY-RUN: Would add PR automerge comment to PR #${pr.number}` | ||
); | ||
return false; | ||
} | ||
if (rebaseRequested) { | ||
await platform.ensureCommentRemoval({ | ||
number: pr.number, | ||
content: automergeComment, | ||
}); | ||
} | ||
return platform.ensureComment({ | ||
number: pr.number, | ||
topic: null, | ||
content: automergeComment, | ||
}); | ||
} | ||
// Let's merge this | ||
logger.debug(`Automerging #${pr.number}`); | ||
// istanbul ignore if | ||
if (getAdminConfig().dryRun) { | ||
logger.info(`DRY-RUN: Would merge PR #${pr.number}`); | ||
return false; | ||
} | ||
const res = await platform.mergePr(pr.number, branchName); | ||
if (res) { | ||
logger.info({ pr: pr.number, prTitle: pr.title }, 'PR automerged'); | ||
} | ||
return res; | ||
} | ||
logger.debug('No automerge'); | ||
return false; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.