/
automerge.ts
84 lines (82 loc) · 2.73 KB
/
automerge.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
import { getAdminConfig } from '../../config/admin';
import type { RenovateConfig } from '../../config/types';
import { logger } from '../../logger';
import { platform } from '../../platform';
import { BranchStatus } from '../../types';
import { mergeBranch } from '../../util/git';
export type AutomergeResult =
| 'automerged'
| 'automerge aborted - PR exists'
| 'branch status error'
| 'failed'
| 'no automerge'
| 'stale'
| 'not ready';
export async function tryBranchAutomerge(
config: RenovateConfig
): Promise<AutomergeResult> {
logger.debug('Checking if we can automerge branch');
if (!(config.automerge && config.automergeType === 'branch')) {
return 'no automerge';
}
const existingPr = await platform.getBranchPr(config.branchName);
if (existingPr) {
return 'automerge aborted - PR exists';
}
const branchStatus = await platform.getBranchStatus(
config.branchName,
config.requiredStatusChecks
);
if (branchStatus === BranchStatus.green) {
logger.debug(`Automerging branch`);
try {
if (getAdminConfig().dryRun) {
logger.info('DRY-RUN: Would automerge branch' + config.branchName);
} else {
await mergeBranch(config.branchName);
}
logger.info({ branch: config.branchName }, 'Branch automerged');
return 'automerged'; // Branch no longer exists
} catch (err) /* istanbul ignore next */ {
if (err.message === 'not ready') {
logger.debug('Branch is not ready for automerge');
return 'not ready';
}
if (
err.message.includes('refusing to merge unrelated histories') ||
err.message.includes('Not possible to fast-forward')
) {
logger.warn({ err }, 'Branch is not up to date - cannot automerge');
return 'stale';
}
if (err.message.includes('Protected branch')) {
if (err.message.includes('status check')) {
logger.debug(
{ err },
'Branch is not ready for automerge: required status checks are remaining'
);
return 'not ready';
}
if (err.stack?.includes('reviewers')) {
logger.info(
{ err },
'Branch automerge is not possible due to branch protection (required reviewers)'
);
return 'failed';
}
logger.info(
{ err },
'Branch automerge is not possible due to branch protection'
);
return 'failed';
}
logger.warn({ err }, 'Unknown error when attempting branch automerge');
return 'failed';
}
} else if (branchStatus === BranchStatus.red) {
return 'branch status error';
} else {
logger.debug(`Branch status is "${branchStatus}" - skipping automerge`);
}
return 'no automerge';
}