@vibe-validate/cli 0.9.4 → 0.9.5
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 +79 -0
- package/dist/bin.js +2 -0
- package/dist/bin.js.map +1 -1
- package/dist/commands/generate-workflow.d.ts +64 -0
- package/dist/commands/generate-workflow.d.ts.map +1 -0
- package/dist/commands/generate-workflow.js +466 -0
- package/dist/commands/generate-workflow.js.map +1 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -227,6 +227,85 @@ npx vibe-validate cleanup
|
|
|
227
227
|
|
|
228
228
|
---
|
|
229
229
|
|
|
230
|
+
### `generate-workflow`
|
|
231
|
+
|
|
232
|
+
Generate GitHub Actions workflow from vibe-validate configuration.
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
npx vibe-validate generate-workflow [options]
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
**Options:**
|
|
239
|
+
- `--node-versions <versions>` - Node.js versions to test (comma-separated, default: `"20,22"`)
|
|
240
|
+
- `--os <systems>` - Operating systems to test (comma-separated, default: `"ubuntu-latest"`)
|
|
241
|
+
- `--fail-fast` - Fail fast in matrix strategy (default: `false`)
|
|
242
|
+
- `--coverage` - Enable coverage reporting with Codecov
|
|
243
|
+
- `--dry-run` - Show generated workflow without writing to file
|
|
244
|
+
- `--check` - Check if workflow is in sync with config (exit 0 if in sync, 1 if not)
|
|
245
|
+
|
|
246
|
+
**Examples:**
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
# Generate workflow with defaults (Node 20,22 on ubuntu-latest)
|
|
250
|
+
npx vibe-validate generate-workflow
|
|
251
|
+
|
|
252
|
+
# Generate workflow with full matrix
|
|
253
|
+
npx vibe-validate generate-workflow \
|
|
254
|
+
--node-versions "20,22,24" \
|
|
255
|
+
--os "ubuntu-latest,macos-latest,windows-latest"
|
|
256
|
+
|
|
257
|
+
# Enable coverage reporting
|
|
258
|
+
npx vibe-validate generate-workflow --coverage
|
|
259
|
+
|
|
260
|
+
# Enable fail-fast (stop on first failure)
|
|
261
|
+
npx vibe-validate generate-workflow --fail-fast
|
|
262
|
+
|
|
263
|
+
# Preview without writing
|
|
264
|
+
npx vibe-validate generate-workflow --dry-run
|
|
265
|
+
|
|
266
|
+
# Check if workflow is in sync
|
|
267
|
+
npx vibe-validate generate-workflow --check
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
**What it generates:**
|
|
271
|
+
|
|
272
|
+
Creates `.github/workflows/validate.yml` with:
|
|
273
|
+
- Matrix strategy for multi-OS and multi-Node.js testing
|
|
274
|
+
- Automatic pnpm/npm detection
|
|
275
|
+
- Validation state artifact upload on failure
|
|
276
|
+
- Separate coverage job (if `--coverage` is enabled)
|
|
277
|
+
- All-validation-passed gate job
|
|
278
|
+
|
|
279
|
+
**Matrix mode** (default when multiple versions/OSes):
|
|
280
|
+
```yaml
|
|
281
|
+
strategy:
|
|
282
|
+
fail-fast: false
|
|
283
|
+
matrix:
|
|
284
|
+
os: [ubuntu-latest, macos-latest, windows-latest]
|
|
285
|
+
node: [20, 22, 24]
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
**Non-matrix mode** (single version/OS or `--no-matrix`):
|
|
289
|
+
- Creates individual jobs per validation step
|
|
290
|
+
- Preserves phase dependencies
|
|
291
|
+
|
|
292
|
+
**Workflow sync checking:**
|
|
293
|
+
|
|
294
|
+
Use `--check` in CI to ensure workflow stays in sync with config:
|
|
295
|
+
|
|
296
|
+
```yaml
|
|
297
|
+
# .github/workflows/validate.yml
|
|
298
|
+
- name: Check workflow sync
|
|
299
|
+
run: npx vibe-validate generate-workflow --check
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
**Exit codes:**
|
|
303
|
+
- `0` - Workflow generated successfully or in sync
|
|
304
|
+
- `1` - Workflow out of sync (when using `--check`)
|
|
305
|
+
- `2` - Configuration or runtime error
|
|
306
|
+
|
|
307
|
+
---
|
|
308
|
+
|
|
230
309
|
### `doctor`
|
|
231
310
|
|
|
232
311
|
Check repository health and best practices.
|
package/dist/bin.js
CHANGED
|
@@ -15,6 +15,7 @@ import { stateCommand } from './commands/state.js';
|
|
|
15
15
|
import { syncCheckCommand } from './commands/sync-check.js';
|
|
16
16
|
import { cleanupCommand } from './commands/cleanup.js';
|
|
17
17
|
import { configCommand } from './commands/config.js';
|
|
18
|
+
import { generateWorkflowCommand } from './commands/generate-workflow.js';
|
|
18
19
|
// Read version from package.json at runtime
|
|
19
20
|
// This approach works with ESM and survives TypeScript compilation
|
|
20
21
|
const __filename = fileURLToPath(import.meta.url);
|
|
@@ -42,6 +43,7 @@ stateCommand(program); // vibe-validate state
|
|
|
42
43
|
syncCheckCommand(program); // vibe-validate sync-check
|
|
43
44
|
cleanupCommand(program); // vibe-validate cleanup
|
|
44
45
|
configCommand(program); // vibe-validate config
|
|
46
|
+
generateWorkflowCommand(program); // vibe-validate generate-workflow
|
|
45
47
|
// Parse command line arguments
|
|
46
48
|
program.parse();
|
|
47
49
|
//# sourceMappingURL=bin.js.map
|
package/dist/bin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA;;;;GAIG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACpC,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,uBAAuB,EAAE,MAAM,iCAAiC,CAAC;AAE1E,4CAA4C;AAC5C,mEAAmE;AACnE,MAAM,UAAU,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClD,MAAM,SAAS,GAAG,OAAO,CAAC,UAAU,CAAC,CAAC;AACtC,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC;AAE3D,IAAI,OAAO,GAAG,OAAO,CAAC,CAAC,mBAAmB;AAC1C,IAAI,CAAC;IACH,MAAM,WAAW,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,eAAe,EAAE,OAAO,CAAC,CAAC,CAAC;IACvE,OAAO,GAAG,WAAW,CAAC,OAAO,CAAC;AAChC,CAAC;AAAC,OAAO,MAAM,EAAE,CAAC;IAChB,+EAA+E;IAC/E,OAAO,CAAC,IAAI,CAAC,8DAA8D,CAAC,CAAC;AAC/E,CAAC;AAED,MAAM,OAAO,GAAG,IAAI,OAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,eAAe,CAAC;KACrB,WAAW,CAAC,gEAAgE,CAAC;KAC7E,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,oBAAoB;AACpB,eAAe,CAAC,OAAO,CAAC,CAAC,CAAY,yBAAyB;AAC9D,WAAW,CAAC,OAAO,CAAC,CAAC,CAAiB,qBAAqB;AAC3D,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAY,2BAA2B;AACjE,YAAY,CAAC,OAAO,CAAC,CAAC,CAAgB,sBAAsB;AAC5D,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAY,2BAA2B;AACjE,cAAc,CAAC,OAAO,CAAC,CAAC,CAAc,wBAAwB;AAC9D,aAAa,CAAC,OAAO,CAAC,CAAC,CAAe,uBAAuB;AAC7D,uBAAuB,CAAC,OAAO,CAAC,CAAC,CAAK,kCAAkC;AAExE,+BAA+B;AAC/B,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* GitHub Actions Workflow Generator Command
|
|
4
|
+
*
|
|
5
|
+
* Generates .github/workflows/validate.yml from vibe-validate.config.mjs
|
|
6
|
+
* Ensures perfect sync between local validation and CI validation.
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - Reads vibe-validate.config.mjs configuration
|
|
10
|
+
* - Generates GitHub Actions workflow with proper job dependencies
|
|
11
|
+
* - Supports multi-OS and multi-Node.js version testing
|
|
12
|
+
* - Includes coverage reporting integration
|
|
13
|
+
* - Provides --check mode to verify workflow sync
|
|
14
|
+
*
|
|
15
|
+
* @packageDocumentation
|
|
16
|
+
*/
|
|
17
|
+
import { Command } from 'commander';
|
|
18
|
+
import type { VibeValidateConfig, ValidationPhase } from '@vibe-validate/config';
|
|
19
|
+
/**
|
|
20
|
+
* Generate GitHub Actions workflow options
|
|
21
|
+
*/
|
|
22
|
+
export interface GenerateWorkflowOptions {
|
|
23
|
+
/** Node.js versions to test (default: ['20', '22']) - set to single version to disable matrix */
|
|
24
|
+
nodeVersions?: string[];
|
|
25
|
+
/** Operating systems to test (default: ['ubuntu-latest']) - set to single OS to disable matrix */
|
|
26
|
+
os?: string[];
|
|
27
|
+
/** Package manager (default: 'npm', auto-detects pnpm) */
|
|
28
|
+
packageManager?: 'npm' | 'pnpm';
|
|
29
|
+
/** Enable coverage reporting (default: false) */
|
|
30
|
+
enableCoverage?: boolean;
|
|
31
|
+
/** Coverage provider (default: 'codecov') */
|
|
32
|
+
coverageProvider?: 'codecov' | 'coveralls';
|
|
33
|
+
/** Codecov token secret name (default: 'CODECOV_TOKEN') */
|
|
34
|
+
codecovTokenSecret?: string;
|
|
35
|
+
/** Use matrix strategy for multi-OS/Node testing (default: true if multiple values provided) */
|
|
36
|
+
useMatrix?: boolean;
|
|
37
|
+
/** Fail fast in matrix (default: false) */
|
|
38
|
+
matrixFailFast?: boolean;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Convert phase/step name to valid GitHub Actions job ID
|
|
42
|
+
* (lowercase, replace spaces with dashes, remove special chars)
|
|
43
|
+
*/
|
|
44
|
+
export declare function toJobId(name: string): string;
|
|
45
|
+
/**
|
|
46
|
+
* Get all job IDs from validation phases
|
|
47
|
+
*/
|
|
48
|
+
export declare function getAllJobIds(phases: ValidationPhase[]): string[];
|
|
49
|
+
/**
|
|
50
|
+
* Generate GitHub Actions workflow from validation config
|
|
51
|
+
*/
|
|
52
|
+
export declare function generateWorkflow(config: VibeValidateConfig, options?: GenerateWorkflowOptions): string;
|
|
53
|
+
/**
|
|
54
|
+
* Check if workflow file is in sync with validation config
|
|
55
|
+
*/
|
|
56
|
+
export declare function checkSync(config: VibeValidateConfig, options?: GenerateWorkflowOptions): {
|
|
57
|
+
inSync: boolean;
|
|
58
|
+
diff?: string;
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* Main command handler for Commander.js
|
|
62
|
+
*/
|
|
63
|
+
export declare function generateWorkflowCommand(program: Command): void;
|
|
64
|
+
//# sourceMappingURL=generate-workflow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-workflow.d.ts","sourceRoot":"","sources":["../../src/commands/generate-workflow.ts"],"names":[],"mappings":";AACA;;;;;;;;;;;;;;GAcG;AAKH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,KAAK,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAyCjF;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,iGAAiG;IACjG,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,kGAAkG;IAClG,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC;IACd,0DAA0D;IAC1D,cAAc,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IAChC,iDAAiD;IACjD,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,6CAA6C;IAC7C,gBAAgB,CAAC,EAAE,SAAS,GAAG,WAAW,CAAC;IAC3C,2DAA2D;IAC3D,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,gGAAgG;IAChG,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,2CAA2C;IAC3C,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED;;;GAGG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM5C;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,EAAE,CAUhE;AAuED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,kBAAkB,EAC1B,OAAO,GAAE,uBAA4B,GACpC,MAAM,CAkSR;AAED;;GAEG;AACH,wBAAgB,SAAS,CACvB,MAAM,EAAE,kBAAkB,EAC1B,OAAO,GAAE,uBAA4B,GACpC;IAAE,MAAM,EAAE,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CA4BpC;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAyF9D"}
|
|
@@ -0,0 +1,466 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* GitHub Actions Workflow Generator Command
|
|
4
|
+
*
|
|
5
|
+
* Generates .github/workflows/validate.yml from vibe-validate.config.mjs
|
|
6
|
+
* Ensures perfect sync between local validation and CI validation.
|
|
7
|
+
*
|
|
8
|
+
* Features:
|
|
9
|
+
* - Reads vibe-validate.config.mjs configuration
|
|
10
|
+
* - Generates GitHub Actions workflow with proper job dependencies
|
|
11
|
+
* - Supports multi-OS and multi-Node.js version testing
|
|
12
|
+
* - Includes coverage reporting integration
|
|
13
|
+
* - Provides --check mode to verify workflow sync
|
|
14
|
+
*
|
|
15
|
+
* @packageDocumentation
|
|
16
|
+
*/
|
|
17
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from 'fs';
|
|
18
|
+
import { dirname, join } from 'path';
|
|
19
|
+
import yaml from 'js-yaml';
|
|
20
|
+
import { loadConfig } from '../utils/config-loader.js';
|
|
21
|
+
/**
|
|
22
|
+
* Convert phase/step name to valid GitHub Actions job ID
|
|
23
|
+
* (lowercase, replace spaces with dashes, remove special chars)
|
|
24
|
+
*/
|
|
25
|
+
export function toJobId(name) {
|
|
26
|
+
return name
|
|
27
|
+
.toLowerCase()
|
|
28
|
+
.replace(/[^a-z0-9-]/g, '-')
|
|
29
|
+
.replace(/-+/g, '-')
|
|
30
|
+
.replace(/^-|-$/g, '');
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Get all job IDs from validation phases
|
|
34
|
+
*/
|
|
35
|
+
export function getAllJobIds(phases) {
|
|
36
|
+
const jobIds = [];
|
|
37
|
+
for (const phase of phases) {
|
|
38
|
+
for (const step of phase.steps) {
|
|
39
|
+
jobIds.push(toJobId(step.name));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return jobIds;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Get job IDs for a specific phase
|
|
46
|
+
*/
|
|
47
|
+
function getPhaseJobIds(phases, phaseName) {
|
|
48
|
+
const phase = phases.find(p => p.name === phaseName);
|
|
49
|
+
if (!phase) {
|
|
50
|
+
return [];
|
|
51
|
+
}
|
|
52
|
+
return phase.steps.map(step => toJobId(step.name));
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Generate bash script to check all job statuses
|
|
56
|
+
*/
|
|
57
|
+
function generateCheckScript(jobNames) {
|
|
58
|
+
const checks = jobNames
|
|
59
|
+
.map(job => {
|
|
60
|
+
const envVar = `needs.${job}.result`;
|
|
61
|
+
return `[ "\${{ ${envVar} }}" != "success" ]`;
|
|
62
|
+
})
|
|
63
|
+
.join(' || \\\n ');
|
|
64
|
+
return `if ${checks}; then
|
|
65
|
+
echo "❌ Some validation checks failed"
|
|
66
|
+
exit 1
|
|
67
|
+
fi
|
|
68
|
+
echo "✅ All validation checks passed!"`;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Detect package manager from lockfile
|
|
72
|
+
*/
|
|
73
|
+
function detectPackageManager(cwd = process.cwd()) {
|
|
74
|
+
if (existsSync(join(cwd, 'pnpm-lock.yaml'))) {
|
|
75
|
+
return 'pnpm';
|
|
76
|
+
}
|
|
77
|
+
return 'npm';
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Detect Node.js version from package.json engines field
|
|
81
|
+
* Returns major version only (e.g., "20" from ">=20.0.0")
|
|
82
|
+
*/
|
|
83
|
+
function detectNodeVersion(cwd = process.cwd()) {
|
|
84
|
+
const DEFAULT_NODE_VERSION = '22'; // Node 22 LTS
|
|
85
|
+
try {
|
|
86
|
+
const packageJsonPath = join(cwd, 'package.json');
|
|
87
|
+
if (!existsSync(packageJsonPath)) {
|
|
88
|
+
return DEFAULT_NODE_VERSION;
|
|
89
|
+
}
|
|
90
|
+
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
|
|
91
|
+
const engines = packageJson.engines?.node;
|
|
92
|
+
if (!engines) {
|
|
93
|
+
return DEFAULT_NODE_VERSION;
|
|
94
|
+
}
|
|
95
|
+
// Parse version from various formats:
|
|
96
|
+
// ">=20.0.0", "^20.0.0", "~20.0.0", "20.x", "20", ">=20"
|
|
97
|
+
const match = engines.match(/(\d+)/);
|
|
98
|
+
return match ? match[1] : DEFAULT_NODE_VERSION;
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
return DEFAULT_NODE_VERSION;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Generate GitHub Actions workflow from validation config
|
|
106
|
+
*/
|
|
107
|
+
export function generateWorkflow(config, options = {}) {
|
|
108
|
+
const { nodeVersions = [detectNodeVersion()], os = ['ubuntu-latest'], packageManager = detectPackageManager(), enableCoverage = false, coverageProvider = 'codecov', codecovTokenSecret = 'CODECOV_TOKEN', matrixFailFast = false, } = options;
|
|
109
|
+
// Determine if we should use matrix strategy
|
|
110
|
+
const useMatrix = options.useMatrix ?? (nodeVersions.length > 1 || os.length > 1);
|
|
111
|
+
const jobs = {};
|
|
112
|
+
const phases = config.validation.phases;
|
|
113
|
+
if (useMatrix) {
|
|
114
|
+
// Matrix strategy: Create single job that runs validation with matrix
|
|
115
|
+
const jobSteps = [
|
|
116
|
+
{ uses: 'actions/checkout@v4' },
|
|
117
|
+
];
|
|
118
|
+
// Add pnpm setup if needed
|
|
119
|
+
if (packageManager === 'pnpm') {
|
|
120
|
+
jobSteps.push({
|
|
121
|
+
name: 'Setup pnpm',
|
|
122
|
+
uses: 'pnpm/action-setup@v2',
|
|
123
|
+
with: { version: '9' },
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
// Setup Node.js with matrix variable
|
|
127
|
+
jobSteps.push({
|
|
128
|
+
name: 'Setup Node.js ${{ matrix.node }}',
|
|
129
|
+
uses: 'actions/setup-node@v4',
|
|
130
|
+
with: {
|
|
131
|
+
'node-version': '${{ matrix.node }}',
|
|
132
|
+
cache: packageManager,
|
|
133
|
+
},
|
|
134
|
+
});
|
|
135
|
+
// Install dependencies
|
|
136
|
+
jobSteps.push({
|
|
137
|
+
name: 'Install dependencies',
|
|
138
|
+
run: packageManager === 'pnpm' ? 'pnpm install' : 'npm ci',
|
|
139
|
+
});
|
|
140
|
+
// Add build step if needed (common pattern)
|
|
141
|
+
const hasBuildPhase = phases.some(p => p.steps.some(s => s.name.toLowerCase().includes('build')));
|
|
142
|
+
if (hasBuildPhase) {
|
|
143
|
+
jobSteps.push({
|
|
144
|
+
name: 'Build packages',
|
|
145
|
+
run: packageManager === 'pnpm' ? 'pnpm -r build' : 'npm run build',
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
// Run validation
|
|
149
|
+
jobSteps.push({
|
|
150
|
+
name: 'Run validation',
|
|
151
|
+
run: packageManager === 'pnpm' ? 'pnpm validate' : 'npm run validate',
|
|
152
|
+
env: {
|
|
153
|
+
LLM_OUTPUT: '1',
|
|
154
|
+
},
|
|
155
|
+
});
|
|
156
|
+
// Add validation state upload on failure
|
|
157
|
+
jobSteps.push({
|
|
158
|
+
name: 'Upload validation state on failure',
|
|
159
|
+
if: 'failure()',
|
|
160
|
+
uses: 'actions/upload-artifact@v4',
|
|
161
|
+
with: {
|
|
162
|
+
name: 'validation-state-${{ matrix.os }}-node${{ matrix.node }}',
|
|
163
|
+
path: '.vibe-validate-state.yaml',
|
|
164
|
+
'retention-days': 7,
|
|
165
|
+
},
|
|
166
|
+
});
|
|
167
|
+
jobs['validate'] = {
|
|
168
|
+
name: 'Run vibe-validate validation',
|
|
169
|
+
'runs-on': '${{ matrix.os }}',
|
|
170
|
+
steps: jobSteps,
|
|
171
|
+
strategy: {
|
|
172
|
+
'fail-fast': matrixFailFast,
|
|
173
|
+
matrix: {
|
|
174
|
+
os,
|
|
175
|
+
node: nodeVersions,
|
|
176
|
+
},
|
|
177
|
+
},
|
|
178
|
+
};
|
|
179
|
+
// Add coverage job if enabled (separate, runs on ubuntu only)
|
|
180
|
+
if (enableCoverage) {
|
|
181
|
+
const coverageSteps = [
|
|
182
|
+
{ uses: 'actions/checkout@v4' },
|
|
183
|
+
];
|
|
184
|
+
if (packageManager === 'pnpm') {
|
|
185
|
+
coverageSteps.push({
|
|
186
|
+
name: 'Setup pnpm',
|
|
187
|
+
uses: 'pnpm/action-setup@v2',
|
|
188
|
+
with: { version: '9' },
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
coverageSteps.push({
|
|
192
|
+
name: 'Setup Node.js',
|
|
193
|
+
uses: 'actions/setup-node@v4',
|
|
194
|
+
with: {
|
|
195
|
+
'node-version': nodeVersions[0],
|
|
196
|
+
cache: packageManager,
|
|
197
|
+
},
|
|
198
|
+
});
|
|
199
|
+
coverageSteps.push({
|
|
200
|
+
name: 'Install dependencies',
|
|
201
|
+
run: packageManager === 'pnpm' ? 'pnpm install' : 'npm ci',
|
|
202
|
+
});
|
|
203
|
+
if (hasBuildPhase) {
|
|
204
|
+
coverageSteps.push({
|
|
205
|
+
name: 'Build packages',
|
|
206
|
+
run: packageManager === 'pnpm' ? 'pnpm -r build' : 'npm run build',
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
coverageSteps.push({
|
|
210
|
+
name: 'Run tests with coverage',
|
|
211
|
+
run: packageManager === 'pnpm' ? 'pnpm test:coverage' : 'npm run test:coverage',
|
|
212
|
+
env: {
|
|
213
|
+
LLM_OUTPUT: '1',
|
|
214
|
+
},
|
|
215
|
+
});
|
|
216
|
+
if (coverageProvider === 'codecov') {
|
|
217
|
+
coverageSteps.push({
|
|
218
|
+
name: 'Upload coverage to Codecov',
|
|
219
|
+
uses: 'codecov/codecov-action@v4',
|
|
220
|
+
with: {
|
|
221
|
+
token: `\${{ secrets.${codecovTokenSecret} }}`,
|
|
222
|
+
files: './coverage/coverage-final.json',
|
|
223
|
+
'fail_ci_if_error': false,
|
|
224
|
+
},
|
|
225
|
+
});
|
|
226
|
+
}
|
|
227
|
+
jobs['validate-coverage'] = {
|
|
228
|
+
name: 'Run validation with coverage',
|
|
229
|
+
'runs-on': 'ubuntu-latest',
|
|
230
|
+
steps: coverageSteps,
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
else {
|
|
235
|
+
// Non-matrix: Create individual jobs for each validation step
|
|
236
|
+
for (const phase of phases) {
|
|
237
|
+
// Determine job dependencies based on dependsOn
|
|
238
|
+
let needs;
|
|
239
|
+
if (phase.dependsOn && phase.dependsOn.length > 0) {
|
|
240
|
+
needs = [];
|
|
241
|
+
for (const depPhaseName of phase.dependsOn) {
|
|
242
|
+
needs.push(...getPhaseJobIds(phases, depPhaseName));
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
for (const step of phase.steps) {
|
|
246
|
+
const jobId = toJobId(step.name);
|
|
247
|
+
const jobSteps = [
|
|
248
|
+
{ uses: 'actions/checkout@v4' },
|
|
249
|
+
{
|
|
250
|
+
uses: 'actions/setup-node@v4',
|
|
251
|
+
with: {
|
|
252
|
+
'node-version': nodeVersions[0],
|
|
253
|
+
cache: packageManager,
|
|
254
|
+
},
|
|
255
|
+
},
|
|
256
|
+
];
|
|
257
|
+
// Install dependencies
|
|
258
|
+
if (packageManager === 'pnpm') {
|
|
259
|
+
jobSteps.push({
|
|
260
|
+
name: 'Install pnpm',
|
|
261
|
+
uses: 'pnpm/action-setup@v2',
|
|
262
|
+
with: { version: '8' },
|
|
263
|
+
}, { run: 'pnpm install' });
|
|
264
|
+
}
|
|
265
|
+
else {
|
|
266
|
+
jobSteps.push({ run: 'npm ci' });
|
|
267
|
+
}
|
|
268
|
+
// Add the actual validation command
|
|
269
|
+
const testStep = { run: step.command };
|
|
270
|
+
// Add environment variables from step config
|
|
271
|
+
if (step.env) {
|
|
272
|
+
testStep.env = { ...step.env };
|
|
273
|
+
}
|
|
274
|
+
else {
|
|
275
|
+
testStep.env = {};
|
|
276
|
+
}
|
|
277
|
+
// Add LLM_OUTPUT=1 for concise CI output
|
|
278
|
+
if (!testStep.env.LLM_OUTPUT) {
|
|
279
|
+
testStep.env.LLM_OUTPUT = '1';
|
|
280
|
+
}
|
|
281
|
+
jobSteps.push(testStep);
|
|
282
|
+
// Add coverage reporting if enabled
|
|
283
|
+
if (enableCoverage && step.name.toLowerCase().includes('coverage')) {
|
|
284
|
+
if (coverageProvider === 'codecov') {
|
|
285
|
+
jobSteps.push({
|
|
286
|
+
name: 'Upload coverage to Codecov',
|
|
287
|
+
uses: 'codecov/codecov-action@v3',
|
|
288
|
+
with: {
|
|
289
|
+
'fail_ci_if_error': true,
|
|
290
|
+
},
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
else if (coverageProvider === 'coveralls') {
|
|
294
|
+
jobSteps.push({
|
|
295
|
+
name: 'Upload coverage to Coveralls',
|
|
296
|
+
uses: 'coverallsapp/github-action@v2',
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
jobs[jobId] = {
|
|
301
|
+
name: step.name,
|
|
302
|
+
'runs-on': os[0],
|
|
303
|
+
...(needs && { needs }),
|
|
304
|
+
steps: jobSteps,
|
|
305
|
+
};
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
// Add gate job - all validation must pass
|
|
310
|
+
const allJobs = useMatrix
|
|
311
|
+
? enableCoverage
|
|
312
|
+
? ['validate', 'validate-coverage']
|
|
313
|
+
: ['validate']
|
|
314
|
+
: getAllJobIds(phases);
|
|
315
|
+
jobs['all-validation-passed'] = {
|
|
316
|
+
name: 'All Validation Passed',
|
|
317
|
+
'runs-on': 'ubuntu-latest',
|
|
318
|
+
needs: allJobs,
|
|
319
|
+
if: 'always()',
|
|
320
|
+
steps: [
|
|
321
|
+
{
|
|
322
|
+
name: 'Check all validation jobs',
|
|
323
|
+
run: generateCheckScript(allJobs),
|
|
324
|
+
},
|
|
325
|
+
],
|
|
326
|
+
};
|
|
327
|
+
const workflow = {
|
|
328
|
+
name: 'Validation Pipeline',
|
|
329
|
+
on: {
|
|
330
|
+
push: {
|
|
331
|
+
branches: [config.git?.mainBranch || 'main'],
|
|
332
|
+
},
|
|
333
|
+
pull_request: {
|
|
334
|
+
branches: [config.git?.mainBranch || 'main'],
|
|
335
|
+
},
|
|
336
|
+
},
|
|
337
|
+
jobs,
|
|
338
|
+
};
|
|
339
|
+
// Generate YAML with header comment
|
|
340
|
+
const header = [
|
|
341
|
+
'# THIS FILE IS AUTO-GENERATED by vibe-validate generate-workflow',
|
|
342
|
+
'# DO NOT EDIT MANUALLY - Edit vibe-validate.config.mjs instead',
|
|
343
|
+
'# Regenerate with: npx vibe-validate generate-workflow',
|
|
344
|
+
'#',
|
|
345
|
+
'# Source of truth: vibe-validate.config.mjs',
|
|
346
|
+
`# Generated: ${new Date().toISOString()}`,
|
|
347
|
+
'',
|
|
348
|
+
].join('\n');
|
|
349
|
+
const workflowYaml = yaml.dump(workflow, {
|
|
350
|
+
lineWidth: -1,
|
|
351
|
+
noRefs: true,
|
|
352
|
+
quotingType: '"',
|
|
353
|
+
forceQuotes: false,
|
|
354
|
+
});
|
|
355
|
+
return header + workflowYaml;
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Check if workflow file is in sync with validation config
|
|
359
|
+
*/
|
|
360
|
+
export function checkSync(config, options = {}) {
|
|
361
|
+
const workflowPath = '.github/workflows/validate.yml';
|
|
362
|
+
if (!existsSync(workflowPath)) {
|
|
363
|
+
return {
|
|
364
|
+
inSync: false,
|
|
365
|
+
diff: 'Workflow file does not exist - needs generation',
|
|
366
|
+
};
|
|
367
|
+
}
|
|
368
|
+
const currentWorkflow = readFileSync(workflowPath, 'utf8');
|
|
369
|
+
const expectedWorkflow = generateWorkflow(config, options);
|
|
370
|
+
// Normalize for comparison (strip timestamps)
|
|
371
|
+
const normalize = (content) => content.replace(/# Generated: .+/g, '# Generated: <timestamp>');
|
|
372
|
+
const currentNormalized = normalize(currentWorkflow);
|
|
373
|
+
const expectedNormalized = normalize(expectedWorkflow);
|
|
374
|
+
if (currentNormalized === expectedNormalized) {
|
|
375
|
+
return { inSync: true };
|
|
376
|
+
}
|
|
377
|
+
return {
|
|
378
|
+
inSync: false,
|
|
379
|
+
diff: 'Workflow file differs from validation config',
|
|
380
|
+
};
|
|
381
|
+
}
|
|
382
|
+
/**
|
|
383
|
+
* Main command handler for Commander.js
|
|
384
|
+
*/
|
|
385
|
+
export function generateWorkflowCommand(program) {
|
|
386
|
+
program
|
|
387
|
+
.command('generate-workflow')
|
|
388
|
+
.description('Generate GitHub Actions workflow from vibe-validate config')
|
|
389
|
+
.option('--check', 'Check if workflow is in sync with config (exit 0 if in sync, 1 if not)')
|
|
390
|
+
.option('--dry-run', 'Show generated workflow without writing to file')
|
|
391
|
+
.option('--coverage', 'Enable coverage reporting (Codecov)')
|
|
392
|
+
.option('--node-versions <versions>', 'Node.js versions to test (comma-separated, default: "20,22")')
|
|
393
|
+
.option('--os <systems>', 'Operating systems to test (comma-separated, default: "ubuntu-latest")')
|
|
394
|
+
.option('--fail-fast', 'Fail fast in matrix strategy (default: false)')
|
|
395
|
+
.action(async (options) => {
|
|
396
|
+
try {
|
|
397
|
+
// Load configuration
|
|
398
|
+
const config = await loadConfig();
|
|
399
|
+
if (!config) {
|
|
400
|
+
console.error('❌ Failed to load vibe-validate config');
|
|
401
|
+
console.error(' Make sure vibe-validate.config.mjs exists and is valid.');
|
|
402
|
+
process.exit(1);
|
|
403
|
+
}
|
|
404
|
+
// Parse options
|
|
405
|
+
const generateOptions = {
|
|
406
|
+
packageManager: detectPackageManager(),
|
|
407
|
+
enableCoverage: options.coverage || false,
|
|
408
|
+
// Parse comma-separated node versions
|
|
409
|
+
nodeVersions: options.nodeVersions
|
|
410
|
+
? options.nodeVersions.split(',').map(v => v.trim())
|
|
411
|
+
: undefined,
|
|
412
|
+
// Parse comma-separated OS values
|
|
413
|
+
os: options.os
|
|
414
|
+
? options.os.split(',').map(o => o.trim())
|
|
415
|
+
: undefined,
|
|
416
|
+
// Parse fail-fast flag
|
|
417
|
+
matrixFailFast: options.failFast || false,
|
|
418
|
+
};
|
|
419
|
+
if (options.check) {
|
|
420
|
+
// Check sync only
|
|
421
|
+
const { inSync, diff } = checkSync(config, generateOptions);
|
|
422
|
+
if (inSync) {
|
|
423
|
+
console.log('✅ Workflow file is in sync with validation config');
|
|
424
|
+
process.exit(0);
|
|
425
|
+
}
|
|
426
|
+
else {
|
|
427
|
+
console.log('❌ Workflow file is out of sync with validation config');
|
|
428
|
+
console.log('');
|
|
429
|
+
console.log(diff);
|
|
430
|
+
console.log('');
|
|
431
|
+
console.log('Run this to regenerate:');
|
|
432
|
+
console.log(' npx vibe-validate generate-workflow');
|
|
433
|
+
process.exit(1);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
else if (options.dryRun) {
|
|
437
|
+
// Show output without writing
|
|
438
|
+
const workflow = generateWorkflow(config, generateOptions);
|
|
439
|
+
console.log(workflow);
|
|
440
|
+
}
|
|
441
|
+
else {
|
|
442
|
+
// Generate and write workflow
|
|
443
|
+
const workflow = generateWorkflow(config, generateOptions);
|
|
444
|
+
const workflowPath = '.github/workflows/validate.yml';
|
|
445
|
+
// Ensure directory exists
|
|
446
|
+
const workflowDir = dirname(workflowPath);
|
|
447
|
+
if (!existsSync(workflowDir)) {
|
|
448
|
+
mkdirSync(workflowDir, { recursive: true });
|
|
449
|
+
}
|
|
450
|
+
writeFileSync(workflowPath, workflow);
|
|
451
|
+
console.log('✅ Generated workflow file:');
|
|
452
|
+
console.log(` ${workflowPath}`);
|
|
453
|
+
console.log('');
|
|
454
|
+
console.log('📝 Commit this file to version control');
|
|
455
|
+
}
|
|
456
|
+
}
|
|
457
|
+
catch (error) {
|
|
458
|
+
console.error('❌ Failed to generate workflow:');
|
|
459
|
+
console.error(error instanceof Error ? error.message : String(error));
|
|
460
|
+
console.error('');
|
|
461
|
+
console.error('Make sure vibe-validate.config.mjs exists and is valid.');
|
|
462
|
+
process.exit(1);
|
|
463
|
+
}
|
|
464
|
+
});
|
|
465
|
+
}
|
|
466
|
+
//# sourceMappingURL=generate-workflow.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-workflow.js","sourceRoot":"","sources":["../../src/commands/generate-workflow.ts"],"names":[],"mappings":"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"}
|