package-versioner 0.7.0 → 0.7.2

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.
@@ -73,20 +73,23 @@ While primarily used for single packages now, `package-versioner` retains option
73
73
 
74
74
  This is the default if the `synced` flag is present and true.
75
75
 
76
- - **Behavior:** The tool calculates **one** version bump based on the overall history (or branch pattern). This single new version is applied to **all** packages within the repository (or just the root `package.json` if not a structured monorepo). A single Git tag is created (e.g., `v1.2.3`).
76
+ - **Behaviour:** The tool calculates **one** version bump based on the overall history (or branch pattern). This single new version is applied to **all** packages within the repository (or just the root `package.json` if not a structured monorepo). A single Git tag is created.
77
+ - **Tag Behaviour:**
78
+ - In **multi-package monorepos**: Creates global tags like `v1.2.3` regardless of `packageSpecificTags` setting
79
+ - In **single-package repositories**: Respects the `packageSpecificTags` setting - can create either `v1.2.3` or `package-name@v1.2.3`
77
80
  - **Use Case:** Suitable for monorepos where all packages are tightly coupled and released together with the same version number. Also the effective mode for single-package repositories.
78
81
 
79
82
  ### Async Mode (`synced: false`)
80
83
 
81
84
  *(Note: This mode relies heavily on monorepo tooling and structure, like `pnpm workspaces` and correctly configured package dependencies.)*
82
85
 
83
- - **Behavior (Default - No `-t` flag):** The tool analyzes commits to determine which specific packages within the monorepo have changed since the last relevant commit/tag.
86
+ - **Behaviour (Default - No `-t` flag):** The tool analyzes commits to determine which specific packages within the monorepo have changed since the last relevant commit/tag.
84
87
  - It calculates an appropriate version bump **independently for each changed package** based on the commits affecting that package.
85
88
  - Only the `package.json` files of the changed packages are updated.
86
89
  - A **single commit** is created grouping all the version bumps, using the commit message template. **No Git tags are created** in this mode.
87
90
  - **Use Case:** Suitable for monorepos where packages are versioned independently, but a single commit represents the batch of updates for traceability.
88
91
 
89
- - **Behavior (Targeted - With `-t` flag):** When using the `-t, --target <targets>` flag:
92
+ - **Behaviour (Targeted - With `-t` flag):** When using the `-t, --target <targets>` flag:
90
93
  - Only the specified packages (respecting the `skip` list) are considered for versioning.
91
94
  - It calculates an appropriate version bump **independently for each targeted package** based on its commit history.
92
95
  - The `package.json` file of each successfully updated targeted package is modified.
@@ -127,7 +130,7 @@ npx package-versioner --bump major
127
130
  # Result: 1.0.0-beta.1 -> 2.0.0 (not 2.0.0-beta.0)
