-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathgenerate-changelog.js
More file actions
97 lines (91 loc) · 3.81 KB
/
Copy pathgenerate-changelog.js
File metadata and controls
97 lines (91 loc) · 3.81 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
#!/usr/bin/env node
// generate-changelog.js
// Script Node.js per generare un CHANGELOG.md completo dai commit git
import { execSync } from 'child_process';
import { writeFileSync } from 'fs';
function getGitLogByTag() {
// Ottieni i log raggruppati per tag (release)
// Usa git tag per trovare le release, poi git log per ogni intervallo
const tags = execSync('git tag --sort=-creatordate', { encoding: 'utf8' })
.split('\n')
.filter(Boolean);
let changelog = '';
// Funzione per categorizzare i commit
function categorizeCommits(logLines) {
const features = [];
const fixes = [];
const others = [];
for (const line of logLines) {
// Salta i commit di merge
if (/Merge (branch|pull request|remote-tracking branch|.*)/i.test(line)) continue;
const match = line.match(/^(\w+) (\d{4}-\d{2}-\d{2}) (.+)$/);
if (match) {
let [, hash, date, message] = match;
// Replace (close #123) or (#123) with markdown link to GitHub issue
message = message.replace(/\(close #(\d+)\)/gi, (_, p1) => `(close [#${p1}](https://github.com/sensorario/quadrato/issues/${p1}))`);
const hashLink = `[${hash}](https://github.com/sensorario/quadrato/commit/${hash})`;
if (/^(feat|feature|add|implement)/i.test(message)) {
features.push(`- ${message} (${hashLink}, ${date})`);
} else if (/^(fix|bug|hotfix|patch|resolve)/i.test(message)) {
fixes.push(`- ${message} (${hashLink}, ${date})`);
} else {
others.push(`- ${message} (${hashLink}, ${date})`);
}
}
}
let result = '';
if (features.length) {
result += '\n\n### Features\n' + features.join('\n') + '\n';
}
if (fixes.length) {
result += '\n\n### Fixes\n' + fixes.join('\n') + '\n';
}
// Salta la sezione Other
return result;
}
if (tags.length === 0) {
// Nessun tag: mostra tutti i commit
const log = execSync('git log --pretty=format:"%h %ad %s" --date=short', { encoding: 'utf8' });
changelog += '\n\n## Unreleased (??/??/???)\n';
changelog += categorizeCommits(log.split('\n'));
return changelog;
}
// Prima release: dalla prima commit al primo tag
for (let i = 0; i < tags.length; i++) {
const tag = tags[i];
let range = '';
if (i === tags.length - 1) {
range = tag;
} else {
range = `${tags[i + 1]}..${tag}`;
}
// Recupera la data del tag
let tagDate = '';
try {
tagDate = execSync(`git log -1 --format=%ad --date=short ${tag}`, { encoding: 'utf8' }).trim();
} catch (e) {
console.warn(`Impossibile ottenere la data per il tag ${tag}:`, e);
tagDate = '';
}
const log = execSync(`git log ${range} --pretty=format:"%h %ad %s" --date=short`, { encoding: 'utf8' });
changelog += `\n\n## ${tag}${tagDate ? ` (${tagDate})` : ''}\n`;
changelog += categorizeCommits(log.split('\n'));
}
// Commits dopo l'ultimo tag (Unreleased)
const latestTag = tags[0];
const logUnreleased = execSync(`git log ${latestTag}..HEAD --pretty=format:"%h %ad %s" --date=short`, { encoding: 'utf8' });
if (logUnreleased.trim()) {
changelog = '\n\n## Unreleased (??/??/????)\n' + categorizeCommits(logUnreleased.split('\n')) + changelog;
}
return changelog;
}
function formatChangelog(log) {
return '# CHANGELOG\n' + log;
}
function main() {
const log = getGitLogByTag();
const changelog = formatChangelog(log);
writeFileSync('CHANGELOG.md', changelog);
console.log('CHANGELOG.md generato!');
}
main();