zephyr-enterprise-tools 1.3.1 → 1.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -117
- package/cli.js +5 -128
- package/mcp-server.js +0 -100
- package/package.json +2 -4
- package/zephyr-enterprise-tools.d.ts +0 -117
- package/zephyr-enterprise-tools.js +2 -9
package/README.md
CHANGED
|
@@ -1,22 +1,11 @@
|
|
|
1
1
|
# Zephyr Enterprise Tools
|
|
2
2
|
|
|
3
|
-
Comprehensive tools for Zephyr Enterprise —
|
|
3
|
+
Comprehensive tools for Zephyr Enterprise — Project Health, Test Analytics & More.
|
|
4
4
|
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
## 🛠️ Available Tools
|
|
8
8
|
|
|
9
|
-
### 🚦 Release Readiness (Quality Gates)
|
|
10
|
-
|
|
11
|
-
| Tool | Description | Thresholds |
|
|
12
|
-
|------|-------------|------------|
|
|
13
|
-
| `release-readiness` | Run all 4 quality gates | Combined assessment |
|
|
14
|
-
| `compare-releases` | Compare readiness across two releases | MCP/programmatic API |
|
|
15
|
-
| `requirement-coverage` | Are requirements covered by tests? | ≥70% = GO |
|
|
16
|
-
| `test-plan` | Are tests planned and assigned? | <80% = NO GO, 80–90% = CONDITIONAL, ≥90% = GO |
|
|
17
|
-
| `test-execution` | Have tests been executed? | <90% = NO GO, 90–97% = CONDITIONAL, ≥97% = GO |
|
|
18
|
-
| `defect-quality` | Are critical defects resolved? | Blocker > 0 = NO GO, High-risk > 10 = NO GO |
|
|
19
|
-
|
|
20
9
|
### 📊 Analytics & Insights
|
|
21
10
|
|
|
22
11
|
| Tool | Description |
|
|
@@ -69,12 +58,6 @@ Use `zephyr-enterprise-tools` as an MCP (Model Context Protocol) server with you
|
|
|
69
58
|
|------|-----------|-------------|
|
|
70
59
|
| `list_projects` | _(none)_ | List all Zephyr projects |
|
|
71
60
|
| `list_releases` | `projectId` | List releases for a project |
|
|
72
|
-
| `release_readiness` | `projectId`, `releaseId` | Run all 4 quality gates |
|
|
73
|
-
| `compare_releases` | `projectId`, `releaseId1`, `releaseId2`, `query?` _(ZQL)_ | Compare readiness between two releases in the same project |
|
|
74
|
-
| `requirement_coverage` | `projectId`, `releaseId` | Check requirement coverage |
|
|
75
|
-
| `test_plan_analysis` | `projectId`, `releaseId`, `query?` _(ZQL)_ | Analyze test planning status — supports ZQL filter e.g. `priority = "P1"` |
|
|
76
|
-
| `test_execution` | `projectId`, `releaseId` | Check test execution progress |
|
|
77
|
-
| `defect_quality` | `projectId`, `releaseId` | Analyze defect status |
|
|
78
61
|
| `project_health` | `projectId`, `releaseId` | Get project health score |
|
|
79
62
|
| `test_coverage` | `projectId`, `releaseId` | Get test coverage details |
|
|
80
63
|
| `failed_tests` | `projectId`, `releaseId`, `limit?` | List failed tests |
|
|
@@ -89,8 +72,6 @@ Use `zephyr-enterprise-tools` as an MCP (Model Context Protocol) server with you
|
|
|
89
72
|
|
|
90
73
|
> **\* `user_trend` — `userName` must be the user's full email address** (e.g. `jane.doe@yourcompany.com`). Short names or display names will return 0 results. `pageSize` supports up to 1000 records per request.
|
|
91
74
|
|
|
92
|
-
> **`test_plan_analysis` ZQL filter** — Use the `query` parameter to scope results to a specific priority, e.g. `priority = "P1"`. This is the recommended way to filter test plan metrics by priority. Note: `search_test_cases` accepts keyword queries but does not support ZQL priority filtering.
|
|
93
|
-
|
|
94
75
|
> **Execution chart date range** — Use `startDate` and `endDate` (format: `YYYY-MM-DD`) to scope `execution_burnup` and `execution_burndown` to a specific period within the release window.
|
|
95
76
|
|
|
96
77
|
> **Execution status IDs** — Test execution, failed tests, trends, user activity, burnup, burndown, and cycle status counts resolve status IDs from Zephyr v4 system preferences using `testresult.testresultStatus.LOV` from `/admin/preference/all/system`. Built-in IDs are used only as a fallback when the preference cannot be loaded or parsed.
|
|
@@ -172,9 +153,6 @@ Add to your `mcp.json` configuration:
|
|
|
172
153
|
The CLI binary is `zephyr-enterprise-tools`:
|
|
173
154
|
|
|
174
155
|
```bash
|
|
175
|
-
# Run all quality gates (release readiness)
|
|
176
|
-
zephyr-enterprise-tools -p <projectId> -r <releaseId>
|
|
177
|
-
|
|
178
156
|
# Run a specific tool
|
|
179
157
|
zephyr-enterprise-tools -p 364 -r 4312 -t project-health
|
|
180
158
|
zephyr-enterprise-tools -p 364 -r 4312 -t failed-tests
|
|
@@ -183,9 +161,6 @@ zephyr-enterprise-tools -p 364 -r 4312 -t user-activity
|
|
|
183
161
|
# Search test cases by keyword
|
|
184
162
|
zephyr-enterprise-tools -p 364 -r 4312 -t search-tests -q "login"
|
|
185
163
|
|
|
186
|
-
# Test plan analysis filtered to P1 priority (ZQL)
|
|
187
|
-
zephyr-enterprise-tools -p 364 -r 4312 -t test-plan -q 'priority = "P1"'
|
|
188
|
-
|
|
189
164
|
# Get trends for last 14 days
|
|
190
165
|
zephyr-enterprise-tools -p 364 -r 4312 -t test-trends -d 14
|
|
191
166
|
|
|
@@ -214,8 +189,8 @@ zephyr-enterprise-tools --help
|
|
|
214
189
|
|--------|-------------|
|
|
215
190
|
| `-p, --project <id>` | Project ID (required for most tools) |
|
|
216
191
|
| `-r, --release <id>` | Release ID (required for most tools) |
|
|
217
|
-
| `-t, --tool <name>` | Tool to run (default: `
|
|
218
|
-
| `-q, --query <text>` | Keyword query
|
|
192
|
+
| `-t, --tool <name>` | Tool to run (default: `project-health`) |
|
|
193
|
+
| `-q, --query <text>` | Keyword query for `search-tests` |
|
|
219
194
|
| `-d, --days <n>` | Days for trends/activity (default: 30) |
|
|
220
195
|
| `-l, --limit <n>` | Max results (default: 50) |
|
|
221
196
|
| `-c, --cycle <id>` | Cycle ID for `get-cycle` |
|
|
@@ -246,20 +221,6 @@ const tools = new ZephyrEnterpriseTools({
|
|
|
246
221
|
token: 'your-api-token',
|
|
247
222
|
});
|
|
248
223
|
|
|
249
|
-
// ── Release Readiness ──────────────────────────────────────
|
|
250
|
-
const report = await tools.runAllGates(364, 4312);
|
|
251
|
-
console.log(report.overallStatus); // "GO" | "CONDITIONAL GO" | "NO GO"
|
|
252
|
-
|
|
253
|
-
const comparison = await tools.compareReleases(364, 4312, 4313, { query: 'priority = "P1"' });
|
|
254
|
-
console.log(comparison.overallStatusChanged); // true when release readiness status changed
|
|
255
|
-
|
|
256
|
-
// Individual gates
|
|
257
|
-
const coverage = await tools.requirementCoverageGate(364, 4312);
|
|
258
|
-
const planning = await tools.testPlanAnalysisGate(364, 4312);
|
|
259
|
-
const planningP1 = await tools.testPlanAnalysisGate(364, 4312, { query: 'priority = "P1"' });
|
|
260
|
-
const execution = await tools.testExecutionGate(364, 4312);
|
|
261
|
-
const defects = await tools.defectQualityGate(364, 4312);
|
|
262
|
-
|
|
263
224
|
// ── Analytics & Insights ───────────────────────────────────
|
|
264
225
|
const health = await tools.getProjectHealth(364, 4312);
|
|
265
226
|
console.log(health.healthScore); // 0–100
|
|
@@ -298,27 +259,6 @@ const burndown = await tools.getExecutionBurndown(364, 4312, {
|
|
|
298
259
|
|
|
299
260
|
## 📊 Sample Outputs
|
|
300
261
|
|
|
301
|
-
### Release Readiness Report
|
|
302
|
-
|
|
303
|
-
```
|
|
304
|
-
════════════════════════════════════════════════════════════════════════════════
|
|
305
|
-
RELEASE READINESS REPORT
|
|
306
|
-
════════════════════════════════════════════════════════════════════════════════
|
|
307
|
-
Project: 364 | Release: 4312 | 2026-08-12T10:30:00.000Z
|
|
308
|
-
────────────────────────────────────────────────────────────────────────────────
|
|
309
|
-
|
|
310
|
-
┌─────────────────────────┬──────────┬──────────────────┬─────────────────────────┐
|
|
311
|
-
│ Gate │ Score │ Status │ Threshold │
|
|
312
|
-
├─────────────────────────┼──────────┼──────────────────┼─────────────────────────┤
|
|
313
|
-
│ Requirement Coverage │ 37.04% │ 🔴 NO GO │ ≥70% coverage │
|
|
314
|
-
│ Test Plan Analysis │ 19.53% │ 🔴 NO GO │ ≥90% planned & assigned │
|
|
315
|
-
│ Test Execution │ 80% │ 🔴 NO GO │ ≥97% executed │
|
|
316
|
-
│ Defect Quality │ 0B / 0H │ 🟢 GO │ 0 blockers, ≤10 high │
|
|
317
|
-
└─────────────────────────┴──────────┴──────────────────┴─────────────────────────┘
|
|
318
|
-
|
|
319
|
-
OVERALL: 🔴 NO GO (1/4 passed, 3 failed, 0 conditional)
|
|
320
|
-
```
|
|
321
|
-
|
|
322
262
|
### Project Health
|
|
323
263
|
|
|
324
264
|
```
|
|
@@ -362,60 +302,6 @@ Health Score: 🟡 65/100 (MODERATE)
|
|
|
362
302
|
|
|
363
303
|
## 🔧 CI/CD Integration
|
|
364
304
|
|
|
365
|
-
### GitHub Actions
|
|
366
|
-
|
|
367
|
-
```yaml
|
|
368
|
-
- name: Check Release Readiness
|
|
369
|
-
env:
|
|
370
|
-
ZEPHYR_BASE_URL: ${{ secrets.ZEPHYR_BASE_URL }}
|
|
371
|
-
ZEPHYR_TOKEN: ${{ secrets.ZEPHYR_TOKEN }}
|
|
372
|
-
run: |
|
|
373
|
-
npx zephyr-enterprise-tools -p ${{ vars.PROJECT_ID }} -r ${{ vars.RELEASE_ID }} --json > report.json
|
|
374
|
-
cat report.json
|
|
375
|
-
```
|
|
376
|
-
|
|
377
|
-
### Jenkins
|
|
378
|
-
|
|
379
|
-
```groovy
|
|
380
|
-
stage('Quality Gates') {
|
|
381
|
-
environment {
|
|
382
|
-
ZEPHYR_BASE_URL = credentials('zephyr-base-url')
|
|
383
|
-
ZEPHYR_TOKEN = credentials('zephyr-token')
|
|
384
|
-
}
|
|
385
|
-
steps {
|
|
386
|
-
sh 'npx zephyr-enterprise-tools -p ${PROJECT_ID} -r ${RELEASE_ID}'
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
```
|
|
390
|
-
|
|
391
|
-
---
|
|
392
|
-
|
|
393
|
-
## 📝 Customizing Thresholds
|
|
394
|
-
|
|
395
|
-
Edit `quality-gates.js`:
|
|
396
|
-
|
|
397
|
-
```javascript
|
|
398
|
-
export const THRESHOLDS = {
|
|
399
|
-
requirementCoverage: {
|
|
400
|
-
go: 70, // Raise to 80 for stricter coverage requirements
|
|
401
|
-
},
|
|
402
|
-
testPlanAnalysis: {
|
|
403
|
-
noGo: 80,
|
|
404
|
-
conditionalGo: 90,
|
|
405
|
-
},
|
|
406
|
-
testExecution: {
|
|
407
|
-
noGo: 90,
|
|
408
|
-
conditionalGo: 97,
|
|
409
|
-
},
|
|
410
|
-
defectQuality: {
|
|
411
|
-
blockerLimit: 0,
|
|
412
|
-
highRiskLimit: 10, // Lower to 5 for a stricter defect policy
|
|
413
|
-
}
|
|
414
|
-
};
|
|
415
|
-
```
|
|
416
|
-
|
|
417
|
-
---
|
|
418
|
-
|
|
419
305
|
## 🐛 Common Issues
|
|
420
306
|
|
|
421
307
|
| Problem | Cause | Fix |
|
package/cli.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
/**
|
|
4
4
|
* Zephyr Enterprise Tools CLI
|
|
5
5
|
*
|
|
6
|
-
* Run
|
|
6
|
+
* Run Zephyr analytics from the command line.
|
|
7
7
|
*
|
|
8
8
|
* Usage:
|
|
9
9
|
* export ZEPHYR_BASE_URL="https://your-zephyr.com/flex/services/rest/latest"
|
|
@@ -35,8 +35,7 @@ function parseArgs() {
|
|
|
35
35
|
const options = {
|
|
36
36
|
projectId: null,
|
|
37
37
|
releaseId: null,
|
|
38
|
-
tool: '
|
|
39
|
-
gate: null, // Legacy support
|
|
38
|
+
tool: 'project-health',
|
|
40
39
|
format: 'table',
|
|
41
40
|
help: false,
|
|
42
41
|
query: '',
|
|
@@ -62,11 +61,6 @@ function parseArgs() {
|
|
|
62
61
|
case '--tool':
|
|
63
62
|
options.tool = args[++i];
|
|
64
63
|
break;
|
|
65
|
-
case '-g':
|
|
66
|
-
case '--gate':
|
|
67
|
-
// Legacy support - map to tool
|
|
68
|
-
options.gate = args[++i];
|
|
69
|
-
break;
|
|
70
64
|
case '-q':
|
|
71
65
|
case '--query':
|
|
72
66
|
options.query = args[++i] || '';
|
|
@@ -102,11 +96,6 @@ function parseArgs() {
|
|
|
102
96
|
}
|
|
103
97
|
}
|
|
104
98
|
|
|
105
|
-
// Legacy gate support
|
|
106
|
-
if (options.gate) {
|
|
107
|
-
options.tool = options.gate === 'all' ? 'release-readiness' : options.gate;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
99
|
return options;
|
|
111
100
|
}
|
|
112
101
|
|
|
@@ -126,7 +115,7 @@ REQUIRED:
|
|
|
126
115
|
-r, --release <id> Release ID
|
|
127
116
|
|
|
128
117
|
OPTIONS:
|
|
129
|
-
-t, --tool <name> Tool to run (default:
|
|
118
|
+
-t, --tool <name> Tool to run (default: project-health)
|
|
130
119
|
-q, --query <text> Search query (for search-tests)
|
|
131
120
|
-d, --days <n> Number of days for trends/activity (default: 30)
|
|
132
121
|
-l, --limit <n> Max results to return (default: 50)
|
|
@@ -137,15 +126,7 @@ OPTIONS:
|
|
|
137
126
|
|
|
138
127
|
AVAILABLE TOOLS:
|
|
139
128
|
┌─────────────────────────────────────────────────────────────────────────────┐
|
|
140
|
-
│
|
|
141
|
-
├─────────────────────────────────────────────────────────────────────────────┤
|
|
142
|
-
│ release-readiness Run all 4 quality gates (default) │
|
|
143
|
-
│ requirement-coverage Requirement coverage gate only │
|
|
144
|
-
│ test-plan Test plan analysis gate only │
|
|
145
|
-
│ test-execution Test execution gate only │
|
|
146
|
-
│ defect-quality Defect quality gate only │
|
|
147
|
-
├─────────────────────────────────────────────────────────────────────────────┤
|
|
148
|
-
│ ANALYTICS & INSIGHTS │
|
|
129
|
+
│ AVAILABLE ANALYTICS │
|
|
149
130
|
├─────────────────────────────────────────────────────────────────────────────┤
|
|
150
131
|
│ project-health Overall project health score and metrics │
|
|
151
132
|
│ test-coverage Detailed test coverage analysis │
|
|
@@ -165,9 +146,6 @@ ENVIRONMENT VARIABLES:
|
|
|
165
146
|
ZEPHYR_TOKEN API token for authentication (required)
|
|
166
147
|
|
|
167
148
|
EXAMPLES:
|
|
168
|
-
# Run all quality gates (release readiness)
|
|
169
|
-
zephyr-tools -p 364 -r 4312
|
|
170
|
-
|
|
171
149
|
# Check project health
|
|
172
150
|
zephyr-tools -p 364 -r 4312 -t project-health
|
|
173
151
|
|
|
@@ -192,83 +170,9 @@ EXAMPLES:
|
|
|
192
170
|
# Get a single cycle detail
|
|
193
171
|
zephyr-tools -p 364 -r 4312 -t get-cycle -c 98765
|
|
194
172
|
|
|
195
|
-
QUALITY GATE THRESHOLDS:
|
|
196
|
-
Requirement Coverage: ≥70% = GO
|
|
197
|
-
Test Plan Analysis: <80% = NO GO, 80-90% = CONDITIONAL, ≥90% = GO
|
|
198
|
-
Test Execution: <90% = NO GO, 90-97% = CONDITIONAL, ≥97% = GO
|
|
199
|
-
Defect Quality: Blocker >0 = NO GO, High-risk >10 = NO GO
|
|
200
173
|
`);
|
|
201
174
|
}
|
|
202
175
|
|
|
203
|
-
// ─── Formatters ───────────────────────────────────────────────────────────────
|
|
204
|
-
|
|
205
|
-
function formatTable(report) {
|
|
206
|
-
const { gates, overallStatus, summary, recommendation } = report;
|
|
207
|
-
|
|
208
|
-
const statusIcon = (s) => s === 'GO' ? '🟢' : s === 'CONDITIONAL GO' ? '🟡' : s === 'NO GO' ? '🔴' : '⚪';
|
|
209
|
-
|
|
210
|
-
console.log('\n' + '═'.repeat(80));
|
|
211
|
-
console.log(' RELEASE READINESS REPORT');
|
|
212
|
-
console.log('═'.repeat(80));
|
|
213
|
-
console.log(`Project: ${report.projectId} | Release: ${report.releaseId} | ${report.timestamp}`);
|
|
214
|
-
console.log('─'.repeat(80));
|
|
215
|
-
|
|
216
|
-
console.log('\n┌─────────────────────────┬──────────┬───────────┬─────────────────────────┐');
|
|
217
|
-
console.log('│ Gate │ Score │ Status │ Threshold │');
|
|
218
|
-
console.log('├─────────────────────────┼──────────┼───────────┼─────────────────────────┤');
|
|
219
|
-
|
|
220
|
-
// Gate 1
|
|
221
|
-
const g1 = gates.requirementCoverage;
|
|
222
|
-
console.log(`│ Requirement Coverage │ ${String(g1.coveragePercentage + '%').padEnd(8)} │ ${statusIcon(g1.status)} ${g1.status.padEnd(7)} │ ≥70% coverage │`);
|
|
223
|
-
|
|
224
|
-
// Gate 2
|
|
225
|
-
const g2 = gates.testPlanAnalysis;
|
|
226
|
-
console.log(`│ Test Plan Analysis │ ${String(g2.overallPlanningPercentage + '%').padEnd(8)} │ ${statusIcon(g2.status)} ${g2.status.padEnd(7)} │ ≥90% planned & assigned │`);
|
|
227
|
-
|
|
228
|
-
// Gate 3
|
|
229
|
-
const g3 = gates.testExecution;
|
|
230
|
-
console.log(`│ Test Execution │ ${String(g3.executionPercentage + '%').padEnd(8)} │ ${statusIcon(g3.status)} ${g3.status.padEnd(7)} │ ≥97% executed │`);
|
|
231
|
-
|
|
232
|
-
// Gate 4
|
|
233
|
-
const g4 = gates.defectQuality;
|
|
234
|
-
const defectScore = `${g4.breakdown?.blocker?.count || 0}B/${g4.breakdown?.highRisk?.count || 0}H`;
|
|
235
|
-
console.log(`│ Defect Quality │ ${defectScore.padEnd(8)} │ ${statusIcon(g4.status)} ${g4.status.padEnd(7)} │ 0 blocker, ≤10 high │`);
|
|
236
|
-
|
|
237
|
-
console.log('└─────────────────────────┴──────────┴───────────┴─────────────────────────┘');
|
|
238
|
-
|
|
239
|
-
console.log('\n' + '─'.repeat(80));
|
|
240
|
-
console.log(`OVERALL: ${statusIcon(overallStatus)} ${overallStatus} (${summary.passed}/4 passed, ${summary.failed} failed, ${summary.conditional} conditional)`);
|
|
241
|
-
console.log('─'.repeat(80));
|
|
242
|
-
console.log('\n' + recommendation);
|
|
243
|
-
console.log('\n' + '═'.repeat(80) + '\n');
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
function formatSingleGate(result) {
|
|
247
|
-
const statusIcon = (s) => s === 'GO' ? '🟢' : s === 'CONDITIONAL GO' ? '🟡' : s === 'NO GO' ? '🔴' : '⚪';
|
|
248
|
-
|
|
249
|
-
console.log('\n' + '─'.repeat(60));
|
|
250
|
-
console.log(`${result.gate.toUpperCase()} GATE`);
|
|
251
|
-
console.log('─'.repeat(60));
|
|
252
|
-
console.log(`Status: ${statusIcon(result.status)} ${result.status}`);
|
|
253
|
-
console.log(`Message: ${result.statusMessage}`);
|
|
254
|
-
|
|
255
|
-
if (result.coveragePercentage !== undefined) {
|
|
256
|
-
console.log(`Coverage: ${result.coveragePercentage}% (${result.coveredRequirements}/${result.totalRequirements})`);
|
|
257
|
-
}
|
|
258
|
-
if (result.overallPlanningPercentage !== undefined) {
|
|
259
|
-
console.log(`Planning: ${result.overallPlanningPercentage}%`);
|
|
260
|
-
}
|
|
261
|
-
if (result.executionPercentage !== undefined) {
|
|
262
|
-
console.log(`Execution: ${result.executionPercentage}% (${result.completedTests}/${result.totalPlannedTests})`);
|
|
263
|
-
const b = result.breakdown;
|
|
264
|
-
console.log(`Breakdown: ✅${b.passed} ❌${b.failed} ⏸️${b.blocked} 🔄${b.wip} ⏳${b.notExecuted}`);
|
|
265
|
-
}
|
|
266
|
-
if (result.breakdown?.blocker !== undefined) {
|
|
267
|
-
console.log(`Defects: ${result.breakdown.blocker.count} blocker, ${result.breakdown.highRisk.count} high-risk, ${result.breakdown.lowRisk.count} low-risk`);
|
|
268
|
-
}
|
|
269
|
-
console.log('─'.repeat(60) + '\n');
|
|
270
|
-
}
|
|
271
|
-
|
|
272
176
|
// ─── Generic Result Formatter ─────────────────────────────────────────────────
|
|
273
177
|
|
|
274
178
|
function formatGenericResult(result) {
|
|
@@ -552,25 +456,6 @@ async function main() {
|
|
|
552
456
|
const { projectId, releaseId, tool, query, days, limit } = options;
|
|
553
457
|
|
|
554
458
|
switch (tool) {
|
|
555
|
-
// Quality Gates (Release Readiness)
|
|
556
|
-
case 'release-readiness':
|
|
557
|
-
case 'all':
|
|
558
|
-
result = await tools.runAllGates(projectId, releaseId);
|
|
559
|
-
break;
|
|
560
|
-
case 'requirement-coverage':
|
|
561
|
-
result = await tools.requirementCoverageGate(projectId, releaseId);
|
|
562
|
-
break;
|
|
563
|
-
case 'test-plan':
|
|
564
|
-
result = await tools.testPlanAnalysisGate(projectId, releaseId);
|
|
565
|
-
break;
|
|
566
|
-
case 'test-execution':
|
|
567
|
-
result = await tools.testExecutionGate(projectId, releaseId);
|
|
568
|
-
break;
|
|
569
|
-
case 'defect-quality':
|
|
570
|
-
result = await tools.defectQualityGate(projectId, releaseId);
|
|
571
|
-
break;
|
|
572
|
-
|
|
573
|
-
// Analytics & Insights
|
|
574
459
|
case 'project-health':
|
|
575
460
|
result = await tools.getProjectHealth(projectId, releaseId);
|
|
576
461
|
break;
|
|
@@ -620,18 +505,10 @@ async function main() {
|
|
|
620
505
|
console.error('Use --help to see available tools.');
|
|
621
506
|
process.exit(1);
|
|
622
507
|
}
|
|
623
|
-
|
|
624
508
|
if (options.format === 'json') {
|
|
625
509
|
console.log(JSON.stringify(result, null, 2));
|
|
626
510
|
} else {
|
|
627
|
-
|
|
628
|
-
if (tool === 'release-readiness' || tool === 'all') {
|
|
629
|
-
formatTable(result);
|
|
630
|
-
} else if (['requirement-coverage', 'test-plan', 'test-execution', 'defect-quality'].includes(tool)) {
|
|
631
|
-
formatSingleGate(result);
|
|
632
|
-
} else {
|
|
633
|
-
formatGenericResult(result);
|
|
634
|
-
}
|
|
511
|
+
formatGenericResult(result);
|
|
635
512
|
}
|
|
636
513
|
|
|
637
514
|
// Exit code based on status
|
package/mcp-server.js
CHANGED
|
@@ -18,82 +18,6 @@ import QualityGates from './zephyr-enterprise-tools.js';
|
|
|
18
18
|
// ─── Tool Definitions ─────────────────────────────────────────────────────────
|
|
19
19
|
|
|
20
20
|
const TOOLS = [
|
|
21
|
-
{
|
|
22
|
-
name: 'release_readiness',
|
|
23
|
-
description: 'Run all 4 quality gates with calculation details and action items. Optionally scope Test Plan Analysis to a Zephyr ZQL expression. Returns GO, CONDITIONAL GO, or NO GO status.',
|
|
24
|
-
inputSchema: {
|
|
25
|
-
type: 'object',
|
|
26
|
-
properties: {
|
|
27
|
-
projectId: { type: 'number', description: 'Zephyr project ID' },
|
|
28
|
-
releaseId: { type: 'number', description: 'Zephyr release ID' },
|
|
29
|
-
query: { type: 'string', description: 'Optional Zephyr ZQL expression for Test Plan Analysis, e.g. priority = "P1"' },
|
|
30
|
-
},
|
|
31
|
-
required: ['projectId', 'releaseId'],
|
|
32
|
-
},
|
|
33
|
-
},
|
|
34
|
-
{
|
|
35
|
-
name: 'compare_releases',
|
|
36
|
-
description: 'Run release readiness for two releases in the same project and return a side-by-side diff across all 4 gates, including which gate statuses changed and their metric deltas.',
|
|
37
|
-
inputSchema: {
|
|
38
|
-
type: 'object',
|
|
39
|
-
properties: {
|
|
40
|
-
projectId: { type: 'number', description: 'Zephyr project ID' },
|
|
41
|
-
releaseId1: { type: 'number', description: 'First (baseline) Zephyr release ID' },
|
|
42
|
-
releaseId2: { type: 'number', description: 'Second (comparison) Zephyr release ID' },
|
|
43
|
-
query: { type: 'string', description: 'Optional Zephyr ZQL expression for Test Plan Analysis, e.g. priority = "P1"' },
|
|
44
|
-
},
|
|
45
|
-
required: ['projectId', 'releaseId1', 'releaseId2'],
|
|
46
|
-
},
|
|
47
|
-
},
|
|
48
|
-
{
|
|
49
|
-
name: 'requirement_coverage',
|
|
50
|
-
description: 'Check if requirements are covered by test cases. Threshold: ≥70% = GO.',
|
|
51
|
-
inputSchema: {
|
|
52
|
-
type: 'object',
|
|
53
|
-
properties: {
|
|
54
|
-
projectId: { type: 'number', description: 'Zephyr project ID' },
|
|
55
|
-
releaseId: { type: 'number', description: 'Zephyr release ID' },
|
|
56
|
-
},
|
|
57
|
-
required: ['projectId', 'releaseId'],
|
|
58
|
-
},
|
|
59
|
-
},
|
|
60
|
-
{
|
|
61
|
-
name: 'test_plan_analysis',
|
|
62
|
-
description: 'Analyze test planning status, optionally scoped to testcase IDs returned by a Zephyr ZQL expression. Threshold: <80% = NO GO, 80-90% = CONDITIONAL, ≥90% = GO.',
|
|
63
|
-
inputSchema: {
|
|
64
|
-
type: 'object',
|
|
65
|
-
properties: {
|
|
66
|
-
projectId: { type: 'number', description: 'Zephyr project ID' },
|
|
67
|
-
releaseId: { type: 'number', description: 'Zephyr release ID' },
|
|
68
|
-
query: { type: 'string', description: 'Optional Zephyr ZQL expression, e.g. priority = "P1"' },
|
|
69
|
-
},
|
|
70
|
-
required: ['projectId', 'releaseId'],
|
|
71
|
-
},
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
name: 'test_execution',
|
|
75
|
-
description: 'Check test execution progress. Threshold: <90% = NO GO, 90-97% = CONDITIONAL, ≥97% = GO.',
|
|
76
|
-
inputSchema: {
|
|
77
|
-
type: 'object',
|
|
78
|
-
properties: {
|
|
79
|
-
projectId: { type: 'number', description: 'Zephyr project ID' },
|
|
80
|
-
releaseId: { type: 'number', description: 'Zephyr release ID' },
|
|
81
|
-
},
|
|
82
|
-
required: ['projectId', 'releaseId'],
|
|
83
|
-
},
|
|
84
|
-
},
|
|
85
|
-
{
|
|
86
|
-
name: 'defect_quality',
|
|
87
|
-
description: 'Analyze defect status. Threshold: Blocker >0 = NO GO, High-risk >10 = NO GO.',
|
|
88
|
-
inputSchema: {
|
|
89
|
-
type: 'object',
|
|
90
|
-
properties: {
|
|
91
|
-
projectId: { type: 'number', description: 'Zephyr project ID' },
|
|
92
|
-
releaseId: { type: 'number', description: 'Zephyr release ID' },
|
|
93
|
-
},
|
|
94
|
-
required: ['projectId', 'releaseId'],
|
|
95
|
-
},
|
|
96
|
-
},
|
|
97
21
|
{
|
|
98
22
|
name: 'project_health',
|
|
99
23
|
description: 'Get overall project health score (0-100) with metrics, team info, releases, and recommendations.',
|
|
@@ -326,30 +250,6 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
|
326
250
|
const releaseId = args.releaseId;
|
|
327
251
|
|
|
328
252
|
switch (name) {
|
|
329
|
-
case 'release_readiness':
|
|
330
|
-
result = await tools.runAllGates(projectId, releaseId, { query: args.query });
|
|
331
|
-
break;
|
|
332
|
-
|
|
333
|
-
case 'compare_releases':
|
|
334
|
-
result = await tools.compareReleases(projectId, args.releaseId1, args.releaseId2, { query: args.query });
|
|
335
|
-
break;
|
|
336
|
-
|
|
337
|
-
case 'requirement_coverage':
|
|
338
|
-
result = await tools.requirementCoverageGate(projectId, releaseId);
|
|
339
|
-
break;
|
|
340
|
-
|
|
341
|
-
case 'test_plan_analysis':
|
|
342
|
-
result = await tools.testPlanAnalysisGate(projectId, releaseId, { query: args.query });
|
|
343
|
-
break;
|
|
344
|
-
|
|
345
|
-
case 'test_execution':
|
|
346
|
-
result = await tools.testExecutionGate(projectId, releaseId);
|
|
347
|
-
break;
|
|
348
|
-
|
|
349
|
-
case 'defect_quality':
|
|
350
|
-
result = await tools.defectQualityGate(projectId, releaseId);
|
|
351
|
-
break;
|
|
352
|
-
|
|
353
253
|
case 'project_health':
|
|
354
254
|
result = await tools.getProjectHealth(projectId, releaseId);
|
|
355
255
|
break;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zephyr-enterprise-tools",
|
|
3
|
-
"version": "1.3.
|
|
4
|
-
"description": "Comprehensive Zephyr Enterprise Tools -
|
|
3
|
+
"version": "1.3.2",
|
|
4
|
+
"description": "Comprehensive Zephyr Enterprise Tools - Project Health, Test Analytics & More",
|
|
5
5
|
"main": "zephyr-enterprise-tools.js",
|
|
6
6
|
"types": "zephyr-enterprise-tools.d.ts",
|
|
7
7
|
"exports": {
|
|
@@ -29,8 +29,6 @@
|
|
|
29
29
|
"keywords": [
|
|
30
30
|
"zephyr",
|
|
31
31
|
"zephyr-enterprise",
|
|
32
|
-
"quality-gates",
|
|
33
|
-
"release-readiness",
|
|
34
32
|
"testing",
|
|
35
33
|
"qa",
|
|
36
34
|
"test-management",
|
|
@@ -7,111 +7,8 @@ export interface ZephyrConfig {
|
|
|
7
7
|
token?: string;
|
|
8
8
|
}
|
|
9
9
|
|
|
10
|
-
export interface ThresholdConfig {
|
|
11
|
-
requirementCoverage: { go: number; description: string };
|
|
12
|
-
testPlanAnalysis: { noGo: number; conditionalGo: number; description: string };
|
|
13
|
-
testExecution: { noGo: number; conditionalGo: number; description: string };
|
|
14
|
-
defectQuality: { blockerLimit: number; highRiskLimit: number; description: string };
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
export type GateStatus = "GO" | "CONDITIONAL GO" | "NO GO";
|
|
18
10
|
export type HealthStatus = "HEALTHY" | "MODERATE" | "AT RISK" | "CRITICAL";
|
|
19
11
|
|
|
20
|
-
export interface GateResult {
|
|
21
|
-
gate: string;
|
|
22
|
-
status: GateStatus;
|
|
23
|
-
statusMessage: string;
|
|
24
|
-
[key: string]: unknown;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export interface RequirementCoverageResult extends GateResult {
|
|
28
|
-
coveragePercentage: number;
|
|
29
|
-
coveredRequirements: number;
|
|
30
|
-
notCoveredRequirements: number;
|
|
31
|
-
totalRequirements: number;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
export interface TestPlanResult extends GateResult {
|
|
35
|
-
overallPlanningPercentage: number;
|
|
36
|
-
totalTests: number;
|
|
37
|
-
plannedTests: number;
|
|
38
|
-
assignedTests: number;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export interface TestPlanOptions {
|
|
42
|
-
/** Optional Zephyr ZQL expression, e.g. `priority = "P1"`. */
|
|
43
|
-
query?: string;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
export interface TestExecutionResult extends GateResult {
|
|
47
|
-
executionPercentage: number;
|
|
48
|
-
completedTests: number;
|
|
49
|
-
totalPlannedTests: number;
|
|
50
|
-
breakdown: {
|
|
51
|
-
passed: number;
|
|
52
|
-
failed: number;
|
|
53
|
-
blocked: number;
|
|
54
|
-
wip: number;
|
|
55
|
-
notExecuted: number;
|
|
56
|
-
};
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export interface DefectQualityResult extends GateResult {
|
|
60
|
-
totalDefects: number;
|
|
61
|
-
breakdown: {
|
|
62
|
-
blocker: { count: number; defects: unknown[] };
|
|
63
|
-
highRisk: { count: number; defects: unknown[] };
|
|
64
|
-
lowRisk: { count: number; defects: unknown[] };
|
|
65
|
-
resolved: { count: number };
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export interface ReleaseReadinessResult {
|
|
70
|
-
projectId: number;
|
|
71
|
-
releaseId: number;
|
|
72
|
-
timestamp: string;
|
|
73
|
-
report: {
|
|
74
|
-
projectName: string;
|
|
75
|
-
releaseName: string;
|
|
76
|
-
generatedAt: string;
|
|
77
|
-
fileName: string;
|
|
78
|
-
};
|
|
79
|
-
overallStatus: GateStatus;
|
|
80
|
-
summary: { passed: number; failed: number; conditional: number };
|
|
81
|
-
details: Record<string, unknown>;
|
|
82
|
-
recommendation: string;
|
|
83
|
-
gates: {
|
|
84
|
-
requirementCoverage: RequirementCoverageResult;
|
|
85
|
-
testPlanAnalysis: TestPlanResult;
|
|
86
|
-
testExecution: TestExecutionResult;
|
|
87
|
-
defectQuality: DefectQualityResult;
|
|
88
|
-
};
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
export interface GateComparison {
|
|
92
|
-
metric: string;
|
|
93
|
-
releaseA: { status: GateStatus; value: number };
|
|
94
|
-
releaseB: { status: GateStatus; value: number };
|
|
95
|
-
delta: number;
|
|
96
|
-
statusChanged: boolean;
|
|
97
|
-
trend: 'improved' | 'regressed' | 'unchanged';
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
export interface CompareReleasesResult {
|
|
101
|
-
projectId: number;
|
|
102
|
-
timestamp: string;
|
|
103
|
-
query?: string;
|
|
104
|
-
releaseA: { releaseId: number; projectName: string; releaseName: string; generatedAt: string; fileName: string; overallStatus: GateStatus };
|
|
105
|
-
releaseB: { releaseId: number; projectName: string; releaseName: string; generatedAt: string; fileName: string; overallStatus: GateStatus };
|
|
106
|
-
overallStatusChanged: boolean;
|
|
107
|
-
gates: {
|
|
108
|
-
requirementCoverage: GateComparison;
|
|
109
|
-
testPlanAnalysis: GateComparison;
|
|
110
|
-
testExecution: GateComparison;
|
|
111
|
-
defectQuality: GateComparison;
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
|
|
115
12
|
export interface ProjectHealthResult {
|
|
116
13
|
tool: string;
|
|
117
14
|
projectId: number;
|
|
@@ -335,14 +232,6 @@ export interface GetCycleResult {
|
|
|
335
232
|
export declare class QualityGates {
|
|
336
233
|
constructor(config: ZephyrConfig);
|
|
337
234
|
|
|
338
|
-
// Quality Gates (Release Readiness)
|
|
339
|
-
requirementCoverageGate(projectId: number, releaseId: number): Promise<RequirementCoverageResult>;
|
|
340
|
-
testPlanAnalysisGate(projectId: number, releaseId: number, options?: TestPlanOptions): Promise<TestPlanResult>;
|
|
341
|
-
testExecutionGate(projectId: number, releaseId: number): Promise<TestExecutionResult>;
|
|
342
|
-
defectQualityGate(projectId: number, releaseId: number): Promise<DefectQualityResult>;
|
|
343
|
-
runAllGates(projectId: number, releaseId: number, options?: TestPlanOptions): Promise<ReleaseReadinessResult>;
|
|
344
|
-
compareReleases(projectId: number, releaseId1: number, releaseId2: number, options?: TestPlanOptions): Promise<CompareReleasesResult>;
|
|
345
|
-
|
|
346
235
|
// Analytics & Insights
|
|
347
236
|
getProjectHealth(projectId: number, releaseId: number): Promise<ProjectHealthResult>;
|
|
348
237
|
getTestCoverage(projectId: number, releaseId: number): Promise<TestCoverageResult>;
|
|
@@ -358,12 +247,6 @@ export declare class QualityGates {
|
|
|
358
247
|
getCycle(cycleId: number): Promise<GetCycleResult>;
|
|
359
248
|
}
|
|
360
249
|
|
|
361
|
-
export declare const THRESHOLDS: ThresholdConfig;
|
|
362
|
-
export declare const RESOLVED_STATUSES: string[];
|
|
363
|
-
export declare const BLOCKER_PRIORITIES: string[];
|
|
364
|
-
export declare const HIGH_RISK_PRIORITIES: string[];
|
|
365
|
-
export declare const LOW_RISK_PRIORITIES: string[];
|
|
366
|
-
|
|
367
250
|
/** Alias for QualityGates — kept for backward compatibility */
|
|
368
251
|
export { QualityGates as ZephyrTools };
|
|
369
252
|
export default QualityGates;
|
|
@@ -3,12 +3,6 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Provides comprehensive tools for Zephyr Enterprise:
|
|
5
5
|
*
|
|
6
|
-
* RELEASE READINESS (Quality Gates):
|
|
7
|
-
* 1. Requirement Coverage Gate - Are requirements covered by tests?
|
|
8
|
-
* 2. Test Plan Analysis Gate - Are tests planned and assigned?
|
|
9
|
-
* 3. Test Execution Gate - Have tests been executed?
|
|
10
|
-
* 4. Defect Quality Gate - Are critical defects resolved?
|
|
11
|
-
*
|
|
12
6
|
* ANALYTICS & INSIGHTS:
|
|
13
7
|
* 5. Project Health - Overall project health metrics
|
|
14
8
|
* 6. Test Coverage - Detailed test coverage analysis
|
|
@@ -21,13 +15,12 @@
|
|
|
21
15
|
* Usage:
|
|
22
16
|
* import { ZephyrTools } from './quality-gates.js';
|
|
23
17
|
* const tools = new ZephyrTools({ baseUrl, username, password });
|
|
24
|
-
* const report = await tools.runAllGates(projectId, releaseId);
|
|
25
18
|
* const health = await tools.getProjectHealth(projectId, releaseId);
|
|
26
19
|
*/
|
|
27
20
|
|
|
28
|
-
// ─── Configuration
|
|
21
|
+
// ─── Configuration ────────────────────────────────────────────────────────────
|
|
29
22
|
|
|
30
|
-
|
|
23
|
+
const THRESHOLDS = {
|
|
31
24
|
requirementCoverage: {
|
|
32
25
|
go: 70,
|
|
33
26
|
description: "≥70% coverage = GO, <70% = NO GO"
|