128
131
  ```
129
132
 
130
- This intuitive behavior means you don't need to use an empty prerelease identifier (`--prerelease ""`) to promote a prerelease to a stable version. Simply specify the standard bump type and the tool will automatically produce a clean version number.
133
+ This intuitive behaviour means you don't need to use an empty prerelease identifier (`--prerelease ""`) to promote a prerelease to a stable version. Simply specify the standard bump type and the tool will automatically produce a clean version number.
131
134
 
132
135
  This applies to all standard bump types:
133
136
  - `--bump major`: 1.0.0-beta.1 -> 2.0.0
@@ -163,6 +166,64 @@ This allows you to maintain consistent versioning across JavaScript and Rust com
163
166
 
164
167
  This dual support makes `package-versioner` suitable for both JavaScript/TypeScript and Rust repositories, as well as monorepos or projects containing both types of packages.
165
168
 
169
+ ## Package Targeting in Monorepos
170
+
171
+ When working with monorepos, you can control which packages are processed for versioning using the `packages` configuration option. This provides flexible targeting with support for various pattern types.
172
+
173
+ ### Package Discovery vs. Targeting
174
+
175
+ It's important to understand the distinction:
176
+
177
+ - **Package Discovery**: Handled by your workspace configuration (pnpm-workspace.yaml, package.json workspaces, etc.)
178
+ - **Package Targeting**: Controlled by the `packages` option in version.config.json to filter which discovered packages to process
179
+
180
+ ### Targeting Patterns
181
+
182
+ #### Exact Package Names
183
+ Target specific packages by their exact names:
184
+ ```json
185
+ {
186
+ "packages": ["@mycompany/core", "@mycompany/utils", "standalone-package"]
187
+ }
188
+ ```
189
+
190
+ #### Scope Wildcards
191
+ Target all packages within a specific scope:
192
+ ```json
193
+ {
194
+ "packages": ["@mycompany/*"]
195
+ }
196
+ ```
197
+ This will match all packages whose names start with `@mycompany/`.
198
+
199
+ #### Global Wildcard
200
+ Target all packages in the workspace:
201
+ ```json
202
+ {
203
+ "packages": ["*"]
204
+ }
205
+ ```
206
+
207
+ #### Mixed Patterns
208
+ Combine different pattern types for flexible targeting:
209
+ ```json
210
+ {
211
+ "packages": ["@mycompany/*", "@utils/logger", "legacy-package"]
212
+ }
213
+ ```
214
+
215
+ ### Excluding Packages
216
+
217
+ Use the `skip` option to exclude specific packages from processing:
218
+ ```json
219
+ {
220
+ "packages": ["@mycompany/*"],
221
+ "skip": ["@mycompany/deprecated-package"]
222
+ }
223
+ ```
224
+
225
+ This configuration will process all packages in the `@mycompany` scope except for `@mycompany/deprecated-package`.
226
+
166
227
  ## Tag Templates and Configuration
167
228
 
168
229
  `package-versioner` provides flexible configuration for how Git tags are formatted, allowing you to customize the tag structure for both single package repositories and monorepos.
@@ -175,34 +236,57 @@ You can customize how tags are formatted using the following configuration optio
175
236
  {
176
237
  "versionPrefix": "v",
177
238
  "tagTemplate": "${prefix}${version}",
178
- "packageTagTemplate": "${packageName}@${prefix}${version}"
239
+ "packageSpecificTags": false
179
240
  }
180
241
  ```
181
242
 
182
243
  - **versionPrefix**: The prefix used for all version numbers in tags (default: `"v"`)
183
- - **tagTemplate**: The template for the main Git tag (default: `"${prefix}${version}"`)
184
- - **packageTagTemplate**: The template for package-specific Git tags in monorepos (default: `"${packageName}@${prefix}${version}"`)
244
+ - **tagTemplate**: The template for Git tags (default: `"${prefix}${version}"`)
245
+ - **packageSpecificTags**: Whether to enable package-specific tagging behaviour (default: `false`)
185
246
 
186
247
  ### Available Template Variables
187
248
 
188
- The tag templates support the following variables:
249
+ The tag template supports the following variables:
189
250
 
190
251
  - `${prefix}`: Replaced with the value of `versionPrefix`
191
252
  - `${version}`: Replaced with the calculated version number
192
- - `${packageName}`: (Only in `packageTagTemplate`) Replaced with the package name
253
+ - `${packageName}`: Replaced with the package name (only populated when `packageSpecificTags` is `true`)
254
+
255
+ ### How Package-Specific Tagging Works
256
+
257
+ The `packageSpecificTags` option controls whether the `${packageName}` variable is populated in your template:
258
+
259
+ - **When `packageSpecificTags` is `false`**: The `${packageName}` variable is empty, so use templates like `${prefix}${version}`
260
+ - **When `packageSpecificTags` is `true`**: The `${packageName}` variable contains the actual package name
193
261
 
194
262
  ### Examples
195
263
 
