@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,483 @@
1
+ # Enhance Test Pipeline — Java Spring Boot
2
+
3
+ Detect gaps and fill them in a Java/Spring Boot 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 mutation tests 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
+ ## Reference Implementations
18
+
19
+ Before writing any code, check these canonical repos. They are the ground truth — use them instead of guessing.
20
+
21
+ **Java canonical repos:**
22
+ - `mp-installation` — PIT mutation, JaCoCo, multi-product Postman, API coverage matrix, quality report, Jenkins ShiftLeft
23
+ - `dp-apps` — same stack, original reference
24
+
25
+ **Script source (the `shiftleft-tools` package — pulled at runtime):**
26
+ ```bash
27
+ # Stage the latest library scripts from the installed package into postman/scripts/.
28
+ # Gitignored and refreshed on every run — never copy or commit them by hand.
29
+ shiftleft stage-scripts
30
+ ```
31
+
32
+ The library scripts live only in the `shiftleft-tools` package. `shiftleft stage-scripts`
33
+ (and `shiftleft test`, which stages then runs) pulls the current versions in — do
34
+ not copy from a templates directory or write them from scratch.
35
+
36
+ ---
37
+
38
+ ## Phase 1: Inspect — Full Audit
39
+
40
+ ### 1.1 Unit tests — health check
41
+
42
+ ```bash
43
+ mvn test -q 2>&1 | tail -10
44
+ ```
45
+
46
+ Are they passing? How many? Any flaky failures?
47
+
48
+ ### 1.2 JaCoCo — version check
49
+
50
+ ```bash
51
+ grep -A2 "jacoco-maven-plugin" pom.xml | grep version
52
+ ```
53
+
54
+ If JaCoCo version < 0.8.8 and JDK >= 17: this will cause instrumentation errors. Must upgrade to 0.8.11+.
55
+
56
+ ### 1.3 PIT mutation testing — configuration audit
57
+
58
+ ```bash
59
+ grep -A50 "pitest-maven" pom.xml | head -60
60
+ ```
61
+
62
+ Check:
63
+ - Is it inside a `<profile id="mutation-tests">`? (It should be — if it's in `<build><plugins>` it runs on every `mvn install`, which is wrong)
64
+ - Does `targetClasses` list actual packages (not `com.yourcompany.*`)? Read the actual src/main/java structure and compare
65
+ - Is `<timestampedReports>false</timestampedReports>` set? (Required for CI report linking)
66
+ - Are XML + HTML output formats both enabled? (XML required for quality report)
67
+ - Is `pitest-junit5-plugin` present? (Required for JUnit 5)
68
+
69
+ ```bash
70
+ find src/main/java -type d | sort
71
+ ```
72
+
73
+ Compare actual packages to what's configured in `targetClasses`. If they don't match, the config needs updating.
74
+
75
+ ### 1.4 run-all.sh — version check
76
+
77
+ ```bash
78
+ ls postman/scripts/run-all.sh
79
+ grep "skip-report\|skip-mutation\|skip-postman\|skip-unit\|no-delay\|--env" postman/scripts/run-all.sh 2>/dev/null | head -10
80
+ ```
81
+
82
+ Does it have the full `--skip-*` flag set? Old versions may only have `--skip-mutation`. The current version needs:
83
+ - `--env {local|staging}` — target environment
84
+ - `--skip-unit`, `--skip-mutation`, `--skip-postman`, `--skip-coverage`, `--skip-report`
85
+ - `--no-delay` — for CI
86
+
87
+ ### 1.5 Missing scripts audit
88
+
89
+ Check which scripts exist and which are missing:
90
+
91
+ ```bash
92
+ ls postman/scripts/
93
+ ls postman/scripts/lib/ 2>/dev/null
94
+ ls postman/scripts/runners/ 2>/dev/null
95
+ ```
96
+
97
+ Required scripts that may be missing:
98
+
99
+ **Top-level scripts:**
100
+ - `stage-report-artifacts.sh` — copies JaCoCo/PIT HTML to `postman/reports/jacoco/` and `postman/reports/pit/` for Jenkins-safe links in quality report
101
+ - `generate-quality-report.sh` — standalone Jenkins quality report generator
102
+ - `runners/run-tests-local.sh` — runs Postman against local + WireMock
103
+ - `runners/run-tests-staging.sh` — runs Postman against staging (ShiftLeft)
104
+
105
+ **Python library modules (all required):**
106
+ - `lib/report_generator.py` — CLI entry point (dispatches to report modules, ~100 lines)
107
+ - `lib/report_utils.py` — shared CSS, helper functions, UI component builders
108
+ - `lib/report_consolidated.py` — consolidated Newman test results report
109
+ - `lib/report_migration.py` — migration comparison report
110
+ - `lib/report_mutation.py` — PIT mutation testing report
111
+ - `lib/report_unit.py` — Surefire + JaCoCo + mutation parsers and unit report
112
+ - `lib/report_combined.py` — combined quality report (unit + API tabs) — THE main report
113
+ - `lib/api_coverage.py` — API coverage matrix generator from source + Postman
114
+
115
+ ### 1.6 Jenkinsfile — stage audit
116
+
117
+ ```bash
118
+ grep -E "stage\(|runMutationTests|quality.report|QualityReport|ShiftLeft|stage-report" Jenkinsfile 2>/dev/null
119
+ ```
120
+
121
+ Check for:
122
+ - Mutation Tests stage: does it call `run-all.sh --skip-unit --skip-postman --skip-coverage --skip-report`?
123
+ - ShiftLeft stage: does it generate API coverage and quality report after Postman tests?
124
+ - Quality report publishing: does it `publishHTML` with `includes: '**/*'`? (without `includes`, CSS won't load)
125
+ - Artifacts: does it `archiveArtifacts postman/reports/**`?
126
+
127
+ ---
128
+
129
+ ## Phase 2: Report Gaps
130
+
131
+ Present a precise audit:
132
+
133
+ ```
134
+ Enhancement Audit Results
135
+ =========================
136
+ Component Issue / Action Needed
137
+ ------------------------------------------------------------------
138
+ Unit Tests [OK / N failures need fixing before mutation]
139
+ JaCoCo [OK / version X.X.X needs upgrade to 0.8.11]
140
+ PIT Config [OK / targetClasses has placeholders — needs real packages
141
+ / missing XML output / missing profile / timestampedReports not set]
142
+ run-all.sh [OK / STALE — missing --skip-* flags / MISSING]
143
+ stage-report-artifacts.sh [OK / MISSING — required for quality report]
144
+ generate-quality-report.sh [OK / MISSING]
145
+ runners/run-tests-local.sh [OK / MISSING]
146
+ runners/run-tests-staging.sh [OK / MISSING]
147
+ lib/report_generator.py [OK / MISSING / STALE — entry point only, ~120 lines]
148
+ lib/report_utils.py [OK / MISSING — shared CSS + helpers]
149
+ lib/report_consolidated.py [OK / MISSING]
150
+ lib/report_migration.py [OK / MISSING]
151
+ lib/report_mutation.py [OK / MISSING]
152
+ lib/report_unit.py [OK / MISSING]
153
+ lib/report_combined.py [OK / MISSING]
154
+ lib/api_coverage.py [OK / MISSING / STALE]
155
+ Jenkinsfile [OK / missing mutation stage / missing quality report / wrong run-all.sh args]
156
+ ```
157
+
158
+ ---
159
+
160
+ ## Phase 3: Confirm
161
+
162
+ Show the user exactly what will change:
163
+
164
+ ```
165
+ I will make the following targeted changes:
166
+ 1. Upgrade JaCoCo from X.X.X to 0.8.11 in pom.xml
167
+ 2. Fix PIT targetClasses — replace placeholders with actual packages
168
+ Found: service, mapper, util (not validator — doesn't exist in this repo)
169
+ 3. Add <timestampedReports>false</timestampedReports> to PIT config
170
+ 4. Update run-all.sh to current version (adds --skip-*, --env, --no-delay flags)
171
+ 5. Add missing stage-report-artifacts.sh
172
+ 6. Add missing generate-quality-report.sh
173
+ 7. Add missing runners/run-tests-local.sh and runners/run-tests-staging.sh
174
+ 8. Copy all lib/report_*.py modules and lib/api_coverage.py from shiftleft-tools templates
175
+ 9. Update Jenkinsfile ShiftLeft stage to add quality report generation
176
+
177
+ I will NOT change:
178
+ - Existing unit tests (passing, no issues)
179
+ - Existing Postman collections
180
+ - Existing WireMock mocks
181
+
182
+ Proceed? [Y/n]
183
+ ```
184
+
185
+ Wait for confirmation before any changes.
186
+
187
+ ---
188
+
189
+ ## Phase 4: Execute — Targeted Changes Only
190
+
191
+ ### 4.1 JaCoCo version upgrade (if needed)
192
+
193
+ Only if current version < 0.8.8 or JDK >= 17:
194
+
195
+ ```xml
196
+ <!-- Update version only, preserve all other config -->
197
+ <version>0.8.11</version>
198
+ ```
199
+
200
+ ### 4.2 Fix PIT configuration (if needed)
201
+
202
+ For each issue found:
203
+
204
+ **Issue: not in profile** — wrap existing config in `<profile id="mutation-tests">`:
205
+ ```xml
206
+ <profiles>
207
+ <profile>
208
+ <id>mutation-tests</id>
209
+ <activation><activeByDefault>false</activeByDefault></activation>
210
+ <build><plugins>
211
+ <!-- move existing pitest-maven config here -->
212
+ </plugins></build>
213
+ </profile>
214
+ </profiles>
215
+ ```
216
+
217
+ **Issue: placeholder targetClasses** — read actual packages first, then update:
218
+ ```bash
219
+ find src/main/java -type d | grep -v test | sort
220
+ ```
221
+ Update `targetClasses` and `targetTests` with the actual package paths found.
222
+
223
+ **Issue: missing timestampedReports** — add:
224
+ ```xml
225
+ <timestampedReports>false</timestampedReports>
226
+ ```
227
+
228
+ **Issue: missing XML output** — add:
229
+ ```xml
230
+ <outputFormats>
231
+ <outputFormat>HTML</outputFormat>
232
+ <outputFormat>XML</outputFormat>
233
+ </outputFormats>
234
+ ```
235
+
236
+ **Issue: missing pitest-junit5-plugin** — add to PIT plugin dependencies.
237
+
238
+ ### 4.3 Refresh scripts from the shiftleft-tools package
239
+
240
+ Run `shiftleft stage-scripts` — it re-stages every library script from the
241
+ installed package, so stale or missing ones are replaced automatically. You do
242
+ not pick individual files or copy by hand; staging always brings the current
243
+ versions (the committed `run-all.sh` shim and repo-owned files are left alone).
244
+
245
+ **Data flow between scripts:**
246
+ ```
247
+ mvn test → target/surefire-reports/*.xml → report_unit.py
248
+ mvn jacoco:report → target/site/jacoco/jacoco.xml → report_unit.py
249
+ mvn pitest → target/pit-reports/mutations.xml → report_mutation.py, report_unit.py
250
+ Newman run → postman/reports/newman/*.json → report_consolidated.py
251
+ coverage matrix → postman/reports/api-coverage.json → api_coverage.py
252
+ stage-artifacts → postman/reports/jacoco/, pit/ → quality report HTML links
253
+
254
+ report_generator.py (CLI entry) dispatches to:
255
+ ├─ report_unit.py → postman/reports/unit-test-report-*.html
256
+ ├─ report_consolidated.py → postman/reports/consolidated-report-*.html
257
+ ├─ report_mutation.py → postman/reports/mutation-report-*.html
258
+ └─ report_combined.py → postman/reports/quality-report-*.html (THE main report)
259
+ ```
260
+
261
+ **Quality report HTML structure** — `report_combined.py` generates a single-page HTML with:
262
+
263
+ ```
264
+ ┌──────────────────────────────────────────────────────────────┐
265
+ │ [Health Badge: 🟢 Healthy | 🟡 Good | 🔴 Needs Attention] │
266
+ │ Health: all green = Healthy, any warning = Good, any red = Needs Attention │
267
+ ├─────────────┬─────────────┬─────────────┬──────────┬─────────┤
268
+ │ Unit Tests │ Line Cov │ Mutation │ API │ API Cov │
269
+ │ N/M passed │ XX.X% │ Score XX.X% │ N passed │ XX.X% │
270
+ │ [green/red] │ [green/warn │ [green/warn │ [grn/red]│[grn/wrn]│
271
+ │ │ /red] │ /red] │ │ /red] │
272
+ └─────────────┴─────────────┴─────────────┴──────────┴─────────┘
273
+
274
+ ┌─────────────────────────────────────────────────────────────┐
275
+ │ [Unit Tests tab] | [API Tests tab] ← CSS tab switcher │
276
+ ├─────────────────────────────────────────────────────────────┤
277
+ │ Unit Tests tab contains sub-tabs: │
278
+ │ [Test Results] [Coverage] [Mutations] [Survived Mutations]│
279
+ │ │
280
+ │ API Tests tab contains sub-tabs: │
281
+ │ [Summary] [by Collection] [API Coverage Matrix] │
282
+ └─────────────────────────────────────────────────────────────┘
283
+ ```
284
+
285
+ Card thresholds:
286
+ - Unit Tests: green if 0 failures, red if any failures
287
+ - Line Coverage: green ≥80%, yellow ≥60%, red <60%
288
+ - Mutation Score: green ≥80%, yellow ≥60%, red <60%
289
+ - API Tests: green if 0 failed, red if any failed
290
+ - API Coverage: green ≥80%, yellow ≥60%, red <60%
291
+
292
+ **Survived Mutations tab** shows up to 15 survived mutations (class, method, line, description). Empty state: "No survived mutations. All mutations were killed by tests."
293
+
294
+ **If the repo has a Maven submodule** (e.g., `installation/`), adjust `stage-report-artifacts.sh`:
295
+ ```bash
296
+ # Default template uses target/ — for submodules, change to:
297
+ JACOCO_SRC="$PROJECT_ROOT/installation/target/site/jacoco"
298
+ PIT_DIR="$PROJECT_ROOT/installation/target/pit-reports"
299
+ ```
300
+
301
+ Scripts to update if stale:
302
+ - `run-all.sh` — if missing `--skip-*` flags
303
+ - `lib/report_generator.py` — if it's a monolith (>500 lines); replace with split modules
304
+
305
+ Scripts to add if missing:
306
+ - `stage-report-artifacts.sh`
307
+ - `generate-quality-report.sh`
308
+ - `runners/run-tests-local.sh` (if only `run-local.sh` exists)
309
+ - `runners/run-tests-staging.sh` (if only `run-staging.sh` exists)
310
+
311
+ Make all `.sh` files executable:
312
+ ```bash
313
+ chmod +x postman/scripts/*.sh postman/scripts/runners/*.sh
314
+ ```
315
+
316
+ ### 4.4 Update Jenkinsfile (targeted edits only)
317
+
318
+ Only modify the specific missing pieces. Do NOT rewrite the Jenkinsfile.
319
+
320
+ **Missing mutation stage** — add after Unit Tests stage:
321
+ ```groovy
322
+ stage('Mutation Tests') {
323
+ when {
324
+ expression {
325
+ params.deployTo == 'dev' && !params.deployOnly
326
+ }
327
+ }
328
+ steps {
329
+ script {
330
+ runMutationTests()
331
+ }
332
+ }
333
+ }
334
+ ```
335
+
336
+ And add the function:
337
+ ```groovy
338
+ def runMutationTests() {
339
+ echo "Running PIT Mutation Tests..."
340
+ try {
341
+ sh """#!/bin/bash --login
342
+ cd postman/scripts
343
+ ./run-all.sh --skip-unit --skip-postman --skip-coverage --skip-report --no-delay
344
+ """
345
+ } catch (Exception e) {
346
+ echo "Mutation tests failed: ${e.getMessage()}"
347
+ throw e
348
+ }
349
+ }
350
+ ```
351
+
352
+ **Missing quality report in ShiftLeft** — add after Postman test block:
353
+ ```groovy
354
+ // API coverage matrix
355
+ sh """cd postman/scripts && ./run-all.sh --skip-unit --skip-mutation --skip-postman --skip-report --no-delay"""
356
+
357
+ // Quality report
358
+ sh """cd postman/scripts
359
+ ./stage-report-artifacts.sh "\${WORKSPACE}" "\${WORKSPACE}/postman/reports" || true
360
+ ./run-all.sh --skip-unit --skip-mutation --skip-postman --skip-coverage --no-delay"""
361
+
362
+ publishHTML([
363
+ allowMissing: true,
364
+ alwaysLinkToLastBuild: true,
365
+ keepAll: true,
366
+ reportDir: 'postman/reports',
367
+ reportFiles: 'quality-report-*.html',
368
+ includes: '**/*', // REQUIRED — without this, CSS/subdirs won't load
369
+ reportName: 'QualityReport',
370
+ reportTitles: 'Combined Quality Report'
371
+ ])
372
+ archiveArtifacts artifacts: 'postman/reports/**', allowEmptyArchive: true
373
+ ```
374
+
375
+ ---
376
+
377
+ ## PIT XML Format Spec
378
+
379
+ When writing or debugging `report_mutation.py` or `report_unit.py`, the PIT XML format is:
380
+
381
+ ```xml
382
+ <mutations>
383
+ <mutation detected="true" status="KILLED" numberOfTestsRun="3">
384
+ <sourceFile>MyClass.java</sourceFile>
385
+ <mutatedClass>com.example.service.MyClass</mutatedClass>
386
+ <mutatedMethod>myMethod</mutatedMethod>
387
+ <methodDescription>(Ljava/lang/String;)Z</methodDescription>
388
+ <lineNumber>42</lineNumber>
389
+ <mutator>org.pitest.mutationtest.engine.gregor.mutators.NegateConditionalsMutator</mutator>
390
+ <indexes><index>5</index></indexes>
391
+ <blocks><block>2</block></blocks>
392
+ <killingTest>com.example.service.MyClassTest.[engine:junit-jupiter]/...</killingTest>
393
+ <description>negated conditional</description>
394
+ </mutation>
395
+ </mutations>
396
+ ```
397
+
398
+ **Status attribute values** (read from `mutation.get('status')`, NOT from `detected` attribute):
399
+ - `KILLED` — test caught the mutation (good)
400
+ - `SURVIVED` — no test caught it (bad — report these in Survived Mutations tab)
401
+ - `NO_COVERAGE` — no test covers this line at all
402
+ - `TIMED_OUT` — mutation caused an infinite loop (treated as killed)
403
+ - `RUN_ERROR` — mutation caused a runtime error (treated as killed)
404
+
405
+ **Common bug:** Do NOT use `mutation.get('detected')` — use `mutation.get('status')`. The `detected` attribute (`"true"/"false"`) loses the distinction between NO_COVERAGE and SURVIVED.
406
+
407
+ ---
408
+
409
+ ## Error Handling Rules
410
+
411
+ When any input file is missing, degrade gracefully — never crash the report:
412
+
413
+ | Missing file | Behavior |
414
+ |---|---|
415
+ | `surefire-reports/*.xml` | Show "No unit test data" card, continue |
416
+ | `jacoco.xml` | Show "Coverage data unavailable", skip coverage card |
417
+ | `mutations.xml` | Show "Mutation data unavailable", skip mutation card |
418
+ | `newman/*.json` | Show "No API test results", skip API tabs |
419
+ | `api-coverage.json` | Show "API coverage data unavailable", skip coverage card |
420
+
421
+ Pattern from `report_unit.py`:
422
+ ```python
423
+ try:
424
+ tree = ET.parse(mutations_xml)
425
+ # ... parse
426
+ except Exception as e:
427
+ print(f"Warning: Could not parse mutations.xml: {e}")
428
+ # return empty/default results dict, not None
429
+ ```
430
+
431
+ Always return a results dict with zero values rather than `None` — callers check keys, not None.
432
+
433
+ ---
434
+
435
+ ## Phase 5: Verify
436
+
437
+ Run the minimum verification needed for what was changed:
438
+
439
+ If PIT config was updated:
440
+ ```bash
441
+ mvn org.pitest:pitest-maven:mutationCoverage -Pmutation-tests -q
442
+ # For submodule: mvn -pl <module> org.pitest:pitest-maven:mutationCoverage -Pmutation-tests -q
443
+ ```
444
+
445
+ Confirm `target/pit-reports/mutations.xml` exists and has `status` attributes on `<mutation>` elements.
446
+
447
+ If scripts were updated:
448
+ ```bash
449
+ cd postman/scripts
450
+ ./run-all.sh --skip-postman --no-delay
451
+ ```
452
+
453
+ If quality report was added:
454
+ ```bash
455
+ # Run with existing data to verify quality report generates
456
+ ./run-all.sh --skip-unit --skip-mutation --skip-postman --skip-coverage --no-delay
457
+ ```
458
+
459
+ Report what changed and the current state of each component.
460
+
461
+ ---
462
+
463
+ ## Verification Checklist
464
+
465
+ - [ ] All targeted changes made (none more, none less)
466
+ - [ ] JaCoCo version is 0.8.8+ (if applicable)
467
+ - [ ] PIT targetClasses matches actual packages (verified with `find src/main/java -type d`)
468
+ - [ ] PIT is inside a `mutation-tests` profile
469
+ - [ ] `<timestampedReports>false</timestampedReports>` is set
470
+ - [ ] XML output format is enabled
471
+ - [ ] `target/pit-reports/mutations.xml` has `status` attributes (not just `detected`)
472
+ - [ ] `run-all.sh` has full `--skip-*` flag set
473
+ - [ ] `stage-report-artifacts.sh` exists and uses correct `target/` path for this repo
474
+ - [ ] `generate-quality-report.sh` exists
475
+ - [ ] Jenkinsfile has Mutation Tests stage
476
+ - [ ] Jenkinsfile ShiftLeft stage generates and publishes quality report
477
+ - [ ] Jenkinsfile `publishHTML` has `includes: '**/*'`
478
+ - [ ] `./run-all.sh --skip-postman --no-delay` completes successfully
479
+ - [ ] Quality report HTML is generated with 5 metric cards
480
+ - [ ] Quality report has Unit Tests tab + API Tests tab
481
+ - [ ] Unit Tests tab has Survived Mutations sub-tab
482
+ - [ ] JaCoCo and PIT links in quality report open correctly (not 404)
483
+ - [ ] All `.sh` files are executable