@freshworks/shiftleft-tools 1.1.8

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.
Files changed (106) hide show
  1. package/README.md +351 -0
  2. package/bin/shiftleft.js +95 -0
  3. package/package.json +57 -0
  4. package/src/commands/doctor.js +208 -0
  5. package/src/commands/init-postman.js +298 -0
  6. package/src/commands/init-rules.js +78 -0
  7. package/src/commands/link.js +172 -0
  8. package/src/commands/protect.js +61 -0
  9. package/src/commands/run-tests.js +182 -0
  10. package/src/commands/setup-pipeline.js +209 -0
  11. package/src/commands/update.js +203 -0
  12. package/src/index.js +4 -0
  13. package/src/utils/copy-tree.js +98 -0
  14. package/src/utils/gitignore.js +26 -0
  15. package/src/utils/logger.js +9 -0
  16. package/src/utils/manifest.js +145 -0
  17. package/src/utils/stack.js +80 -0
  18. package/src/utils/template.js +135 -0
  19. package/templates/AGENTS.md +109 -0
  20. package/templates/CLAUDE.md +3 -0
  21. package/templates/jenkins/Jenkinsfile-java.groovy +432 -0
  22. package/templates/jenkins/Jenkinsfile-node.groovy +450 -0
  23. package/templates/postman/.husky/pre-commit +19 -0
  24. package/templates/postman/.prettierrc.json +5 -0
  25. package/templates/postman/README.md.ejs +147 -0
  26. package/templates/postman/collections/01-core.json.ejs +91 -0
  27. package/templates/postman/config/local.json.ejs +12 -0
  28. package/templates/postman/config/staging.json.ejs +26 -0
  29. package/templates/postman/environments/local.postman_environment.json.ejs +31 -0
  30. package/templates/postman/environments/staging.postman_environment.json.ejs +31 -0
  31. package/templates/postman/gitignore +16 -0
  32. package/templates/postman/npmrc +31 -0
  33. package/templates/postman/package.json.ejs +66 -0
  34. package/templates/postman/run-all-shim.sh +16 -0
  35. package/templates/postman/scripts/auth/generate-jwt.sh +113 -0
  36. package/templates/postman/scripts/auth/get-issuer-secret.sh +140 -0
  37. package/templates/postman/scripts/infra/start-mocks.sh +138 -0
  38. package/templates/postman/scripts/infra/stop-mocks.sh +43 -0
  39. package/templates/postman/scripts/lib/api_coverage.py +1122 -0
  40. package/templates/postman/scripts/lib/cleanup-reports.sh +101 -0
  41. package/templates/postman/scripts/lib/cleanup-stryker.sh +44 -0
  42. package/templates/postman/scripts/lib/report_combined.py +527 -0
  43. package/templates/postman/scripts/lib/report_consolidated.py +363 -0
  44. package/templates/postman/scripts/lib/report_generator.py +121 -0
  45. package/templates/postman/scripts/lib/report_migration.py +156 -0
  46. package/templates/postman/scripts/lib/report_mutation.py +110 -0
  47. package/templates/postman/scripts/lib/report_unit.py +353 -0
  48. package/templates/postman/scripts/lib/report_utils.py +973 -0
  49. package/templates/postman/scripts/report-generators/generate-consolidated-report.sh +445 -0
  50. package/templates/postman/scripts/report-generators/java-api-coverage-matrix.sh +257 -0
  51. package/templates/postman/scripts/report-generators/mutation-report.sh +672 -0
  52. package/templates/postman/scripts/report-generators/node-api-coverage-matrix.sh +167 -0
  53. package/templates/postman/scripts/report-generators/stage-report-artifacts.sh +27 -0
  54. package/templates/postman/scripts/run-all.sh +452 -0
  55. package/templates/postman/scripts/runners/run-mutation-tests.sh +113 -0
  56. package/templates/postman/scripts/runners/run-tests-local.sh +936 -0
  57. package/templates/postman/scripts/runners/run-tests-staging.sh +741 -0
  58. package/templates/postman-node/README.md.ejs +26 -0
  59. package/templates/postman-node/collections/crud/01-bootstrap.json.ejs +34 -0
  60. package/templates/postman-node/config/local.json.ejs +46 -0
  61. package/templates/postman-node/config/staging.json.ejs +31 -0
  62. package/templates/postman-node/local.test.env.ejs +3 -0
  63. package/templates/postman-node/mocks/external.js +14 -0
  64. package/templates/postman-node/package.json.ejs +39 -0
  65. package/templates/postman-node/requirements.txt +1 -0
  66. package/templates/postman-node/scripts/database/cleanup-mysql.sh +12 -0
  67. package/templates/postman-node/scripts/database/run-migrations.js +29 -0
  68. package/templates/postman-node/scripts/database/start-mysql.sh +34 -0
  69. package/templates/postman-node/scripts/database/wait-for-mysql.sh +36 -0
  70. package/templates/postman-node/scripts/lib/api_coverage_node.py +1137 -0
  71. package/templates/postman-node/scripts/lib/fetch-jwt.sh +86 -0
  72. package/templates/postman-node/scripts/lib/run-newman.sh +104 -0
  73. package/templates/postman-node/scripts/lib/setup-database.sh +55 -0
  74. package/templates/postman-node/scripts/lib/start-app.sh +48 -0
  75. package/templates/postman-node/scripts/lib/utils.sh +114 -0
  76. package/templates/postman-node/scripts/report-generators/stage-report-artifacts.sh +26 -0
  77. package/templates/postman-node/scripts/run-all.sh +303 -0
  78. package/templates/postman-node/scripts/runners/run-tests.sh +123 -0
  79. package/templates/postman-node/scripts/setup-mocks.js.ejs +29 -0
  80. package/templates/postman-node/stryker.config.js.ejs +51 -0
  81. package/templates/rules/local-test-setup.mdc +420 -0
  82. package/templates/rules/testing-node.mdc +66 -0
  83. package/templates/rules/testing.mdc +248 -0
  84. package/templates/skills/_shared/postman-standards.md +380 -0
  85. package/templates/skills/enhance-test-pipeline/SKILL-java.md +483 -0
  86. package/templates/skills/enhance-test-pipeline/SKILL-node.md +431 -0
  87. package/templates/skills/enhance-test-pipeline/SKILL.md +9 -0
  88. package/templates/skills/review-test-suite/SKILL-java.md +137 -0
  89. package/templates/skills/review-test-suite/SKILL-node.md +78 -0
  90. package/templates/skills/review-test-suite/SKILL.md +9 -0
  91. package/templates/skills/run-test-suite/SKILL-java.md +186 -0
  92. package/templates/skills/run-test-suite/SKILL-node.md +191 -0
  93. package/templates/skills/run-test-suite/SKILL.md +9 -0
  94. package/templates/skills/setup-api-tests/SKILL-java.md +1094 -0
  95. package/templates/skills/setup-api-tests/SKILL-node.md +141 -0
  96. package/templates/skills/setup-api-tests/SKILL.md +9 -0
  97. package/templates/skills/setup-mutation-tests/SKILL-java.md +303 -0
  98. package/templates/skills/setup-mutation-tests/SKILL-node.md +408 -0
  99. package/templates/skills/setup-mutation-tests/SKILL.md +9 -0
  100. package/templates/skills/setup-test-pipeline/SKILL-java.md +454 -0
  101. package/templates/skills/setup-test-pipeline/SKILL-node.md +318 -0
  102. package/templates/skills/setup-test-pipeline/SKILL.md +9 -0
  103. package/templates/skills/write-api-tests/SKILL-java.md +115 -0
  104. package/templates/skills/write-api-tests/SKILL-node.md +83 -0
  105. package/templates/skills/write-api-tests/SKILL.md +9 -0
  106. package/templates/stryker.config.js +50 -0