196
- #### Default Tag Format
197
- With default settings, tags will look like:
198
- - Single repository or synced monorepo: `v1.2.3`
199
- - Package-specific tag in async monorepo: `@scope/package-name@v1.2.3`
264
+ #### Global Versioning (Default)
265
+ ```json
266
+ {
267
+ "versionPrefix": "v",
268
+ "tagTemplate": "${prefix}${version}",
269
+ "packageSpecificTags": false
270
+ }
271
+ ```
272
+ This produces tags like `v1.2.3` for all packages.
273
+
274
+ #### Package-Specific Versioning
275
+ ```json
276
+ {
277
+ "versionPrefix": "v",
278
+ "tagTemplate": "${packageName}@${prefix}${version}",
279
+ "packageSpecificTags": true
280
+ }
281
+ ```
282
+ This produces tags like `@scope/package-name@v1.2.3` for each package.
200
283
 
201
284
  #### Custom Tag Format Examples
202
285
  ```json
203
286
  {
204
287
  "versionPrefix": "",
205
- "tagTemplate": "release-${version}"
288
+ "tagTemplate": "release-${version}",
289
+ "packageSpecificTags": false
206
290
  }
207
291
  ```
208
292
  This would produce tags like `release-1.2.3` instead of `v1.2.3`.
@@ -210,7 +294,89 @@ This would produce tags like `release-1.2.3` instead of `v1.2.3`.
210
294
  ```json
211
295
  {
212
296
  "versionPrefix": "v",
213
- "packageTagTemplate": "${packageName}-${prefix}${version}"
297
+ "tagTemplate": "${packageName}-${prefix}${version}",
298
+ "packageSpecificTags": true
299
+ }
300
+ ```
301
+ This would produce package tags like `@scope/package-name-v1.2.3` instead of `@scope/package-name@v1.2.3`.
302
+
303
+ ### Behaviour in Different Modes
304
+
305
+ - **Synced Mode with Single Package**: When `packageSpecificTags` is `true`, the package name is used even though all packages are versioned together
306
+ - **Synced Mode with Multiple Packages**: Package names are not used regardless of the `packageSpecificTags` setting
307
+ - **Async Mode**: Each package gets its own tag when `packageSpecificTags` is enabled
308
+
309
+ ## Troubleshooting Template Configuration
310
+
311
+ `package-versioner` provides helpful warnings when template configurations don't match your project setup. Here are common issues and their solutions:
312
+
313
+ ### Template Contains ${packageName} but No Package Name Available
314
+
315
+ If you see this warning, it means your template includes `${packageName}` but the tool cannot determine a package name for the current context.
316
+
317
+ **Example Warning:**
318
+ ```
319
+ Warning: Your tagTemplate contains ${packageName} but no package name is available.
320
+ This will result in an empty package name in the tag (e.g., "@v1.0.0" instead of "my-package@v1.0.0").
321
+
322
+ To fix this:
323
+ • If using synced mode: Set "packageSpecificTags": true in your config to enable package names in tags
324
+ • If you want global tags: Remove ${packageName} from your tagTemplate (e.g., use "${prefix}${version}")
325
+ • If using single/async mode: Ensure your package.json has a valid "name" field
326
+ ```
327
+
328
+ **Solutions:**
329
+
330
+ 1. **For Synced Mode with Package Names**: Enable package-specific tags
331
+ ```json
332
+ {
333
+ "synced": true,
334
+ "packageSpecificTags": true,
335
+ "tagTemplate": "${packageName}@${prefix}${version}"
336
+ }
337
+ ```
338
+
339
+ 2. **For Global Tags**: Remove `${packageName}` from your template
340
+ ```json
341
+ {
342
+ "tagTemplate": "${prefix}${version}",
343
+ "packageSpecificTags": false
344
+ }
345
+ ```
346
+
347
+ 3. **For Single/Async Mode**: Ensure your `package.json` has a valid `name` field
348
+ ```json
349
+ {
350
+ "name": "my-package",
351
+ "version": "1.0.0"
352
+ }
353
+ ```
354
+
355
+ ### Common Template Patterns
356
+
357
+ Here are some common template patterns and when to use them:
358
+
359
+ | Pattern | Use Case | Example Output |
360
+ |---------|----------|----------------|
361
+ | `"${prefix}${version}"` | Global versioning, all packages get same tag | `v1.2.3` |
362
+ | `"${packageName}@${prefix}${version}"` | Package-specific versioning | `@scope/package@v1.2.3` |
363
+ | `"release-${version}"` | Custom release format | `release-1.2.3` |
364
+ | `"${packageName}-${version}"` | Simple package versioning | `@scope/package-1.2.3` |
365
+
366
+ ### Commit Message Templates
367
+
368
+ The same principles apply to `commitMessage` templates. If your commit message template includes `${packageName}`, ensure that package names are available in your current mode:
369
+
370
+ ```json
371
+ {
372
+ "commitMessage": "chore: release ${packageName}@${version}",
373
+ "packageSpecificTags": true
374
+ }
375
+ ```
376
+
377
+ For global commit messages, use templates without `${packageName}`:
378
+ ```json
379
+ {
380
+ "commitMessage": "chore: release ${version}"
214
381
  }
215
382
  ```
