-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathindex.js
More file actions
118 lines (104 loc) · 4.05 KB
/
index.js
File metadata and controls
118 lines (104 loc) · 4.05 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
109
110
111
112
113
114
115
116
117
118
/* eslint-disable import/no-dynamic-require */
/* eslint-disable @typescript-eslint/no-var-requires */
const fs = require('fs');
const path = require('path');
const conventionalRecommendedBump = require('conventional-recommended-bump');
const conventionalChangelog = require('conventional-changelog');
const semver = require('semver');
const pkg = require(path.join(process.cwd(), 'package.json'));
const defaultPreset = require.resolve('conventional-changelog-conventionalcommits');
const startOfLastReleasePattern = /(^#+ \[?[0-9]+\.[0-9]+\.[0-9]+|<a name=)/m;
const changelogFile = path.join(process.cwd(), 'CHANGELOG.md');
const releaseBotDir = path.join(process.cwd(), '.release_bot');
const releaseNotesDir = path.join(process.cwd(), '.release_notes');
const preset = {
name: defaultPreset,
};
const header =
'# Changelog\n\nAll notable changes to this project will be documented in this file. ' +
'See [conventional commits](https://www.conventionalcommits.org/en/v1.0.0/) for commit guidelines.\n\n';
async function bumpVersion(currentVersion, tagPrefix = 'v') {
const release = await new Promise((resolve, reject) => {
conventionalRecommendedBump(
{
preset,
},
(err, release) => (err ? reject(err) : resolve(release)),
);
});
const newVersion = semver.valid(release.releaseType) || semver.inc(currentVersion, release.releaseType);
return {
summary: release.reason,
type: release.releaseType,
newVersion,
newTag: `${tagPrefix}${newVersion}`,
};
}
function createChangelogFileIfMissing() {
try {
fs.accessSync(changelogFile, fs.F_OK);
} catch (err) {
if (err.code === 'ENOENT') {
fs.writeFileSync(changelogFile, '\n');
}
}
}
function createReleaseBotDirIfMissing() {
try {
fs.accessSync(releaseBotDir, fs.F_OK);
} catch (err) {
if (err.code === 'ENOENT') {
fs.mkdirSync(releaseBotDir);
}
}
}
function createReleaseNotesDirIfMissing() {
try {
fs.accessSync(releaseNotesDir, fs.F_OK);
} catch (err) {
if (err.code === 'ENOENT') {
fs.mkdirSync(releaseNotesDir);
}
}
}
function changelog(newVersion, tagPrefix = 'v') {
createChangelogFileIfMissing();
return new Promise((resolve, reject) => {
let history = fs.readFileSync(changelogFile, 'utf-8');
const historyStart = history.search(startOfLastReleasePattern);
// find the position of the last release and remove header:
if (historyStart !== -1) {
history = history.substring(historyStart);
}
let release = '';
const context = { version: newVersion };
const changelogStream = conventionalChangelog(
{
preset: defaultPreset,
tagPrefix,
},
context,
{ merges: null },
).on('error', (err) => reject(err));
changelogStream.on('data', (buffer) => {
release += buffer.toString();
});
changelogStream.on('end', () => resolve({ header, release, history }));
});
}
(async () => {
const release = await bumpVersion(pkg.version);
const log = await changelog(release.newVersion);
// remove first line with title to check commits in release
// throw error if empty
const isReleaseContainsChanges = Boolean(log.release.split('\n').slice(1).join('\n').trim());
if (!isReleaseContainsChanges) {
throw new Error('There are no changes in the release. Do some commits before next one 😎');
}
createReleaseBotDirIfMissing();
createReleaseNotesDirIfMissing();
fs.writeFileSync('version', release.newVersion);
fs.writeFileSync(path.join(releaseBotDir, 'body'), [`## Summary\n`, `Release type: __${release.type}__. ${release.summary}.\n`, log.release].join('\n'));
fs.writeFileSync(path.join(releaseNotesDir, `${release.newVersion}.md`), log.release);
fs.writeFileSync(changelogFile, (log.header + log.release + log.history).replace(/\n+$/, '\n'));
})();