@releasekit/publish 0.4.1 → 0.6.0
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/dist/{chunk-ZMMZ7S6G.js → chunk-53BGK2JF.js} +64 -25
- package/dist/cli.js +1 -1
- package/dist/index.js +1 -1
- package/docs/github-releases.md +25 -1
- package/package.json +3 -3
|
@@ -93,6 +93,9 @@ var EXIT_CODES = {
|
|
|
93
93
|
VERSION_ERROR: 8,
|
|
94
94
|
PUBLISH_ERROR: 9
|
|
95
95
|
};
|
|
96
|
+
function sanitizePackageName(name) {
|
|
97
|
+
return name.startsWith("@") ? name.slice(1).replace(/\//g, "-") : name;
|
|
98
|
+
}
|
|
96
99
|
|
|
97
100
|
// ../config/dist/index.js
|
|
98
101
|
import * as fs2 from "fs";
|
|
@@ -230,7 +233,13 @@ var GitHubReleaseConfigSchema = z.object({
|
|
|
230
233
|
* - 'generated': Use GitHub's auto-generated notes.
|
|
231
234
|
* - 'none': No body.
|
|
232
235
|
*/
|
|
233
|
-
body: z.enum(["auto", "releaseNotes", "changelog", "generated", "none"]).default("auto")
|
|
236
|
+
body: z.enum(["auto", "releaseNotes", "changelog", "generated", "none"]).default("auto"),
|
|
237
|
+
/**
|
|
238
|
+
* Template string for the GitHub release title when a package name is resolved.
|
|
239
|
+
* Available variables: ${packageName} (original scoped name), ${version} (e.g. "v1.0.0").
|
|
240
|
+
* Version-only tags (e.g. "v1.0.0") always use the tag as-is.
|
|
241
|
+
*/
|
|
242
|
+
titleTemplate: z.string().default("${packageName}: ${version}")
|
|
234
243
|
});
|
|
235
244
|
var VerifyRegistryConfigSchema = z.object({
|
|
236
245
|
enabled: z.boolean().default(true),
|
|
@@ -274,7 +283,8 @@ var PublishConfigSchema = z.object({
|
|
|
274
283
|
draft: true,
|
|
275
284
|
perPackage: true,
|
|
276
285
|
prerelease: "auto",
|
|
277
|
-
body: "auto"
|
|
286
|
+
body: "auto",
|
|
287
|
+
titleTemplate: "${packageName}: ${version}"
|
|
278
288
|
}),
|
|
279
289
|
verify: VerifyConfigSchema.default({
|
|
280
290
|
npm: {
|
|
@@ -547,7 +557,8 @@ function getDefaultConfig() {
|
|
|
547
557
|
draft: true,
|
|
548
558
|
perPackage: true,
|
|
549
559
|
prerelease: "auto",
|
|
550
|
-
body: "auto"
|
|
560
|
+
body: "auto",
|
|
561
|
+
titleTemplate: "${packageName}: ${version}"
|
|
551
562
|
},
|
|
552
563
|
verify: {
|
|
553
564
|
npm: {
|
|
@@ -597,7 +608,8 @@ function toPublishConfig(config) {
|
|
|
597
608
|
draft: config.githubRelease?.draft ?? defaults.githubRelease.draft,
|
|
598
609
|
perPackage: config.githubRelease?.perPackage ?? defaults.githubRelease.perPackage,
|
|
599
610
|
prerelease: config.githubRelease?.prerelease ?? defaults.githubRelease.prerelease,
|
|
600
|
-
body: config.githubRelease?.body ?? defaults.githubRelease.body
|
|
611
|
+
body: config.githubRelease?.body ?? defaults.githubRelease.body,
|
|
612
|
+
titleTemplate: config.githubRelease?.titleTemplate ?? defaults.githubRelease.titleTemplate
|
|
601
613
|
},
|
|
602
614
|
verify: {
|
|
603
615
|
npm: {
|
|
@@ -1264,9 +1276,9 @@ function resolveNotes(bodySource, tag, changelogs, releaseNotesEnabled, pipeline
|
|
|
1264
1276
|
return { useGithubNotes: true };
|
|
1265
1277
|
}
|
|
1266
1278
|
if (bodySource === "changelog") {
|
|
1267
|
-
const
|
|
1268
|
-
if (
|
|
1269
|
-
return { body:
|
|
1279
|
+
const packageBody = formatChangelogForTag(tag, changelogs);
|
|
1280
|
+
if (packageBody) {
|
|
1281
|
+
return { body: packageBody, useGithubNotes: false };
|
|
1270
1282
|
}
|
|
1271
1283
|
warn("No changelog found for tag, falling back to GitHub auto-notes");
|
|
1272
1284
|
return { useGithubNotes: true };
|
|
@@ -1274,30 +1286,45 @@ function resolveNotes(bodySource, tag, changelogs, releaseNotesEnabled, pipeline
|
|
|
1274
1286
|
if (releaseNotesEnabled && pipelineNotes) {
|
|
1275
1287
|
const body = findNotesForTag(tag, pipelineNotes);
|
|
1276
1288
|
if (body) return { body, useGithubNotes: false };
|
|
1277
|
-
|
|
1278
|
-
const packageBody = formatChangelogForTag(tag, changelogs);
|
|
1279
|
-
if (packageBody) {
|
|
1280
|
-
return { body: packageBody, useGithubNotes: false };
|
|
1289
|
+
warn(`Release notes configured but no content found for tag ${tag}, falling back to GitHub auto-generated notes`);
|
|
1281
1290
|
}
|
|
1282
1291
|
return { useGithubNotes: true };
|
|
1283
1292
|
}
|
|
1284
1293
|
function isVersionOnlyTag(tag) {
|
|
1285
1294
|
return /^v?\d+\.\d+\.\d+/.test(tag);
|
|
1286
1295
|
}
|
|
1287
|
-
function
|
|
1288
|
-
const
|
|
1289
|
-
|
|
1290
|
-
|
|
1296
|
+
function resolveTagPackage(tag, packageNames) {
|
|
1297
|
+
const sorted = [...packageNames].sort((a, b) => sanitizePackageName(b).length - sanitizePackageName(a).length);
|
|
1298
|
+
for (const packageName of sorted) {
|
|
1299
|
+
const atPrefix = `${packageName}@`;
|
|
1300
|
+
if (tag.startsWith(atPrefix)) {
|
|
1301
|
+
return { packageName, version: tag.slice(atPrefix.length) };
|
|
1302
|
+
}
|
|
1303
|
+
const dashPrefix = `${sanitizePackageName(packageName)}-`;
|
|
1304
|
+
if (tag.startsWith(dashPrefix)) {
|
|
1305
|
+
const versionPart = tag.slice(dashPrefix.length);
|
|
1306
|
+
if (/^v?\d/.test(versionPart)) {
|
|
1307
|
+
return { packageName, version: versionPart };
|
|
1308
|
+
}
|
|
1309
|
+
}
|
|
1291
1310
|
}
|
|
1292
|
-
|
|
1293
|
-
|
|
1294
|
-
|
|
1311
|
+
return null;
|
|
1312
|
+
}
|
|
1313
|
+
function getTitleFromTag(tag, packageNames, titleTemplate) {
|
|
1314
|
+
const applyTemplate = (packageName, version) => titleTemplate.replace(/\$\{packageName\}/g, packageName).replace(/\$\{version\}/g, version);
|
|
1315
|
+
if (packageNames.length > 0) {
|
|
1316
|
+
const resolved = resolveTagPackage(tag, packageNames);
|
|
1317
|
+
if (resolved) return applyTemplate(resolved.packageName, resolved.version);
|
|
1318
|
+
}
|
|
1319
|
+
const atIndex = tag.lastIndexOf("@");
|
|
1320
|
+
if (atIndex === -1) return tag;
|
|
1321
|
+
return applyTemplate(tag.slice(0, atIndex), tag.slice(atIndex + 1));
|
|
1295
1322
|
}
|
|
1296
1323
|
function findNotesForTag(tag, notes) {
|
|
1297
|
-
|
|
1298
|
-
|
|
1299
|
-
|
|
1300
|
-
|
|
1324
|
+
const resolved = resolveTagPackage(tag, Object.keys(notes));
|
|
1325
|
+
if (resolved) {
|
|
1326
|
+
const body = notes[resolved.packageName];
|
|
1327
|
+
if (body?.trim()) return body;
|
|
1301
1328
|
}
|
|
1302
1329
|
const entries = Object.values(notes).filter((b) => b.trim());
|
|
1303
1330
|
if (entries.length === 1 && isVersionOnlyTag(tag)) return entries[0];
|
|
@@ -1305,8 +1332,16 @@ function findNotesForTag(tag, notes) {
|
|
|
1305
1332
|
}
|
|
1306
1333
|
function formatChangelogForTag(tag, changelogs) {
|
|
1307
1334
|
if (changelogs.length === 0) return void 0;
|
|
1308
|
-
const
|
|
1309
|
-
|
|
1335
|
+
const resolved = resolveTagPackage(
|
|
1336
|
+
tag,
|
|
1337
|
+
changelogs.map((c) => c.packageName)
|
|
1338
|
+
);
|
|
1339
|
+
let target;
|
|
1340
|
+
if (resolved) {
|
|
1341
|
+
target = changelogs.find((c) => c.packageName === resolved.packageName);
|
|
1342
|
+
} else if (changelogs.length === 1 && isVersionOnlyTag(tag)) {
|
|
1343
|
+
target = changelogs[0];
|
|
1344
|
+
}
|
|
1310
1345
|
if (!target || target.entries.length === 0) return void 0;
|
|
1311
1346
|
const lines = [];
|
|
1312
1347
|
for (const entry of target.entries) {
|
|
@@ -1343,7 +1378,11 @@ async function runGithubReleaseStage(ctx) {
|
|
|
1343
1378
|
success: false
|
|
1344
1379
|
};
|
|
1345
1380
|
const ghArgs = ["release", "create", tag];
|
|
1346
|
-
|
|
1381
|
+
const titlePackageNames = [
|
|
1382
|
+
...ctx.input.changelogs.map((c) => c.packageName),
|
|
1383
|
+
...ctx.releaseNotes ? Object.keys(ctx.releaseNotes) : []
|
|
1384
|
+
];
|
|
1385
|
+
ghArgs.push("--title", getTitleFromTag(tag, [...new Set(titlePackageNames)], config.githubRelease.titleTemplate));
|
|
1347
1386
|
if (config.githubRelease.draft) {
|
|
1348
1387
|
ghArgs.push("--draft");
|
|
1349
1388
|
}
|
package/dist/cli.js
CHANGED
package/dist/index.js
CHANGED
package/docs/github-releases.md
CHANGED
|
@@ -140,6 +140,29 @@ Set `"draft": false` to publish releases immediately.
|
|
|
140
140
|
|
|
141
141
|
---
|
|
142
142
|
|
|
143
|
+
## Release Title (`titleTemplate`)
|
|
144
|
+
|
|
145
|
+
Controls the title of each GitHub Release when a package name is resolved from the tag.
|
|
146
|
+
|
|
147
|
+
```json
|
|
148
|
+
{
|
|
149
|
+
"publish": {
|
|
150
|
+
"githubRelease": {
|
|
151
|
+
"titleTemplate": "${packageName}: ${version}"
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
| Variable | Value |
|
|
158
|
+
|----------|-------|
|
|
159
|
+
| `${packageName}` | Original scoped package name, e.g. `@scope/pkg` |
|
|
160
|
+
| `${version}` | Version string extracted from the tag, e.g. `v1.0.0` |
|
|
161
|
+
|
|
162
|
+
The default produces titles like `@releasekit/version: v1.0.0`. Version-only tags (e.g. `v1.0.0` with no package prefix) always use the tag string directly.
|
|
163
|
+
|
|
164
|
+
---
|
|
165
|
+
|
|
143
166
|
## Per-Package Releases
|
|
144
167
|
|
|
145
168
|
In a monorepo, a separate GitHub Release is created for each published package by default.
|
|
@@ -168,7 +191,8 @@ Set `"perPackage": false` to create a single release for the entire repo.
|
|
|
168
191
|
"draft": true,
|
|
169
192
|
"prerelease": "auto",
|
|
170
193
|
"perPackage": true,
|
|
171
|
-
"body": "auto"
|
|
194
|
+
"body": "auto",
|
|
195
|
+
"titleTemplate": "${packageName}: ${version}"
|
|
172
196
|
}
|
|
173
197
|
}
|
|
174
198
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@releasekit/publish",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.6.0",
|
|
4
4
|
"description": "Publish packages to npm and crates.io with git tagging and GitHub releases",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -63,8 +63,8 @@
|
|
|
63
63
|
"tsup": "^8.5.1",
|
|
64
64
|
"typescript": "^5.9.3",
|
|
65
65
|
"vitest": "^4.1.0",
|
|
66
|
-
"@releasekit/
|
|
67
|
-
"@releasekit/
|
|
66
|
+
"@releasekit/config": "0.0.0",
|
|
67
|
+
"@releasekit/core": "0.0.0"
|
|
68
68
|
},
|
|
69
69
|
"engines": {
|
|
70
70
|
"node": ">=20"
|