@@ -0,0 +1,431 @@
1
+ # Enhance Test Pipeline — Node.js / Express
2
+
3
+ Detect gaps and fill them in a Node.js/Express repo that ALREADY HAS some test pipeline pieces but not all. The key difference from `/setup-test-pipeline` is being careful NOT to overwrite existing configs that are working correctly.
4
+
5
+ ## When to Use
6
+
7
+ Invoke when:
8
+ - "enhance the test pipeline", "improve the test pipeline"
9
+ - "we have unit tests but no mutation tests"
10
+ - "add Stryker to existing setup"
11
+ - "our Jenkinsfile is missing the quality report stage"
12
+ - "update the scripts to the latest version"
13
+ - The repo already has postman/ and/or unit tests but is missing mutation, API coverage, or quality report
14
+
15
+ ---
16
+
17
+ ## Phase 1: Inspect — Full Audit
18
+
19
+ ### 1.1 Unit tests — health check
20
+
21
+ ```bash
22
+ cat package.json | grep '"test"'
23
+ yarn test 2>&1 | tail -10
24
+ ```
25
+
26
+ Are they passing? How many? Any flaky failures?
27
+
28
+ ### 1.2 Coverage configuration — check
29
+
30
+ ```bash
31
+ cat package.json | grep -E '"nyc"|"c8"|"istanbul"|"coverage"'
32
+ ls .nycrc .nycrc.json .istanbul.yml 2>/dev/null
33
+ ```
34
+
35
+ Is coverage configured? Does `yarn test:coverage` (or equivalent) work?
36
+
37
+ ### 1.3 Stryker — configuration audit
38
+
39
+ ```bash
40
+ cat package.json | grep stryker
41
+ ls stryker.config.js stryker.config.ts 2>/dev/null
42
+ cat stryker.config.js 2>/dev/null
43
+ ```
44
+
45
+ Check:
46
+ - Is `mutate` array **narrow** (no `src/**`, no blanket `src/helpers/**`)? Count files — must be **under 80**
47
+ - Are `controllers/`, `routes/`, `models/`, `config/` **absent** from mutate?
48
+ - Are external-service wrappers excluded from `mutate`? (aws.js, freshid.js, chargebee.js, etc.)
49
+ - Is `coverageAnalysis: 'perTest'` set? (Fastest mode)
50
+ - Is `incremental: true` set? (Reuse previous results)
51
+ - Are both `mutation-tests` (since mode) and `mutation-tests:full` scripts in package.json?
52
+ - Is `thresholds.break` set to 0? (Should never hard-fail CI on score alone)
53
+
54
+ ```bash
55
+ ls src/
56
+ find src -maxdepth 1 -type d | sort
57
+ ```
58
+
59
+ Compare actual src structure to what's in `mutate` array.
60
+
61
+ ### 1.4 run-all.sh — version check
62
+
63
+ ```bash
64
+ ls postman/scripts/run-all.sh
65
+ grep "skip-report\|skip-mutation\|skip-postman\|skip-unit\|no-delay\|--env" postman/scripts/run-all.sh 2>/dev/null | head -10
66
+ ```
67
+
68
+ Does it have the full `--skip-*` flag set? Does it have `--env {local|staging}` support?
69
+
70
+ ### 1.5 Missing scripts audit
71
+
72
+ ```bash
73
+ ls postman/scripts/
74
+ ls postman/scripts/lib/ 2>/dev/null
75
+ ```
76
+
77
+ Required scripts that may be missing:
78
+ - `run-mutation-tests.sh` — Stryker two-mode runner (since vs full)
79
+ - `lib/cleanup-stryker.sh` — kills Stryker processes, cleans temp files
80
+ - `report-generators/node-api-coverage-matrix.sh` — generates endpoint coverage matrix
81
+ - `report-generators/stage-report-artifacts.sh` — required for Jenkins-safe artifact links
82
+ - `lib/report_generator.py` — CLI entry point (dispatches to report modules)
83
+ - `lib/report_utils.py` — shared CSS, helpers, UI component builders
84
+ - `lib/report_consolidated.py` — consolidated Newman test results report
85
+ - `lib/report_migration.py` — migration comparison report
86
+ - `lib/report_mutation.py` — Stryker/PIT mutation testing report
87
+ - `lib/report_unit.py` — unit test parsers and report
88
+ - `lib/report_combined.py` — combined quality report (unit + API tabs)
89
+ - `lib/api_coverage_node.py` — Express API coverage generator
90
+
91
+ ### 1.6 Node security guardrails — audit
92
+
93
+ ```bash
94
+ cat postman/.npmrc 2>/dev/null || echo "MISSING: postman/.npmrc"
95
+ ls postman/package-lock.json 2>/dev/null || echo "MISSING: package-lock.json"
96
+ grep "npm install\|npm ci\|ignore-scripts" Jenkinsfile 2>/dev/null
97
+ grep "GH_TOKEN\|GITHUB_RUNWAYCI_TOKEN\|AWS_ACCESS_KEY_ID\|AWS_SECRET_ACCESS_KEY" Jenkinsfile 2>/dev/null
98
+ ```
99
+
100
+ Required `.npmrc` in `postman/` directory:
101
+ ```ini
102
+ ignore-scripts=true
103
+ audit-level=high
104
+ audit-signatures=true
105
+ strict-ssl=true
106
+ registry=https://registry.npmjs.org/
107
+ ```
108
+
109
+ Check:
110
+ - Does `postman/.npmrc` exist with all five settings?
111
+ - Does `postman/package-lock.json` exist? (CI must use `npm ci`, never `npm install`)
112
+ - Does the Jenkinsfile use `npm ci --ignore-scripts` (not `npm install`)?
113
+ - Does the ShiftLeft stage include `npm audit --audit-level=critical`, `npm audit signatures`, and save `audit-report.json`?
114
+ - Are `GH_TOKEN` / `GITHUB_RUNWAYCI_TOKEN` inside `withCredentials` blocks only — never in `environment {}` block?
115
+ - Are AWS credentials supplied via IRSA (pod IAM role) — never static `AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY` in Jenkins env?
116
+
117
+ ### 1.7 Jenkinsfile — stage audit
118
+
119
+ ```bash
120
+ grep -E "stage\(|mutation|stryker|quality.report|QualityReport|ShiftLeft|api.coverage" Jenkinsfile 2>/dev/null
121
+ ```
122
+
123
+ Check for:
124
+ - Mutation Tests stage: does it run `yarn mutation-tests:full` (full mode for CI)?
125
+ - Does it publish the Stryker HTML report via `publishHTML`?
126
+ - ShiftLeft stage: does it run `node-api-coverage-matrix.sh`?
127
+ - Quality report: does it call `run-all.sh --skip-unit --skip-mutation --skip-postman --skip-coverage`?
128
+ - Does it `publishHTML` the quality report?
129
+ - Does it `archiveArtifacts postman/reports/**`?
130
+
131
+ ---
132
+
133
+ ## Phase 2: Report Gaps
134
+
135
+ Present a precise audit:
136
+
137
+ ```
138
+ Enhancement Audit Results
139
+ =========================
140
+ Component Issue / Action Needed
141
+ ------------------------------------------------------------------
142
+ Unit Tests [OK / N failures need fixing before mutation]
143
+ nyc Coverage [OK / MISSING]
144
+ Stryker Config [OK / mutate scope too broad (includes controllers)
145
+ / missing since-mode script / break:0 not set
146
+ / external-service wrappers not excluded]
147
+ run-all.sh [OK / STALE — missing --skip-* flags / MISSING]
148
+ run-mutation-tests.sh [OK / MISSING — needed for two-mode approach]
149
+ lib/cleanup-stryker.sh [OK / MISSING]
150
+ node-api-coverage-matrix.sh [OK / MISSING]
151
+ stage-report-artifacts.sh [OK / MISSING]
152
+ lib/report_generator.py [OK / MISSING / STALE — entry point only, ~120 lines]
153
+ lib/report_utils.py [OK / MISSING — shared CSS + helpers]
154
+ lib/report_consolidated.py [OK / MISSING]
155
+ lib/report_migration.py [OK / MISSING]
156
+ lib/report_mutation.py [OK / MISSING]
157
+ lib/report_unit.py [OK / MISSING]
158
+ lib/report_combined.py [OK / MISSING]
159
+ lib/api_coverage_node.py [OK / MISSING / STALE]
160
+ postman/.npmrc [OK / MISSING / incomplete — audit-signatures missing etc.]
161
+ postman/package-lock.json [OK / MISSING — must exist for npm ci]
162
+ Jenkinsfile [OK / full mutation mode not set / stryker report not published
163
+ / missing api coverage stage / missing quality report
164
+ / npm audit incomplete / GH_TOKEN in environment{} (wrong) / static AWS keys (wrong)]
165
+ ```
166
+
167
+ ---
168
+
169
+ ## Phase 3: Confirm
170
+
171
+ Show the user exactly what will change:
172
+
173
+ ```
174
+ I will make the following targeted changes:
175
+ 1. Update Stryker mutate scope — remove controllers/, add missing helpers filtering
176
+ Will add: src/services/** (not currently included)
177
+ Will exclude: src/helpers/aws.js, src/helpers/freshid.js (wrapper files)
178
+ 2. Add mutation-tests:full script to package.json for Jenkins CI
179
+ 3. Set break:0 in stryker thresholds
180
+ 4. Add missing run-mutation-tests.sh (two-mode runner)
181
+ 5. Add missing lib/cleanup-stryker.sh
182
+ 6. Update run-all.sh to current version
183
+ 7. Add missing stage-report-artifacts.sh
184
+ 8. Update Jenkinsfile: add yarn mutation-tests:full, add quality report generation
185
+
186
+ I will NOT change:
187
+ - Existing unit tests
188
+ - Existing Postman collections
189
+ - Passing parts of stryker.config.js (reporters, concurrency, mochaOpts)
190
+
191
+ Proceed? [Y/n]
192
+ ```
193
+
194
+ Wait for confirmation before any changes.
195
+
196
+ ---
197
+
198
+ ## Phase 4: Execute — Targeted Changes Only
199
+
200
+ ### 4.1 Fix Stryker configuration (if needed)
201
+
202
+ **Issue: mutate scope too broad** — Stryker will run for hours. Read `src/`, count files, then narrow:
203
+
204
+ ```bash
205
+ # Count current scope (adjust to match stryker.config.js mutate globs)
206
+ find src/actions src/serializers src/middlewares -name '*.js' 2>/dev/null | wc -l
207
+ ```
208
+
209
+ If over 80 files, remove pass-through folders and exclude helper wrappers before anything else.
210
+
211
+ Read actual src structure, then update:
212
+ ```bash
213
+ find src -maxdepth 2 -type d | sort
214
+ # For each helpers file, check if it only wraps external services:
215
+ cat src/helpers/aws.js # → exclude
216
+ cat src/helpers/utils.js # → include
217
+ ```
218
+
219
+ Update only the `mutate` array — preserve everything else.
220
+
221
+ **Issue: missing since-mode script** — add to package.json scripts:
222
+ ```json
223
+ "mutation-tests": "bash postman/scripts/runners/run-mutation-tests.sh",
224
+ "mutation-tests:full": "MUTATION_MODE=full bash postman/scripts/runners/run-mutation-tests.sh"
225
+ ```
226
+
227
+ **Issue: break:0 not set**:
228
+ ```javascript
229
+ thresholds: { high: 80, low: 60, break: 0 }
230
+ ```
231
+
232
+ **Issue: coverageAnalysis not perTest**:
233
+ ```javascript
234
+ coverageAnalysis: 'perTest'
235
+ ```
236
+
237
+ **Issue: incremental not enabled**:
238
+ ```javascript
239
+ incremental: true,
240
+ incrementalFile: 'coverage/mutation/stryker-incremental.json',
241
+ ```
242
+
243
+ ### 4.2 Fix Node security guardrails (if needed)
244
+
245
+ **Missing or incomplete `postman/.npmrc`** — create/update with all five settings:
246
+ ```ini
247
+ ignore-scripts=true
248
+ audit-level=high
249
+ audit-signatures=true
250
+ strict-ssl=true
251
+ registry=https://registry.npmjs.org/
252
+ ```
253
+
254
+ **Missing `postman/package-lock.json`** — if absent, run once locally:
255
+ ```bash
256
+ cd postman && npm install
257
+ ```
258
+ Then commit `package-lock.json`. After this, all CI runs must use `npm ci --ignore-scripts` — never `npm install`.
259
+
260
+ **Jenkinsfile npm audit incomplete** — the ShiftLeft `npm ci` block must include all three audit lines:
261
+ ```groovy
262
+ npm ci --ignore-scripts
263
+ npm audit --audit-level=critical 2>&1 || echo "WARNING: audit found issues"
264
+ npm audit signatures 2>&1 || echo "WARNING: signature verification failed"
265
+ npm audit --json > ../audit-report.json 2>&1 || true
266
+ ```
267
+ And archive the report:
268
+ ```groovy
269
+ archiveArtifacts artifacts: 'audit-report.json', allowEmptyArchive: true
270
+ ```
271
+
272
+ **`GH_TOKEN` in `environment {}` block** — move to `withCredentials` wrapping only the `sh` block that needs it:
273
+ ```groovy
274
+ // WRONG — exposes token to all stages:
275
+ environment { GH_TOKEN = credentials('github-token') }
276
+
277
+ // CORRECT — scoped to specific sh block only:
278
+ withCredentials([string(credentialsId: 'github-token', variable: 'GH_TOKEN')]) {
279
+ sh '...'
280
+ }
281
+ ```
282
+
283
+ **Static AWS keys in Jenkins env** — remove `AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY` from `environment {}`. Use IRSA (pod IAM role annotation on the pod spec). The pod supplies credentials automatically via the metadata service — no env vars needed.
284
+
285
+ ### 4.3 Refresh scripts from the shiftleft-tools package
286
+
287
+ Run `shiftleft stage-scripts` — it pulls every library script from the installed
288
+ package into `postman/scripts/` (gitignored, made executable, refreshed on every
289
+ `shiftleft test` run), so missing and stale scripts are both handled in one step:
290
+
291
+ - `runners/run-mutation-tests.sh`, `lib/cleanup-stryker.sh`
292
+ - `report-generators/node-api-coverage-matrix.sh`, `report-generators/stage-report-artifacts.sh`
293
+ - `lib/report_generator.py` and the split report modules
294
+ (`report_utils.py`, `report_consolidated.py`, `report_migration.py`,
295
+ `report_mutation.py`, `report_unit.py`, `report_combined.py`), `lib/api_coverage_node.py`
296
+
297
+ The committed `run-all.sh` shim and repo-owned files (`setup-mocks.js`,
298
+ collections, config) are never touched by staging. Don't copy or chmod these by hand.
299
+
300
+ ### 4.3 Update Jenkinsfile (targeted edits only)
301
+
302
+ Only modify the specific missing pieces.
303
+
304
+ **Mutation Tests stage not using full mode**:
305
+ ```groovy
306
+ // BEFORE (wrong for CI):
307
+ sh "yarn mutation-tests"
308
+
309
+ // AFTER (correct for CI):
310
+ utilObj.runCmd('yarn install --ignore-engines && yarn mutation-tests:full', env.NODE_VERSION)
311
+ ```
312
+
313
+ **Stryker report not published** — add to Mutation Tests stage `post.always`:
314
+ ```groovy
315
+ publishHTML([
316
+ allowMissing: true,
317
+ alwaysLinkToLastBuild: true,
318
+ keepAll: true,
319
+ reportDir: 'coverage/mutation',
320
+ reportFiles: 'index.html',
321
+ reportName: 'Stryker Mutation Report',
322
+ reportTitles: 'Mutation testing (full scan)'
323
+ ])
324
+ ```
325
+
326
+ **Missing API coverage in ShiftLeft stage**:
327
+ ```groovy
328
+ sh """
329
+ set -e
330
+ chmod +x postman/scripts/report-generators/node-api-coverage-matrix.sh
331
+ ./postman/scripts/report-generators/node-api-coverage-matrix.sh ./src/controllers ./postman
332
+ """
333
+ publishHTML([
334
+ allowMissing: true,
335
+ alwaysLinkToLastBuild: true,
336
+ keepAll: true,
337
+ reportDir: 'postman/reports',
338
+ reportFiles: 'api-coverage-matrix-latest.html',
339
+ reportName: 'API Coverage Matrix',
340
+ reportTitles: 'Postman vs Express route coverage'
341
+ ])
342
+ ```
343
+
344
+ **Missing quality report generation**:
345
+ ```groovy
346
+ def generateQualityReport() {
347
+ echo "Generating Combined Quality Report..."
348
+ try {
349
+ utilObj.runCmd("""
350
+ set -euo pipefail
351
+ cd postman/scripts
352
+ ./stage-report-artifacts.sh "\${WORKSPACE}" "\${WORKSPACE}/postman/reports" || true
353
+ ./run-all.sh --skip-unit --skip-mutation --skip-postman --skip-coverage --no-delay
354
+ """, NODE_VERSION)
355
+ } catch (Exception e) {
356
+ echo "Quality report generation failed: ${e.getMessage()}"
357
+ currentBuild.result = 'UNSTABLE'
358
+ }
359
+
360
+ if (fileExists('postman/reports')) {
361
+ def qualityReport = sh(
362
+ returnStdout: true,
363
+ script: "ls -t postman/reports/quality-report-*.html 2>/dev/null | head -1 | xargs -r basename"
364
+ ).trim()
365
+ if (qualityReport) {
366
+ publishHTML([
367
+ allowMissing: true, alwaysLinkToLastBuild: true, keepAll: true,
368
+ reportDir: 'postman/reports', reportFiles: qualityReport,
369
+ includes: '**/*', reportName: 'QualityReport', reportTitles: 'Combined Quality Report'
370
+ ])
371
+ }
372
+ archiveArtifacts artifacts: 'postman/reports/**', allowEmptyArchive: true
373
+ }
374
+ }
375
+ ```
376
+
377
+ Call `generateQualityReport()` at the end of the ShiftLeft stage steps.
378
+
379
+ ---
380
+
381
+ ## Phase 5: Verify
382
+
383
+ Run minimum verification for what was changed:
384
+
385
+ If Stryker config was updated:
386
+ ```bash
387
+ yarn mutation-tests # since mode — fast check
388
+ yarn mutation-tests:full # full mode — complete check
389
+ ```
390
+
391
+ If scripts were updated:
392
+ ```bash
393
+ cd postman/scripts
394
+ ./run-all.sh --skip-postman --no-delay
395
+ ```
396
+
397
+ If quality report was added (with existing test data):
398
+ ```bash
399
+ cd postman/scripts
400
+ ./run-all.sh --skip-unit --skip-mutation --skip-postman --skip-coverage --no-delay
401
+ ```
402
+
403
+ Report what changed and confirm quality-report-*.html was generated.
404
+
405
+ ---
406
+
407
+ ## Verification Checklist
408
+
409
+ - [ ] Only targeted changes made (nothing extra overwritten)
410
+ - [ ] Stryker mutate scope includes actual business logic folders
411
+ - [ ] External-service wrappers excluded from mutate
412
+ - [ ] `break: 0` is set in thresholds
413
+ - [ ] `coverageAnalysis: 'perTest'` is set
414
+ - [ ] Both `mutation-tests` and `mutation-tests:full` in package.json
415
+ - [ ] `run-mutation-tests.sh` exists and is executable
416
+ - [ ] `lib/cleanup-stryker.sh` exists and is executable
417
+ - [ ] `node-api-coverage-matrix.sh` exists (pointing to correct routes dir)
418
+ - [ ] `stage-report-artifacts.sh` exists
419
+ - [ ] `run-all.sh` has full `--skip-*` flag set
420
+ - [ ] Jenkinsfile runs `yarn mutation-tests:full` in CI (NOT `since` mode)
421
+ - [ ] Jenkinsfile publishes Stryker HTML report
422
+ - [ ] Jenkinsfile runs API coverage matrix and publishes it
423
+ - [ ] Jenkinsfile generates and publishes quality report
424
+ - [ ] `./run-all.sh --skip-postman --no-delay` completes successfully
425
+ - [ ] `postman/.npmrc` exists with all five settings (ignore-scripts, audit-level, audit-signatures, strict-ssl, registry)
426
+ - [ ] `postman/package-lock.json` exists
427
+ - [ ] Jenkinsfile uses `npm ci --ignore-scripts` (never `npm install`)
428
+ - [ ] Jenkinsfile ShiftLeft has: npm audit critical + npm audit signatures + audit-report.json saved
429
+ - [ ] `audit-report.json` archived as build artifact
430
+ - [ ] `GH_TOKEN` / `GITHUB_RUNWAYCI_TOKEN` only inside `withCredentials` blocks (not in `environment {}`)
431
+ - [ ] No static `AWS_ACCESS_KEY_ID` / `AWS_SECRET_ACCESS_KEY` in Jenkins env (IRSA only)
@@ -0,0 +1,9 @@
1
+ # Enhance Test Pipeline Skill
2
+
3
+ ## Detect Project Type First
4
+
5
+ Before doing anything, detect the stack:
6
+
7
+ 1. `pom.xml` in project root → **Java Spring Boot** → read `SKILL-java.md` in this folder and follow it completely
8
+ 2. `package.json` (no `pom.xml`) → **Node.js** → read `SKILL-node.md` in this folder and follow it completely
9
+ 3. If unsure → ask the user: "Is this a Java or Node.js project?"
@@ -0,0 +1,137 @@
1
+ Validate the integration test suite setup for the current repository by reading and analysing the actual content of relevant files. Do not judge by file names or folder locations — developers may name and organise things differently.
2
+
3
+ ## How to run this validation
4
+
5
+ 1. Find and read the CI pipeline file (Jenkinsfile, or equivalent).
6
+ 2. Find and read the build config file (pom.xml, build.gradle, package.json, etc.).
7
+ 3. Find the test/scripts folder — search broadly (postman/, integration-test/, e2e/, test/scripts/, etc.).
8
+ 4. Find GitHub Actions workflows under `.github/workflows/`.
9
+ 5. Read the actual content of collection files, scripts, and config to answer each check.
10
+
11
+ ---
12
+
13
+ ## Validations (20 checks across 6 categories)
14
+
15
+ ### A. Unit Testing & Coverage (3 checks)
16
+
17
+ **A1. Unit tests run in CI**
18
+ Look for: a CI stage that compiles and executes unit tests. Check whether test results (pass/fail counts, surefire reports) are captured.
19
+
20
+ **A2. Line/branch coverage measured and published**
21
+ Look for: a coverage tool configured in the build file (JaCoCo, Istanbul, coverage.py, etc.) with both a measurement execution and a report execution. Check that the HTML report is published to a CI tab or artifact — not just generated silently.
22
+
23
+ **A3. Mutation testing runs in CI and report is published**
24
+ Look for: a mutation testing tool configured (PIT/pitest, Stryker, mutmut, etc.) that runs as part of CI. Check:
25
+ - It targets the right source packages (service, mapper, util layers) and excludes boilerplate (DTOs, entities, configs, generated mapper implementations, Application class)
26
+ - The HTML and XML reports are published to a CI tab or artifact
27
+ - It does NOT re-run in a phase where tests have already been skipped
28
+
29
+ ---
30
+
31
+ ### B. Integration / API Tests (4 checks)
32
+
33
+ **B1. API test suite is split into small focused collections with a defined lifecycle**
34
+ Look for: multiple smaller collections (not one large monolithic collection), each covering a specific concern (e.g., CRUD happy path, negative/validation tests, auth/401 tests, bulk operations, edge cases). Check that they follow a lifecycle:
35
+ - A bootstrap/setup collection that creates prerequisite test data and always runs first
36
+ - Focused mid-collections grouped by concern (not dumped into one file)
37
+ - A cleanup/teardown collection that removes test data and always runs last
38
+ Check that collections are run in a defined order (e.g., numbered filenames, explicit sequence in the runner script), so the suite is deterministic.
39
+
40
+ **B2. Environment variable chaining between collections**
41
+ Look for: test runner logic that exports variables created in one collection (e.g., `installation_id`, `account_id`) and passes them as input to subsequent collections. Without this, later collections cannot reference data created by earlier ones.
42
+
43
+ **B3. Isolation environment with automated setup and teardown**
44
+ Look for: a mechanism that routes test traffic to an isolated service instance (isoforge, docker-compose, testcontainers, feature flags, etc.) so tests do not mutate shared/staging data. Check:
45
+ - Setup of the isolation stack is automated in CI before tests run
46
+ - Teardown is automated after tests complete (even on failure)
47
+ - The isolation routing identifier (header, flag, etc.) is passed to the test runner
48
+
49
+ **B4. Integration test results published — per-collection and consolidated**
50
+ Look for: each collection producing its own individual HTML report (so failures can be pinpointed to a specific collection), PLUS a consolidated summary report that aggregates pass/fail counts across all collections into a single view. Both should be published as CI artifacts or HTML tabs. A single merged report with no per-collection breakdown is insufficient.
51
+
52
+ ---
53
+
54
+ ### C. API Coverage & Assertion Quality (3 checks)
55
+
56
+ **C1. API coverage matrix exists**
57
+ Look for: a script or tool that statically compares controller endpoint definitions (Java @GetMapping/@PostMapping/etc., or OpenAPI spec) against what the test collections actually exercise. It should report untested endpoints.
58
+
59
+ **C2. Coverage matrix checks assertion quality**
60
+ Look for: the coverage matrix also detecting low-quality assertions such as:
61
+ - Endpoints with tests but no 2xx success path tested
62
+ - Weak status code assertions (e.g., `oneOf([200, 201])` instead of a specific code)
63
+ - 5xx assertions in tests (usually a sign of testing the wrong thing)
64
+ - Endpoints with no response body validation
65
+
66
+ **C3. Skipped tests are documented**
67
+ Look for: any environment-conditional test skips (`pm.execution.skipRequest()`, `pytest.skip()`, etc.) include a documented reason and the environment they are skipped in (e.g., `[SKIP] Reason: requires WireMock | Env: staging`). Undocumented skips should be flagged.
68
+
69
+ ---
70
+
71
+ ### D. Credential & Secret Security (3 checks)
72
+
73
+ **D1. Secrets fetched from a secure store at runtime**
74
+ Look for: the test runner fetching credentials (JWT signing keys, API keys, etc.) from a secure store (AWS Secrets Manager, HashiCorp Vault, environment variables injected by CI, etc.) rather than hardcoding them in scripts or committing them to the repo.
75
+
76
+ **D2. Secrets cleared from the shell environment BEFORE the Node/npm layer runs**
77
+ Look for: the test runner following this specific order: (1) fetch secret from secure store, (2) use secret in the shell layer to generate a token (e.g., JWT), (3) unset/clear the secret (`unset JWT_SECRET` or equivalent) BEFORE invoking npm, Newman, or any Node process. The Node layer should receive only the derived token — never the raw signing key or credential. This is critical because Node packages (including transitive dependencies) can read shell environment variables, making an uncleared secret accessible to potentially malicious npm packages.
78
+
79
+ **D3. npm/package installs are protected against script execution**
80
+ Look for: any mechanism that prevents npm package lifecycle scripts from running during install — either `--ignore-scripts` on the install command, or `ignore-scripts=true` in an `.npmrc` file. This prevents lifecycle scripts in npm packages (including transitive dependencies) from executing arbitrary code during install — a defense against supply chain attacks.
81
+
82
+ ---
83
+
84
+ ### E. Security & Static Analysis (3 checks)
85
+
86
+ **E1. Dependency vulnerability scan in CI**
87
+ Look for: a step that scans dependencies for known vulnerabilities (`npm audit --audit-level=critical`, OWASP dependency-check, Snyk, etc.). Check that it runs on the test/postman dependencies as well as the main application dependencies.
88
+
89
+ **E2. Static analysis / SAST in CI**
90
+ Look for: a static analysis step (SonarQube, CodeQL, SpotBugs, etc.) that runs on the main application source code.
91
+
92
+ **E3. GitHub Actions repo authorization check**
93
+ Look for: a GitHub Actions workflow that fires on every push and verifies the repository belongs to an authorised organisation. This prevents the pipeline from running if the repo is forked to an unauthorised account.
94
+
95
+ ---
96
+
97
+ ### F. Developer Experience & Feedback Loop (4 checks)
98
+
99
+ **F1. Single command runs the full local suite**
100
+ Look for: a script or Maven/Gradle profile that a developer can run locally with one command to execute unit tests + mutation tests + API tests + report generation. Check that it supports skip flags (e.g., `--skip-unit`, `--skip-postman`) so developers can re-run only the phases they need.
101
+
102
+ **F2. Combined / unified quality report**
103
+ Look for: a single HTML report that presents unit test results, code coverage, mutation score, API test results, and the API coverage matrix in one place — not just separate disconnected Jenkins tabs. This is the key artifact a developer or reviewer should look at after a build.
104
+
105
+ **F3. PR / commit status updated with integration test result**
106
+ Look for: the CI pipeline posting a GitHub commit status check (pass/fail) back to the PR specifically for the integration test run, separate from the overall build status. This gives immediate feedback on the PR without navigating into Jenkins.
107
+
108
+ **F4. Test collection format validated on every PR**
109
+ Look for: a GitHub Actions workflow that fires when test collection files are changed and validates their JSON format / structure (not just that the file is valid JSON, but that it follows the expected collection schema). This catches malformed collections before they break the CI run.
110
+
111
+ ---
112
+
113
+ ## Output format
114
+
115
+ For each check (A1 through F4), output:
116
+
117
+ **PASS** — fully implemented
118
+ **PARTIAL** — something is there but incomplete (explain what exists and what is missing)
119
+ **FAIL** — not present
120
+ **N/A** — not applicable for this repo's tech stack (explain why)
121
+
122
+ One-line note for every check. For every FAIL or PARTIAL, add a **Recommendation** explaining what behaviour to implement (not what to name files).
123
+
124
+ At the end output:
125
+ - Score: `X / Y applicable checks passed`
126
+ - Top 5 gaps to fix, ranked by impact on test confidence and developer feedback speed
127
+
128
+ ---
129
+
130
+ ## After validation
131
+
132
+ If significant gaps are found, run the setup-api-tests skill to scaffold the missing infrastructure:
133
+ ```
134
+ /setup-api-tests
135
+ ```
136
+
137
+ The setup skill uses `shiftleft init-postman` to generate all scripts, collection templates, and CI configuration — it is the recommended way to implement the patterns this validation checks for.
@@ -0,0 +1,78 @@
1
+ # Review Test Suite — Node.js / Express
2
+
3
+ Validate test pipeline maturity. Read actual file contents — do not judge by filenames alone.
4
+
5
+ Reference: `freshapps_api_node`
6
+
7
+ ## How to run
8
+
9
+ 1. Read `Jenkinsfile`, root `package.json`, `stryker.config.js`
10
+ 2. Read `postman/config/`, `postman/scripts/run-all.sh`, collections
11
+ 3. Answer each check below with PRESENT / MISSING / PARTIAL and evidence
12
+
13
+ ---
14
+
15
+ ## Validations (20 checks)
16
+
17
+ ### A. Unit Testing & Coverage
18
+
19
+ **A1. Unit tests in CI** — Mocha/Jest stage runs `yarn test` or `yarn unit-tests`
20
+
21
+ **A2. nyc coverage published** — `coverage/unit-tests/` HTML report archived or published in Jenkins
22
+
23
+ **A3. Stryker in CI** — `mutation-tests:full` in Jenkins; HTML report published; `mutate` targets actions/helpers/serializers/middlewares, excludes external wrappers
24
+
25
+ ### B. API / Integration Tests
26
+
27
+ **B1. Split collections with lifecycle** — `collections/crud/` with bootstrap (01), domain (02-N), cleanup (99)
28
+
29
+ **B2. Env var chaining** — Newman `--export-environment` passes IDs between collections
30
+
31
+ **B3. Isolation** — ShiftLeft/isoforge or local Docker MySQL; automated setup/teardown
32
+
33
+ **B4. Per-collection + consolidated reports** — individual HTML per collection + `consolidated-*.html`
34
+
35
+ ### C. API Coverage
36
+
37
+ **C1. Coverage matrix** — `report-generators/node-api-coverage-matrix.sh` scans `src/controllers/`
38
+
39
+ **C2. Assertion quality** — matrix flags missing 2xx paths, weak assertions, 5xx-as-success
40
+
41
+ **C3. Documented skips** — `[SKIP] Reason: ... | Env: ...` format
42
+
43
+ ### D. Security
44
+
45
+ **D1. Secrets from secure store** — AWS Secrets Manager for staging JWT
46
+
47
+ **D2. Secrets unset before Newman** — `unset` after JWT generation, before `npm`/`newman`
48
+
49
+ **D3. npm hardening** — `postman/.npmrc` with `ignore-scripts=true`; CI uses `npm ci --ignore-scripts`
50
+
51
+ ### E. Mutation Testing
52
+
53
+ **E1. Two modes** — `mutation-tests` (since/git diff) for local; `mutation-tests:full` for CI
54
+
55
+ **E2. perTest coverage** — `coverageAnalysis: 'perTest'` in stryker.config.js
56
+
57
+ **E3. Thresholds** — `thresholds.break: 0` (report score, don't hard-fail CI on threshold alone)
58
+
59
+ ### F. Quality Report
60
+
61
+ **F1. run-all.sh** — `--skip-*`, `--env`, `--no-delay` flags
62
+
63
+ **F2. Combined report** — `report_generator.py combined` with unit + mutation + Postman + API coverage tabs
64
+
65
+ **F3. stage-report-artifacts.sh** — copies coverage HTML for Jenkins-relative links
66
+
67
+ ---
68
+
69
+ ## Output format
70
+
71
+ ```
72
+ Category | Check | Status | Evidence
73
+ ---------|-------|--------|----------
74
+ A | A1 | PRESENT| Jenkinsfile stage 'Unit Tests'
75
+ ...
76
+ ```
77
+
78
+ Score: X/20. List top 3 gaps with recommended skill (`/setup-mutation-tests`, `/setup-api-tests`, etc.).
@@ -0,0 +1,9 @@
1
+ # Review Test Suite Skill
2
+
3
+ ## Detect Project Type First
4
+
5
+ Before doing anything, detect the stack:
6
+
7
+ 1. `pom.xml` in project root → **Java Spring Boot** → read `SKILL-java.md` in this folder and follow it completely
8
+ 2. `package.json` (no `pom.xml`) → **Node.js** → read `SKILL-node.md` in this folder and follow it completely
9
+ 3. If unsure → ask the user: "Is this a Java or Node.js project?"