@edcalderon/versioning 1.0.3 → 1.0.4
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/README.md +37 -23
- package/dist/cli.js +19 -4
- package/dist/extensions.d.ts +17 -0
- package/dist/extensions.js +104 -0
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -11,6 +11,7 @@ A comprehensive versioning and changelog management tool designed for monorepos
|
|
|
11
11
|
- 📦 NPM publishable
|
|
12
12
|
- 🏷️ Git tagging and committing
|
|
13
13
|
- ✅ Validation of version sync
|
|
14
|
+
- 🔌 **Extensible plugin system** for custom business logic
|
|
14
15
|
|
|
15
16
|
## Installation
|
|
16
17
|
|
|
@@ -22,21 +23,34 @@ pnpm add -g @edcalderon/versioning
|
|
|
22
23
|
yarn global add @edcalderon/versioning
|
|
23
24
|
```
|
|
24
25
|
|
|
26
|
+
## Extensions
|
|
27
|
+
|
|
28
|
+
The versioning tool supports a **composable extension system** that allows you to add custom business logic and commands. Extensions can:
|
|
29
|
+
|
|
30
|
+
- Add new CLI commands
|
|
31
|
+
- Hook into existing workflows (pre/post version bumps, releases, etc.)
|
|
32
|
+
- Integrate with external services
|
|
33
|
+
- Implement custom versioning strategies
|
|
34
|
+
|
|
35
|
+
Extensions are loaded automatically from:
|
|
36
|
+
- Built-in extensions in the `src/extensions/` directory
|
|
37
|
+
- External packages listed in `versioning.config.json`
|
|
38
|
+
|
|
25
39
|
## Quick Start
|
|
26
40
|
|
|
27
41
|
1. Initialize configuration:
|
|
28
42
|
```bash
|
|
29
|
-
|
|
43
|
+
versioning init
|
|
30
44
|
```
|
|
31
45
|
|
|
32
46
|
2. Bump version and generate changelog:
|
|
33
47
|
```bash
|
|
34
|
-
|
|
48
|
+
versioning bump patch
|
|
35
49
|
```
|
|
36
50
|
|
|
37
51
|
3. Sync versions across packages (for monorepos):
|
|
38
52
|
```bash
|
|
39
|
-
|
|
53
|
+
versioning sync
|
|
40
54
|
```
|
|
41
55
|
|
|
42
56
|
### Edward's Monorepo Example
|
|
@@ -45,7 +59,7 @@ For this specific monorepo with dashboard app:
|
|
|
45
59
|
|
|
46
60
|
```bash
|
|
47
61
|
# Initialize config
|
|
48
|
-
|
|
62
|
+
versioning init
|
|
49
63
|
|
|
50
64
|
# Edit versioning.config.json to:
|
|
51
65
|
{
|
|
@@ -54,10 +68,10 @@ ed-version init
|
|
|
54
68
|
}
|
|
55
69
|
|
|
56
70
|
# Sync dashboard with main version
|
|
57
|
-
|
|
71
|
+
versioning patch --packages "apps/dashboard"
|
|
58
72
|
|
|
59
73
|
# Versioning package maintains its own version
|
|
60
|
-
cd packages/versioning &&
|
|
74
|
+
cd packages/versioning && versioning patch --skip-sync
|
|
61
75
|
```
|
|
62
76
|
|
|
63
77
|
## Configuration
|
|
@@ -101,39 +115,39 @@ For monorepos:
|
|
|
101
115
|
|
|
102
116
|
### Release Commands
|
|
103
117
|
|
|
104
|
-
#### `
|
|
118
|
+
#### `versioning patch [options]`
|
|
105
119
|
|
|
106
120
|
Create a patch release (bumps 1.0.0 → 1.0.1)
|
|
107
121
|
|
|
108
122
|
```bash
|
|
109
|
-
|
|
110
|
-
|
|
123
|
+
versioning patch
|
|
124
|
+
versioning patch --packages "packages/app1,packages/app2" --message "Fix critical bug"
|
|
111
125
|
```
|
|
112
126
|
|
|
113
|
-
#### `
|
|
127
|
+
#### `versioning minor [options]`
|
|
114
128
|
|
|
115
129
|
Create a minor release (bumps 1.0.0 → 1.1.0)
|
|
116
130
|
|
|
117
131
|
```bash
|
|
118
|
-
|
|
119
|
-
|
|
132
|
+
versioning minor
|
|
133
|
+
versioning minor --packages "apps/dashboard" --message "Add new features"
|
|
120
134
|
```
|
|
121
135
|
|
|
122
|
-
#### `
|
|
136
|
+
#### `versioning major [options]`
|
|
123
137
|
|
|
124
138
|
Create a major release (bumps 1.0.0 → 2.0.0)
|
|
125
139
|
|
|
126
140
|
```bash
|
|
127
|
-
|
|
141
|
+
versioning major --message "Breaking changes"
|
|
128
142
|
```
|
|
129
143
|
|
|
130
|
-
#### `
|
|
144
|
+
#### `versioning release <version> [options]`
|
|
131
145
|
|
|
132
146
|
Create a custom release with specific version
|
|
133
147
|
|
|
134
148
|
```bash
|
|
135
|
-
|
|
136
|
-
|
|
149
|
+
versioning release 1.2.3 --message "Custom release"
|
|
150
|
+
versioning release 2.0.0-beta.1 --skip-sync
|
|
137
151
|
```
|
|
138
152
|
|
|
139
153
|
**Options for release commands:**
|
|
@@ -156,7 +170,7 @@ Options:
|
|
|
156
170
|
- `--no-commit`: Don't commit changes
|
|
157
171
|
- `--no-tag`: Don't create git tag
|
|
158
172
|
|
|
159
|
-
### `
|
|
173
|
+
### `versioning changelog [options]`
|
|
160
174
|
|
|
161
175
|
Generate changelog from commits.
|
|
162
176
|
|
|
@@ -165,7 +179,7 @@ Options:
|
|
|
165
179
|
- `-t, --to <commit>`: To commit
|
|
166
180
|
- `-c, --config <file>`: Config file path
|
|
167
181
|
|
|
168
|
-
### `
|
|
182
|
+
### `versioning sync [options]`
|
|
169
183
|
|
|
170
184
|
Sync versions across all packages.
|
|
171
185
|
|
|
@@ -173,14 +187,14 @@ Options:
|
|
|
173
187
|
- `-v, --version <version>`: Target version to sync to
|
|
174
188
|
- `-c, --config <file>`: Config file path
|
|
175
189
|
|
|
176
|
-
### `
|
|
190
|
+
### `versioning validate [options]`
|
|
177
191
|
|
|
178
192
|
Validate that all packages have the correct version.
|
|
179
193
|
|
|
180
194
|
Options:
|
|
181
195
|
- `-c, --config <file>`: Config file path
|
|
182
196
|
|
|
183
|
-
### `
|
|
197
|
+
### `versioning init [options]`
|
|
184
198
|
|
|
185
199
|
Initialize a new versioning config file.
|
|
186
200
|
|
|
@@ -205,7 +219,7 @@ Add to your release workflow:
|
|
|
205
219
|
Use with husky for automated versioning:
|
|
206
220
|
|
|
207
221
|
```bash
|
|
208
|
-
npx husky add .husky/pre-commit "
|
|
222
|
+
npx husky add .husky/pre-commit "versioning validate"
|
|
209
223
|
```
|
|
210
224
|
|
|
211
225
|
## Conventional Commits
|
|
@@ -232,7 +246,7 @@ This package uses GitHub Actions for automated publishing to NPM when version ta
|
|
|
232
246
|
|
|
233
247
|
1. **Update Version**: Use the versioning commands to bump version and update changelog
|
|
234
248
|
```bash
|
|
235
|
-
|
|
249
|
+
versioning patch # or minor, major
|
|
236
250
|
```
|
|
237
251
|
|
|
238
252
|
2. **Create Git Tag**: The package includes a helper script to create and push version tags
|
package/dist/cli.js
CHANGED
|
@@ -40,11 +40,12 @@ const versioning_1 = require("./versioning");
|
|
|
40
40
|
const changelog_1 = require("./changelog");
|
|
41
41
|
const sync_1 = require("./sync");
|
|
42
42
|
const release_1 = require("./release");
|
|
43
|
+
const extensions_1 = require("./extensions");
|
|
43
44
|
const program = new commander_1.Command();
|
|
44
45
|
program
|
|
45
|
-
.name('
|
|
46
|
+
.name('versioning')
|
|
46
47
|
.description('Comprehensive versioning and changelog management for monorepos')
|
|
47
|
-
.version('1.0.
|
|
48
|
+
.version('1.0.4');
|
|
48
49
|
program
|
|
49
50
|
.command('bump <type>')
|
|
50
51
|
.description('Bump version (patch, minor, major, prerelease)')
|
|
@@ -290,7 +291,8 @@ program
|
|
|
290
291
|
changelogFile: 'CHANGELOG.md',
|
|
291
292
|
conventionalCommits: true,
|
|
292
293
|
syncDependencies: false,
|
|
293
|
-
ignorePackages: []
|
|
294
|
+
ignorePackages: [],
|
|
295
|
+
extensions: [] // Add extensions array to config
|
|
294
296
|
};
|
|
295
297
|
await fs.writeJson(configPath, defaultConfig, { spaces: 2 });
|
|
296
298
|
console.log('✅ Initialized versioning config at versioning.config.json');
|
|
@@ -302,9 +304,22 @@ program
|
|
|
302
304
|
});
|
|
303
305
|
async function loadConfig(configPath) {
|
|
304
306
|
if (!(await fs.pathExists(configPath))) {
|
|
305
|
-
throw new Error(`Config file not found: ${configPath}. Run '
|
|
307
|
+
throw new Error(`Config file not found: ${configPath}. Run 'versioning init' to create one.`);
|
|
306
308
|
}
|
|
307
309
|
return await fs.readJson(configPath);
|
|
308
310
|
}
|
|
309
311
|
program.parse();
|
|
312
|
+
async function main() {
|
|
313
|
+
try {
|
|
314
|
+
// Load and register extensions
|
|
315
|
+
await (0, extensions_1.loadExtensions)(program);
|
|
316
|
+
// Parse command line arguments
|
|
317
|
+
program.parse();
|
|
318
|
+
}
|
|
319
|
+
catch (error) {
|
|
320
|
+
console.error('❌ Error loading extensions:', error instanceof Error ? error.message : String(error));
|
|
321
|
+
process.exit(1);
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
main();
|
|
310
325
|
//# sourceMappingURL=cli.js.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Command } from 'commander';
|
|
2
|
+
export interface VersioningExtension {
|
|
3
|
+
name: string;
|
|
4
|
+
description: string;
|
|
5
|
+
version: string;
|
|
6
|
+
register: (program: Command, config: any) => void | Promise<void>;
|
|
7
|
+
}
|
|
8
|
+
export interface ExtensionContext {
|
|
9
|
+
config: any;
|
|
10
|
+
versionManager?: any;
|
|
11
|
+
changelogManager?: any;
|
|
12
|
+
syncManager?: any;
|
|
13
|
+
releaseManager?: any;
|
|
14
|
+
}
|
|
15
|
+
export declare function loadExtensions(program: Command): Promise<void>;
|
|
16
|
+
export declare function createExtensionContext(config: any): ExtensionContext;
|
|
17
|
+
//# sourceMappingURL=extensions.d.ts.map
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.loadExtensions = loadExtensions;
|
|
37
|
+
exports.createExtensionContext = createExtensionContext;
|
|
38
|
+
const fs = __importStar(require("fs-extra"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
async function loadExtensions(program) {
|
|
41
|
+
try {
|
|
42
|
+
// Try to load config to get extensions list
|
|
43
|
+
let config = {};
|
|
44
|
+
if (await fs.pathExists('versioning.config.json')) {
|
|
45
|
+
config = await fs.readJson('versioning.config.json');
|
|
46
|
+
}
|
|
47
|
+
const extensions = config.extensions || [];
|
|
48
|
+
// Load built-in extensions from local extensions directory
|
|
49
|
+
const extensionsDir = path.join(__dirname, 'extensions');
|
|
50
|
+
if (await fs.pathExists(extensionsDir)) {
|
|
51
|
+
const extensionFiles = await fs.readdir(extensionsDir);
|
|
52
|
+
for (const file of extensionFiles) {
|
|
53
|
+
if (file.endsWith('.js') || file.endsWith('.ts')) {
|
|
54
|
+
try {
|
|
55
|
+
const extensionPath = path.join(extensionsDir, file);
|
|
56
|
+
const extension = require(extensionPath);
|
|
57
|
+
if (extension && typeof extension.register === 'function') {
|
|
58
|
+
await extension.register(program, config);
|
|
59
|
+
console.log(`✅ Loaded extension: ${extension.name}@${extension.version}`);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
catch (error) {
|
|
63
|
+
console.warn(`⚠️ Failed to load extension ${file}:`, error instanceof Error ? error.message : String(error));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// Load external extensions from node_modules or specified paths
|
|
69
|
+
for (const extConfig of extensions) {
|
|
70
|
+
try {
|
|
71
|
+
let extension;
|
|
72
|
+
if (typeof extConfig === 'string') {
|
|
73
|
+
// Load from node_modules
|
|
74
|
+
extension = require(extConfig);
|
|
75
|
+
}
|
|
76
|
+
else if (extConfig.path) {
|
|
77
|
+
// Load from custom path
|
|
78
|
+
extension = require(path.resolve(extConfig.path));
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (extension && typeof extension.register === 'function') {
|
|
84
|
+
await extension.register(program, config);
|
|
85
|
+
console.log(`✅ Loaded external extension: ${extension.name}@${extension.version}`);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
console.warn(`⚠️ Failed to load external extension:`, error instanceof Error ? error.message : String(error));
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
catch (error) {
|
|
94
|
+
// Don't fail if extensions can't be loaded, just warn
|
|
95
|
+
console.warn('⚠️ Could not load extensions:', error instanceof Error ? error.message : String(error));
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function createExtensionContext(config) {
|
|
99
|
+
return {
|
|
100
|
+
config,
|
|
101
|
+
// Managers will be injected when available
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
//# sourceMappingURL=extensions.js.map
|
package/package.json
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@edcalderon/versioning",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.4",
|
|
4
4
|
"description": "A comprehensive versioning and changelog management tool for monorepos",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
7
|
-
"
|
|
7
|
+
"versioning": "dist/cli.js"
|
|
8
8
|
},
|
|
9
9
|
"scripts": {
|
|
10
10
|
"build": "tsc",
|