@kors/generate-changelog 0.1.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -0
- package/distribution/cli.d.ts +2 -0
- package/distribution/cli.js +4 -0
- package/distribution/index.d.ts +1 -0
- package/distribution/index.js +1 -0
- package/distribution/lib/index.d.ts +5 -0
- package/distribution/lib/index.js +105 -0
- package/package.json +61 -0
package/README.md
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { generateChangelog } from './lib/index.js';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { generateChangelog } from './lib/index.js';
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
// run with `npx tsx scripts/generate-changelog.ts` or something
|
|
2
|
+
import { execSync } from 'node:child_process';
|
|
3
|
+
import * as fs from 'node:fs';
|
|
4
|
+
const generateChangelog = ({ write }) => {
|
|
5
|
+
try {
|
|
6
|
+
// Get git log output
|
|
7
|
+
const gitLog = execSync('git log --oneline --no-color').toString();
|
|
8
|
+
const lines = gitLog.split('\n');
|
|
9
|
+
// Initialize changelog object
|
|
10
|
+
const changelog = {
|
|
11
|
+
releases: {},
|
|
12
|
+
};
|
|
13
|
+
let currentVersion = "0.0.0";
|
|
14
|
+
const versionRegex = /^[0-9a-f]+\s+(\d+\.\d+\.\d+(?:-[a-zA-Z0-9]+(?:\.\d+)?)?)/;
|
|
15
|
+
const prNumberRegex = /#(\d+)/;
|
|
16
|
+
lines.forEach((line) => {
|
|
17
|
+
// Check if line contains a version
|
|
18
|
+
const versionMatch = line.match(versionRegex);
|
|
19
|
+
if (versionMatch?.[1]) {
|
|
20
|
+
currentVersion = versionMatch[1];
|
|
21
|
+
changelog.releases[currentVersion] = [];
|
|
22
|
+
}
|
|
23
|
+
else if (currentVersion && line.trim()) {
|
|
24
|
+
// Process commit message
|
|
25
|
+
const commitMessage = line.substring(8).trim(); // Remove commit hash
|
|
26
|
+
const prMatch = commitMessage.match(prNumberRegex);
|
|
27
|
+
let formattedMessage = commitMessage;
|
|
28
|
+
// Determine the type of change
|
|
29
|
+
let changeType = '[Fixed]';
|
|
30
|
+
if (commitMessage.toLowerCase().includes('add')) {
|
|
31
|
+
changeType = '[Added]';
|
|
32
|
+
}
|
|
33
|
+
else if (commitMessage.toLowerCase().includes('improve')) {
|
|
34
|
+
changeType = '[Improved]';
|
|
35
|
+
}
|
|
36
|
+
else if (commitMessage.toLowerCase().includes('remove')) {
|
|
37
|
+
changeType = '[Removed]';
|
|
38
|
+
}
|
|
39
|
+
// Format the message similar to the example
|
|
40
|
+
if (prMatch) {
|
|
41
|
+
formattedMessage = `${changeType} ${commitMessage} - #${prMatch[1]}`;
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
formattedMessage = `${changeType} ${commitMessage}`;
|
|
45
|
+
}
|
|
46
|
+
const isMergeCommit = formattedMessage.includes('Merge branch') || formattedMessage.includes('Merge pull request');
|
|
47
|
+
const isVersionBump = /^\d+\.\d+\.\d+/.test(formattedMessage);
|
|
48
|
+
if (!isMergeCommit &&
|
|
49
|
+
!isVersionBump &&
|
|
50
|
+
formattedMessage !== '' &&
|
|
51
|
+
currentVersion) {
|
|
52
|
+
if (!changelog.releases[currentVersion]) {
|
|
53
|
+
changelog.releases[currentVersion] = [];
|
|
54
|
+
}
|
|
55
|
+
changelog.releases[currentVersion].push(formattedMessage);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
// fallback and defaults
|
|
60
|
+
console.log('fallback and defaults', line);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
// check version and if it's still the default, rename it.
|
|
64
|
+
if (currentVersion === '0.0.0') {
|
|
65
|
+
delete Object.assign(changelog.releases, { ['changes']: changelog.releases['0.0.0'] })['0.0.0'];
|
|
66
|
+
}
|
|
67
|
+
// Sort versions using semver comparison
|
|
68
|
+
const sortedReleases = {};
|
|
69
|
+
Object.keys(changelog.releases)
|
|
70
|
+
.sort((a, b) => {
|
|
71
|
+
// Keep 'changes' at the end
|
|
72
|
+
if (a === 'changes')
|
|
73
|
+
return 1;
|
|
74
|
+
if (b === 'changes')
|
|
75
|
+
return -1;
|
|
76
|
+
// Split version strings into components and ensure numbers (default to 0)
|
|
77
|
+
const aParts = a.split('.').map(part => Number(part) || 0);
|
|
78
|
+
const bParts = b.split('.').map(part => Number(part) || 0);
|
|
79
|
+
// Compare major, minor, and patch versions
|
|
80
|
+
for (let i = 0; i < 3; i++) {
|
|
81
|
+
if (aParts[i] !== bParts[i]) {
|
|
82
|
+
return (bParts?.[i] ?? 0) - (aParts?.[i] ?? 0);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return 0;
|
|
86
|
+
})
|
|
87
|
+
.forEach(key => {
|
|
88
|
+
if (changelog.releases[key]) {
|
|
89
|
+
sortedReleases[key] = changelog.releases[key];
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
changelog.releases = sortedReleases;
|
|
93
|
+
if (write) {
|
|
94
|
+
// Write changelog to file
|
|
95
|
+
fs.writeFileSync('changelog.json', JSON.stringify(changelog, null, 2));
|
|
96
|
+
}
|
|
97
|
+
console.log('Changelog has been generated successfully!');
|
|
98
|
+
return changelog;
|
|
99
|
+
}
|
|
100
|
+
catch (error) {
|
|
101
|
+
console.error('Error generating changelog:', error);
|
|
102
|
+
return {};
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
export { generateChangelog };
|
package/package.json
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kors/generate-changelog",
|
|
3
|
+
"description": "Generate a changelog json from a git commit history",
|
|
4
|
+
"version": "0.1.11",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"bin": {
|
|
7
|
+
"generate-changelog": "./distribution/cli.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"dev": "vite",
|
|
11
|
+
"build": "tsc",
|
|
12
|
+
"preview": "vite preview"
|
|
13
|
+
},
|
|
14
|
+
"author": {
|
|
15
|
+
"name": "Stef Kors",
|
|
16
|
+
"email": "stef.kors+npmpackage@gmail.com",
|
|
17
|
+
"url": "https://github.com/StefKors"
|
|
18
|
+
},
|
|
19
|
+
"repository": "https://github.com/StefKors/generate-changelog",
|
|
20
|
+
"files": [
|
|
21
|
+
"distribution"
|
|
22
|
+
],
|
|
23
|
+
"sideEffects": false,
|
|
24
|
+
"engines": {
|
|
25
|
+
"node": ">=20"
|
|
26
|
+
},
|
|
27
|
+
"exports": {
|
|
28
|
+
"types": "./distribution/index.d.ts",
|
|
29
|
+
"default": "./distribution/index.js"
|
|
30
|
+
},
|
|
31
|
+
"devDependencies": {
|
|
32
|
+
"@types/node": "^22.10.1",
|
|
33
|
+
"typescript": "^5.7.2",
|
|
34
|
+
"vite": "^6.0.1",
|
|
35
|
+
"vite-plugin-dts": "^4.3.0"
|
|
36
|
+
},
|
|
37
|
+
"packageManager": "npm@10.1.0",
|
|
38
|
+
"keywords": [
|
|
39
|
+
"npm",
|
|
40
|
+
"package",
|
|
41
|
+
"changelog",
|
|
42
|
+
"semver",
|
|
43
|
+
"json",
|
|
44
|
+
"versioning",
|
|
45
|
+
"release notes",
|
|
46
|
+
"version tracking",
|
|
47
|
+
"automation",
|
|
48
|
+
"software development",
|
|
49
|
+
"continuous integration",
|
|
50
|
+
"CI/CD",
|
|
51
|
+
"development tools",
|
|
52
|
+
"change tracking",
|
|
53
|
+
"release management",
|
|
54
|
+
"git",
|
|
55
|
+
"git hooks",
|
|
56
|
+
"node.js",
|
|
57
|
+
"command-line tool",
|
|
58
|
+
"open source",
|
|
59
|
+
"developer tools"
|
|
60
|
+
]
|
|
61
|
+
}
|