216
- This would produce package tags like `@scope/package-name-v1.2.3` instead of `@scope/package-name@v1.2.3`.
@@ -18,11 +18,10 @@
18
18
  "default": "${prefix}${version}",
19
19
  "description": "Template for formatting Git tags"
20
20
  },
21
- "packageTagTemplate": {
22
- "type": "string",
23
- "minLength": 1,
24
- "default": "${packageName}@${prefix}${version}",
25
- "description": "Template for formatting package-specific Git tags"
21
+ "packageSpecificTags": {
22
+ "type": "boolean",
23
+ "default": false,
24
+ "description": "Whether to enable package-specific tagging behavior"
26
25
  },
27
26
  "preset": {
28
27
  "type": "string",
@@ -54,7 +53,12 @@
54
53
  "minLength": 1
55
54
  },
56
55
  "default": [],
57
- "description": "List of packages to include in versioning"
56
+ "description": "Array of package names or patterns to target for versioning. Supports exact names (e.g., '@scope/package-a'), scope wildcards (e.g., '@scope/*'), and global wildcards (e.g., '*')"
57
+ },
58
+ "mainPackage": {
59
+ "type": "string",
60
+ "minLength": 1,
61
+ "description": "The package to use for version determination"
58
62
  },
59
63
  "versionStrategy": {
60
64
  "type": "string",
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "package-versioner",
3
3
  "description": "A lightweight yet powerful CLI tool for automated semantic versioning based on Git history and conventional commits.",
4
- "version": "0.7.0",
4
+ "version": "0.7.2",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.mjs",
@@ -39,23 +39,23 @@
39
39
  "devDependencies": {
40
40
  "@biomejs/biome": "^1.9.4",
41
41
  "@types/figlet": "^1.5.5",
42
- "@types/node": "^22.15.17",
42
+ "@types/node": "^24.0.3",
43
43
  "@types/semver": "^7.3.13",
44
- "@vitest/coverage-v8": "^3.1.3",
44
+ "@vitest/coverage-v8": "^3.2.3",
45
45
  "husky": "^9.1.7",
46
- "lint-staged": "^16.0.0",
47
- "tsup": "^8.4.0",
48
- "tsx": "^4.19.4",
46
+ "lint-staged": "^16.1.2",
47
+ "tsup": "^8.5.0",
48
+ "tsx": "^4.20.3",
49
49
  "typescript": "^5.8.3",
50
- "vitest": "^3.1.3"
50
+ "vitest": "^3.2.3"
51
51
  },
52
52
  "dependencies": {
53
53
  "@manypkg/get-packages": "^3.0.0",
54
54
  "chalk": "^5.4.1",
55
- "commander": "^13.1.0",
55
+ "commander": "^14.0.0",
56
56
  "conventional-changelog-angular": "^8.0.0",
57
57
  "conventional-commits-filter": "^5.0.0",
58
- "conventional-recommended-bump": "^11.0.0",
58
+ "conventional-recommended-bump": "^11.2.0",
59
59
  "figlet": "^1.8.1",
60
60
  "git-semver-tags": "^8.0.0",
61
61
  "semver": "^7.7.2",