-
-
Notifications
You must be signed in to change notification settings - Fork 55
Expand file tree
/
Copy path.versionrc.js
More file actions
146 lines (125 loc) · 4.94 KB
/
.versionrc.js
File metadata and controls
146 lines (125 loc) · 4.94 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
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
const sectionTitleByType = {
feat: 'Features',
fix: 'Bug Fixes',
docs: 'Documentation',
test: 'Tests',
ci: 'Continuous Integration',
// chore/refactor/build stay hidden via "types" in package.json (you already did that)
};
// Pretty names for well-known scopes -> shown as bold subsection labels
const prettyScope = (scope) => {
if (!scope) return null;
const map = {
connection: 'Connection Rendering Improvements',
connections: 'Connection Rendering Improvements',
canvas: 'Canvas & Zoom',
zoom: 'Canvas & Zoom',
examples: 'Examples',
docs: 'Documentation',
};
return map[scope.toLowerCase()] || null;
};
// group commits with the same subject (or very similar) to avoid duplicates
function dedupeCommitGroups(commitGroups) {
for (const group of commitGroups) {
const seen = new Map(); // subject -> commit
const next = [];
for (const c of group.commits) {
const key = (c.subject || '').trim().toLowerCase();
if (!key) {
next.push(c);
continue;
}
if (!seen.has(key)) {
seen.set(key, c);
next.push(c);
} else {
// merge hashes into the first occurrence (so you can show multiple short hashes if desired)
const first = seen.get(key);
first._extraHashes = first._extraHashes || [];
first._extraHashes.push(c.shortHash);
}
}
group.commits = next;
}
return commitGroups;
}
module.exports = {
header:
'# Changelog\n\nAll notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines.\n',
types: [
// Order here defines section order
{ type: 'feat', section: sectionTitleByType.feat },
{ type: 'fix', section: sectionTitleByType.fix },
{ type: 'docs', section: sectionTitleByType.docs },
{ type: 'test', section: sectionTitleByType.test },
{ type: 'ci', section: sectionTitleByType.ci, hidden: true },
{ type: 'chore', hidden: true },
{ type: 'style', hidden: true },
{ type: 'refactor', hidden: true },
{ type: 'build', hidden: true },
{ type: 'revert', hidden: true },
],
commitUrlFormat: '{{host}}/{{owner}}/{{repository}}/commit/{{hash}}',
compareUrlFormat: '{{host}}/{{owner}}/{{repository}}/compare/{{previousTag}}...{{currentTag}}',
issueUrlFormat: '{{host}}/{{owner}}/{{repository}}/issues/{{id}}',
// Fine-grained control over how commits are transformed & printed
writerOpts: {
groupBy: 'type',
// Ensure groups/commits are sorted predictably
commitGroupsSort: (a, b) => {
const order = ['Features', 'Bug Fixes', 'Documentation', 'Tests', 'Continuous Integration'];
return order.indexOf(a.title) - order.indexOf(b.title);
},
commitsSort: ['scope', 'subject'],
// Transform each commit: normalize titles, enrich scope, strip noise
transform: (commit, context) => {
if (!commit || !commit.type) return;
// map conventional commit type -> section title
const mapped = sectionTitleByType[commit.type];
if (!mapped) return; // hidden types are dropped
// Standardize commit header elements
commit.type = mapped;
// Normalize subject spacing
if (commit.subject) commit.subject = commit.subject.replace(/\s+/g, ' ').trim();
// Pretty scope (optional bold label in output)
commit._prettyScope = prettyScope(commit.scope);
// Render a short commit URL
if (context.repository && context.commit && commit.hash) {
commit.shortHash = commit.hash.substring(0, 7);
}
return commit;
},
// After the parser groups commits, we can adjust groups, dedupe, etc.
finalizeContext: (context) => {
if (Array.isArray(context.commitGroups)) {
// Deduplicate identical subjects inside each group
context.commitGroups = dedupeCommitGroups(context.commitGroups);
// Optionally: bubble "Documentation" to the end if present (already covered by commitGroupsSort)
}
return context;
},
// Main section template (matches your style)
mainTemplate: `{{> header}}
{{#each releases}}
### [{{version}}]({{compareUrl}}) ({{datetime date}})
{{#each commitGroups}}
### {{title}}
{{#if commits}}
{{#each commits}}
- {{#if this._prettyScope}}**{{this._prettyScope}}** — {{/if}}{{subject}} ({{#if @root.commitUrlFormat}}[{{shortHash}}]({{commitUrl}}){{else}}{{shortHash}}{{/if}}{{#if this._extraHashes}}; also {{#each this._extraHashes}}[{{this}}]({{../commitUrl}}){{#unless @last}}, {{/unless}}{{/each}}{{/if}})
{{/each}}
{{/if}}
{{/each}}
{{/each}}
`,
// Header partial — keep the top “Changelog” header as-is
headerPartial: '{{#if isPatch}}##{{/if}}',
// Commit partial — unused because we fully control the bullet above
commitPartial: '',
},
// Use the default parserOpts (Conventional Commits). You can tweak if needed:
parserOpts: {
noteKeywords: ['BREAKING CHANGE', 'BREAKING CHANGES'],
},
};