-
Notifications
You must be signed in to change notification settings - Fork 227
Expand file tree
/
Copy pathprepare-release.js
More file actions
108 lines (92 loc) · 5.18 KB
/
Copy pathprepare-release.js
File metadata and controls
108 lines (92 loc) · 5.18 KB
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
const { execSync } = require('child_process');
const { promisify } = require('util');
const readline = require('readline');
const fs = require('fs');
const semver = require('semver');
const conventionalRecommendedBump = require('conventional-recommended-bump');
const packagejson = require('./package.json');
const exec = (command) => execSync(command, { stdio: [0, 1, 2] });
const replaceVersionNumber = (path, oldString, newString) => {
const fileContent = fs.readFileSync(path, { encoding: 'UTF-8' });
if (!fileContent.includes(oldString)) {
throw new Error(`The file at ${path} did not contain ${oldString}!`);
}
const oldStringStart = fileContent.indexOf(oldString);
const oldStringEnd = oldStringStart + oldString.length;
const updatedFileContent = fileContent.substr(0, oldStringStart) + newString + fileContent.substr(oldStringEnd);
fs.writeFileSync(path, updatedFileContent, { encoding: 'UTF-8' });
};
const sharedVersionPropsFile = './src/Directory.Build.props';
const oldVersionPrefix = packagejson.versionPrefix;
const oldVersionSuffix = packagejson.versionSuffix;
const oldVersion = oldVersionPrefix + (oldVersionSuffix ? '-' : '') + oldVersionSuffix;
const bump = promisify(conventionalRecommendedBump);
(async () => {
const recommendation = await bump({ preset: 'angular', tagPrefix: 'dotnet-stryker@' });
const releaseType = recommendation.releaseType ?? 'patch';
const suggestedVersion = semver.inc(oldVersionPrefix, releaseType);
console.log(`Current package version is ${oldVersion}`);
if (recommendation.releaseType) {
console.log(`Suggested next version: ${suggestedVersion} (${releaseType} bump based on conventional commits)`);
} else {
console.log(`No conventional commits found since last tag. Defaulting to patch bump: ${suggestedVersion}`);
}
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
rl.question(`What should the new package version be? [${suggestedVersion}] `, (input) => {
const newVersionNumber = input.trim() || suggestedVersion;
let commitMessageLines = ['Publish', '', ''];
let versionPrefix = newVersionNumber;
let versionSuffix = '';
if (newVersionNumber.indexOf('-') >= 0) {
versionPrefix = newVersionNumber.split('-')[0];
versionSuffix = newVersionNumber.split('-')[1] ?? '';
}
console.log('Updating package.json');
replaceVersionNumber('./package.json', `"version": "${packagejson.version}",`, `"version": "${newVersionNumber}",`);
replaceVersionNumber('./package.json', `"versionPrefix": "${oldVersionPrefix}",`, `"versionPrefix": "${versionPrefix}",`);
replaceVersionNumber('./package.json', `"versionSuffix": "${oldVersionSuffix}",`, `"versionSuffix": "${versionSuffix}",`);
console.log(`Updating version numbers in ${sharedVersionPropsFile}`);
replaceVersionNumber(sharedVersionPropsFile, `<VersionPrefix>${oldVersionPrefix}</VersionPrefix>`, `<VersionPrefix>${versionPrefix}</VersionPrefix>`);
replaceVersionNumber(sharedVersionPropsFile, `<VersionSuffix>${oldVersionSuffix}</VersionSuffix>`, `<VersionSuffix>${versionSuffix}</VersionSuffix>`);
let releaseNotes = '';
if (!versionSuffix) {
console.log(`Updating changelog`);
commitMessageLines.push(`- dotnet-stryker@${newVersionNumber}`);
releaseNotes = execSync(`npx conventional-changelog-cli -p angular --tag-prefix "dotnet-stryker@"`, { encoding: 'utf8' }).trim();
const changelogPath = './CHANGELOG.md';
const changelog = fs.readFileSync(changelogPath, { encoding: 'UTF-8' });
const marker = '<!-- changelog -->';
if (!changelog.includes(marker)) {
throw new Error(`${changelogPath} is missing the '${marker}' insertion marker`);
}
fs.writeFileSync(changelogPath, changelog.replace(marker, `${marker}\n\n${releaseNotes}`), { encoding: 'UTF-8' });
}
console.log('Updating azure-pipelines.yml');
replaceVersionNumber('./azure-pipelines.yml', `VersionBuildNumber: $[counter('${oldVersion}', 1)]`, `VersionBuildNumber: $[counter('${versionPrefix}', 1)]`);
replaceVersionNumber('./azure-pipelines.yml', `PackageVersion: '${oldVersion}'`, `PackageVersion: '${versionPrefix}'`);
console.log(`Creating commit`);
exec('git add .');
exec(`git commit ${commitMessageLines.map(entry => `-m "${entry}"`).join(' ')}`);
if (!versionSuffix) {
console.log('Tagging commit');
const tmpTagFile = '.release-notes.md';
fs.writeFileSync(tmpTagFile, releaseNotes);
exec(`git tag -a dotnet-stryker@${newVersionNumber} --cleanup=verbatim -F ${tmpTagFile}`);
fs.unlinkSync(tmpTagFile);
}
console.log(`Pushing commit ${versionSuffix?'':' and tag'}`);
exec('git push --follow-tags');
if (!versionSuffix) {
try {
execSync(`gh release create dotnet-stryker@${newVersionNumber} --title "dotnet-stryker@${newVersionNumber}" --notes-from-tag`);
console.log(`Created GitHub release for dotnet-stryker@${newVersionNumber}`);
} catch (e) {
console.warn('Failed to create GitHub release:', e.message);
}
}
rl.close();
});
})().catch(console.error);