create-qa-architect 5.11.2 → 5.12.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/.github/workflows/auto-release.yml +39 -0
- package/.github/workflows/quality.yml +1 -1
- package/config/defaults.js +3 -0
- package/config/quality-config.schema.json +75 -0
- package/lib/project-maturity.js +5 -0
- package/lib/quality-tools-generator.js +36 -17
- package/lib/security-enhancements.js +5 -34
- package/lib/workflow-config.js +12 -1
- package/package.json +3 -2
- package/scripts/smart-test-strategy.sh +10 -4
- package/setup.js +38 -2
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
name: Auto Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags:
|
|
6
|
+
- 'v*'
|
|
7
|
+
|
|
8
|
+
permissions:
|
|
9
|
+
contents: write
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
release:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
steps:
|
|
15
|
+
- uses: actions/checkout@v4
|
|
16
|
+
with:
|
|
17
|
+
fetch-depth: 0
|
|
18
|
+
|
|
19
|
+
- name: Get previous tag
|
|
20
|
+
id: prev_tag
|
|
21
|
+
run: |
|
|
22
|
+
PREV_TAG=$(git describe --tags --abbrev=0 HEAD^ 2>/dev/null || echo "")
|
|
23
|
+
echo "tag=$PREV_TAG" >> $GITHUB_OUTPUT
|
|
24
|
+
|
|
25
|
+
- name: Generate release notes
|
|
26
|
+
run: |
|
|
27
|
+
TAG=${GITHUB_REF#refs/tags/}
|
|
28
|
+
PREV_TAG=${{ steps.prev_tag.outputs.tag }}
|
|
29
|
+
if [ -n "$PREV_TAG" ]; then
|
|
30
|
+
echo "## Changes since $PREV_TAG" > notes.md
|
|
31
|
+
git log ${PREV_TAG}..${TAG} --pretty=format:"- %s" >> notes.md
|
|
32
|
+
echo -e "\n\n**Full Changelog**: https://github.com/${{ github.repository }}/compare/${PREV_TAG}...${TAG}" >> notes.md
|
|
33
|
+
else
|
|
34
|
+
echo "Initial release" > notes.md
|
|
35
|
+
fi
|
|
36
|
+
|
|
37
|
+
- uses: softprops/action-gh-release@v2
|
|
38
|
+
with:
|
|
39
|
+
body_path: notes.md
|
|
@@ -341,7 +341,7 @@ jobs:
|
|
|
341
341
|
gitleaks-8.28.0-linux-x64-
|
|
342
342
|
|
|
343
343
|
- name: Run real gitleaks binary verification test
|
|
344
|
-
if: runner.os == 'Linux'
|
|
344
|
+
if: runner.os == 'Linux' && hashFiles('tests/gitleaks-real-binary-test.js') != ''
|
|
345
345
|
run: |
|
|
346
346
|
echo "🔐 Running real gitleaks binary verification test..."
|
|
347
347
|
QAA_DEVELOPER=true RUN_REAL_BINARY_TEST=1 node tests/gitleaks-real-binary-test.js
|
package/config/defaults.js
CHANGED
|
@@ -75,6 +75,9 @@ const baseDevDependencies = {
|
|
|
75
75
|
'@lhci/cli': '^0.14.0',
|
|
76
76
|
vitest: '^2.1.8',
|
|
77
77
|
'@vitest/coverage-v8': '^2.1.8',
|
|
78
|
+
commitlint: '^20.4.1',
|
|
79
|
+
'@commitlint/cli': '^20.4.1',
|
|
80
|
+
'@commitlint/config-conventional': '^20.4.1',
|
|
78
81
|
}
|
|
79
82
|
|
|
80
83
|
const typeScriptDevDependencies = {
|
|
@@ -91,6 +91,81 @@
|
|
|
91
91
|
},
|
|
92
92
|
"additionalProperties": false
|
|
93
93
|
}
|
|
94
|
+
},
|
|
95
|
+
"performance": {
|
|
96
|
+
"type": "object",
|
|
97
|
+
"description": "Performance budget configuration",
|
|
98
|
+
"properties": {
|
|
99
|
+
"lighthouse": {
|
|
100
|
+
"type": "object",
|
|
101
|
+
"description": "Lighthouse CI performance thresholds",
|
|
102
|
+
"properties": {
|
|
103
|
+
"performance": {
|
|
104
|
+
"type": "number",
|
|
105
|
+
"minimum": 0,
|
|
106
|
+
"maximum": 1,
|
|
107
|
+
"description": "Minimum performance score (0-1)"
|
|
108
|
+
},
|
|
109
|
+
"accessibility": {
|
|
110
|
+
"type": "number",
|
|
111
|
+
"minimum": 0,
|
|
112
|
+
"maximum": 1,
|
|
113
|
+
"description": "Minimum accessibility score (0-1)"
|
|
114
|
+
},
|
|
115
|
+
"bestPractices": {
|
|
116
|
+
"type": "number",
|
|
117
|
+
"minimum": 0,
|
|
118
|
+
"maximum": 1,
|
|
119
|
+
"description": "Minimum best practices score (0-1)"
|
|
120
|
+
},
|
|
121
|
+
"seo": {
|
|
122
|
+
"type": "number",
|
|
123
|
+
"minimum": 0,
|
|
124
|
+
"maximum": 1,
|
|
125
|
+
"description": "Minimum SEO score (0-1)"
|
|
126
|
+
},
|
|
127
|
+
"maxFCP": {
|
|
128
|
+
"type": "number",
|
|
129
|
+
"minimum": 0,
|
|
130
|
+
"description": "Max First Contentful Paint in ms"
|
|
131
|
+
},
|
|
132
|
+
"maxLCP": {
|
|
133
|
+
"type": "number",
|
|
134
|
+
"minimum": 0,
|
|
135
|
+
"description": "Max Largest Contentful Paint in ms"
|
|
136
|
+
},
|
|
137
|
+
"maxCLS": {
|
|
138
|
+
"type": "number",
|
|
139
|
+
"minimum": 0,
|
|
140
|
+
"description": "Max Cumulative Layout Shift"
|
|
141
|
+
},
|
|
142
|
+
"maxTBT": {
|
|
143
|
+
"type": "number",
|
|
144
|
+
"minimum": 0,
|
|
145
|
+
"description": "Max Total Blocking Time in ms"
|
|
146
|
+
}
|
|
147
|
+
},
|
|
148
|
+
"additionalProperties": false
|
|
149
|
+
},
|
|
150
|
+
"bundleSize": {
|
|
151
|
+
"type": "object",
|
|
152
|
+
"description": "Bundle size limits",
|
|
153
|
+
"properties": {
|
|
154
|
+
"maxJs": {
|
|
155
|
+
"type": "string",
|
|
156
|
+
"pattern": "^[0-9]+ [kKmM][bB]$",
|
|
157
|
+
"description": "Max JS bundle size (e.g., '250 kB')"
|
|
158
|
+
},
|
|
159
|
+
"maxCss": {
|
|
160
|
+
"type": "string",
|
|
161
|
+
"pattern": "^[0-9]+ [kKmM][bB]$",
|
|
162
|
+
"description": "Max CSS bundle size (e.g., '50 kB')"
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
"additionalProperties": false
|
|
166
|
+
}
|
|
167
|
+
},
|
|
168
|
+
"additionalProperties": false
|
|
94
169
|
}
|
|
95
170
|
},
|
|
96
171
|
"additionalProperties": false
|
package/lib/project-maturity.js
CHANGED
|
@@ -119,6 +119,11 @@ class ProjectMaturityDetector {
|
|
|
119
119
|
stats.testFiles === 0
|
|
120
120
|
) {
|
|
121
121
|
maturity = 'bootstrap'
|
|
122
|
+
} else if (
|
|
123
|
+
stats.totalSourceFiles < MATURITY_THRESHOLDS.MIN_BOOTSTRAP_FILES &&
|
|
124
|
+
stats.testFiles > 0
|
|
125
|
+
) {
|
|
126
|
+
maturity = 'bootstrap'
|
|
122
127
|
} else if (
|
|
123
128
|
stats.testFiles > 0 &&
|
|
124
129
|
stats.totalSourceFiles >= MATURITY_THRESHOLDS.MIN_BOOTSTRAP_FILES &&
|
|
@@ -25,6 +25,7 @@ function generateLighthouseConfig(options = {}) {
|
|
|
25
25
|
hasThresholds = false,
|
|
26
26
|
collectUrl = 'http://localhost:3000',
|
|
27
27
|
staticDistDir = null,
|
|
28
|
+
budgets = null,
|
|
28
29
|
} = options
|
|
29
30
|
|
|
30
31
|
const collectConfig = staticDistDir
|
|
@@ -34,29 +35,42 @@ function generateLighthouseConfig(options = {}) {
|
|
|
34
35
|
startServerReadyPattern: 'ready|listening|started',
|
|
35
36
|
startServerReadyTimeout: 30000,`
|
|
36
37
|
|
|
37
|
-
|
|
38
|
-
|
|
38
|
+
let assertConfig
|
|
39
|
+
if (hasThresholds) {
|
|
40
|
+
// Use custom budgets from .qualityrc.json if provided, otherwise defaults
|
|
41
|
+
const b = budgets || {}
|
|
42
|
+
const fcp = b.maxFCP || 2000
|
|
43
|
+
const lcp = b.maxLCP || 2500
|
|
44
|
+
const cls = b.maxCLS || 0.1
|
|
45
|
+
const tbt = b.maxTBT || 300
|
|
46
|
+
const perf = b.performance || 0.8
|
|
47
|
+
const a11y = b.accessibility || 0.9
|
|
48
|
+
const bp = b.bestPractices || 0.9
|
|
49
|
+
const seo = b.seo || 0.9
|
|
50
|
+
|
|
51
|
+
assertConfig = `
|
|
39
52
|
assert: {
|
|
40
53
|
preset: 'lighthouse:recommended',
|
|
41
54
|
assertions: {
|
|
42
55
|
// Performance
|
|
43
|
-
'first-contentful-paint': ['warn', { maxNumericValue:
|
|
44
|
-
'largest-contentful-paint': ['error', { maxNumericValue:
|
|
45
|
-
'cumulative-layout-shift': ['error', { maxNumericValue:
|
|
46
|
-
'total-blocking-time': ['warn', { maxNumericValue:
|
|
56
|
+
'first-contentful-paint': ['warn', { maxNumericValue: ${fcp} }],
|
|
57
|
+
'largest-contentful-paint': ['error', { maxNumericValue: ${lcp} }],
|
|
58
|
+
'cumulative-layout-shift': ['error', { maxNumericValue: ${cls} }],
|
|
59
|
+
'total-blocking-time': ['warn', { maxNumericValue: ${tbt} }],
|
|
47
60
|
|
|
48
61
|
// Categories (0-1 scale)
|
|
49
|
-
'categories:performance': ['warn', { minScore:
|
|
50
|
-
'categories:accessibility': ['error', { minScore:
|
|
51
|
-
'categories:best-practices': ['warn', { minScore:
|
|
52
|
-
'categories:seo': ['warn', { minScore:
|
|
62
|
+
'categories:performance': ['warn', { minScore: ${perf} }],
|
|
63
|
+
'categories:accessibility': ['error', { minScore: ${a11y} }],
|
|
64
|
+
'categories:best-practices': ['warn', { minScore: ${bp} }],
|
|
65
|
+
'categories:seo': ['warn', { minScore: ${seo} }],
|
|
53
66
|
|
|
54
67
|
// Allow some common warnings
|
|
55
68
|
'unsized-images': 'off',
|
|
56
69
|
'uses-responsive-images': 'off',
|
|
57
70
|
},
|
|
58
71
|
},`
|
|
59
|
-
|
|
72
|
+
} else {
|
|
73
|
+
assertConfig = `
|
|
60
74
|
assert: {
|
|
61
75
|
// Basic assertions for Free tier - just warnings, no failures
|
|
62
76
|
assertions: {
|
|
@@ -64,6 +78,7 @@ function generateLighthouseConfig(options = {}) {
|
|
|
64
78
|
'categories:best-practices': ['warn', { minScore: 0.7 }],
|
|
65
79
|
},
|
|
66
80
|
},`
|
|
81
|
+
}
|
|
67
82
|
|
|
68
83
|
return `module.exports = {
|
|
69
84
|
ci: {
|
|
@@ -86,7 +101,7 @@ function generateLighthouseConfig(options = {}) {
|
|
|
86
101
|
* @returns {Array} size-limit config array
|
|
87
102
|
*/
|
|
88
103
|
function generateSizeLimitConfig(options = {}) {
|
|
89
|
-
const { projectPath = process.cwd() } = options
|
|
104
|
+
const { projectPath = process.cwd(), budgets = null } = options
|
|
90
105
|
|
|
91
106
|
// Detect build output paths
|
|
92
107
|
const possibleDists = ['dist', 'build', '.next', 'out', 'public']
|
|
@@ -99,6 +114,10 @@ function generateSizeLimitConfig(options = {}) {
|
|
|
99
114
|
}
|
|
100
115
|
}
|
|
101
116
|
|
|
117
|
+
// Use custom budgets from .qualityrc.json if provided
|
|
118
|
+
const jsLimit = (budgets && budgets.maxJs) || null
|
|
119
|
+
const cssLimit = (budgets && budgets.maxCss) || null
|
|
120
|
+
|
|
102
121
|
// Detect if it's a Next.js app
|
|
103
122
|
const isNextJS =
|
|
104
123
|
fs.existsSync(path.join(projectPath, 'next.config.js')) ||
|
|
@@ -108,7 +127,7 @@ function generateSizeLimitConfig(options = {}) {
|
|
|
108
127
|
return [
|
|
109
128
|
{
|
|
110
129
|
path: '.next/static/**/*.js',
|
|
111
|
-
limit: '300 kB',
|
|
130
|
+
limit: jsLimit || '300 kB',
|
|
112
131
|
webpack: false,
|
|
113
132
|
},
|
|
114
133
|
]
|
|
@@ -117,11 +136,11 @@ function generateSizeLimitConfig(options = {}) {
|
|
|
117
136
|
return [
|
|
118
137
|
{
|
|
119
138
|
path: `${distDir}/**/*.js`,
|
|
120
|
-
limit: '250 kB',
|
|
139
|
+
limit: jsLimit || '250 kB',
|
|
121
140
|
},
|
|
122
141
|
{
|
|
123
142
|
path: `${distDir}/**/*.css`,
|
|
124
|
-
limit: '50 kB',
|
|
143
|
+
limit: cssLimit || '50 kB',
|
|
125
144
|
},
|
|
126
145
|
]
|
|
127
146
|
}
|
|
@@ -525,8 +544,8 @@ function getQualityToolsDependencies(features = {}) {
|
|
|
525
544
|
}
|
|
526
545
|
|
|
527
546
|
if (features.commitlint) {
|
|
528
|
-
deps['@commitlint/cli'] = '^
|
|
529
|
-
deps['@commitlint/config-conventional'] = '^
|
|
547
|
+
deps['@commitlint/cli'] = '^20.4.1'
|
|
548
|
+
deps['@commitlint/config-conventional'] = '^20.4.1'
|
|
530
549
|
}
|
|
531
550
|
|
|
532
551
|
if (features.axeCore) {
|
|
@@ -109,46 +109,17 @@ id = "jwt-token"
|
|
|
109
109
|
regex = '''eyJ[A-Za-z0-9_/+-]{10,}={0,2}'''
|
|
110
110
|
tags = ["key", "JWT"]
|
|
111
111
|
|
|
112
|
-
[[rules]]
|
|
113
|
-
description = "Base64 encoded secrets (long)"
|
|
114
|
-
id = "base64-secret"
|
|
115
|
-
regex = '''[A-Za-z0-9+/]{40,}={0,2}'''
|
|
116
|
-
tags = ["secret", "base64"]
|
|
117
|
-
keywords = ["secret", "key", "token", "password"]
|
|
118
|
-
|
|
119
112
|
[[rules]]
|
|
120
113
|
description = "Environment variable secrets"
|
|
121
114
|
id = "env-secret"
|
|
122
115
|
regex = '''(?i)(api_key|secret|password|token)\\s*=\\s*['""][^'"\\s]{10,}['""]'''
|
|
123
116
|
tags = ["env", "secret"]
|
|
124
117
|
|
|
125
|
-
# Allowlist for test files
|
|
126
|
-
[
|
|
127
|
-
description = "Test
|
|
128
|
-
regexes = [
|
|
129
|
-
|
|
130
|
-
'''example_.*''',
|
|
131
|
-
'''dummy_.*''',
|
|
132
|
-
'''fake_.*'''
|
|
133
|
-
]
|
|
134
|
-
paths = [
|
|
135
|
-
'''tests/''',
|
|
136
|
-
'''test/''',
|
|
137
|
-
'''__tests__/''',
|
|
138
|
-
'''examples/''',
|
|
139
|
-
'''docs/''',
|
|
140
|
-
'''.md$'''
|
|
141
|
-
]
|
|
142
|
-
|
|
143
|
-
# Global allowlist for common false positives
|
|
144
|
-
[[allowlist]]
|
|
145
|
-
description = "Common false positives"
|
|
146
|
-
regexes = [
|
|
147
|
-
'''EXAMPLE_.*''',
|
|
148
|
-
'''your_.*_here''',
|
|
149
|
-
'''replace_with_.*''',
|
|
150
|
-
'''TODO:.*'''
|
|
151
|
-
]
|
|
118
|
+
# Allowlist for test/example files (broad exclusion)
|
|
119
|
+
[allowlist]
|
|
120
|
+
description = "Test and example files"
|
|
121
|
+
regexes = ['''test_secret_.*|example_.*|dummy_.*|fake_.*|EXAMPLE_.*|your_.*_here|replace_with_.*|TODO:.*''']
|
|
122
|
+
paths = ['''(tests/|test/|__tests__/|examples/|docs/|\\.md$|\\.gitleaksignore$|node_modules/|dist/|build/|\\.next/|coverage/)''']
|
|
152
123
|
`
|
|
153
124
|
}
|
|
154
125
|
|
package/lib/workflow-config.js
CHANGED
|
@@ -179,7 +179,18 @@ function injectWorkflowMode(workflowContent, mode) {
|
|
|
179
179
|
"has-css: 'false'"
|
|
180
180
|
)
|
|
181
181
|
|
|
182
|
-
// 4.
|
|
182
|
+
// 4. Remove dev-only gitleaks binary test steps (only relevant for qa-architect itself)
|
|
183
|
+
// The restore-keys block has 3 lines after `|`, match all of them to avoid stray lines
|
|
184
|
+
updated = updated.replace(
|
|
185
|
+
/\s+- name: Cache gitleaks binary for real download test[\s\S]*?restore-keys: \|[^\n]*\n[^\n]*\n[^\n]*\n/,
|
|
186
|
+
'\n'
|
|
187
|
+
)
|
|
188
|
+
updated = updated.replace(
|
|
189
|
+
/\s+- name: Run real gitleaks binary verification test[\s\S]*?node tests\/gitleaks-real-binary-test\.js\n/,
|
|
190
|
+
'\n'
|
|
191
|
+
)
|
|
192
|
+
|
|
193
|
+
// 5. Simplify "Display Detection Report" to show only package manager info
|
|
183
194
|
updated = updated.replace(
|
|
184
195
|
/- name: Display Detection Report\s+run: \|[\s\S]*?echo "Has CSS files:[^"]*"/,
|
|
185
196
|
`- name: Display Detection Report
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "create-qa-architect",
|
|
3
|
-
"version": "5.
|
|
3
|
+
"version": "5.12.1",
|
|
4
4
|
"description": "QA Architect - Bootstrap quality automation for JavaScript/TypeScript and Python projects with GitHub Actions, pre-commit hooks, linting, formatting, and smart test strategy",
|
|
5
5
|
"main": "setup.js",
|
|
6
6
|
"bin": {
|
|
@@ -51,7 +51,8 @@
|
|
|
51
51
|
"size": "size-limit",
|
|
52
52
|
"size:why": "size-limit --why",
|
|
53
53
|
"test:a11y": "vitest run tests/accessibility.test.js",
|
|
54
|
-
"test:coverage:check": "vitest run --coverage --coverage.thresholds.lines=70 --coverage.thresholds.functions=70"
|
|
54
|
+
"test:coverage:check": "vitest run --coverage --coverage.thresholds.lines=70 --coverage.thresholds.functions=70",
|
|
55
|
+
"test:changed": "vitest run --changed HEAD~1 --passWithNoTests"
|
|
55
56
|
},
|
|
56
57
|
"keywords": [
|
|
57
58
|
"qa-architect",
|
|
@@ -82,11 +82,17 @@ echo " ⚡ Speed Bonus: $SPEED_BONUS"
|
|
|
82
82
|
echo ""
|
|
83
83
|
|
|
84
84
|
# Test tier selection based on risk score
|
|
85
|
+
# NOTE: E2E tests and slow command tests are ALWAYS excluded from pre-push
|
|
86
|
+
# - E2E tests: Require dev server, browsers, proper infrastructure (run in CI only)
|
|
87
|
+
# - Command tests: Take 60+ seconds, verify npm scripts work (run in CI only)
|
|
88
|
+
# These run in GitHub Actions on every PR and push to main
|
|
89
|
+
|
|
85
90
|
if [[ $RISK_SCORE -ge 7 ]]; then
|
|
86
|
-
echo "🔴 HIGH RISK - Comprehensive validation"
|
|
87
|
-
echo " •
|
|
88
|
-
|
|
89
|
-
npm run test:
|
|
91
|
+
echo "🔴 HIGH RISK - Comprehensive validation (pre-push)"
|
|
92
|
+
echo " • Unit + integration tests + security audit"
|
|
93
|
+
echo " • (E2E and command tests run in CI only)"
|
|
94
|
+
# Runs: npm run test:medium 2>/dev/null || npm run test:fast 2>/dev/null || npm test
|
|
95
|
+
npm run test:medium 2>/dev/null || npm run test:fast 2>/dev/null || npm test
|
|
90
96
|
elif [[ $RISK_SCORE -ge 4 ]]; then
|
|
91
97
|
echo "🟡 MEDIUM RISK - Standard validation"
|
|
92
98
|
echo " • Fast tests + integration (excludes slow tests)"
|
package/setup.js
CHANGED
|
@@ -927,13 +927,44 @@ HELP:
|
|
|
927
927
|
const hasConventionalCommits = hasFeature('conventionalCommits')
|
|
928
928
|
const hasCoverageThresholds = hasFeature('coverageThresholds')
|
|
929
929
|
|
|
930
|
+
// Load .qualityrc.json for performance budgets and check overrides
|
|
931
|
+
let performanceBudgets = null
|
|
932
|
+
let qualityChecks = {}
|
|
933
|
+
const qualityrcPath = path.join(projectPath, '.qualityrc.json')
|
|
934
|
+
if (fs.existsSync(qualityrcPath)) {
|
|
935
|
+
try {
|
|
936
|
+
const qualityrc = JSON.parse(fs.readFileSync(qualityrcPath, 'utf8'))
|
|
937
|
+
if (qualityrc.performance) {
|
|
938
|
+
performanceBudgets = qualityrc.performance
|
|
939
|
+
}
|
|
940
|
+
if (qualityrc.checks) {
|
|
941
|
+
qualityChecks = qualityrc.checks
|
|
942
|
+
}
|
|
943
|
+
} catch {
|
|
944
|
+
// Ignore parse errors - config validation handles this elsewhere
|
|
945
|
+
}
|
|
946
|
+
}
|
|
947
|
+
|
|
948
|
+
// Helper: check if a quality check is enabled (respects .qualityrc.json overrides)
|
|
949
|
+
function isCheckEnabled(checkName, licenseDefault) {
|
|
950
|
+
const override = qualityChecks[checkName]
|
|
951
|
+
if (override && override.enabled === false) return false
|
|
952
|
+
if (override && override.enabled === true) return true
|
|
953
|
+
// "auto" or missing: use license-based default
|
|
954
|
+
return licenseDefault
|
|
955
|
+
}
|
|
956
|
+
|
|
930
957
|
// 1. Lighthouse CI - available to all, thresholds for Pro+
|
|
931
|
-
if (hasLighthouse) {
|
|
958
|
+
if (isCheckEnabled('lighthouse', hasLighthouse)) {
|
|
932
959
|
try {
|
|
933
960
|
const lighthousePath = path.join(projectPath, 'lighthouserc.js')
|
|
934
961
|
if (!fs.existsSync(lighthousePath)) {
|
|
935
962
|
writeLighthouseConfig(projectPath, {
|
|
936
963
|
hasThresholds: hasLighthouseThresholds,
|
|
964
|
+
budgets:
|
|
965
|
+
performanceBudgets && performanceBudgets.lighthouse
|
|
966
|
+
? performanceBudgets.lighthouse
|
|
967
|
+
: null,
|
|
937
968
|
})
|
|
938
969
|
addedTools.push(
|
|
939
970
|
hasLighthouseThresholds
|
|
@@ -953,7 +984,12 @@ HELP:
|
|
|
953
984
|
if (hasBundleSizeLimits) {
|
|
954
985
|
try {
|
|
955
986
|
if (!pkgJson.content['size-limit']) {
|
|
956
|
-
writeSizeLimitConfig(projectPath
|
|
987
|
+
writeSizeLimitConfig(projectPath, {
|
|
988
|
+
budgets:
|
|
989
|
+
performanceBudgets && performanceBudgets.bundleSize
|
|
990
|
+
? performanceBudgets.bundleSize
|
|
991
|
+
: null,
|
|
992
|
+
})
|
|
957
993
|
addedTools.push('Bundle size limits (size-limit)')
|
|
958
994
|
}
|
|
959
995
|
} catch (error) {
|