@releasekit/publish 0.4.0 → 0.5.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.
@@ -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: {
@@ -1284,20 +1296,38 @@ function resolveNotes(bodySource, tag, changelogs, releaseNotesEnabled, pipeline
1284
1296
  function isVersionOnlyTag(tag) {
1285
1297
  return /^v?\d+\.\d+\.\d+/.test(tag);
1286
1298
  }
1287
- function getTitleFromTag(tag) {
1288
- const atIndex = tag.lastIndexOf("@");
1289
- if (atIndex === -1) {
1290
- return tag;
1299
+ function resolveTagPackage(tag, packageNames) {
1300
+ const sorted = [...packageNames].sort((a, b) => sanitizePackageName(b).length - sanitizePackageName(a).length);
1301
+ for (const packageName of sorted) {
1302
+ const atPrefix = `${packageName}@`;
1303
+ if (tag.startsWith(atPrefix)) {
1304
+ return { packageName, version: tag.slice(atPrefix.length) };
1305
+ }
1306
+ const dashPrefix = `${sanitizePackageName(packageName)}-`;
1307
+ if (tag.startsWith(dashPrefix)) {
1308
+ const versionPart = tag.slice(dashPrefix.length);
1309
+ if (/^v?\d/.test(versionPart)) {
1310
+ return { packageName, version: versionPart };
1311
+ }
1312
+ }
1291
1313
  }
1292
- const packageName = tag.slice(0, atIndex);
1293
- const version = tag.slice(atIndex + 1);
1294
- return `${packageName} @ ${version}`;
1314
+ return null;
1315
+ }
1316
+ function getTitleFromTag(tag, packageNames, titleTemplate) {
1317
+ const applyTemplate = (packageName, version) => titleTemplate.replace(/\$\{packageName\}/g, packageName).replace(/\$\{version\}/g, version);
1318
+ if (packageNames.length > 0) {
1319
+ const resolved = resolveTagPackage(tag, packageNames);
1320
+ if (resolved) return applyTemplate(resolved.packageName, resolved.version);
1321
+ }
1322
+ const atIndex = tag.lastIndexOf("@");
1323
+ if (atIndex === -1) return tag;
1324
+ return applyTemplate(tag.slice(0, atIndex), tag.slice(atIndex + 1));
1295
1325
  }
1296
1326
  function findNotesForTag(tag, notes) {
1297
- for (const [packageName, body] of Object.entries(notes)) {
1298
- if (tag.startsWith(`${packageName}@`) && body.trim()) {
1299
- return body;
1300
- }
1327
+ const resolved = resolveTagPackage(tag, Object.keys(notes));
1328
+ if (resolved) {
1329
+ const body = notes[resolved.packageName];
1330
+ if (body?.trim()) return body;
1301
1331
  }
1302
1332
  const entries = Object.values(notes).filter((b) => b.trim());
1303
1333
  if (entries.length === 1 && isVersionOnlyTag(tag)) return entries[0];
@@ -1305,8 +1335,16 @@ function findNotesForTag(tag, notes) {
1305
1335
  }
1306
1336
  function formatChangelogForTag(tag, changelogs) {
1307
1337
  if (changelogs.length === 0) return void 0;
1308
- const changelog = changelogs.find((c) => tag.startsWith(`${c.packageName}@`));
1309
- const target = changelog ?? (changelogs.length === 1 && isVersionOnlyTag(tag) ? changelogs[0] : void 0);
1338
+ const resolved = resolveTagPackage(
1339
+ tag,
1340
+ changelogs.map((c) => c.packageName)
1341
+ );
1342
+ let target;
1343
+ if (resolved) {
1344
+ target = changelogs.find((c) => c.packageName === resolved.packageName);
1345
+ } else if (changelogs.length === 1 && isVersionOnlyTag(tag)) {
1346
+ target = changelogs[0];
1347
+ }
1310
1348
  if (!target || target.entries.length === 0) return void 0;
1311
1349
  const lines = [];
1312
1350
  for (const entry of target.entries) {
@@ -1343,7 +1381,11 @@ async function runGithubReleaseStage(ctx) {
1343
1381
  success: false
1344
1382
  };
1345
1383
  const ghArgs = ["release", "create", tag];
1346
- ghArgs.push("--title", getTitleFromTag(tag));
1384
+ const titlePackageNames = [
1385
+ ...ctx.input.changelogs.map((c) => c.packageName),
1386
+ ...ctx.releaseNotes ? Object.keys(ctx.releaseNotes) : []
1387
+ ];
1388
+ ghArgs.push("--title", getTitleFromTag(tag, [...new Set(titlePackageNames)], config.githubRelease.titleTemplate));
1347
1389
  if (config.githubRelease.draft) {
1348
1390
  ghArgs.push("--draft");
1349
1391
  }
package/dist/cli.js CHANGED
@@ -9,7 +9,7 @@ import {
9
9
  runPipeline,
10
10
  setJsonMode,
11
11
  setLogLevel
12
- } from "./chunk-ZMMZ7S6G.js";
12
+ } from "./chunk-J7B2M2BH.js";
13
13
 
14
14
  // src/cli.ts
15
15
  import { realpathSync } from "fs";
package/dist/index.js CHANGED
@@ -16,7 +16,7 @@ import {
16
16
  parseInput,
17
17
  runPipeline,
18
18
  updateCargoVersion
19
- } from "./chunk-ZMMZ7S6G.js";
19
+ } from "./chunk-J7B2M2BH.js";
20
20
  export {
21
21
  BasePublishError,
22
22
  PipelineError,
@@ -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.4.0",
3
+ "version": "0.5.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",