@paths.design/caws-cli 7.0.2 ā 7.0.3
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/dist/budget-derivation.js +5 -4
- package/dist/commands/diagnose.js +24 -19
- package/dist/commands/init.js +51 -4
- package/dist/commands/specs.js +40 -1
- package/dist/commands/status.js +2 -2
- package/dist/commands/tool.js +2 -3
- package/dist/config/index.js +17 -8
- package/dist/generators/working-spec.js +19 -6
- package/dist/scaffold/git-hooks.js +127 -29
- package/dist/scaffold/index.js +53 -7
- package/dist/templates/.caws/tools/README.md +20 -0
- package/dist/templates/.cursor/README.md +311 -0
- package/dist/templates/.cursor/hooks/audit.sh +55 -0
- package/dist/templates/.cursor/hooks/block-dangerous.sh +83 -0
- package/dist/templates/.cursor/hooks/caws-quality-check.sh +52 -0
- package/dist/templates/.cursor/hooks/caws-scope-guard.sh +130 -0
- package/dist/templates/.cursor/hooks/caws-tool-validation.sh +121 -0
- package/dist/templates/.cursor/hooks/format.sh +38 -0
- package/dist/templates/.cursor/hooks/naming-check.sh +64 -0
- package/dist/templates/.cursor/hooks/scan-secrets.sh +46 -0
- package/dist/templates/.cursor/hooks/scope-guard.sh +52 -0
- package/dist/templates/.cursor/hooks/validate-spec.sh +83 -0
- package/dist/templates/.cursor/hooks.json +59 -0
- package/dist/templates/.cursor/rules/00-claims-verification.mdc +144 -0
- package/dist/templates/.cursor/rules/01-working-style.mdc +50 -0
- package/dist/templates/.cursor/rules/02-quality-gates.mdc +370 -0
- package/dist/templates/.cursor/rules/03-naming-and-refactor.mdc +33 -0
- package/dist/templates/.cursor/rules/04-logging-language-style.mdc +23 -0
- package/dist/templates/.cursor/rules/05-safe-defaults-guards.mdc +23 -0
- package/dist/templates/.cursor/rules/06-typescript-conventions.mdc +36 -0
- package/dist/templates/.cursor/rules/07-process-ops.mdc +20 -0
- package/dist/templates/.cursor/rules/08-solid-and-architecture.mdc +16 -0
- package/dist/templates/.cursor/rules/09-docstrings.mdc +89 -0
- package/dist/templates/.cursor/rules/10-documentation-quality-standards.mdc +390 -0
- package/dist/templates/.cursor/rules/11-scope-management-waivers.mdc +385 -0
- package/dist/templates/.cursor/rules/12-implementation-completeness.mdc +516 -0
- package/dist/templates/.cursor/rules/13-language-agnostic-standards.mdc +588 -0
- package/dist/templates/.cursor/rules/README.md +148 -0
- package/dist/templates/.github/copilot/instructions.md +311 -0
- package/dist/templates/.idea/runConfigurations/CAWS_Evaluate.xml +5 -0
- package/dist/templates/.idea/runConfigurations/CAWS_Validate.xml +5 -0
- package/dist/templates/.vscode/launch.json +56 -0
- package/dist/templates/.vscode/settings.json +93 -0
- package/dist/templates/.windsurf/workflows/caws-guided-development.md +92 -0
- package/dist/templates/COMMIT_CONVENTIONS.md +86 -0
- package/dist/templates/OIDC_SETUP.md +300 -0
- package/dist/templates/agents.md +1047 -0
- package/dist/templates/codemod/README.md +1 -0
- package/dist/templates/codemod/test.js +93 -0
- package/dist/templates/docs/README.md +150 -0
- package/dist/templates/scripts/quality-gates/check-god-objects.js +146 -0
- package/dist/templates/scripts/quality-gates/run-quality-gates.js +50 -0
- package/dist/templates/scripts/v3/analysis/todo_analyzer.py +1997 -0
- package/dist/tool-loader.js +6 -1
- package/dist/tool-validator.js +8 -2
- package/dist/utils/detection.js +4 -3
- package/dist/utils/git-lock.js +118 -0
- package/dist/utils/gitignore-updater.js +148 -0
- package/dist/utils/quality-gates.js +47 -7
- package/dist/utils/spec-resolver.js +23 -3
- package/dist/utils/yaml-validation.js +155 -0
- package/dist/validation/spec-validation.js +81 -2
- package/package.json +2 -2
- package/templates/.caws/schemas/waivers.schema.json +30 -0
- package/templates/.caws/schemas/working-spec.schema.json +133 -0
- package/templates/.caws/templates/working-spec.template.yml +74 -0
- package/templates/.caws/tools/README.md +20 -0
- package/templates/.caws/tools/scope-guard.js +208 -0
- package/templates/.caws/tools-allow.json +331 -0
- package/templates/.caws/waivers.yml +19 -0
- package/templates/.cursor/hooks/scope-guard.sh +2 -2
- package/templates/.cursor/hooks/validate-spec.sh +42 -7
- package/templates/apps/tools/caws/COMPLETION_REPORT.md +0 -331
- package/templates/apps/tools/caws/MIGRATION_SUMMARY.md +0 -360
- package/templates/apps/tools/caws/README.md +0 -463
- package/templates/apps/tools/caws/TEST_STATUS.md +0 -365
- package/templates/apps/tools/caws/attest.js +0 -357
- package/templates/apps/tools/caws/ci-optimizer.js +0 -642
- package/templates/apps/tools/caws/config.ts +0 -245
- package/templates/apps/tools/caws/cross-functional.js +0 -876
- package/templates/apps/tools/caws/dashboard.js +0 -1112
- package/templates/apps/tools/caws/flake-detector.ts +0 -362
- package/templates/apps/tools/caws/gates.js +0 -198
- package/templates/apps/tools/caws/gates.ts +0 -271
- package/templates/apps/tools/caws/language-adapters.ts +0 -381
- package/templates/apps/tools/caws/language-support.d.ts +0 -367
- package/templates/apps/tools/caws/language-support.d.ts.map +0 -1
- package/templates/apps/tools/caws/language-support.js +0 -585
- package/templates/apps/tools/caws/legacy-assessment.ts +0 -408
- package/templates/apps/tools/caws/legacy-assessor.js +0 -764
- package/templates/apps/tools/caws/mutant-analyzer.js +0 -734
- package/templates/apps/tools/caws/perf-budgets.ts +0 -349
- package/templates/apps/tools/caws/prompt-lint.js.backup +0 -274
- package/templates/apps/tools/caws/property-testing.js +0 -707
- package/templates/apps/tools/caws/provenance.d.ts +0 -14
- package/templates/apps/tools/caws/provenance.d.ts.map +0 -1
- package/templates/apps/tools/caws/provenance.js +0 -132
- package/templates/apps/tools/caws/provenance.js.backup +0 -73
- package/templates/apps/tools/caws/provenance.ts +0 -211
- package/templates/apps/tools/caws/security-provenance.ts +0 -483
- package/templates/apps/tools/caws/shared/base-tool.ts +0 -281
- package/templates/apps/tools/caws/shared/config-manager.ts +0 -366
- package/templates/apps/tools/caws/shared/gate-checker.ts +0 -849
- package/templates/apps/tools/caws/shared/types.ts +0 -444
- package/templates/apps/tools/caws/shared/validator.ts +0 -305
- package/templates/apps/tools/caws/shared/waivers-manager.ts +0 -174
- package/templates/apps/tools/caws/spec-test-mapper.ts +0 -391
- package/templates/apps/tools/caws/test-quality.js +0 -578
- package/templates/apps/tools/caws/validate.js +0 -76
- package/templates/apps/tools/caws/validate.ts +0 -228
- package/templates/apps/tools/caws/waivers.js +0 -344
- /package/{templates/apps/tools/caws ā dist/templates/.caws}/schemas/waivers.schema.json +0 -0
- /package/{templates/apps/tools/caws ā dist/templates/.caws}/schemas/working-spec.schema.json +0 -0
- /package/{templates/apps/tools/caws ā dist/templates/.caws}/templates/working-spec.template.yml +0 -0
- /package/{templates/apps/tools/caws ā dist/templates/.caws/tools}/scope-guard.js +0 -0
- /package/{templates/apps/tools/caws ā dist/templates/.caws}/tools-allow.json +0 -0
- /package/{templates/apps/tools/caws ā dist/templates/.caws}/waivers.yml +0 -0
|
@@ -1,642 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @fileoverview CAWS CI/CD Pipeline Optimizer
|
|
5
|
-
* Implements risk-driven and change-driven optimizations for faster feedback
|
|
6
|
-
* @author @darianrosebrook
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
const fs = require('fs');
|
|
10
|
-
const path = require('path');
|
|
11
|
-
const yaml = require('js-yaml');
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* CI optimization strategies
|
|
15
|
-
*/
|
|
16
|
-
const OPTIMIZATION_STRATEGIES = {
|
|
17
|
-
TIER_BASED_CONDITIONAL: {
|
|
18
|
-
name: 'Tier-based Conditional Runs',
|
|
19
|
-
description: 'Skip expensive checks for low-risk changes',
|
|
20
|
-
impact: 'high',
|
|
21
|
-
implementation: 'GitHub Actions conditionals',
|
|
22
|
-
},
|
|
23
|
-
SELECTIVE_TEST_EXECUTION: {
|
|
24
|
-
name: 'Selective Test Execution',
|
|
25
|
-
description: 'Run only tests related to changed files',
|
|
26
|
-
impact: 'medium',
|
|
27
|
-
implementation: 'Test selection by file paths',
|
|
28
|
-
},
|
|
29
|
-
TWO_PHASE_PIPELINE: {
|
|
30
|
-
name: 'Two-phase Pipeline',
|
|
31
|
-
description: 'Quick feedback for commits, full validation for PRs',
|
|
32
|
-
impact: 'high',
|
|
33
|
-
implementation: 'Separate push/PR workflows',
|
|
34
|
-
},
|
|
35
|
-
PARALLEL_EXECUTION: {
|
|
36
|
-
name: 'Parallel Execution',
|
|
37
|
-
description: 'Maximize parallelization of independent checks',
|
|
38
|
-
impact: 'medium',
|
|
39
|
-
implementation: 'Job dependencies and matrix strategies',
|
|
40
|
-
},
|
|
41
|
-
INCREMENTAL_BUILDS: {
|
|
42
|
-
name: 'Incremental Builds',
|
|
43
|
-
description: 'Skip unchanged parts of the build',
|
|
44
|
-
impact: 'low',
|
|
45
|
-
implementation: 'Build caching and conditional steps',
|
|
46
|
-
},
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Generate optimized GitHub Actions workflow
|
|
51
|
-
* @param {Object} options - Optimization options
|
|
52
|
-
* @returns {string} GitHub Actions workflow YAML
|
|
53
|
-
*/
|
|
54
|
-
function generateOptimizedWorkflow(options = {}) {
|
|
55
|
-
const {
|
|
56
|
-
language = 'javascript',
|
|
57
|
-
tier = 2,
|
|
58
|
-
enableTwoPhase = true,
|
|
59
|
-
enableSelectiveTests = true,
|
|
60
|
-
enableTierConditionals = true,
|
|
61
|
-
} = options;
|
|
62
|
-
|
|
63
|
-
const workflow = {
|
|
64
|
-
name: 'CAWS Optimized CI/CD',
|
|
65
|
-
on: {
|
|
66
|
-
push: { branches: ['main', 'develop'] },
|
|
67
|
-
pull_request: { branches: ['main', 'develop'] },
|
|
68
|
-
},
|
|
69
|
-
jobs: {},
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
// Setup job (always runs)
|
|
73
|
-
workflow.jobs.setup = {
|
|
74
|
-
'runs-on': 'ubuntu-latest',
|
|
75
|
-
outputs: {
|
|
76
|
-
risk_tier: '${{ steps.detect.outputs.tier }}',
|
|
77
|
-
changed_files: '${{ steps.detect.outputs.files }}',
|
|
78
|
-
is_experimental: '${{ steps.detect.outputs.experimental }}',
|
|
79
|
-
},
|
|
80
|
-
steps: [
|
|
81
|
-
{
|
|
82
|
-
name: 'Checkout code',
|
|
83
|
-
uses: 'actions/checkout@v4',
|
|
84
|
-
with: { 'fetch-depth': 2 },
|
|
85
|
-
},
|
|
86
|
-
{
|
|
87
|
-
id: 'detect',
|
|
88
|
-
name: 'Detect CAWS configuration',
|
|
89
|
-
run: `
|
|
90
|
-
# Detect risk tier from working spec
|
|
91
|
-
if [ -f .caws/working-spec.yaml ]; then
|
|
92
|
-
TIER=$(grep 'risk_tier:' .caws/working-spec.yaml | cut -d':' -f2 | tr -d ' ')
|
|
93
|
-
echo "tier=$TIER" >> $GITHUB_OUTPUT
|
|
94
|
-
|
|
95
|
-
# Check for experimental mode
|
|
96
|
-
if grep -q 'experimental_mode:' .caws/working-spec.yaml; then
|
|
97
|
-
echo "experimental=true" >> $GITHUB_OUTPUT
|
|
98
|
-
else
|
|
99
|
-
echo "experimental=false" >> $GITHUB_OUTPUT
|
|
100
|
-
fi
|
|
101
|
-
else
|
|
102
|
-
echo "tier=2" >> $GITHUB_OUTPUT
|
|
103
|
-
echo "experimental=false" >> $GITHUB_OUTPUT
|
|
104
|
-
fi
|
|
105
|
-
|
|
106
|
-
# Get changed files
|
|
107
|
-
if [ "$GITHUB_EVENT_NAME" = "pull_request" ]; then
|
|
108
|
-
FILES=$(git diff --name-only "$GITHUB_BASE_SHA" "$GITHUB_SHA" | tr '\n' ' ')
|
|
109
|
-
else
|
|
110
|
-
FILES=$(git diff --name-only HEAD~1 HEAD | tr '\n' ' ')
|
|
111
|
-
fi
|
|
112
|
-
echo "files=$FILES" >> $GITHUB_OUTPUT
|
|
113
|
-
`,
|
|
114
|
-
},
|
|
115
|
-
],
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
// Quick feedback job (runs on every push)
|
|
119
|
-
if (enableTwoPhase) {
|
|
120
|
-
workflow.jobs.quick_feedback = {
|
|
121
|
-
'runs-on': 'ubuntu-latest',
|
|
122
|
-
needs: 'setup',
|
|
123
|
-
if: "github.event_name == 'push'",
|
|
124
|
-
steps: [
|
|
125
|
-
{
|
|
126
|
-
name: 'Checkout code',
|
|
127
|
-
uses: 'actions/checkout@v4',
|
|
128
|
-
},
|
|
129
|
-
{
|
|
130
|
-
name: 'Setup Node.js',
|
|
131
|
-
uses: 'actions/setup-node@v4',
|
|
132
|
-
with: { 'node-version': '18', cache: 'npm' },
|
|
133
|
-
},
|
|
134
|
-
{
|
|
135
|
-
name: 'Install dependencies',
|
|
136
|
-
run: 'npm ci',
|
|
137
|
-
},
|
|
138
|
-
{
|
|
139
|
-
name: 'Quick lint',
|
|
140
|
-
run: 'npm run lint || true',
|
|
141
|
-
},
|
|
142
|
-
{
|
|
143
|
-
name: 'Quick tests',
|
|
144
|
-
run: 'npm run test -- --passWithNoTests || true',
|
|
145
|
-
},
|
|
146
|
-
],
|
|
147
|
-
};
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// Main validation job (runs on PR and after successful quick feedback)
|
|
151
|
-
const mainJobCondition = enableTwoPhase
|
|
152
|
-
? "github.event_name == 'pull_request' || (github.event_name == 'push' && needs.quick_feedback.result == 'success')"
|
|
153
|
-
: 'true';
|
|
154
|
-
|
|
155
|
-
workflow.jobs.validate = {
|
|
156
|
-
'runs-on': 'ubuntu-latest',
|
|
157
|
-
needs: enableTwoPhase ? 'setup' : [],
|
|
158
|
-
if: mainJobCondition,
|
|
159
|
-
strategy: {
|
|
160
|
-
matrix: {
|
|
161
|
-
node: ['18', '20'],
|
|
162
|
-
},
|
|
163
|
-
},
|
|
164
|
-
steps: [
|
|
165
|
-
{
|
|
166
|
-
name: 'Checkout code',
|
|
167
|
-
uses: 'actions/checkout@v4',
|
|
168
|
-
with: { 'fetch-depth': 0 },
|
|
169
|
-
},
|
|
170
|
-
{
|
|
171
|
-
name: 'Setup Node.js ${{ matrix.node }}',
|
|
172
|
-
uses: 'actions/setup-node@v4',
|
|
173
|
-
with: {
|
|
174
|
-
'node-version': '${{ matrix.node }}',
|
|
175
|
-
cache: 'npm',
|
|
176
|
-
},
|
|
177
|
-
},
|
|
178
|
-
{
|
|
179
|
-
name: 'Install dependencies',
|
|
180
|
-
run: 'npm ci',
|
|
181
|
-
},
|
|
182
|
-
{
|
|
183
|
-
name: 'Lint code',
|
|
184
|
-
run: 'npm run lint',
|
|
185
|
-
},
|
|
186
|
-
{
|
|
187
|
-
name: 'Run tests',
|
|
188
|
-
run: getTestCommand(language, tier, enableSelectiveTests),
|
|
189
|
-
},
|
|
190
|
-
{
|
|
191
|
-
name: 'Generate coverage',
|
|
192
|
-
run: getCoverageCommand(language, tier),
|
|
193
|
-
},
|
|
194
|
-
{
|
|
195
|
-
name: 'Upload coverage',
|
|
196
|
-
uses: 'codecov/codecov-action@v3',
|
|
197
|
-
if: "matrix.node == '18'",
|
|
198
|
-
},
|
|
199
|
-
],
|
|
200
|
-
};
|
|
201
|
-
|
|
202
|
-
// Tier-based conditional jobs
|
|
203
|
-
if (enableTierConditionals) {
|
|
204
|
-
// Mutation testing (only for tier 1 and 2)
|
|
205
|
-
workflow.jobs.mutation_test = {
|
|
206
|
-
'runs-on': 'ubuntu-latest',
|
|
207
|
-
needs: ['setup', 'validate'],
|
|
208
|
-
if: "(needs.setup.outputs.risk_tier == '1' || needs.setup.outputs.risk_tier == '2') && needs.setup.outputs.is_experimental == 'false'",
|
|
209
|
-
steps: [
|
|
210
|
-
{
|
|
211
|
-
name: 'Checkout code',
|
|
212
|
-
uses: 'actions/checkout@v4',
|
|
213
|
-
},
|
|
214
|
-
{
|
|
215
|
-
name: 'Setup Node.js',
|
|
216
|
-
uses: 'actions/setup-node@v4',
|
|
217
|
-
with: { 'node-version': '18', cache: 'npm' },
|
|
218
|
-
},
|
|
219
|
-
{
|
|
220
|
-
name: 'Install dependencies',
|
|
221
|
-
run: 'npm ci',
|
|
222
|
-
},
|
|
223
|
-
{
|
|
224
|
-
name: 'Run mutation tests',
|
|
225
|
-
run: getMutationCommand(language, tier),
|
|
226
|
-
},
|
|
227
|
-
],
|
|
228
|
-
};
|
|
229
|
-
|
|
230
|
-
// Contract tests (only for tier 1 and 2)
|
|
231
|
-
workflow.jobs.contract_test = {
|
|
232
|
-
'runs-on': 'ubuntu-latest',
|
|
233
|
-
needs: ['setup', 'validate'],
|
|
234
|
-
if: "(needs.setup.outputs.risk_tier == '1' || needs.setup.outputs.risk_tier == '2') && needs.setup.outputs.is_experimental == 'false'",
|
|
235
|
-
steps: [
|
|
236
|
-
{
|
|
237
|
-
name: 'Checkout code',
|
|
238
|
-
uses: 'actions/checkout@v4',
|
|
239
|
-
},
|
|
240
|
-
{
|
|
241
|
-
name: 'Setup Node.js',
|
|
242
|
-
uses: 'actions/setup-node@v4',
|
|
243
|
-
with: { 'node-version': '18', cache: 'npm' },
|
|
244
|
-
},
|
|
245
|
-
{
|
|
246
|
-
name: 'Install dependencies',
|
|
247
|
-
run: 'npm ci',
|
|
248
|
-
},
|
|
249
|
-
{
|
|
250
|
-
name: 'Run contract tests',
|
|
251
|
-
run: getContractCommand(language, tier),
|
|
252
|
-
},
|
|
253
|
-
],
|
|
254
|
-
};
|
|
255
|
-
|
|
256
|
-
// Property-based testing (only for tier 1)
|
|
257
|
-
workflow.jobs.property_tests = {
|
|
258
|
-
'runs-on': 'ubuntu-latest',
|
|
259
|
-
needs: ['setup', 'validate'],
|
|
260
|
-
if: "needs.setup.outputs.risk_tier == '1'",
|
|
261
|
-
steps: [
|
|
262
|
-
{
|
|
263
|
-
name: 'Checkout code',
|
|
264
|
-
uses: 'actions/checkout@v4',
|
|
265
|
-
},
|
|
266
|
-
{
|
|
267
|
-
name: 'Setup Node.js',
|
|
268
|
-
uses: 'actions/setup-node@v4',
|
|
269
|
-
with: { 'node-version': '18', cache: 'npm' },
|
|
270
|
-
},
|
|
271
|
-
{
|
|
272
|
-
name: 'Install dependencies',
|
|
273
|
-
run: 'npm ci',
|
|
274
|
-
},
|
|
275
|
-
{
|
|
276
|
-
name: 'Generate property tests',
|
|
277
|
-
run: 'node apps/tools/caws/property-testing.js generate javascript idempotent,commutative,associative',
|
|
278
|
-
},
|
|
279
|
-
{
|
|
280
|
-
name: 'Install property testing dependencies',
|
|
281
|
-
run: 'npm install --save-dev fast-check',
|
|
282
|
-
},
|
|
283
|
-
{
|
|
284
|
-
name: 'Run property tests',
|
|
285
|
-
run: 'node apps/tools/caws/property-testing.js run javascript tests/property',
|
|
286
|
-
},
|
|
287
|
-
],
|
|
288
|
-
};
|
|
289
|
-
|
|
290
|
-
// Security scan (only for tier 1)
|
|
291
|
-
workflow.jobs.security_scan = {
|
|
292
|
-
'runs-on': 'ubuntu-latest',
|
|
293
|
-
needs: ['setup', 'validate'],
|
|
294
|
-
if: "needs.setup.outputs.risk_tier == '1'",
|
|
295
|
-
steps: [
|
|
296
|
-
{
|
|
297
|
-
name: 'Checkout code',
|
|
298
|
-
uses: 'actions/checkout@v4',
|
|
299
|
-
},
|
|
300
|
-
{
|
|
301
|
-
name: 'Run security scan',
|
|
302
|
-
uses: 'securecodewarrior/github-action-sast-scan@main',
|
|
303
|
-
with: {
|
|
304
|
-
language: 'javascript',
|
|
305
|
-
},
|
|
306
|
-
},
|
|
307
|
-
],
|
|
308
|
-
};
|
|
309
|
-
|
|
310
|
-
// Performance tests (only for tier 1 and 2)
|
|
311
|
-
workflow.jobs.performance_test = {
|
|
312
|
-
'runs-on': 'ubuntu-latest',
|
|
313
|
-
needs: ['setup', 'validate'],
|
|
314
|
-
if: "(needs.setup.outputs.risk_tier == '1' || needs.setup.outputs.risk_tier == '2') && needs.setup.outputs.is_experimental == 'false'",
|
|
315
|
-
steps: [
|
|
316
|
-
{
|
|
317
|
-
name: 'Checkout code',
|
|
318
|
-
uses: 'actions/checkout@v4',
|
|
319
|
-
},
|
|
320
|
-
{
|
|
321
|
-
name: 'Setup Node.js',
|
|
322
|
-
uses: 'actions/setup-node@v4',
|
|
323
|
-
with: { 'node-version': '18', cache: 'npm' },
|
|
324
|
-
},
|
|
325
|
-
{
|
|
326
|
-
name: 'Install dependencies',
|
|
327
|
-
run: 'npm ci',
|
|
328
|
-
},
|
|
329
|
-
{
|
|
330
|
-
name: 'Run performance tests',
|
|
331
|
-
run: 'npm run test:performance || true',
|
|
332
|
-
},
|
|
333
|
-
],
|
|
334
|
-
};
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
// Quality gates job
|
|
338
|
-
workflow.jobs.quality_gates = {
|
|
339
|
-
'runs-on': 'ubuntu-latest',
|
|
340
|
-
needs: enableTierConditionals
|
|
341
|
-
? ['setup', 'validate', 'mutation_test', 'contract_test', 'property_tests'].filter(Boolean)
|
|
342
|
-
: ['setup', 'validate'],
|
|
343
|
-
steps: [
|
|
344
|
-
{
|
|
345
|
-
name: 'Checkout code',
|
|
346
|
-
uses: 'actions/checkout@v4',
|
|
347
|
-
},
|
|
348
|
-
{
|
|
349
|
-
name: 'Setup Node.js',
|
|
350
|
-
uses: 'actions/setup-node@v4',
|
|
351
|
-
with: { 'node-version': '18', cache: 'npm' },
|
|
352
|
-
},
|
|
353
|
-
{
|
|
354
|
-
name: 'Run quality gates',
|
|
355
|
-
run: `
|
|
356
|
-
node apps/tools/caws/gates.js coverage \${{ needs.setup.outputs.risk_tier }} 85
|
|
357
|
-
node apps/tools/caws/gates.js mutation \${{ needs.setup.outputs.risk_tier }} 60
|
|
358
|
-
node apps/tools/caws/gates.js trust \${{ needs.setup.outputs.risk_tier }} 82
|
|
359
|
-
`,
|
|
360
|
-
},
|
|
361
|
-
],
|
|
362
|
-
};
|
|
363
|
-
|
|
364
|
-
return yaml.dump(workflow, { indent: 2 });
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
/**
|
|
368
|
-
* Get test command based on language and optimization settings
|
|
369
|
-
*/
|
|
370
|
-
function getTestCommand(language, tier, enableSelectiveTests) {
|
|
371
|
-
const baseCommands = {
|
|
372
|
-
javascript: 'npm run test',
|
|
373
|
-
python: 'pytest',
|
|
374
|
-
java: 'mvn test',
|
|
375
|
-
go: 'go test ./...',
|
|
376
|
-
rust: 'cargo test',
|
|
377
|
-
};
|
|
378
|
-
|
|
379
|
-
let command = baseCommands[language] || 'npm run test';
|
|
380
|
-
|
|
381
|
-
if (enableSelectiveTests) {
|
|
382
|
-
// Add selective test execution based on changed files
|
|
383
|
-
command += ' -- --findRelatedTests';
|
|
384
|
-
}
|
|
385
|
-
|
|
386
|
-
return command;
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
/**
|
|
390
|
-
* Get coverage command based on language and tier
|
|
391
|
-
*/
|
|
392
|
-
function getCoverageCommand(language, _tier) {
|
|
393
|
-
const commands = {
|
|
394
|
-
javascript: 'npm run test:coverage',
|
|
395
|
-
python: 'pytest --cov',
|
|
396
|
-
java: 'mvn test jacoco:report',
|
|
397
|
-
go: 'go test -coverprofile=coverage.out ./...',
|
|
398
|
-
rust: 'cargo test --no-run && tarpaulin',
|
|
399
|
-
};
|
|
400
|
-
|
|
401
|
-
return commands[language] || 'echo "Coverage not configured for this language"';
|
|
402
|
-
}
|
|
403
|
-
|
|
404
|
-
/**
|
|
405
|
-
* Get mutation testing command based on language and tier
|
|
406
|
-
*/
|
|
407
|
-
function getMutationCommand(language, _tier) {
|
|
408
|
-
const commands = {
|
|
409
|
-
javascript: 'npx stryker run',
|
|
410
|
-
python: 'mutmut run --paths-to-mutate src/',
|
|
411
|
-
java: 'mvn org.pitest:pitest-maven:mutationCoverage',
|
|
412
|
-
go: 'gremlins -path .',
|
|
413
|
-
rust: 'cargo mutagen',
|
|
414
|
-
};
|
|
415
|
-
|
|
416
|
-
return commands[language] || 'echo "Mutation testing not configured for this language"';
|
|
417
|
-
}
|
|
418
|
-
|
|
419
|
-
/**
|
|
420
|
-
* Get contract testing command based on language and tier
|
|
421
|
-
*/
|
|
422
|
-
function getContractCommand(language, _tier) {
|
|
423
|
-
const commands = {
|
|
424
|
-
javascript: 'npm run test:contracts',
|
|
425
|
-
python: 'schemathesis run --checks all http://localhost:3000/api/openapi.json',
|
|
426
|
-
java: 'pact-jvm-provider-maven',
|
|
427
|
-
go: 'pact-go',
|
|
428
|
-
rust: 'pact-rust',
|
|
429
|
-
};
|
|
430
|
-
|
|
431
|
-
return commands[language] || 'echo "Contract testing not configured for this language"';
|
|
432
|
-
}
|
|
433
|
-
|
|
434
|
-
/**
|
|
435
|
-
* Analyze current workflow for optimization opportunities
|
|
436
|
-
* @param {string} workflowPath - Path to current workflow file
|
|
437
|
-
* @returns {Object} Analysis results
|
|
438
|
-
*/
|
|
439
|
-
function analyzeCurrentWorkflow(workflowPath = '.github/workflows/ci.yml') {
|
|
440
|
-
const results = {
|
|
441
|
-
currentOptimizations: [],
|
|
442
|
-
missingOptimizations: [],
|
|
443
|
-
recommendations: [],
|
|
444
|
-
estimatedTimeSavings: 0,
|
|
445
|
-
};
|
|
446
|
-
|
|
447
|
-
try {
|
|
448
|
-
if (!fs.existsSync(workflowPath)) {
|
|
449
|
-
results.missingOptimizations.push('No GitHub Actions workflow found');
|
|
450
|
-
results.recommendations.push('Create a GitHub Actions workflow with CAWS optimizations');
|
|
451
|
-
return results;
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
const workflowContent = fs.readFileSync(workflowPath, 'utf8');
|
|
455
|
-
const workflow = yaml.load(workflowContent);
|
|
456
|
-
|
|
457
|
-
// Check for existing optimizations
|
|
458
|
-
if (workflow.jobs?.setup?.outputs) {
|
|
459
|
-
results.currentOptimizations.push('Setup job with outputs');
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
if (workflow.on?.pull_request && workflow.on?.push) {
|
|
463
|
-
results.currentOptimizations.push('Multi-trigger workflow');
|
|
464
|
-
}
|
|
465
|
-
|
|
466
|
-
if (workflow.jobs?.validate?.strategy?.matrix) {
|
|
467
|
-
results.currentOptimizations.push('Matrix strategy for multi-version testing');
|
|
468
|
-
}
|
|
469
|
-
|
|
470
|
-
// Check for missing optimizations
|
|
471
|
-
if (!workflow.jobs?.quick_feedback) {
|
|
472
|
-
results.missingOptimizations.push('Two-phase pipeline (quick feedback)');
|
|
473
|
-
results.recommendations.push('Add quick feedback job for faster iteration');
|
|
474
|
-
results.estimatedTimeSavings += 30; // seconds
|
|
475
|
-
}
|
|
476
|
-
|
|
477
|
-
if (!workflow.jobs?.mutation_test?.if) {
|
|
478
|
-
results.missingOptimizations.push('Tier-based conditional execution');
|
|
479
|
-
results.recommendations.push('Add conditional execution based on risk tier');
|
|
480
|
-
results.estimatedTimeSavings += 60; // seconds
|
|
481
|
-
}
|
|
482
|
-
|
|
483
|
-
// Calculate potential improvements
|
|
484
|
-
if (results.missingOptimizations.length > 0) {
|
|
485
|
-
results.estimatedTimeSavings += results.missingOptimizations.length * 20;
|
|
486
|
-
}
|
|
487
|
-
} catch (error) {
|
|
488
|
-
results.missingOptimizations.push(`Error analyzing workflow: ${error.message}`);
|
|
489
|
-
}
|
|
490
|
-
|
|
491
|
-
return results;
|
|
492
|
-
}
|
|
493
|
-
|
|
494
|
-
/**
|
|
495
|
-
* Generate optimization recommendations
|
|
496
|
-
* @param {Object} analysis - Workflow analysis results
|
|
497
|
-
* @returns {Array} Detailed recommendations
|
|
498
|
-
*/
|
|
499
|
-
function generateOptimizationRecommendations(analysis) {
|
|
500
|
-
const recommendations = [];
|
|
501
|
-
|
|
502
|
-
if (analysis.missingOptimizations.includes('Two-phase pipeline (quick feedback)')) {
|
|
503
|
-
recommendations.push({
|
|
504
|
-
strategy: OPTIMIZATION_STRATEGIES.TWO_PHASE_PIPELINE,
|
|
505
|
-
priority: 'high',
|
|
506
|
-
effort: 'medium',
|
|
507
|
-
description: 'Implement quick feedback for commits and full validation for PRs',
|
|
508
|
-
benefits: [
|
|
509
|
-
'Faster developer feedback',
|
|
510
|
-
'Reduced CI queue time',
|
|
511
|
-
'Better development velocity',
|
|
512
|
-
],
|
|
513
|
-
implementation: [
|
|
514
|
-
'Add quick_feedback job for push events',
|
|
515
|
-
'Run full validation only on pull_request events',
|
|
516
|
-
'Use job dependencies to ensure proper execution order',
|
|
517
|
-
],
|
|
518
|
-
});
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
if (analysis.missingOptimizations.includes('Tier-based conditional execution')) {
|
|
522
|
-
recommendations.push({
|
|
523
|
-
strategy: OPTIMIZATION_STRATEGIES.TIER_BASED_CONDITIONAL,
|
|
524
|
-
priority: 'high',
|
|
525
|
-
effort: 'low',
|
|
526
|
-
description: 'Skip expensive checks for low-risk changes',
|
|
527
|
-
benefits: [
|
|
528
|
-
'Faster CI for low-risk changes',
|
|
529
|
-
'Better resource utilization',
|
|
530
|
-
'Maintained quality for high-risk changes',
|
|
531
|
-
],
|
|
532
|
-
implementation: [
|
|
533
|
-
'Add setup job to detect risk tier from working spec',
|
|
534
|
-
'Use job conditions based on risk tier',
|
|
535
|
-
'Skip mutation tests for Tier 3 changes',
|
|
536
|
-
],
|
|
537
|
-
});
|
|
538
|
-
}
|
|
539
|
-
|
|
540
|
-
return recommendations;
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
// CLI interface
|
|
544
|
-
if (require.main === module) {
|
|
545
|
-
const command = process.argv[2];
|
|
546
|
-
|
|
547
|
-
switch (command) {
|
|
548
|
-
case 'analyze':
|
|
549
|
-
console.log('š Analyzing current CI/CD setup for optimization opportunities...');
|
|
550
|
-
|
|
551
|
-
const analysis = analyzeCurrentWorkflow();
|
|
552
|
-
|
|
553
|
-
console.log('\nš Current Workflow Analysis:');
|
|
554
|
-
console.log(`ā
Current optimizations: ${analysis.currentOptimizations.length}`);
|
|
555
|
-
analysis.currentOptimizations.forEach((opt) => console.log(` - ${opt}`));
|
|
556
|
-
|
|
557
|
-
console.log(`\nā Missing optimizations: ${analysis.missingOptimizations.length}`);
|
|
558
|
-
analysis.missingOptimizations.forEach((opt) => console.log(` - ${opt}`));
|
|
559
|
-
|
|
560
|
-
if (analysis.recommendations.length > 0) {
|
|
561
|
-
console.log('\nš” Quick recommendations:');
|
|
562
|
-
analysis.recommendations.forEach((rec) => console.log(` - ${rec}`));
|
|
563
|
-
}
|
|
564
|
-
|
|
565
|
-
if (analysis.estimatedTimeSavings > 0) {
|
|
566
|
-
console.log(`\nā±ļø Estimated time savings: ${analysis.estimatedTimeSavings}s per run`);
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
const detailedRecommendations = generateOptimizationRecommendations(analysis);
|
|
570
|
-
if (detailedRecommendations.length > 0) {
|
|
571
|
-
console.log('\nš Detailed Optimization Plan:');
|
|
572
|
-
detailedRecommendations.forEach((rec, index) => {
|
|
573
|
-
console.log(`\n${index + 1}. ${rec.strategy.name} [${rec.priority} priority]`);
|
|
574
|
-
console.log(` ${rec.description}`);
|
|
575
|
-
console.log(` Effort: ${rec.effort} | Impact: ${rec.strategy.impact}`);
|
|
576
|
-
console.log(` Benefits: ${rec.benefits.join(', ')}`);
|
|
577
|
-
console.log(` Implementation steps:`);
|
|
578
|
-
rec.implementation.forEach((step) => console.log(` - ${step}`));
|
|
579
|
-
});
|
|
580
|
-
}
|
|
581
|
-
break;
|
|
582
|
-
|
|
583
|
-
case 'generate':
|
|
584
|
-
const language = process.argv[3] || 'javascript';
|
|
585
|
-
const tier = parseInt(process.argv[4]) || 2;
|
|
586
|
-
const outputPath = process.argv[5] || '.github/workflows/caws-ci.yml';
|
|
587
|
-
|
|
588
|
-
console.log(`š Generating optimized workflow for ${language} (Tier ${tier})...`);
|
|
589
|
-
|
|
590
|
-
try {
|
|
591
|
-
const workflow = generateOptimizedWorkflow({
|
|
592
|
-
language,
|
|
593
|
-
tier,
|
|
594
|
-
enableTwoPhase: true,
|
|
595
|
-
enableSelectiveTests: true,
|
|
596
|
-
enableTierConditionals: true,
|
|
597
|
-
});
|
|
598
|
-
|
|
599
|
-
// Ensure directory exists
|
|
600
|
-
const dir = path.dirname(outputPath);
|
|
601
|
-
if (!fs.existsSync(dir)) {
|
|
602
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
fs.writeFileSync(outputPath, workflow);
|
|
606
|
-
console.log(`ā
Generated optimized workflow: ${outputPath}`);
|
|
607
|
-
|
|
608
|
-
console.log('\nš§ Next steps:');
|
|
609
|
-
console.log(' 1. Review the generated workflow file');
|
|
610
|
-
console.log(' 2. Commit and push to trigger the new pipeline');
|
|
611
|
-
console.log(' 3. Monitor CI performance and adjust as needed');
|
|
612
|
-
console.log(' 4. Consider enabling branch protection rules');
|
|
613
|
-
} catch (error) {
|
|
614
|
-
console.error('ā Error generating workflow:', error.message);
|
|
615
|
-
process.exit(1);
|
|
616
|
-
}
|
|
617
|
-
break;
|
|
618
|
-
|
|
619
|
-
default:
|
|
620
|
-
console.log('CAWS CI/CD Pipeline Optimizer');
|
|
621
|
-
console.log('Usage:');
|
|
622
|
-
console.log(' node ci-optimizer.js analyze [workflow-path]');
|
|
623
|
-
console.log(' node ci-optimizer.js generate [language] [tier] [output-path]');
|
|
624
|
-
console.log('');
|
|
625
|
-
console.log('Optimization strategies:');
|
|
626
|
-
Object.values(OPTIMIZATION_STRATEGIES).forEach((strategy) => {
|
|
627
|
-
console.log(` - ${strategy.name}: ${strategy.description} (${strategy.impact} impact)`);
|
|
628
|
-
});
|
|
629
|
-
console.log('');
|
|
630
|
-
console.log('Examples:');
|
|
631
|
-
console.log(' node ci-optimizer.js analyze');
|
|
632
|
-
console.log(' node ci-optimizer.js generate python 2 .github/workflows/ci.yml');
|
|
633
|
-
process.exit(1);
|
|
634
|
-
}
|
|
635
|
-
}
|
|
636
|
-
|
|
637
|
-
module.exports = {
|
|
638
|
-
OPTIMIZATION_STRATEGIES,
|
|
639
|
-
generateOptimizedWorkflow,
|
|
640
|
-
analyzeCurrentWorkflow,
|
|
641
|
-
generateOptimizationRecommendations,
|
|
642
|
-
};
|