-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrelease.config.cjs
More file actions
170 lines (158 loc) · 5.53 KB
/
Copy pathrelease.config.cjs
File metadata and controls
170 lines (158 loc) · 5.53 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
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
const { execFileSync } = require("node:child_process");
const path = require("node:path");
const COMMIT_HASH_LENGTH = 7;
const DEPENDENCY_SECTION = "Dependencies";
/** Un commit de mise à jour de dépendances (chore/build sur deps|deps-dev). */
function isDependencyCommit(commit) {
const isDepsScope = commit.scope === "deps" || commit.scope === "deps-dev";
return isDepsScope && (commit.type === "build" || commit.type === "chore");
}
// Transform basé sur le préset `conventional-changelog-angular`, étendu pour
// regrouper les commits de dépendances dans une section « Dependencies » (qui
// serait sinon masquée). Le reste du comportement (liens, hash court, notes de
// breaking changes) est conservé à l'identique.
//
// Pourquoi un transform maison plutôt que le préset `conventionalcommits`
// (qui supporte nativement des sections par type/scope) :
// - `@semantic-release/release-notes-generator@14` (dernière version, tout
// comme `semantic-release@25`) est câblé sur `conventional-changelog-writer@8`.
// - Le préset `conventional-changelog-conventionalcommits@10` présent dans
// l'arbre (tiré par `@commitlint/config-conventional`, PAS par
// semantic-release) cible l'API du writer@9 → notes entièrement VIDES.
// - Aligner les versions est impossible sans casse : commitlint exige
// conventionalcommits@10, le notes-generator exigerait @8 ; un override npm
// global casserait l'un ou l'autre, et aucune release semantic-release
// n'utilise encore writer@9.
// À migrer vers `preset: "conventionalcommits"` + `presetConfig.types` le jour
// où un release-notes-generator basé sur writer@9 sera publié.
function transformCommit(commit, context) {
let discard = true;
const notes = commit.notes.map((note) => {
discard = false;
return { ...note, title: "BREAKING CHANGES" };
});
let { type } = commit;
if (isDependencyCommit(commit)) {
type = DEPENDENCY_SECTION;
} else if (commit.type === "feat") {
type = "Features";
} else if (commit.type === "fix") {
type = "Bug Fixes";
} else if (commit.type === "perf") {
type = "Performance Improvements";
} else if (commit.type === "revert" || commit.revert) {
type = "Reverts";
} else if (discard) {
return undefined;
} else if (commit.type === "docs") {
type = "Documentation";
} else if (commit.type === "style") {
type = "Styles";
} else if (commit.type === "refactor") {
type = "Code Refactoring";
} else if (commit.type === "test") {
type = "Tests";
} else if (commit.type === "build") {
type = "Build System";
} else if (commit.type === "ci") {
type = "Continuous Integration";
}
const scope = commit.scope === "*" ? "" : commit.scope;
const shortHash =
typeof commit.hash === "string"
? commit.hash.substring(0, COMMIT_HASH_LENGTH)
: commit.shortHash;
const issues = [];
let { subject } = commit;
if (typeof subject === "string") {
let url = context.repository
? `${context.host}/${context.owner}/${context.repository}`
: context.repoUrl;
if (url) {
url = `${url}/issues/`;
subject = subject.replace(/#([0-9]+)/g, (_, issue) => {
issues.push(issue);
return `[#${issue}](${url}${issue})`;
});
}
if (context.host) {
subject = subject.replace(
/`[^`]*`|\B@([a-z0-9](?:-?[a-z0-9/]){0,38})/g,
(match, username) => {
if (!username) return match;
if (username.includes("/")) return `@${username}`;
return `[@${username}](${context.host}/${username})`;
}
);
}
}
const references = commit.references.filter(
(reference) => !issues.includes(reference.issue)
);
return { notes, type, scope, shortHash, subject, references };
}
/** @type {import('semantic-release').GlobalConfig} */
module.exports = {
branches: ["main"],
plugins: [
[
"@semantic-release/commit-analyzer",
{
// Les mises à jour de dépendances déclenchent une minor, que ce soit via
// chore(deps) ou via les commits Dependabot build(deps)/build(deps-dev).
// Les règles personnalisées sont évaluées avant les règles par défaut
// (feat → minor, fix → patch).
releaseRules: [
{ type: "chore", scope: "deps", release: "minor" },
{ type: "build", scope: "deps", release: "minor" },
{ type: "build", scope: "deps-dev", release: "minor" },
],
},
],
[
"@semantic-release/release-notes-generator",
{
// Préset angular par défaut, avec un transform étendu pour la section
// « Dependencies ». (Le préset conventionalcommits n'est pas compatible
// avec la version de conventional-changelog-writer utilisée ici.)
writerOpts: { transform: transformCommit },
},
],
[
"@semantic-release/changelog",
{
changelogFile: "CHANGELOG.md",
},
],
[
"@semantic-release/npm",
{
npmPublish: false,
},
],
{
prepare() {
execFileSync(
process.execPath,
[path.join(__dirname, "scripts/sync-release-examples.mjs")],
{ stdio: "inherit" }
);
},
},
[
"@semantic-release/git",
{
assets: [
"CHANGELOG.md",
"package.json",
"package-lock.json",
"docker-compose.yml",
"README.md",
],
message:
"chore(release): ${nextRelease.version} [skip ci]\n\n${nextRelease.notes}",
},
],
"@semantic-release/github",
],
};