@edcalderon/versioning 1.0.4 → 1.0.7
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/CHANGELOG.md +161 -0
- package/README.md +231 -8
- package/dist/changelogManager.d.ts +4 -0
- package/dist/changelogManager.js +12 -0
- package/dist/cli.js +12 -1
- package/dist/extensions/lifecycle-hooks.d.ts +4 -0
- package/dist/extensions/lifecycle-hooks.js +68 -0
- package/dist/extensions/npm-publish.d.ts +4 -0
- package/dist/extensions/npm-publish.js +181 -0
- package/dist/extensions/sample-extension.d.ts +4 -0
- package/dist/extensions/sample-extension.js +54 -0
- package/dist/extensions.d.ts +15 -0
- package/dist/extensions.js +45 -2
- package/dist/release.d.ts +3 -2
- package/package.json +10 -2
- package/scripts/create-tag.js +24 -9
- package/versioning.config.json +15 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,3 +1,164 @@
|
|
|
1
|
+
## 1.0.7 (2026-01-01)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* add publishConfig to explicitly set package as public ([0138dc4](https://github.com/edcalderon/my-second-brain/commit/0138dc4de49bc1f5ee75622440b19ff643fd6224))
|
|
7
|
+
* change package name from @ed/versioning to ed-versioning ([96e4495](https://github.com/edcalderon/my-second-brain/commit/96e4495fe575c6226f319fe62e0f1266fe6d6cfe))
|
|
8
|
+
* change package name to @edcalderon/versioning ([246c7f4](https://github.com/edcalderon/my-second-brain/commit/246c7f445c17464ab63dcbd3bb30be8d8e30066d))
|
|
9
|
+
* configure Next.js for GitHub Pages subdirectory ([af24444](https://github.com/edcalderon/my-second-brain/commit/af2444468d13dcbe2f867ea41208a385f24edb75))
|
|
10
|
+
* correct tag existence check logic in create-tag.js ([f489f89](https://github.com/edcalderon/my-second-brain/commit/f489f89988b4877108b98e7910a79cc2a7e325a5))
|
|
11
|
+
* make SUPERMEMORY_API_KEY private (not NEXT_PUBLIC) ([416d4c0](https://github.com/edcalderon/my-second-brain/commit/416d4c0bf007fbbc3381c9d9745c2cf21c9ae78b))
|
|
12
|
+
* update GitHub release action to use modern softprops/action-gh-release ([dd11de0](https://github.com/edcalderon/my-second-brain/commit/dd11de0cc05dacb9cf7e614e57535a4d54617678))
|
|
13
|
+
* update repository URL in versioning package.json ([3723c78](https://github.com/edcalderon/my-second-brain/commit/3723c781bc61ee9fdf2b9bb0446274be495403ac))
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
### Features
|
|
17
|
+
|
|
18
|
+
* add comprehensive versioning package with CLI, changelog, and NPM publishing ([dba69bd](https://github.com/edcalderon/my-second-brain/commit/dba69bd61cc0a6b11f881a913ee900142b5ddd14))
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
## 1.0.7 (2026-01-01)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
### Bug Fixes
|
|
28
|
+
|
|
29
|
+
* add publishConfig to explicitly set package as public ([0138dc4](https://github.com/edcalderon/my-second-brain/commit/0138dc4de49bc1f5ee75622440b19ff643fd6224))
|
|
30
|
+
* change package name from @ed/versioning to ed-versioning ([96e4495](https://github.com/edcalderon/my-second-brain/commit/96e4495fe575c6226f319fe62e0f1266fe6d6cfe))
|
|
31
|
+
* change package name to @edcalderon/versioning ([246c7f4](https://github.com/edcalderon/my-second-brain/commit/246c7f445c17464ab63dcbd3bb30be8d8e30066d))
|
|
32
|
+
* configure Next.js for GitHub Pages subdirectory ([af24444](https://github.com/edcalderon/my-second-brain/commit/af2444468d13dcbe2f867ea41208a385f24edb75))
|
|
33
|
+
* correct tag existence check logic in create-tag.js ([f489f89](https://github.com/edcalderon/my-second-brain/commit/f489f89988b4877108b98e7910a79cc2a7e325a5))
|
|
34
|
+
* make SUPERMEMORY_API_KEY private (not NEXT_PUBLIC) ([416d4c0](https://github.com/edcalderon/my-second-brain/commit/416d4c0bf007fbbc3381c9d9745c2cf21c9ae78b))
|
|
35
|
+
* update GitHub release action to use modern softprops/action-gh-release ([dd11de0](https://github.com/edcalderon/my-second-brain/commit/dd11de0cc05dacb9cf7e614e57535a4d54617678))
|
|
36
|
+
* update repository URL in versioning package.json ([3723c78](https://github.com/edcalderon/my-second-brain/commit/3723c781bc61ee9fdf2b9bb0446274be495403ac))
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
### Features
|
|
40
|
+
|
|
41
|
+
* add comprehensive versioning package with CLI, changelog, and NPM publishing ([dba69bd](https://github.com/edcalderon/my-second-brain/commit/dba69bd61cc0a6b11f881a913ee900142b5ddd14))
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
## 1.0.6 (2026-01-01)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
### Bug Fixes
|
|
51
|
+
|
|
52
|
+
* add publishConfig to explicitly set package as public ([0138dc4](https://github.com/edcalderon/my-second-brain/commit/0138dc4de49bc1f5ee75622440b19ff643fd6224))
|
|
53
|
+
* change package name from @ed/versioning to ed-versioning ([96e4495](https://github.com/edcalderon/my-second-brain/commit/96e4495fe575c6226f319fe62e0f1266fe6d6cfe))
|
|
54
|
+
* change package name to @edcalderon/versioning ([246c7f4](https://github.com/edcalderon/my-second-brain/commit/246c7f445c17464ab63dcbd3bb30be8d8e30066d))
|
|
55
|
+
* configure Next.js for GitHub Pages subdirectory ([af24444](https://github.com/edcalderon/my-second-brain/commit/af2444468d13dcbe2f867ea41208a385f24edb75))
|
|
56
|
+
* correct tag existence check logic in create-tag.js ([f489f89](https://github.com/edcalderon/my-second-brain/commit/f489f89988b4877108b98e7910a79cc2a7e325a5))
|
|
57
|
+
* make SUPERMEMORY_API_KEY private (not NEXT_PUBLIC) ([416d4c0](https://github.com/edcalderon/my-second-brain/commit/416d4c0bf007fbbc3381c9d9745c2cf21c9ae78b))
|
|
58
|
+
* update GitHub release action to use modern softprops/action-gh-release ([dd11de0](https://github.com/edcalderon/my-second-brain/commit/dd11de0cc05dacb9cf7e614e57535a4d54617678))
|
|
59
|
+
* update repository URL in versioning package.json ([3723c78](https://github.com/edcalderon/my-second-brain/commit/3723c781bc61ee9fdf2b9bb0446274be495403ac))
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
### Features
|
|
63
|
+
|
|
64
|
+
* add comprehensive versioning package with CLI, changelog, and NPM publishing ([dba69bd](https://github.com/edcalderon/my-second-brain/commit/dba69bd61cc0a6b11f881a913ee900142b5ddd14))
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
## 1.0.6 (2026-01-01)
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
### Bug Fixes
|
|
74
|
+
|
|
75
|
+
* add publishConfig to explicitly set package as public ([0138dc4](https://github.com/edcalderon/my-second-brain/commit/0138dc4de49bc1f5ee75622440b19ff643fd6224))
|
|
76
|
+
* change package name from @ed/versioning to ed-versioning ([96e4495](https://github.com/edcalderon/my-second-brain/commit/96e4495fe575c6226f319fe62e0f1266fe6d6cfe))
|
|
77
|
+
* change package name to @edcalderon/versioning ([246c7f4](https://github.com/edcalderon/my-second-brain/commit/246c7f445c17464ab63dcbd3bb30be8d8e30066d))
|
|
78
|
+
* configure Next.js for GitHub Pages subdirectory ([af24444](https://github.com/edcalderon/my-second-brain/commit/af2444468d13dcbe2f867ea41208a385f24edb75))
|
|
79
|
+
* correct tag existence check logic in create-tag.js ([f489f89](https://github.com/edcalderon/my-second-brain/commit/f489f89988b4877108b98e7910a79cc2a7e325a5))
|
|
80
|
+
* make SUPERMEMORY_API_KEY private (not NEXT_PUBLIC) ([416d4c0](https://github.com/edcalderon/my-second-brain/commit/416d4c0bf007fbbc3381c9d9745c2cf21c9ae78b))
|
|
81
|
+
* update GitHub release action to use modern softprops/action-gh-release ([dd11de0](https://github.com/edcalderon/my-second-brain/commit/dd11de0cc05dacb9cf7e614e57535a4d54617678))
|
|
82
|
+
* update repository URL in versioning package.json ([3723c78](https://github.com/edcalderon/my-second-brain/commit/3723c781bc61ee9fdf2b9bb0446274be495403ac))
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
### Features
|
|
86
|
+
|
|
87
|
+
* add comprehensive versioning package with CLI, changelog, and NPM publishing ([dba69bd](https://github.com/edcalderon/my-second-brain/commit/dba69bd61cc0a6b11f881a913ee900142b5ddd14))
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
|
|
93
|
+
## 1.0.5 (2026-01-01)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
### Bug Fixes
|
|
97
|
+
|
|
98
|
+
* add publishConfig to explicitly set package as public ([0138dc4](https://github.com/edcalderon/my-second-brain/commit/0138dc4de49bc1f5ee75622440b19ff643fd6224))
|
|
99
|
+
* change package name from @ed/versioning to ed-versioning ([96e4495](https://github.com/edcalderon/my-second-brain/commit/96e4495fe575c6226f319fe62e0f1266fe6d6cfe))
|
|
100
|
+
* change package name to @edcalderon/versioning ([246c7f4](https://github.com/edcalderon/my-second-brain/commit/246c7f445c17464ab63dcbd3bb30be8d8e30066d))
|
|
101
|
+
* configure Next.js for GitHub Pages subdirectory ([af24444](https://github.com/edcalderon/my-second-brain/commit/af2444468d13dcbe2f867ea41208a385f24edb75))
|
|
102
|
+
* correct tag existence check logic in create-tag.js ([f489f89](https://github.com/edcalderon/my-second-brain/commit/f489f89988b4877108b98e7910a79cc2a7e325a5))
|
|
103
|
+
* make SUPERMEMORY_API_KEY private (not NEXT_PUBLIC) ([416d4c0](https://github.com/edcalderon/my-second-brain/commit/416d4c0bf007fbbc3381c9d9745c2cf21c9ae78b))
|
|
104
|
+
* update GitHub release action to use modern softprops/action-gh-release ([dd11de0](https://github.com/edcalderon/my-second-brain/commit/dd11de0cc05dacb9cf7e614e57535a4d54617678))
|
|
105
|
+
* update repository URL in versioning package.json ([3723c78](https://github.com/edcalderon/my-second-brain/commit/3723c781bc61ee9fdf2b9bb0446274be495403ac))
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
### Features
|
|
109
|
+
|
|
110
|
+
* add comprehensive versioning package with CLI, changelog, and NPM publishing ([dba69bd](https://github.com/edcalderon/my-second-brain/commit/dba69bd61cc0a6b11f881a913ee900142b5ddd14))
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
## 1.0.5 (2026-01-01)
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
### Bug Fixes
|
|
120
|
+
|
|
121
|
+
* add publishConfig to explicitly set package as public ([0138dc4](https://github.com/edcalderon/my-second-brain/commit/0138dc4de49bc1f5ee75622440b19ff643fd6224))
|
|
122
|
+
* change package name from @ed/versioning to ed-versioning ([96e4495](https://github.com/edcalderon/my-second-brain/commit/96e4495fe575c6226f319fe62e0f1266fe6d6cfe))
|
|
123
|
+
* change package name to @edcalderon/versioning ([246c7f4](https://github.com/edcalderon/my-second-brain/commit/246c7f445c17464ab63dcbd3bb30be8d8e30066d))
|
|
124
|
+
* configure Next.js for GitHub Pages subdirectory ([af24444](https://github.com/edcalderon/my-second-brain/commit/af2444468d13dcbe2f867ea41208a385f24edb75))
|
|
125
|
+
* correct tag existence check logic in create-tag.js ([f489f89](https://github.com/edcalderon/my-second-brain/commit/f489f89988b4877108b98e7910a79cc2a7e325a5))
|
|
126
|
+
* make SUPERMEMORY_API_KEY private (not NEXT_PUBLIC) ([416d4c0](https://github.com/edcalderon/my-second-brain/commit/416d4c0bf007fbbc3381c9d9745c2cf21c9ae78b))
|
|
127
|
+
* update GitHub release action to use modern softprops/action-gh-release ([dd11de0](https://github.com/edcalderon/my-second-brain/commit/dd11de0cc05dacb9cf7e614e57535a4d54617678))
|
|
128
|
+
* update repository URL in versioning package.json ([3723c78](https://github.com/edcalderon/my-second-brain/commit/3723c781bc61ee9fdf2b9bb0446274be495403ac))
|
|
129
|
+
|
|
130
|
+
|
|
131
|
+
### Features
|
|
132
|
+
|
|
133
|
+
* add comprehensive versioning package with CLI, changelog, and NPM publishing ([dba69bd](https://github.com/edcalderon/my-second-brain/commit/dba69bd61cc0a6b11f881a913ee900142b5ddd14))
|
|
134
|
+
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
## 1.0.4 (2026-01-01)
|
|
140
|
+
|
|
141
|
+
|
|
142
|
+
### Bug Fixes
|
|
143
|
+
|
|
144
|
+
* add publishConfig to explicitly set package as public ([0138dc4](https://github.com/edcalderon/my-second-brain/commit/0138dc4de49bc1f5ee75622440b19ff643fd6224))
|
|
145
|
+
* change package name from @ed/versioning to ed-versioning ([96e4495](https://github.com/edcalderon/my-second-brain/commit/96e4495fe575c6226f319fe62e0f1266fe6d6cfe))
|
|
146
|
+
* change package name to @edcalderon/versioning ([246c7f4](https://github.com/edcalderon/my-second-brain/commit/246c7f445c17464ab63dcbd3bb30be8d8e30066d))
|
|
147
|
+
* configure Next.js for GitHub Pages subdirectory ([af24444](https://github.com/edcalderon/my-second-brain/commit/af2444468d13dcbe2f867ea41208a385f24edb75))
|
|
148
|
+
* correct tag existence check logic in create-tag.js ([f489f89](https://github.com/edcalderon/my-second-brain/commit/f489f89988b4877108b98e7910a79cc2a7e325a5))
|
|
149
|
+
* make SUPERMEMORY_API_KEY private (not NEXT_PUBLIC) ([416d4c0](https://github.com/edcalderon/my-second-brain/commit/416d4c0bf007fbbc3381c9d9745c2cf21c9ae78b))
|
|
150
|
+
* update GitHub release action to use modern softprops/action-gh-release ([dd11de0](https://github.com/edcalderon/my-second-brain/commit/dd11de0cc05dacb9cf7e614e57535a4d54617678))
|
|
151
|
+
* update repository URL in versioning package.json ([3723c78](https://github.com/edcalderon/my-second-brain/commit/3723c781bc61ee9fdf2b9bb0446274be495403ac))
|
|
152
|
+
|
|
153
|
+
|
|
154
|
+
### Features
|
|
155
|
+
|
|
156
|
+
* add comprehensive versioning package with CLI, changelog, and NPM publishing ([dba69bd](https://github.com/edcalderon/my-second-brain/commit/dba69bd61cc0a6b11f881a913ee900142b5ddd14))
|
|
157
|
+
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
|
|
1
162
|
# Changelog
|
|
2
163
|
|
|
3
164
|
All notable changes to this project will be documented in this file.
|
package/README.md
CHANGED
|
@@ -36,6 +36,156 @@ Extensions are loaded automatically from:
|
|
|
36
36
|
- Built-in extensions in the `src/extensions/` directory
|
|
37
37
|
- External packages listed in `versioning.config.json`
|
|
38
38
|
|
|
39
|
+
### Creating Extensions
|
|
40
|
+
|
|
41
|
+
Extensions are TypeScript modules that implement the `VersioningExtension` interface:
|
|
42
|
+
|
|
43
|
+
```typescript
|
|
44
|
+
import { Command } from 'commander';
|
|
45
|
+
import { VersioningExtension } from '@edcalderon/versioning';
|
|
46
|
+
|
|
47
|
+
const extension: VersioningExtension = {
|
|
48
|
+
name: 'my-extension',
|
|
49
|
+
description: 'My custom extension',
|
|
50
|
+
version: '1.0.0',
|
|
51
|
+
|
|
52
|
+
register: async (program: Command, config: any) => {
|
|
53
|
+
// Add custom commands here
|
|
54
|
+
program
|
|
55
|
+
.command('my-command')
|
|
56
|
+
.description('My custom command')
|
|
57
|
+
.action(async () => {
|
|
58
|
+
console.log('Custom command executed!');
|
|
59
|
+
});
|
|
60
|
+
},
|
|
61
|
+
|
|
62
|
+
hooks: {
|
|
63
|
+
preVersion: async (type: string, options: any) => {
|
|
64
|
+
console.log(`About to bump ${type} version...`);
|
|
65
|
+
},
|
|
66
|
+
postVersion: async (type: string, version: string, options: any) => {
|
|
67
|
+
console.log(`Version bumped to ${version}`);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
export default extension;
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Extension Hooks
|
|
76
|
+
|
|
77
|
+
Extensions can hook into the versioning lifecycle:
|
|
78
|
+
|
|
79
|
+
- `preVersion`: Called before version bump
|
|
80
|
+
- `postVersion`: Called after version bump
|
|
81
|
+
- `preRelease`: Called before release creation
|
|
82
|
+
- `postRelease`: Called after release creation
|
|
83
|
+
- `preChangelog`: Called before changelog generation
|
|
84
|
+
- `postChangelog`: Called after changelog generation
|
|
85
|
+
- `preSync`: Called before version sync
|
|
86
|
+
- `postSync`: Called after version sync
|
|
87
|
+
|
|
88
|
+
### Built-in Extensions
|
|
89
|
+
|
|
90
|
+
#### Lifecycle Hooks Extension
|
|
91
|
+
|
|
92
|
+
Demonstrates all available hooks with example business logic:
|
|
93
|
+
|
|
94
|
+
```bash
|
|
95
|
+
versioning hooks list # List available hooks
|
|
96
|
+
versioning hooks run pre-deploy # Manually run a hook
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
#### NPM Publish Extension
|
|
100
|
+
|
|
101
|
+
Handles NPM publishing with custom logic:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
versioning publish-package --tag latest
|
|
105
|
+
versioning publish-local --registry http://localhost:4873
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
Features:
|
|
109
|
+
- Automatic package building
|
|
110
|
+
- Prepublish checks
|
|
111
|
+
- Publication verification
|
|
112
|
+
- 2FA/OTP support
|
|
113
|
+
- Local registry support
|
|
114
|
+
- Dry-run mode
|
|
115
|
+
|
|
116
|
+
### External Extensions
|
|
117
|
+
|
|
118
|
+
To use external extensions, add them to your `versioning.config.json`:
|
|
119
|
+
|
|
120
|
+
```json
|
|
121
|
+
{
|
|
122
|
+
"extensions": [
|
|
123
|
+
"my-versioning-extension",
|
|
124
|
+
{
|
|
125
|
+
"name": "another-extension",
|
|
126
|
+
"path": "./local-extensions/another-extension"
|
|
127
|
+
}
|
|
128
|
+
]
|
|
129
|
+
}
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
External extensions should be published as NPM packages with the naming convention `*-versioning-extension` or implement the `VersioningExtension` interface.
|
|
133
|
+
|
|
134
|
+
### Extension Development
|
|
135
|
+
|
|
136
|
+
1. Create a new TypeScript file in `src/extensions/`
|
|
137
|
+
2. Implement the `VersioningExtension` interface
|
|
138
|
+
3. Export the extension as default
|
|
139
|
+
4. The extension will be loaded automatically
|
|
140
|
+
|
|
141
|
+
For external extensions:
|
|
142
|
+
1. Create a separate NPM package
|
|
143
|
+
2. Export the extension as the main module
|
|
144
|
+
3. Publish to NPM
|
|
145
|
+
4. Install and configure in target projects
|
|
146
|
+
|
|
147
|
+
### Extension API Reference
|
|
148
|
+
|
|
149
|
+
#### VersioningExtension Interface
|
|
150
|
+
|
|
151
|
+
```typescript
|
|
152
|
+
interface VersioningExtension {
|
|
153
|
+
name: string; // Extension name
|
|
154
|
+
description: string; // Extension description
|
|
155
|
+
version: string; // Extension version
|
|
156
|
+
register: (program: Command, config: any) => void | Promise<void>;
|
|
157
|
+
hooks?: ExtensionHooks; // Optional lifecycle hooks
|
|
158
|
+
}
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
#### ExtensionHooks Interface
|
|
162
|
+
|
|
163
|
+
```typescript
|
|
164
|
+
interface ExtensionHooks {
|
|
165
|
+
preVersion?: (type: string, options: any) => void | Promise<void>;
|
|
166
|
+
postVersion?: (type: string, version: string, options: any) => void | Promise<void>;
|
|
167
|
+
preRelease?: (version: string, options: any) => void | Promise<void>;
|
|
168
|
+
postRelease?: (version: string, options: any) => void | Promise<void>;
|
|
169
|
+
preChangelog?: (options: any) => void | Promise<void>;
|
|
170
|
+
postChangelog?: (options: any) => void | Promise<void>;
|
|
171
|
+
preSync?: (options: any) => void | Promise<void>;
|
|
172
|
+
postSync?: (options: any) => void | Promise<void>;
|
|
173
|
+
}
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
### Extension Context
|
|
177
|
+
|
|
178
|
+
Extensions can access the versioning context:
|
|
179
|
+
|
|
180
|
+
```typescript
|
|
181
|
+
import { getExtensionContext } from '@edcalderon/versioning';
|
|
182
|
+
|
|
183
|
+
const context = getExtensionContext();
|
|
184
|
+
if (context) {
|
|
185
|
+
// Access versionManager, changelogManager, etc.
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
39
189
|
## Quick Start
|
|
40
190
|
|
|
41
191
|
1. Initialize configuration:
|
|
@@ -74,6 +224,61 @@ versioning patch --packages "apps/dashboard"
|
|
|
74
224
|
cd packages/versioning && versioning patch --skip-sync
|
|
75
225
|
```
|
|
76
226
|
|
|
227
|
+
### Internal Versioning
|
|
228
|
+
|
|
229
|
+
This versioning package uses its own versioning system internally for development and releases:
|
|
230
|
+
|
|
231
|
+
```bash
|
|
232
|
+
# Bump version internally
|
|
233
|
+
npm run version:patch # Bump patch version
|
|
234
|
+
npm run version:minor # Bump minor version
|
|
235
|
+
npm run version:major # Bump major version
|
|
236
|
+
|
|
237
|
+
# Generate changelog
|
|
238
|
+
npm run changelog
|
|
239
|
+
|
|
240
|
+
# Publish to NPM
|
|
241
|
+
npm run publish:npm # Publish to NPM
|
|
242
|
+
npm run publish:npm -- --tag beta # Publish with specific tag
|
|
243
|
+
|
|
244
|
+
# Publish to local registry for testing
|
|
245
|
+
npm run publish:local
|
|
246
|
+
|
|
247
|
+
# Create and push version tag
|
|
248
|
+
npm run create-tag
|
|
249
|
+
|
|
250
|
+
# Complete release process
|
|
251
|
+
npm run release # Bump version, changelog, create tag
|
|
252
|
+
npm run release:local # Bump version, changelog, publish locally
|
|
253
|
+
```
|
|
254
|
+
|
|
255
|
+
The package maintains its own version using the same tooling it provides, ensuring consistency and testing the functionality in production. The NPM publishing extension handles all the complex publishing logic including building, verification, and 2FA support.
|
|
256
|
+
|
|
257
|
+
#### NPM Publish Extension
|
|
258
|
+
|
|
259
|
+
The package includes a built-in NPM publishing extension for streamlined publishing:
|
|
260
|
+
|
|
261
|
+
```bash
|
|
262
|
+
# Publish to NPM
|
|
263
|
+
npm run publish:npm
|
|
264
|
+
|
|
265
|
+
# Publish to NPM with specific tag
|
|
266
|
+
npm run publish:npm -- --tag beta
|
|
267
|
+
|
|
268
|
+
# Publish to local registry for testing
|
|
269
|
+
npm run publish:local
|
|
270
|
+
|
|
271
|
+
# Publish to custom local registry
|
|
272
|
+
npm run publish:local -- --registry http://localhost:4873
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
The extension automatically:
|
|
276
|
+
- Builds the package if needed
|
|
277
|
+
- Runs prepublish checks
|
|
278
|
+
- Verifies publication
|
|
279
|
+
- Handles 2FA/OTP if required
|
|
280
|
+
- Supports dry-run mode
|
|
281
|
+
|
|
77
282
|
## Configuration
|
|
78
283
|
|
|
79
284
|
Create a `versioning.config.json` file in your project root:
|
|
@@ -244,21 +449,39 @@ This package uses GitHub Actions for automated publishing to NPM when version ta
|
|
|
244
449
|
|
|
245
450
|
#### Release Process
|
|
246
451
|
|
|
247
|
-
1. **Update Version**: Use the versioning
|
|
452
|
+
1. **Update Version**: Use the internal versioning scripts to bump version and update changelog
|
|
453
|
+
```bash
|
|
454
|
+
npm run version:patch # or version:minor, version:major
|
|
455
|
+
npm run changelog
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
2. **Publish Locally (Optional)**: Test publishing to a local registry
|
|
248
459
|
```bash
|
|
249
|
-
|
|
460
|
+
npm run publish:local
|
|
250
461
|
```
|
|
251
462
|
|
|
252
|
-
|
|
463
|
+
3. **Create Git Tag**: Use the create-tag script to create and push version tags
|
|
253
464
|
```bash
|
|
254
465
|
npm run create-tag
|
|
255
466
|
```
|
|
256
467
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
468
|
+
4. **Automated Publishing**: GitHub Actions will automatically publish to NPM using the publish extension
|
|
469
|
+
|
|
470
|
+
#### Quick Release Commands
|
|
471
|
+
|
|
472
|
+
```bash
|
|
473
|
+
# Full production release
|
|
474
|
+
npm run release # Bump version, changelog, create tag
|
|
475
|
+
|
|
476
|
+
# Local testing release
|
|
477
|
+
npm run release:local # Bump version, changelog, publish locally
|
|
478
|
+
|
|
479
|
+
# Manual publishing
|
|
480
|
+
npm run publish:npm # Publish current version to NPM
|
|
481
|
+
npm run publish:npm -- --tag beta # Publish with specific tag
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
This uses the same versioning and publishing logic that the package provides to users, ensuring the tool "eats its own dog food".
|
|
262
485
|
|
|
263
486
|
#### Manual Publishing (First Release)
|
|
264
487
|
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ChangelogManager = void 0;
|
|
4
|
+
class ChangelogManager {
|
|
5
|
+
async generate(from, to) {
|
|
6
|
+
// TODO: Implement changelog generation logic
|
|
7
|
+
console.log('Generating changelog...');
|
|
8
|
+
return '';
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
exports.ChangelogManager = ChangelogManager;
|
|
12
|
+
//# sourceMappingURL=changelogManager.js.map
|
package/dist/cli.js
CHANGED
|
@@ -58,6 +58,8 @@ program
|
|
|
58
58
|
const config = await loadConfig(options.config);
|
|
59
59
|
const versionManager = new versioning_1.VersionManager(config);
|
|
60
60
|
const changelogManager = new changelog_1.ChangelogManager(config);
|
|
61
|
+
// Pre-version hook
|
|
62
|
+
await (0, extensions_1.runExtensionHooks)('preVersion', type, options);
|
|
61
63
|
const newVersion = await versionManager.bumpVersion(type, options.preRelease);
|
|
62
64
|
console.log(`Bumped version to ${newVersion}`);
|
|
63
65
|
// Generate changelog
|
|
@@ -71,6 +73,8 @@ program
|
|
|
71
73
|
await versionManager.createGitTag(newVersion);
|
|
72
74
|
console.log('Created git tag');
|
|
73
75
|
}
|
|
76
|
+
// Post-version hook
|
|
77
|
+
await (0, extensions_1.runExtensionHooks)('postVersion', type, newVersion, options);
|
|
74
78
|
console.log(`✅ Successfully released v${newVersion}`);
|
|
75
79
|
}
|
|
76
80
|
catch (error) {
|
|
@@ -88,7 +92,11 @@ program
|
|
|
88
92
|
try {
|
|
89
93
|
const config = await loadConfig(options.config);
|
|
90
94
|
const changelogManager = new changelog_1.ChangelogManager(config);
|
|
95
|
+
// Pre-changelog hook
|
|
96
|
+
await (0, extensions_1.runExtensionHooks)('preChangelog', options);
|
|
91
97
|
await changelogManager.generate(options.from, options.to);
|
|
98
|
+
// Post-changelog hook
|
|
99
|
+
await (0, extensions_1.runExtensionHooks)('postChangelog', options);
|
|
92
100
|
console.log('✅ Changelog generated');
|
|
93
101
|
}
|
|
94
102
|
catch (error) {
|
|
@@ -105,6 +113,8 @@ program
|
|
|
105
113
|
try {
|
|
106
114
|
const config = await loadConfig(options.config);
|
|
107
115
|
const syncManager = new sync_1.SyncManager(config);
|
|
116
|
+
// Pre-sync hook
|
|
117
|
+
await (0, extensions_1.runExtensionHooks)('preSync', options);
|
|
108
118
|
await syncManager.syncVersions(options.version);
|
|
109
119
|
console.log('✅ Versions synced');
|
|
110
120
|
const validation = await syncManager.validateSync();
|
|
@@ -112,6 +122,8 @@ program
|
|
|
112
122
|
console.log('⚠️ Validation issues:');
|
|
113
123
|
validation.issues.forEach(issue => console.log(` - ${issue}`));
|
|
114
124
|
}
|
|
125
|
+
// Post-sync hook
|
|
126
|
+
await (0, extensions_1.runExtensionHooks)('postSync', options);
|
|
115
127
|
}
|
|
116
128
|
catch (error) {
|
|
117
129
|
console.error('❌ Error:', error instanceof Error ? error.message : String(error));
|
|
@@ -308,7 +320,6 @@ async function loadConfig(configPath) {
|
|
|
308
320
|
}
|
|
309
321
|
return await fs.readJson(configPath);
|
|
310
322
|
}
|
|
311
|
-
program.parse();
|
|
312
323
|
async function main() {
|
|
313
324
|
try {
|
|
314
325
|
// Load and register extensions
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const commander_1 = require("commander");
|
|
4
|
+
const extension = {
|
|
5
|
+
name: 'lifecycle-hooks',
|
|
6
|
+
description: 'Extension demonstrating lifecycle hooks for versioning process',
|
|
7
|
+
version: '1.0.0',
|
|
8
|
+
hooks: {
|
|
9
|
+
preVersion: async (type, options) => {
|
|
10
|
+
console.log(`🔗 Pre-version hook: Preparing for ${type} release...`);
|
|
11
|
+
console.log('📋 Running pre-flight checks...');
|
|
12
|
+
console.log('🔍 Validating environment...');
|
|
13
|
+
console.log('📊 Gathering metrics...');
|
|
14
|
+
},
|
|
15
|
+
postVersion: async (type, version, options) => {
|
|
16
|
+
console.log(`🔗 Post-version hook: ${type} release ${version} completed!`);
|
|
17
|
+
console.log('📈 Updating dashboards...');
|
|
18
|
+
console.log('🔄 Triggering CI/CD pipelines...');
|
|
19
|
+
console.log('📝 Creating release notes...');
|
|
20
|
+
},
|
|
21
|
+
preChangelog: async (options) => {
|
|
22
|
+
console.log('🔗 Pre-changelog hook: Preparing changelog generation...');
|
|
23
|
+
console.log('📚 Analyzing commits...');
|
|
24
|
+
},
|
|
25
|
+
postChangelog: async (options) => {
|
|
26
|
+
console.log('🔗 Post-changelog hook: Changelog updated!');
|
|
27
|
+
console.log('📤 Changelog ready for review...');
|
|
28
|
+
},
|
|
29
|
+
preSync: async (options) => {
|
|
30
|
+
console.log('🔗 Pre-sync hook: Preparing version synchronization...');
|
|
31
|
+
console.log('🔗 Checking package dependencies...');
|
|
32
|
+
},
|
|
33
|
+
postSync: async (options) => {
|
|
34
|
+
console.log('🔗 Post-sync hook: Version sync completed!');
|
|
35
|
+
console.log('✅ All packages aligned...');
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
register: async (program, config) => {
|
|
39
|
+
// Add a command to demonstrate hook management
|
|
40
|
+
program
|
|
41
|
+
.command('hooks')
|
|
42
|
+
.description('Manage versioning lifecycle hooks (sample extension)')
|
|
43
|
+
.addCommand(new commander_1.Command('list')
|
|
44
|
+
.description('List available hooks')
|
|
45
|
+
.action(() => {
|
|
46
|
+
console.log('🔗 Available Lifecycle Hooks:');
|
|
47
|
+
console.log(' • preVersion: Runs before version bump');
|
|
48
|
+
console.log(' • postVersion: Runs after version bump');
|
|
49
|
+
console.log(' • preRelease: Runs before release creation');
|
|
50
|
+
console.log(' • postRelease: Runs after release creation');
|
|
51
|
+
console.log(' • preChangelog: Runs before changelog generation');
|
|
52
|
+
console.log(' • postChangelog: Runs after changelog generation');
|
|
53
|
+
console.log(' • preSync: Runs before version sync');
|
|
54
|
+
console.log(' • postSync: Runs after version sync');
|
|
55
|
+
}))
|
|
56
|
+
.addCommand(new commander_1.Command('run')
|
|
57
|
+
.description('Manually run a hook')
|
|
58
|
+
.argument('<hook>', 'Hook name to run')
|
|
59
|
+
.option('-d, --data <data>', 'Data to pass to hook')
|
|
60
|
+
.action(async (hookName, options) => {
|
|
61
|
+
console.log(`🔗 Running hook: ${hookName}`);
|
|
62
|
+
// This would be implemented to manually trigger hooks
|
|
63
|
+
console.log(`📄 Hook data: ${options.data || 'none'}`);
|
|
64
|
+
}));
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
exports.default = extension;
|
|
68
|
+
//# sourceMappingURL=lifecycle-hooks.js.map
|
|
@@ -0,0 +1,181 @@
|
|
|
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
|
+
const child_process_1 = require("child_process");
|
|
37
|
+
const fs = __importStar(require("fs-extra"));
|
|
38
|
+
const path = __importStar(require("path"));
|
|
39
|
+
const extension = {
|
|
40
|
+
name: 'npm-publish',
|
|
41
|
+
description: 'Extension for NPM publishing with custom logic',
|
|
42
|
+
version: '1.0.0',
|
|
43
|
+
register: async (program, config) => {
|
|
44
|
+
// Add publish command
|
|
45
|
+
program
|
|
46
|
+
.command('publish-package')
|
|
47
|
+
.description('Publish package to NPM with custom logic')
|
|
48
|
+
.option('-t, --tag <tag>', 'NPM dist tag', 'latest')
|
|
49
|
+
.option('-d, --dry-run', 'Dry run mode', false)
|
|
50
|
+
.option('--otp <code>', 'NPM 2FA code')
|
|
51
|
+
.action(async (options) => {
|
|
52
|
+
try {
|
|
53
|
+
await publishToNPM(options);
|
|
54
|
+
}
|
|
55
|
+
catch (error) {
|
|
56
|
+
console.error('❌ Publish failed:', error instanceof Error ? error.message : String(error));
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
// Add local publish command for development
|
|
61
|
+
program
|
|
62
|
+
.command('publish-local')
|
|
63
|
+
.description('Publish to local NPM registry for testing')
|
|
64
|
+
.option('-r, --registry <url>', 'Local registry URL', 'http://localhost:4873')
|
|
65
|
+
.action(async (options) => {
|
|
66
|
+
try {
|
|
67
|
+
await publishToLocalRegistry(options);
|
|
68
|
+
}
|
|
69
|
+
catch (error) {
|
|
70
|
+
console.error('❌ Local publish failed:', error instanceof Error ? error.message : String(error));
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
});
|
|
74
|
+
},
|
|
75
|
+
hooks: {
|
|
76
|
+
postVersion: async (type, version, options) => {
|
|
77
|
+
console.log(`📦 Version bumped to ${version}, ready for publishing`);
|
|
78
|
+
},
|
|
79
|
+
postRelease: async (version, options) => {
|
|
80
|
+
console.log(`🚀 Release ${version} completed, triggering automated publish...`);
|
|
81
|
+
// Auto-publish if configured
|
|
82
|
+
if (process.env.CI && process.env.NPM_TOKEN) {
|
|
83
|
+
console.log('🤖 Running in CI with NPM_TOKEN, auto-publishing...');
|
|
84
|
+
try {
|
|
85
|
+
await publishToNPM({
|
|
86
|
+
tag: 'latest',
|
|
87
|
+
otp: process.env.NPM_OTP
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
catch (error) {
|
|
91
|
+
console.error('❌ Auto-publish failed:', error instanceof Error ? error.message : String(error));
|
|
92
|
+
// Don't exit in CI, let the workflow handle it
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
};
|
|
98
|
+
async function publishToNPM(options) {
|
|
99
|
+
const { tag = 'latest', dryRun = false, otp } = options;
|
|
100
|
+
console.log(`📦 Publishing to NPM with tag: ${tag}`);
|
|
101
|
+
if (dryRun) {
|
|
102
|
+
console.log('🔍 Dry run mode - would publish but not actually doing it');
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
// Check if package.json exists
|
|
106
|
+
const packageJsonPath = path.join(process.cwd(), 'package.json');
|
|
107
|
+
if (!await fs.pathExists(packageJsonPath)) {
|
|
108
|
+
throw new Error('package.json not found');
|
|
109
|
+
}
|
|
110
|
+
// Read package info
|
|
111
|
+
const packageJson = await fs.readJson(packageJsonPath);
|
|
112
|
+
const packageName = packageJson.name;
|
|
113
|
+
const version = packageJson.version;
|
|
114
|
+
console.log(`📦 Publishing ${packageName}@${version}...`);
|
|
115
|
+
// Check if already published
|
|
116
|
+
try {
|
|
117
|
+
const result = (0, child_process_1.execSync)(`npm view ${packageName}@${version} version`, { stdio: 'pipe' });
|
|
118
|
+
if (result.toString().trim() === version) {
|
|
119
|
+
console.log(`⚠️ Version ${version} already published, skipping`);
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
catch (error) {
|
|
124
|
+
// Version doesn't exist, continue with publish
|
|
125
|
+
}
|
|
126
|
+
// Build package if needed
|
|
127
|
+
if (packageJson.scripts && packageJson.scripts.build) {
|
|
128
|
+
console.log('🔨 Building package...');
|
|
129
|
+
(0, child_process_1.execSync)('npm run build', { stdio: 'inherit' });
|
|
130
|
+
}
|
|
131
|
+
// Run prepublish checks
|
|
132
|
+
if (packageJson.scripts && packageJson.scripts.prepublishOnly) {
|
|
133
|
+
console.log('🔍 Running prepublish checks...');
|
|
134
|
+
(0, child_process_1.execSync)('npm run prepublishOnly', { stdio: 'inherit' });
|
|
135
|
+
}
|
|
136
|
+
// Prepare publish command
|
|
137
|
+
let publishCmd = `npm publish --tag ${tag}`;
|
|
138
|
+
if (otp) {
|
|
139
|
+
publishCmd += ` --otp ${otp}`;
|
|
140
|
+
}
|
|
141
|
+
// Execute publish
|
|
142
|
+
console.log(`🚀 Executing: ${publishCmd}`);
|
|
143
|
+
(0, child_process_1.execSync)(publishCmd, { stdio: 'inherit' });
|
|
144
|
+
console.log(`✅ Successfully published ${packageName}@${version} with tag ${tag}`);
|
|
145
|
+
// Verify publication
|
|
146
|
+
console.log('🔍 Verifying publication...');
|
|
147
|
+
const verifyResult = (0, child_process_1.execSync)(`npm view ${packageName}@${version} version`, { stdio: 'pipe' });
|
|
148
|
+
if (verifyResult.toString().trim() === version) {
|
|
149
|
+
console.log(`✅ Publication verified: ${packageName}@${version}`);
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
throw new Error('Publication verification failed');
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
async function publishToLocalRegistry(options) {
|
|
156
|
+
const { registry = 'http://localhost:4873' } = options;
|
|
157
|
+
console.log(`🏠 Publishing to local registry: ${registry}`);
|
|
158
|
+
// Check if local registry is running
|
|
159
|
+
try {
|
|
160
|
+
(0, child_process_1.execSync)(`curl -s ${registry} > /dev/null`, { stdio: 'pipe' });
|
|
161
|
+
}
|
|
162
|
+
catch (error) {
|
|
163
|
+
throw new Error(`Local registry at ${registry} is not accessible`);
|
|
164
|
+
}
|
|
165
|
+
// Set registry for this publish
|
|
166
|
+
const originalRegistry = process.env.npm_config_registry;
|
|
167
|
+
process.env.npm_config_registry = registry;
|
|
168
|
+
try {
|
|
169
|
+
await publishToNPM({
|
|
170
|
+
tag: 'local',
|
|
171
|
+
dryRun: false
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
finally {
|
|
175
|
+
// Restore original registry
|
|
176
|
+
process.env.npm_config_registry = originalRegistry;
|
|
177
|
+
}
|
|
178
|
+
console.log(`✅ Published to local registry: ${registry}`);
|
|
179
|
+
}
|
|
180
|
+
exports.default = extension;
|
|
181
|
+
//# sourceMappingURL=npm-publish.js.map
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const extension = {
|
|
4
|
+
name: 'sample-extension',
|
|
5
|
+
description: 'Sample extension demonstrating custom business logic',
|
|
6
|
+
version: '1.0.0',
|
|
7
|
+
register: async (program, config) => {
|
|
8
|
+
// Add a custom command
|
|
9
|
+
program
|
|
10
|
+
.command('deploy')
|
|
11
|
+
.description('Deploy application after versioning (sample extension)')
|
|
12
|
+
.option('-e, --environment <env>', 'Deployment environment', 'staging')
|
|
13
|
+
.option('-c, --config <file>', 'Config file path', 'versioning.config.json')
|
|
14
|
+
.action(async (options) => {
|
|
15
|
+
try {
|
|
16
|
+
console.log(`🚀 Deploying to ${options.environment} environment...`);
|
|
17
|
+
// Custom deployment logic here
|
|
18
|
+
console.log('📦 Building application...');
|
|
19
|
+
console.log('🔄 Running tests...');
|
|
20
|
+
console.log('☁️ Deploying to cloud...');
|
|
21
|
+
console.log('✅ Deployment completed!');
|
|
22
|
+
console.log(`🎉 Successfully deployed to ${options.environment}`);
|
|
23
|
+
}
|
|
24
|
+
catch (error) {
|
|
25
|
+
console.error('❌ Deployment failed:', error instanceof Error ? error.message : String(error));
|
|
26
|
+
process.exit(1);
|
|
27
|
+
}
|
|
28
|
+
});
|
|
29
|
+
// Add another custom command
|
|
30
|
+
program
|
|
31
|
+
.command('notify')
|
|
32
|
+
.description('Send notifications after versioning (sample extension)')
|
|
33
|
+
.option('-m, --message <msg>', 'Notification message')
|
|
34
|
+
.option('-c, --channels <channels>', 'Comma-separated notification channels', 'slack,email')
|
|
35
|
+
.action(async (options) => {
|
|
36
|
+
try {
|
|
37
|
+
const channels = options.channels.split(',');
|
|
38
|
+
const message = options.message || 'Version update completed';
|
|
39
|
+
console.log(`📢 Sending notification: "${message}"`);
|
|
40
|
+
for (const channel of channels) {
|
|
41
|
+
console.log(`📤 Notifying ${channel}...`);
|
|
42
|
+
// Custom notification logic here
|
|
43
|
+
}
|
|
44
|
+
console.log('✅ Notifications sent!');
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
console.error('❌ Notification failed:', error instanceof Error ? error.message : String(error));
|
|
48
|
+
process.exit(1);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
exports.default = extension;
|
|
54
|
+
//# sourceMappingURL=sample-extension.js.map
|
package/dist/extensions.d.ts
CHANGED
|
@@ -4,6 +4,17 @@ export interface VersioningExtension {
|
|
|
4
4
|
description: string;
|
|
5
5
|
version: string;
|
|
6
6
|
register: (program: Command, config: any) => void | Promise<void>;
|
|
7
|
+
hooks?: ExtensionHooks;
|
|
8
|
+
}
|
|
9
|
+
export interface ExtensionHooks {
|
|
10
|
+
preVersion?: (type: string, options: any) => void | Promise<void>;
|
|
11
|
+
postVersion?: (type: string, version: string, options: any) => void | Promise<void>;
|
|
12
|
+
preRelease?: (version: string, options: any) => void | Promise<void>;
|
|
13
|
+
postRelease?: (version: string, options: any) => void | Promise<void>;
|
|
14
|
+
preChangelog?: (options: any) => void | Promise<void>;
|
|
15
|
+
postChangelog?: (options: any) => void | Promise<void>;
|
|
16
|
+
preSync?: (options: any) => void | Promise<void>;
|
|
17
|
+
postSync?: (options: any) => void | Promise<void>;
|
|
7
18
|
}
|
|
8
19
|
export interface ExtensionContext {
|
|
9
20
|
config: any;
|
|
@@ -11,7 +22,11 @@ export interface ExtensionContext {
|
|
|
11
22
|
changelogManager?: any;
|
|
12
23
|
syncManager?: any;
|
|
13
24
|
releaseManager?: any;
|
|
25
|
+
hooks: ExtensionHooks[];
|
|
14
26
|
}
|
|
27
|
+
export declare function getExtensionContext(): ExtensionContext | null;
|
|
28
|
+
export declare function initializeExtensionContext(config: any): Promise<ExtensionContext>;
|
|
29
|
+
export declare function runExtensionHooks(hookName: keyof ExtensionHooks, ...args: any[]): Promise<void>;
|
|
15
30
|
export declare function loadExtensions(program: Command): Promise<void>;
|
|
16
31
|
export declare function createExtensionContext(config: any): ExtensionContext;
|
|
17
32
|
//# sourceMappingURL=extensions.d.ts.map
|
package/dist/extensions.js
CHANGED
|
@@ -33,10 +33,39 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.getExtensionContext = getExtensionContext;
|
|
37
|
+
exports.initializeExtensionContext = initializeExtensionContext;
|
|
38
|
+
exports.runExtensionHooks = runExtensionHooks;
|
|
36
39
|
exports.loadExtensions = loadExtensions;
|
|
37
40
|
exports.createExtensionContext = createExtensionContext;
|
|
38
41
|
const fs = __importStar(require("fs-extra"));
|
|
39
42
|
const path = __importStar(require("path"));
|
|
43
|
+
let globalExtensionContext = null;
|
|
44
|
+
function getExtensionContext() {
|
|
45
|
+
return globalExtensionContext;
|
|
46
|
+
}
|
|
47
|
+
async function initializeExtensionContext(config) {
|
|
48
|
+
globalExtensionContext = {
|
|
49
|
+
config,
|
|
50
|
+
hooks: []
|
|
51
|
+
};
|
|
52
|
+
return globalExtensionContext;
|
|
53
|
+
}
|
|
54
|
+
async function runExtensionHooks(hookName, ...args) {
|
|
55
|
+
if (!globalExtensionContext)
|
|
56
|
+
return;
|
|
57
|
+
for (const extensionHooks of globalExtensionContext.hooks) {
|
|
58
|
+
const hook = extensionHooks[hookName];
|
|
59
|
+
if (hook) {
|
|
60
|
+
try {
|
|
61
|
+
await hook(...args);
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
console.warn(`⚠️ Extension hook ${hookName} failed:`, error instanceof Error ? error.message : String(error));
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
40
69
|
async function loadExtensions(program) {
|
|
41
70
|
try {
|
|
42
71
|
// Try to load config to get extensions list
|
|
@@ -44,18 +73,25 @@ async function loadExtensions(program) {
|
|
|
44
73
|
if (await fs.pathExists('versioning.config.json')) {
|
|
45
74
|
config = await fs.readJson('versioning.config.json');
|
|
46
75
|
}
|
|
76
|
+
// Initialize extension context
|
|
77
|
+
const context = await initializeExtensionContext(config);
|
|
47
78
|
const extensions = config.extensions || [];
|
|
48
79
|
// Load built-in extensions from local extensions directory
|
|
49
80
|
const extensionsDir = path.join(__dirname, 'extensions');
|
|
50
81
|
if (await fs.pathExists(extensionsDir)) {
|
|
51
82
|
const extensionFiles = await fs.readdir(extensionsDir);
|
|
52
83
|
for (const file of extensionFiles) {
|
|
53
|
-
if (file.endsWith('.js')
|
|
84
|
+
if (file.endsWith('.js')) {
|
|
54
85
|
try {
|
|
55
86
|
const extensionPath = path.join(extensionsDir, file);
|
|
56
|
-
const
|
|
87
|
+
const extensionModule = require(extensionPath);
|
|
88
|
+
const extension = extensionModule.default || extensionModule;
|
|
57
89
|
if (extension && typeof extension.register === 'function') {
|
|
58
90
|
await extension.register(program, config);
|
|
91
|
+
// Register hooks if available
|
|
92
|
+
if (extension.hooks) {
|
|
93
|
+
context.hooks.push(extension.hooks);
|
|
94
|
+
}
|
|
59
95
|
console.log(`✅ Loaded extension: ${extension.name}@${extension.version}`);
|
|
60
96
|
}
|
|
61
97
|
}
|
|
@@ -65,6 +101,8 @@ async function loadExtensions(program) {
|
|
|
65
101
|
}
|
|
66
102
|
}
|
|
67
103
|
}
|
|
104
|
+
// Note: External extensions from config.extensions are not yet implemented
|
|
105
|
+
// This would require a package manager to install and load external extensions
|
|
68
106
|
// Load external extensions from node_modules or specified paths
|
|
69
107
|
for (const extConfig of extensions) {
|
|
70
108
|
try {
|
|
@@ -82,6 +120,10 @@ async function loadExtensions(program) {
|
|
|
82
120
|
}
|
|
83
121
|
if (extension && typeof extension.register === 'function') {
|
|
84
122
|
await extension.register(program, config);
|
|
123
|
+
// Register hooks if available
|
|
124
|
+
if (extension.hooks) {
|
|
125
|
+
context.hooks.push(extension.hooks);
|
|
126
|
+
}
|
|
85
127
|
console.log(`✅ Loaded external extension: ${extension.name}@${extension.version}`);
|
|
86
128
|
}
|
|
87
129
|
}
|
|
@@ -98,6 +140,7 @@ async function loadExtensions(program) {
|
|
|
98
140
|
function createExtensionContext(config) {
|
|
99
141
|
return {
|
|
100
142
|
config,
|
|
143
|
+
hooks: []
|
|
101
144
|
// Managers will be injected when available
|
|
102
145
|
};
|
|
103
146
|
}
|
package/dist/release.d.ts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import { VersionManager
|
|
1
|
+
import { VersionManager } from './index';
|
|
2
|
+
import { ChangelogManager } from './changelog';
|
|
2
3
|
export interface ReleaseConfig {
|
|
3
4
|
versionManager: VersionManager;
|
|
4
5
|
changelogManager: ChangelogManager;
|
|
5
|
-
syncManager:
|
|
6
|
+
syncManager: any;
|
|
6
7
|
createTag?: boolean;
|
|
7
8
|
createCommit?: boolean;
|
|
8
9
|
publish?: boolean;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@edcalderon/versioning",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.7",
|
|
4
4
|
"description": "A comprehensive versioning and changelog management tool for monorepos",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"bin": {
|
|
@@ -14,7 +14,15 @@
|
|
|
14
14
|
"test:coverage": "jest --coverage",
|
|
15
15
|
"lint": "eslint src/**/*.ts",
|
|
16
16
|
"prepublishOnly": "npm run build && npm run test",
|
|
17
|
-
"
|
|
17
|
+
"version:patch": "node dist/cli.js patch --no-commit --no-tag",
|
|
18
|
+
"version:minor": "node dist/cli.js minor --no-commit --no-tag",
|
|
19
|
+
"version:major": "node dist/cli.js major --no-commit --no-tag",
|
|
20
|
+
"changelog": "node dist/cli.js changelog",
|
|
21
|
+
"publish:npm": "node dist/cli.js publish-package",
|
|
22
|
+
"publish:local": "node dist/cli.js publish-local",
|
|
23
|
+
"create-tag": "node scripts/create-tag.js",
|
|
24
|
+
"release": "npm run version:patch && npm run changelog && npm run create-tag",
|
|
25
|
+
"release:local": "npm run version:patch && npm run changelog && npm run publish:local"
|
|
18
26
|
},
|
|
19
27
|
"keywords": [
|
|
20
28
|
"versioning",
|
package/scripts/create-tag.js
CHANGED
|
@@ -1,26 +1,41 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
3
|
const { execSync } = require('child_process');
|
|
4
|
-
const fs = require('fs');
|
|
5
4
|
const path = require('path');
|
|
6
5
|
|
|
7
|
-
|
|
6
|
+
// Use the built versioning tool to get the current version
|
|
7
|
+
async function getCurrentVersion() {
|
|
8
8
|
try {
|
|
9
|
-
|
|
9
|
+
const { VersionManager } = require('../dist/versioning');
|
|
10
|
+
const versionManager = new VersionManager();
|
|
11
|
+
return await versionManager.getCurrentVersion();
|
|
12
|
+
} catch (error) {
|
|
13
|
+
// Fallback to reading package.json directly
|
|
14
|
+
const fs = require('fs');
|
|
10
15
|
const packageJsonPath = path.join(__dirname, '..', 'package.json');
|
|
11
16
|
const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, 'utf8'));
|
|
12
|
-
|
|
17
|
+
return packageJson.version;
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
async function createVersionTag() {
|
|
22
|
+
try {
|
|
23
|
+
// Get current version using the versioning tool
|
|
24
|
+
const version = await getCurrentVersion();
|
|
13
25
|
|
|
14
26
|
// Use versioning prefix to avoid conflicts with monorepo tags
|
|
15
27
|
const tagPrefix = 'versioning-v';
|
|
16
28
|
const fullTag = `${tagPrefix}${version}`;
|
|
17
29
|
|
|
30
|
+
console.log(`📦 Current version: ${version}`);
|
|
31
|
+
console.log(`🏷️ Creating tag: ${fullTag}`);
|
|
32
|
+
|
|
18
33
|
// Check if tag already exists
|
|
19
34
|
try {
|
|
20
35
|
const result = execSync(`git tag -l "${fullTag}"`, { stdio: 'pipe' });
|
|
21
36
|
const output = result.toString().trim();
|
|
22
37
|
if (output === fullTag) {
|
|
23
|
-
console.log(
|
|
38
|
+
console.log(`⚠️ Tag ${fullTag} already exists`);
|
|
24
39
|
return;
|
|
25
40
|
}
|
|
26
41
|
} catch (error) {
|
|
@@ -31,17 +46,17 @@ function createVersionTag() {
|
|
|
31
46
|
const tagMessage = `Release @edcalderon/versioning v${version}`;
|
|
32
47
|
execSync(`git tag -a "${fullTag}" -m "${tagMessage}"`, { stdio: 'inherit' });
|
|
33
48
|
|
|
34
|
-
console.log(
|
|
49
|
+
console.log(`✅ Created tag ${fullTag}`);
|
|
35
50
|
|
|
36
51
|
// Push tag
|
|
37
52
|
execSync('git push origin --tags', { stdio: 'inherit' });
|
|
38
53
|
|
|
39
|
-
console.log(
|
|
40
|
-
console.log(`\n
|
|
54
|
+
console.log(`🚀 Pushed tag ${fullTag} to remote`);
|
|
55
|
+
console.log(`\n🎉 Tag ${fullTag} created and pushed!`);
|
|
41
56
|
console.log(`The NPM publish workflow will now run automatically.`);
|
|
42
57
|
|
|
43
58
|
} catch (error) {
|
|
44
|
-
console.error('Error creating version tag:', error.message);
|
|
59
|
+
console.error('❌ Error creating version tag:', error.message);
|
|
45
60
|
process.exit(1);
|
|
46
61
|
}
|
|
47
62
|
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"rootPackageJson": "package.json",
|
|
3
|
+
"packages": [],
|
|
4
|
+
"changelogFile": "CHANGELOG.md",
|
|
5
|
+
"conventionalCommits": true,
|
|
6
|
+
"syncDependencies": false,
|
|
7
|
+
"ignorePackages": [],
|
|
8
|
+
"changelog": {
|
|
9
|
+
"preset": "angular",
|
|
10
|
+
"releaseCount": 0
|
|
11
|
+
},
|
|
12
|
+
"sync": {
|
|
13
|
+
"includeRoot": true
|
|
14
|
+
}
|
|
15
|
+
}
|