/
index.ts
151 lines (145 loc) · 5.45 KB
/
index.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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
import is from '@sindresorhus/is';
import { RenovateConfig } from '../../../../config';
import { logger } from '../../../../logger';
import { PackageFile } from '../../../../manager/common';
import { platform } from '../../../../platform';
import { emojify } from '../../../../util/emoji';
import { BranchConfig } from '../../../common';
import { addAssigneesReviewers } from '../../../pr';
import { getBaseBranchDesc } from './base-branch';
import { getConfigDesc } from './config-description';
import { getDepWarnings, getErrors, getWarnings } from './errors-warnings';
import { getPrList } from './pr-list';
export async function ensureOnboardingPr(
config: RenovateConfig,
packageFiles: Record<string, PackageFile[]> | null,
branches: BranchConfig[]
): Promise<void> {
if (config.repoIsOnboarded) {
return;
}
logger.debug('ensureOnboardingPr()');
logger.trace({ config });
const existingPr = await platform.getBranchPr(config.onboardingBranch);
logger.debug('Filling in onboarding PR template');
let prTemplate = `Welcome to [Renovate](${config.productLinks.homepage})! This is an onboarding PR to help you understand and configure settings before regular Pull Requests begin.\n\n`;
prTemplate += config.requireConfig
? emojify(
`:vertical_traffic_light: To activate Renovate, merge this Pull Request. To disable Renovate, simply close this Pull Request unmerged.\n\n`
)
: emojify(
`:vertical_traffic_light: Renovate will begin keeping your dependencies up-to-date only once you merge or close this Pull Request.\n\n`
);
prTemplate += emojify(
`
---
{{PACKAGE FILES}}
{{CONFIG}}
{{BASEBRANCH}}
{{PRLIST}}
{{WARNINGS}}
{{ERRORS}}
---
:question: Got questions? Check out Renovate's [Docs](${config.productLinks.documentation}), particularly the Getting Started section.
If you need any further assistance then you can also [request help here](${config.productLinks.help}).
`
);
let prBody = prTemplate;
if (packageFiles && Object.entries(packageFiles).length) {
let files: string[] = [];
for (const [manager, managerFiles] of Object.entries(packageFiles)) {
files = files.concat(
managerFiles.map((file) => ` * \`${file.packageFile}\` (${manager})`)
);
}
prBody =
prBody.replace(
'{{PACKAGE FILES}}',
'### Detected Package Files\n\n' + files.join('\n')
) + '\n';
} else {
prBody = prBody.replace('{{PACKAGE FILES}}\n', '');
}
let configDesc = '';
if (!(existingPr && existingPr.isModified)) {
configDesc = getConfigDesc(config, packageFiles);
} else {
configDesc = emojify(
`### Configuration\n\n:abcd: Renovate has detected a custom config for this PR. Feel free to ask for [help](${config.productLinks.help}) if you have any doubts and would like it reviewed.\n\n`
);
if (existingPr.isConflicted) {
configDesc += emojify(
`:warning: This PR has a merge conflict, however Renovate is unable to automatically fix that due to edits in this branch. Please resolve the merge conflict manually.\n\n`
);
} else {
configDesc += `Important: Now that this branch is edited, Renovate can't rebase it from the base branch any more. If you make changes to the base branch that could impact this onboarding PR, please merge them manually.\n\n`;
}
}
prBody = prBody.replace('{{CONFIG}}\n', configDesc);
prBody = prBody.replace(
'{{WARNINGS}}\n',
getWarnings(config) + getDepWarnings(packageFiles)
);
prBody = prBody.replace('{{ERRORS}}\n', getErrors(config));
prBody = prBody.replace('{{BASEBRANCH}}\n', getBaseBranchDesc(config));
prBody = prBody.replace('{{PRLIST}}\n', getPrList(config, branches));
// istanbul ignore if
if (config.prHeader) {
prBody = (config.prHeader || '') + '\n\n' + prBody;
}
// istanbul ignore if
if (config.prFooter) {
prBody = prBody + '\n---\n\n' + config.prFooter + '\n';
}
logger.trace('prBody:\n' + prBody);
prBody = platform.getPrBody(prBody);
if (existingPr) {
logger.debug('Found open onboarding PR');
// Check if existing PR needs updating
if (
existingPr.body.trim() === prBody.trim() // Bitbucket strips trailing \n
) {
logger.debug(`${existingPr.displayNumber} does not need updating`);
return;
}
// PR must need updating
await platform.updatePr(existingPr.number, existingPr.title, prBody);
logger.info({ pr: existingPr.number }, 'Onboarding PR updated');
return;
}
logger.debug('Creating onboarding PR');
const labels: string[] = [];
const useDefaultBranch = true;
try {
// istanbul ignore if
if (config.dryRun) {
logger.info('DRY-RUN: Would create onboarding PR');
} else {
const pr = await platform.createPr({
branchName: config.onboardingBranch,
prTitle: config.onboardingPrTitle,
prBody,
labels,
useDefaultBranch,
});
logger.info({ pr: pr.displayNumber }, 'Onboarding PR created');
await addAssigneesReviewers(config, pr);
}
} catch (err) /* istanbul ignore next */ {
if (
err.statusCode === 422 &&
err.response &&
err.response.body &&
is.nonEmptyArray(err.response.body.errors) &&
err.response.body.errors[0].message &&
err.response.body.errors[0].message.startsWith(
'A pull request already exists'
)
) {
logger.debug('Onboarding PR already exists but cannot find it');
await platform.deleteBranch(config.onboardingBranch);
return;
}
throw err;
}
}