@claude-flow/deployment 3.0.0-alpha.1
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/.agentic-flow/intelligence.json +16 -0
- package/QUICK_START.md +281 -0
- package/README.md +333 -0
- package/__tests__/coverage/base.css +224 -0
- package/__tests__/coverage/block-navigation.js +87 -0
- package/__tests__/coverage/coverage-final.json +4 -0
- package/__tests__/coverage/favicon.png +0 -0
- package/__tests__/coverage/index.html +146 -0
- package/__tests__/coverage/lcov-report/base.css +224 -0
- package/__tests__/coverage/lcov-report/block-navigation.js +87 -0
- package/__tests__/coverage/lcov-report/favicon.png +0 -0
- package/__tests__/coverage/lcov-report/index.html +146 -0
- package/__tests__/coverage/lcov-report/prettify.css +1 -0
- package/__tests__/coverage/lcov-report/prettify.js +2 -0
- package/__tests__/coverage/lcov-report/publisher.ts.html +811 -0
- package/__tests__/coverage/lcov-report/release-manager.ts.html +1120 -0
- package/__tests__/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/__tests__/coverage/lcov-report/sorter.js +210 -0
- package/__tests__/coverage/lcov-report/validator.ts.html +940 -0
- package/__tests__/coverage/lcov.info +908 -0
- package/__tests__/coverage/prettify.css +1 -0
- package/__tests__/coverage/prettify.js +2 -0
- package/__tests__/coverage/publisher.ts.html +811 -0
- package/__tests__/coverage/release-manager.ts.html +1120 -0
- package/__tests__/coverage/sort-arrow-sprite.png +0 -0
- package/__tests__/coverage/sorter.js +210 -0
- package/__tests__/coverage/validator.ts.html +940 -0
- package/dist/__tests__/release-manager.test.d.ts +2 -0
- package/dist/__tests__/release-manager.test.d.ts.map +1 -0
- package/dist/__tests__/release-manager.test.js +62 -0
- package/dist/__tests__/release-manager.test.js.map +1 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +45 -0
- package/dist/index.js.map +1 -0
- package/dist/publisher.d.ts +58 -0
- package/dist/publisher.d.ts.map +1 -0
- package/dist/publisher.js +229 -0
- package/dist/publisher.js.map +1 -0
- package/dist/release-manager.d.ts +46 -0
- package/dist/release-manager.d.ts.map +1 -0
- package/dist/release-manager.js +282 -0
- package/dist/release-manager.js.map +1 -0
- package/dist/types.d.ts +168 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/dist/validator.d.ts +46 -0
- package/dist/validator.d.ts.map +1 -0
- package/dist/validator.js +251 -0
- package/dist/validator.js.map +1 -0
- package/examples/basic-release.ts +92 -0
- package/examples/dry-run.ts +70 -0
- package/examples/prerelease-workflow.ts +98 -0
- package/package.json +27 -0
- package/src/__tests__/release-manager.test.ts +72 -0
- package/src/index.ts +88 -0
- package/src/publisher.ts +273 -0
- package/src/release-manager.ts +345 -0
- package/src/types.ts +159 -0
- package/src/validator.ts +285 -0
- package/tsconfig.json +9 -0
- package/tsconfig.tsbuildinfo +1 -0
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pre-Release Validator
|
|
3
|
+
* Validates package before release (lint, test, build, dependencies)
|
|
4
|
+
*/
|
|
5
|
+
import { execSync } from 'child_process';
|
|
6
|
+
import { readFileSync, existsSync } from 'fs';
|
|
7
|
+
import { join } from 'path';
|
|
8
|
+
export class Validator {
|
|
9
|
+
cwd;
|
|
10
|
+
constructor(cwd = process.cwd()) {
|
|
11
|
+
this.cwd = cwd;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Run all validation checks
|
|
15
|
+
*/
|
|
16
|
+
async validate(options = {}) {
|
|
17
|
+
const { lint = true, test = true, build = true, checkDependencies = true, checkGitStatus = true, lintCommand = 'npm run lint', testCommand = 'npm test', buildCommand = 'npm run build' } = options;
|
|
18
|
+
const result = {
|
|
19
|
+
valid: true,
|
|
20
|
+
checks: {},
|
|
21
|
+
errors: [],
|
|
22
|
+
warnings: []
|
|
23
|
+
};
|
|
24
|
+
// Validate package.json
|
|
25
|
+
console.log('Validating package.json...');
|
|
26
|
+
result.checks.packageJson = await this.validatePackageJson();
|
|
27
|
+
if (!result.checks.packageJson.passed) {
|
|
28
|
+
result.valid = false;
|
|
29
|
+
result.errors.push(...(result.checks.packageJson.errors || []));
|
|
30
|
+
}
|
|
31
|
+
// Check git status
|
|
32
|
+
if (checkGitStatus) {
|
|
33
|
+
console.log('Checking git status...');
|
|
34
|
+
result.checks.gitStatus = await this.checkGitStatus();
|
|
35
|
+
if (!result.checks.gitStatus.passed) {
|
|
36
|
+
result.warnings.push(...(result.checks.gitStatus.errors || []));
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// Check dependencies
|
|
40
|
+
if (checkDependencies) {
|
|
41
|
+
console.log('Checking dependencies...');
|
|
42
|
+
result.checks.dependencies = await this.checkDependencies();
|
|
43
|
+
if (!result.checks.dependencies.passed) {
|
|
44
|
+
result.valid = false;
|
|
45
|
+
result.errors.push(...(result.checks.dependencies.errors || []));
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
// Run linter
|
|
49
|
+
if (lint) {
|
|
50
|
+
console.log('Running linter...');
|
|
51
|
+
result.checks.lint = await this.runLint(lintCommand);
|
|
52
|
+
if (!result.checks.lint.passed) {
|
|
53
|
+
result.valid = false;
|
|
54
|
+
result.errors.push(...(result.checks.lint.errors || []));
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
// Run tests
|
|
58
|
+
if (test) {
|
|
59
|
+
console.log('Running tests...');
|
|
60
|
+
result.checks.test = await this.runTests(testCommand);
|
|
61
|
+
if (!result.checks.test.passed) {
|
|
62
|
+
result.valid = false;
|
|
63
|
+
result.errors.push(...(result.checks.test.errors || []));
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
// Run build
|
|
67
|
+
if (build) {
|
|
68
|
+
console.log('Running build...');
|
|
69
|
+
result.checks.build = await this.runBuild(buildCommand);
|
|
70
|
+
if (!result.checks.build.passed) {
|
|
71
|
+
result.valid = false;
|
|
72
|
+
result.errors.push(...(result.checks.build.errors || []));
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return result;
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Validate package.json structure and required fields
|
|
79
|
+
*/
|
|
80
|
+
async validatePackageJson() {
|
|
81
|
+
const errors = [];
|
|
82
|
+
try {
|
|
83
|
+
const pkgPath = join(this.cwd, 'package.json');
|
|
84
|
+
if (!existsSync(pkgPath)) {
|
|
85
|
+
errors.push('package.json not found');
|
|
86
|
+
return { passed: false, errors };
|
|
87
|
+
}
|
|
88
|
+
const pkg = JSON.parse(readFileSync(pkgPath, 'utf-8'));
|
|
89
|
+
// Check required fields
|
|
90
|
+
if (!pkg.name) {
|
|
91
|
+
errors.push('package.json missing "name" field');
|
|
92
|
+
}
|
|
93
|
+
if (!pkg.version) {
|
|
94
|
+
errors.push('package.json missing "version" field');
|
|
95
|
+
}
|
|
96
|
+
if (!pkg.description) {
|
|
97
|
+
errors.push('package.json missing "description" field (warning)');
|
|
98
|
+
}
|
|
99
|
+
// Validate version format
|
|
100
|
+
if (pkg.version && !/^\d+\.\d+\.\d+(?:-[a-z]+\.\d+)?$/.test(pkg.version)) {
|
|
101
|
+
errors.push(`Invalid version format: ${pkg.version}`);
|
|
102
|
+
}
|
|
103
|
+
// Check for repository field
|
|
104
|
+
if (!pkg.repository) {
|
|
105
|
+
errors.push('package.json missing "repository" field (recommended)');
|
|
106
|
+
}
|
|
107
|
+
// Warn about private package
|
|
108
|
+
if (pkg.private) {
|
|
109
|
+
errors.push('Package is marked as private - cannot be published');
|
|
110
|
+
}
|
|
111
|
+
return {
|
|
112
|
+
passed: errors.length === 0,
|
|
113
|
+
errors: errors.length > 0 ? errors : undefined
|
|
114
|
+
};
|
|
115
|
+
}
|
|
116
|
+
catch (error) {
|
|
117
|
+
errors.push(`Failed to parse package.json: ${error}`);
|
|
118
|
+
return { passed: false, errors };
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* Check git status for uncommitted changes
|
|
123
|
+
*/
|
|
124
|
+
async checkGitStatus() {
|
|
125
|
+
try {
|
|
126
|
+
const status = this.execCommand('git status --porcelain', true);
|
|
127
|
+
if (status.trim()) {
|
|
128
|
+
return {
|
|
129
|
+
passed: false,
|
|
130
|
+
errors: ['Uncommitted changes detected. Commit or stash changes before release.']
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
return { passed: true };
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
return {
|
|
137
|
+
passed: false,
|
|
138
|
+
errors: [`Git status check failed: ${error}`]
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Check for dependency issues
|
|
144
|
+
*/
|
|
145
|
+
async checkDependencies() {
|
|
146
|
+
const errors = [];
|
|
147
|
+
try {
|
|
148
|
+
// Check for npm audit issues
|
|
149
|
+
try {
|
|
150
|
+
this.execCommand('npm audit --audit-level moderate', false);
|
|
151
|
+
}
|
|
152
|
+
catch (error) {
|
|
153
|
+
errors.push('npm audit found security vulnerabilities');
|
|
154
|
+
}
|
|
155
|
+
// Check for outdated dependencies (non-critical)
|
|
156
|
+
try {
|
|
157
|
+
const outdated = this.execCommand('npm outdated --json', true);
|
|
158
|
+
if (outdated.trim()) {
|
|
159
|
+
const outdatedPkgs = JSON.parse(outdated);
|
|
160
|
+
const count = Object.keys(outdatedPkgs).length;
|
|
161
|
+
if (count > 0) {
|
|
162
|
+
errors.push(`${count} outdated dependencies found (warning)`);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
catch {
|
|
167
|
+
// Outdated check is non-critical
|
|
168
|
+
}
|
|
169
|
+
return {
|
|
170
|
+
passed: errors.length === 0,
|
|
171
|
+
errors: errors.length > 0 ? errors : undefined
|
|
172
|
+
};
|
|
173
|
+
}
|
|
174
|
+
catch (error) {
|
|
175
|
+
errors.push(`Dependency check failed: ${error}`);
|
|
176
|
+
return { passed: false, errors };
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
/**
|
|
180
|
+
* Run linter
|
|
181
|
+
*/
|
|
182
|
+
async runLint(command) {
|
|
183
|
+
try {
|
|
184
|
+
this.execCommand(command, false);
|
|
185
|
+
return { passed: true };
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
return {
|
|
189
|
+
passed: false,
|
|
190
|
+
errors: [`Linting failed: ${error}`]
|
|
191
|
+
};
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* Run tests
|
|
196
|
+
*/
|
|
197
|
+
async runTests(command) {
|
|
198
|
+
try {
|
|
199
|
+
this.execCommand(command, false);
|
|
200
|
+
return { passed: true };
|
|
201
|
+
}
|
|
202
|
+
catch (error) {
|
|
203
|
+
return {
|
|
204
|
+
passed: false,
|
|
205
|
+
errors: [`Tests failed: ${error}`]
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Run build
|
|
211
|
+
*/
|
|
212
|
+
async runBuild(command) {
|
|
213
|
+
try {
|
|
214
|
+
this.execCommand(command, false);
|
|
215
|
+
return { passed: true };
|
|
216
|
+
}
|
|
217
|
+
catch (error) {
|
|
218
|
+
return {
|
|
219
|
+
passed: false,
|
|
220
|
+
errors: [`Build failed: ${error}`]
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Execute command
|
|
226
|
+
*/
|
|
227
|
+
execCommand(cmd, returnOutput = false) {
|
|
228
|
+
try {
|
|
229
|
+
const output = execSync(cmd, {
|
|
230
|
+
cwd: this.cwd,
|
|
231
|
+
encoding: 'utf-8',
|
|
232
|
+
stdio: returnOutput ? 'pipe' : 'inherit'
|
|
233
|
+
});
|
|
234
|
+
return returnOutput ? output : '';
|
|
235
|
+
}
|
|
236
|
+
catch (error) {
|
|
237
|
+
if (returnOutput && error instanceof Error) {
|
|
238
|
+
throw error;
|
|
239
|
+
}
|
|
240
|
+
throw error;
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
/**
|
|
245
|
+
* Convenience function to validate package
|
|
246
|
+
*/
|
|
247
|
+
export async function validate(options = {}) {
|
|
248
|
+
const validator = new Validator();
|
|
249
|
+
return validator.validate(options);
|
|
250
|
+
}
|
|
251
|
+
//# sourceMappingURL=validator.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validator.js","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Basic Release Workflow Example
|
|
3
|
+
*
|
|
4
|
+
* This example demonstrates a complete release workflow:
|
|
5
|
+
* 1. Validate package
|
|
6
|
+
* 2. Prepare release (bump version, generate changelog, create tag)
|
|
7
|
+
* 3. Publish to npm
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
import { Validator, ReleaseManager, Publisher } from '@claude-flow/deployment';
|
|
11
|
+
|
|
12
|
+
async function basicRelease() {
|
|
13
|
+
console.log('Starting release workflow...\n');
|
|
14
|
+
|
|
15
|
+
// Step 1: Validate package
|
|
16
|
+
console.log('1. Validating package...');
|
|
17
|
+
const validator = new Validator();
|
|
18
|
+
const validation = await validator.validate({
|
|
19
|
+
lint: true,
|
|
20
|
+
test: true,
|
|
21
|
+
build: true,
|
|
22
|
+
checkDependencies: true,
|
|
23
|
+
checkGitStatus: true
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
console.log(` Valid: ${validation.valid}`);
|
|
27
|
+
if (validation.errors.length > 0) {
|
|
28
|
+
console.log(` Errors: ${validation.errors.join(', ')}`);
|
|
29
|
+
}
|
|
30
|
+
if (validation.warnings.length > 0) {
|
|
31
|
+
console.log(` Warnings: ${validation.warnings.join(', ')}`);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (!validation.valid) {
|
|
35
|
+
console.error('\n❌ Validation failed. Fix errors before releasing.');
|
|
36
|
+
process.exit(1);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Step 2: Prepare release
|
|
40
|
+
console.log('\n2. Preparing release...');
|
|
41
|
+
const manager = new ReleaseManager();
|
|
42
|
+
const release = await manager.prepareRelease({
|
|
43
|
+
bumpType: 'patch', // or 'minor', 'major', 'prerelease'
|
|
44
|
+
generateChangelog: true,
|
|
45
|
+
createTag: true,
|
|
46
|
+
commit: true,
|
|
47
|
+
dryRun: false // Set to true for testing
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
if (!release.success) {
|
|
51
|
+
console.error(`\n❌ Release preparation failed: ${release.error}`);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
console.log(` Version: ${release.oldVersion} → ${release.newVersion}`);
|
|
56
|
+
console.log(` Tag: ${release.tag}`);
|
|
57
|
+
console.log(` Commit: ${release.commitHash?.substring(0, 7)}`);
|
|
58
|
+
|
|
59
|
+
// Step 3: Publish to npm
|
|
60
|
+
console.log('\n3. Publishing to npm...');
|
|
61
|
+
const publisher = new Publisher();
|
|
62
|
+
|
|
63
|
+
// Verify authentication
|
|
64
|
+
const authenticated = await publisher.verifyAuth();
|
|
65
|
+
if (!authenticated) {
|
|
66
|
+
console.error('\n❌ Not authenticated with npm. Run: npm login');
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
const publish = await publisher.publishToNpm({
|
|
71
|
+
tag: 'latest',
|
|
72
|
+
access: 'public',
|
|
73
|
+
dryRun: false // Set to true for testing
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
if (!publish.success) {
|
|
77
|
+
console.error(`\n❌ Publish failed: ${publish.error}`);
|
|
78
|
+
process.exit(1);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
console.log(` Package: ${publish.packageName}@${publish.version}`);
|
|
82
|
+
console.log(` Tag: ${publish.tag}`);
|
|
83
|
+
console.log(` Tarball: ${publish.tarball}`);
|
|
84
|
+
|
|
85
|
+
console.log('\n✅ Release completed successfully!');
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
// Run the release
|
|
89
|
+
basicRelease().catch(error => {
|
|
90
|
+
console.error('Release failed:', error);
|
|
91
|
+
process.exit(1);
|
|
92
|
+
});
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dry Run Example
|
|
3
|
+
*
|
|
4
|
+
* Test release without making actual changes
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { prepareRelease, publishToNpm, validate } from '@claude-flow/deployment';
|
|
8
|
+
|
|
9
|
+
async function dryRunRelease() {
|
|
10
|
+
console.log('Dry Run Mode - Testing release without changes\n');
|
|
11
|
+
|
|
12
|
+
// Validate package
|
|
13
|
+
console.log('1. Validating package...');
|
|
14
|
+
const validation = await validate();
|
|
15
|
+
|
|
16
|
+
if (!validation.valid) {
|
|
17
|
+
console.log(' ⚠️ Validation issues found:');
|
|
18
|
+
validation.errors.forEach(err => console.log(` - ${err}`));
|
|
19
|
+
console.log('\n (Continuing anyway in dry-run mode)\n');
|
|
20
|
+
} else {
|
|
21
|
+
console.log(' ✅ Package validation passed\n');
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Prepare release (dry run)
|
|
25
|
+
console.log('2. Preparing release (dry run)...');
|
|
26
|
+
const release = await prepareRelease({
|
|
27
|
+
bumpType: 'minor',
|
|
28
|
+
generateChangelog: true,
|
|
29
|
+
createTag: true,
|
|
30
|
+
commit: true,
|
|
31
|
+
dryRun: true // No actual changes
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
if (release.success) {
|
|
35
|
+
console.log(' Would create release:');
|
|
36
|
+
console.log(` Version: ${release.oldVersion} → ${release.newVersion}`);
|
|
37
|
+
console.log(` Tag: ${release.tag}`);
|
|
38
|
+
console.log(' \n Generated changelog:');
|
|
39
|
+
if (release.changelog) {
|
|
40
|
+
release.changelog.split('\n').forEach(line => {
|
|
41
|
+
console.log(` ${line}`);
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
console.log();
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Publish (dry run)
|
|
48
|
+
console.log('3. Publishing to npm (dry run)...');
|
|
49
|
+
const publish = await publishToNpm({
|
|
50
|
+
tag: 'latest',
|
|
51
|
+
access: 'public',
|
|
52
|
+
dryRun: true // No actual publish
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
if (publish.success) {
|
|
56
|
+
console.log(' Would publish:');
|
|
57
|
+
console.log(` Package: ${publish.packageName}@${publish.version}`);
|
|
58
|
+
console.log(` Tag: ${publish.tag}`);
|
|
59
|
+
console.log();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
console.log('✅ Dry run completed - no changes were made');
|
|
63
|
+
console.log(' To perform actual release, remove dryRun: true option');
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Run dry run
|
|
67
|
+
dryRunRelease().catch(error => {
|
|
68
|
+
console.error('Dry run failed:', error);
|
|
69
|
+
process.exit(1);
|
|
70
|
+
});
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prerelease Workflow Example
|
|
3
|
+
*
|
|
4
|
+
* Demonstrates publishing alpha/beta/rc versions
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
import { prepareRelease, publishToNpm } from '@claude-flow/deployment';
|
|
8
|
+
|
|
9
|
+
async function prereleaseWorkflow() {
|
|
10
|
+
console.log('Prerelease Workflow\n');
|
|
11
|
+
|
|
12
|
+
// Alpha release (early development)
|
|
13
|
+
console.log('1. Creating alpha release...');
|
|
14
|
+
const alpha = await prepareRelease({
|
|
15
|
+
bumpType: 'prerelease',
|
|
16
|
+
channel: 'alpha',
|
|
17
|
+
generateChangelog: true,
|
|
18
|
+
createTag: true,
|
|
19
|
+
commit: true
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
if (alpha.success) {
|
|
23
|
+
console.log(` Created: ${alpha.newVersion}`);
|
|
24
|
+
|
|
25
|
+
await publishToNpm({
|
|
26
|
+
tag: 'alpha',
|
|
27
|
+
access: 'public'
|
|
28
|
+
});
|
|
29
|
+
console.log(' Published to npm with tag "alpha"\n');
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Beta release (feature complete, testing)
|
|
33
|
+
console.log('2. Creating beta release...');
|
|
34
|
+
const beta = await prepareRelease({
|
|
35
|
+
bumpType: 'prerelease',
|
|
36
|
+
channel: 'beta',
|
|
37
|
+
generateChangelog: true,
|
|
38
|
+
createTag: true,
|
|
39
|
+
commit: true
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
if (beta.success) {
|
|
43
|
+
console.log(` Created: ${beta.newVersion}`);
|
|
44
|
+
|
|
45
|
+
await publishToNpm({
|
|
46
|
+
tag: 'beta',
|
|
47
|
+
access: 'public'
|
|
48
|
+
});
|
|
49
|
+
console.log(' Published to npm with tag "beta"\n');
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// RC release (release candidate)
|
|
53
|
+
console.log('3. Creating release candidate...');
|
|
54
|
+
const rc = await prepareRelease({
|
|
55
|
+
bumpType: 'prerelease',
|
|
56
|
+
channel: 'rc',
|
|
57
|
+
generateChangelog: true,
|
|
58
|
+
createTag: true,
|
|
59
|
+
commit: true
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
if (rc.success) {
|
|
63
|
+
console.log(` Created: ${rc.newVersion}`);
|
|
64
|
+
|
|
65
|
+
await publishToNpm({
|
|
66
|
+
tag: 'rc',
|
|
67
|
+
access: 'public'
|
|
68
|
+
});
|
|
69
|
+
console.log(' Published to npm with tag "rc"\n');
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// Final release (stable)
|
|
73
|
+
console.log('4. Creating final release...');
|
|
74
|
+
const final = await prepareRelease({
|
|
75
|
+
bumpType: 'patch',
|
|
76
|
+
generateChangelog: true,
|
|
77
|
+
createTag: true,
|
|
78
|
+
commit: true
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
if (final.success) {
|
|
82
|
+
console.log(` Created: ${final.newVersion}`);
|
|
83
|
+
|
|
84
|
+
await publishToNpm({
|
|
85
|
+
tag: 'latest',
|
|
86
|
+
access: 'public'
|
|
87
|
+
});
|
|
88
|
+
console.log(' Published to npm with tag "latest"\n');
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
console.log('✅ Prerelease workflow completed!');
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Run the workflow
|
|
95
|
+
prereleaseWorkflow().catch(error => {
|
|
96
|
+
console.error('Workflow failed:', error);
|
|
97
|
+
process.exit(1);
|
|
98
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@claude-flow/deployment",
|
|
3
|
+
"version": "3.0.0-alpha.1",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"description": "Deployment module - Release management, CI/CD, versioning",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": "./dist/index.js"
|
|
10
|
+
},
|
|
11
|
+
"scripts": {
|
|
12
|
+
"build": "tsc",
|
|
13
|
+
"test": "vitest run",
|
|
14
|
+
"release": "semantic-release"
|
|
15
|
+
},
|
|
16
|
+
"dependencies": {
|
|
17
|
+
"@claude-flow/shared": "^3.0.0-alpha.1"
|
|
18
|
+
},
|
|
19
|
+
"devDependencies": {
|
|
20
|
+
"semantic-release": "^22.0.0",
|
|
21
|
+
"vitest": "^1.6.0"
|
|
22
|
+
},
|
|
23
|
+
"publishConfig": {
|
|
24
|
+
"access": "public",
|
|
25
|
+
"tag": "v3alpha"
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tests for Deployment Module
|
|
3
|
+
*/
|
|
4
|
+
import { describe, it, expect } from 'vitest';
|
|
5
|
+
import { ReleaseManager } from '../index.js';
|
|
6
|
+
|
|
7
|
+
describe('ReleaseManager', () => {
|
|
8
|
+
describe('Constructor', () => {
|
|
9
|
+
it('should create with default cwd', () => {
|
|
10
|
+
const manager = new ReleaseManager();
|
|
11
|
+
expect(manager).toBeDefined();
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
it('should create with custom cwd', () => {
|
|
15
|
+
const manager = new ReleaseManager('/custom/path');
|
|
16
|
+
expect(manager).toBeDefined();
|
|
17
|
+
});
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
describe('Version Bump Logic', () => {
|
|
22
|
+
it('should parse version parts', () => {
|
|
23
|
+
const version = '1.2.3';
|
|
24
|
+
const parts = version.split('.').map(Number);
|
|
25
|
+
|
|
26
|
+
expect(parts[0]).toBe(1);
|
|
27
|
+
expect(parts[1]).toBe(2);
|
|
28
|
+
expect(parts[2]).toBe(3);
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it('should bump patch version', () => {
|
|
32
|
+
const parts = '1.0.0'.split('.').map(Number);
|
|
33
|
+
const newVersion = [parts[0], parts[1], parts[2] + 1].join('.');
|
|
34
|
+
expect(newVersion).toBe('1.0.1');
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('should bump minor version', () => {
|
|
38
|
+
const parts = '1.0.0'.split('.').map(Number);
|
|
39
|
+
const newVersion = [parts[0], parts[1] + 1, 0].join('.');
|
|
40
|
+
expect(newVersion).toBe('1.1.0');
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it('should bump major version', () => {
|
|
44
|
+
const parts = '1.0.0'.split('.').map(Number);
|
|
45
|
+
const newVersion = [parts[0] + 1, 0, 0].join('.');
|
|
46
|
+
expect(newVersion).toBe('2.0.0');
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
describe('Changelog Generation', () => {
|
|
51
|
+
it('should format date correctly', () => {
|
|
52
|
+
const date = new Date('2026-01-05');
|
|
53
|
+
const formatted = date.toISOString().split('T')[0];
|
|
54
|
+
expect(formatted).toBe('2026-01-05');
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
it('should categorize commits by type', () => {
|
|
58
|
+
const commits = [
|
|
59
|
+
{ message: 'feat: add new feature' },
|
|
60
|
+
{ message: 'fix: fix bug' },
|
|
61
|
+
{ message: 'docs: update docs' },
|
|
62
|
+
];
|
|
63
|
+
|
|
64
|
+
const feat = commits.filter(c => c.message.startsWith('feat:'));
|
|
65
|
+
const fix = commits.filter(c => c.message.startsWith('fix:'));
|
|
66
|
+
const docs = commits.filter(c => c.message.startsWith('docs:'));
|
|
67
|
+
|
|
68
|
+
expect(feat).toHaveLength(1);
|
|
69
|
+
expect(fix).toHaveLength(1);
|
|
70
|
+
expect(docs).toHaveLength(1);
|
|
71
|
+
});
|
|
72
|
+
});
|