@rsaglobaltech/specgate 0.27.9 → 1.0.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +36 -0
- package/dist/packages/core/src/application/ValidateChangeUseCase.js +19 -3
- package/dist/packages/core/src/application/ValidateChangeUseCase.js.map +1 -1
- package/dist/packages/core/src/domain/ApiContract.js +157 -0
- package/dist/packages/core/src/domain/ApiContract.js.map +1 -0
- package/dist/packages/core/src/domain/Approvals.js +127 -0
- package/dist/packages/core/src/domain/Approvals.js.map +1 -0
- package/dist/packages/core/src/domain/ChangeLayers.js +281 -0
- package/dist/packages/core/src/domain/ChangeLayers.js.map +1 -0
- package/dist/packages/core/src/domain/HarnessConfig.js.map +1 -1
- package/dist/packages/core/src/domain/HarnessGaps.js +182 -0
- package/dist/packages/core/src/domain/HarnessGaps.js.map +1 -0
- package/dist/packages/core/src/domain/HarnessReport.js +16 -1
- package/dist/packages/core/src/domain/HarnessReport.js.map +1 -1
- package/dist/packages/core/src/domain/HarnessRun.js.map +1 -1
- package/dist/packages/core/src/domain/Principles.js +119 -0
- package/dist/packages/core/src/domain/Principles.js.map +1 -0
- package/dist/packages/core/src/domain/RequirementGraph.js +12 -1
- package/dist/packages/core/src/domain/RequirementGraph.js.map +1 -1
- package/dist/packages/core/src/domain/Workspace.js +150 -0
- package/dist/packages/core/src/domain/Workspace.js.map +1 -0
- package/dist/packages/core/src/index.js +1 -0
- package/dist/packages/core/src/index.js.map +1 -1
- package/dist/packages/core/src/infrastructure/HarnessConfigFile.js +12 -0
- package/dist/packages/core/src/infrastructure/HarnessConfigFile.js.map +1 -1
- package/dist/packages/mcp-spec-driven/src/tools.js +18 -0
- package/dist/packages/mcp-spec-driven/src/tools.js.map +1 -1
- package/dist/scripts/alm/cli.js +45 -4
- package/dist/scripts/alm/cli.js.map +1 -1
- package/dist/scripts/alm/clients.js +3 -1
- package/dist/scripts/alm/clients.js.map +1 -1
- package/dist/scripts/alm/phases.js +279 -0
- package/dist/scripts/alm/phases.js.map +1 -0
- package/dist/scripts/alm/port.js +33 -5
- package/dist/scripts/alm/port.js.map +1 -1
- package/dist/scripts/alm/providers/azure.js +72 -11
- package/dist/scripts/alm/providers/azure.js.map +1 -1
- package/dist/scripts/alm/providers/github.js +67 -7
- package/dist/scripts/alm/providers/github.js.map +1 -1
- package/dist/scripts/alm/providers/index.js +8 -2
- package/dist/scripts/alm/providers/index.js.map +1 -1
- package/dist/scripts/alm/providers/jira.js +86 -8
- package/dist/scripts/alm/providers/jira.js.map +1 -1
- package/dist/scripts/alm/providers/linear.js +167 -0
- package/dist/scripts/alm/providers/linear.js.map +1 -0
- package/dist/scripts/change/artifacts.js +15 -1
- package/dist/scripts/change/artifacts.js.map +1 -1
- package/dist/scripts/change/instructions.js +39 -5
- package/dist/scripts/change/instructions.js.map +1 -1
- package/dist/scripts/cli/commands/alm/PhaseCommand.js +153 -0
- package/dist/scripts/cli/commands/alm/PhaseCommand.js.map +1 -0
- package/dist/scripts/cli/commands/alm/PullCommand.js +33 -2
- package/dist/scripts/cli/commands/alm/PullCommand.js.map +1 -1
- package/dist/scripts/cli/commands/alm/pull-back.js +104 -0
- package/dist/scripts/cli/commands/alm/pull-back.js.map +1 -0
- package/dist/scripts/cli/commands/change/ChangeCommand.js +92 -14
- package/dist/scripts/cli/commands/change/ChangeCommand.js.map +1 -1
- package/dist/scripts/cli/commands/change/TicketCommand.js +20 -7
- package/dist/scripts/cli/commands/change/TicketCommand.js.map +1 -1
- package/dist/scripts/cli/commands/harness/RunCommand.js +64 -20
- package/dist/scripts/cli/commands/harness/RunCommand.js.map +1 -1
- package/dist/scripts/cli/commands/project/AdoptCommand.js +44 -4
- package/dist/scripts/cli/commands/project/AdoptCommand.js.map +1 -1
- package/dist/scripts/cli/commands/project/MigrateCommand.js +166 -0
- package/dist/scripts/cli/commands/project/MigrateCommand.js.map +1 -0
- package/dist/scripts/cli/commands/project/OnboardCommand.js +23 -5
- package/dist/scripts/cli/commands/project/OnboardCommand.js.map +1 -1
- package/dist/scripts/cli/commands/quality/CheckCommand.js +25 -0
- package/dist/scripts/cli/commands/quality/CheckCommand.js.map +1 -1
- package/dist/scripts/cli/commands/quality/ValidateSpecsCommand.js +15 -0
- package/dist/scripts/cli/commands/quality/ValidateSpecsCommand.js.map +1 -1
- package/dist/scripts/cli/commands/spec/ContractCommand.js +117 -0
- package/dist/scripts/cli/commands/spec/ContractCommand.js.map +1 -0
- package/dist/scripts/cli/commands/spec/DraftCommand.js +22 -8
- package/dist/scripts/cli/commands/spec/DraftCommand.js.map +1 -1
- package/dist/scripts/cli/commands/spec/DriftCommand.js +128 -0
- package/dist/scripts/cli/commands/spec/DriftCommand.js.map +1 -0
- package/dist/scripts/cli/commands/spec/StatusCommand.js +12 -0
- package/dist/scripts/cli/commands/spec/StatusCommand.js.map +1 -1
- package/dist/scripts/cli/commands/spec/StudioCommand.js +43 -1
- package/dist/scripts/cli/commands/spec/StudioCommand.js.map +1 -1
- package/dist/scripts/cli/commands/workspace/WorkspaceCommand.js +485 -0
- package/dist/scripts/cli/commands/workspace/WorkspaceCommand.js.map +1 -0
- package/dist/scripts/contract.js +10 -0
- package/dist/scripts/contract.js.map +1 -0
- package/dist/scripts/docs/nav.js +16 -1
- package/dist/scripts/docs/nav.js.map +1 -1
- package/dist/scripts/draft/drafting-guide.js +6 -0
- package/dist/scripts/draft/drafting-guide.js.map +1 -1
- package/dist/scripts/draft/ticket-guide.js +5 -0
- package/dist/scripts/draft/ticket-guide.js.map +1 -1
- package/dist/scripts/drift.js +10 -0
- package/dist/scripts/drift.js.map +1 -0
- package/dist/scripts/harness/gap-evidence.js +149 -0
- package/dist/scripts/harness/gap-evidence.js.map +1 -0
- package/dist/scripts/harness/prompt.js +5 -1
- package/dist/scripts/harness/prompt.js.map +1 -1
- package/dist/scripts/harness/report.js +104 -5
- package/dist/scripts/harness/report.js.map +1 -1
- package/dist/scripts/lib/approvals.js +243 -0
- package/dist/scripts/lib/approvals.js.map +1 -0
- package/dist/scripts/lib/change-review.js +19 -11
- package/dist/scripts/lib/change-review.js.map +1 -1
- package/dist/scripts/lib/contracts.js +211 -0
- package/dist/scripts/lib/contracts.js.map +1 -0
- package/dist/scripts/lib/drift.js +80 -0
- package/dist/scripts/lib/drift.js.map +1 -0
- package/dist/scripts/lib/live-model.js +1 -0
- package/dist/scripts/lib/live-model.js.map +1 -1
- package/dist/scripts/lib/migrate.js +264 -0
- package/dist/scripts/lib/migrate.js.map +1 -0
- package/dist/scripts/lib/role-packages.js +230 -0
- package/dist/scripts/lib/role-packages.js.map +1 -0
- package/dist/scripts/lib/steering.js +180 -0
- package/dist/scripts/lib/steering.js.map +1 -0
- package/dist/scripts/lib/studio-app-page.js +28 -5
- package/dist/scripts/lib/studio-app-page.js.map +1 -1
- package/dist/scripts/lib/studio-app.js +29 -0
- package/dist/scripts/lib/studio-app.js.map +1 -1
- package/dist/scripts/lib/studio-route.js +20 -0
- package/dist/scripts/lib/studio-route.js.map +1 -1
- package/dist/scripts/lib/surface.js +55 -0
- package/dist/scripts/lib/surface.js.map +1 -1
- package/dist/scripts/lib/workspace-live-page.js +90 -0
- package/dist/scripts/lib/workspace-live-page.js.map +1 -0
- package/dist/scripts/lib/workspace-live.js +216 -0
- package/dist/scripts/lib/workspace-live.js.map +1 -0
- package/dist/scripts/lib/workspace.js +406 -0
- package/dist/scripts/lib/workspace.js.map +1 -0
- package/dist/scripts/migrate.js +10 -0
- package/dist/scripts/migrate.js.map +1 -0
- package/dist/scripts/schema/registry.js +12 -0
- package/dist/scripts/schema/registry.js.map +1 -1
- package/dist/scripts/workspace.js +10 -0
- package/dist/scripts/workspace.js.map +1 -0
- package/package.json +1 -1
package/dist/scripts/alm/cli.js
CHANGED
|
@@ -10,6 +10,8 @@
|
|
|
10
10
|
* specgate alm link <REQ-id> <issue-key> [--project-dir <dir>]
|
|
11
11
|
* specgate alm status [--project-dir <dir>]
|
|
12
12
|
* specgate alm pr <change> [--no-push] [--no-check] [--project-dir <dir>]
|
|
13
|
+
* specgate alm phase <change> [--project-dir <dir>] [--json]
|
|
14
|
+
* specgate alm move <change> [<phase>] [--project-dir <dir>] [--json]
|
|
13
15
|
*/
|
|
14
16
|
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
15
17
|
if (k2 === undefined) k2 = k;
|
|
@@ -51,6 +53,8 @@ const clients_1 = require("./clients");
|
|
|
51
53
|
const diagnostics_1 = require("../lib/diagnostics");
|
|
52
54
|
const PullCommand_1 = require("../cli/commands/alm/PullCommand");
|
|
53
55
|
const PrCommand_1 = require("../cli/commands/alm/PrCommand");
|
|
56
|
+
const PhaseCommand_1 = require("../cli/commands/alm/PhaseCommand");
|
|
57
|
+
const phases_1 = require("./phases");
|
|
54
58
|
const ui = __importStar(require("../lib/ui"));
|
|
55
59
|
function logInfo(msg) {
|
|
56
60
|
process.stdout.write(ui.logLine(msg));
|
|
@@ -67,9 +71,16 @@ function usage() {
|
|
|
67
71
|
" specgate alm link <REQ-id> <issue-key> [--project-dir <dir>]\n" +
|
|
68
72
|
" specgate alm status [--project-dir <dir>]\n" +
|
|
69
73
|
" specgate alm pull [--label <name>] [--project-dir <dir>] [--dry-run]\n" +
|
|
70
|
-
" specgate alm pr <change> [--no-push] [--no-check] [--project-dir <dir>]\n
|
|
74
|
+
" specgate alm pr <change> [--no-push] [--no-check] [--project-dir <dir>]\n" +
|
|
75
|
+
" specgate alm phase <change> [--project-dir <dir>] [--json]\n" +
|
|
76
|
+
" specgate alm move <change> [<phase>] [--project-dir <dir>] [--json]\n\n" +
|
|
71
77
|
"sync Creates an ALM issue for every unlinked REQ, closes issues whose REQ\n" +
|
|
72
78
|
" is Implemented, and reports drift (issue done, REQ still open).\n" +
|
|
79
|
+
" Moves each change's ticket to its phase (proposed, building, archived)\n" +
|
|
80
|
+
" and creates a sub-issue per repository it names. `mirror: false` in\n" +
|
|
81
|
+
" alm.config.yaml skips the issue per REQ when tickets are the source.\n" +
|
|
82
|
+
"phase Where a change stands and what the board was told. No network.\n" +
|
|
83
|
+
"move Move a change's ticket to its phase now, or to the phase named.\n" +
|
|
73
84
|
"link Manually map an existing issue to a requirement.\n" +
|
|
74
85
|
"status Print the current REQ ↔ issue mapping without network access.\n" +
|
|
75
86
|
"pull Open a change per labelled issue, from its title and description;\n" +
|
|
@@ -150,8 +161,30 @@ async function main() {
|
|
|
150
161
|
(0, diagnostics_1.printDiagnostics)(configFindings, process.stdout);
|
|
151
162
|
const client = (0, clients_1.makeClient)(cfg, undefined, projectDir);
|
|
152
163
|
const map = (0, core_1.readAlmMap)(projectDir);
|
|
153
|
-
|
|
164
|
+
// `mirror: false`: the tickets are the source, so no issue per requirement.
|
|
165
|
+
const mirror = cfg.mirror !== false && String(cfg.mirror) !== "false";
|
|
166
|
+
const reqs = mirror ? (0, core_1.extractRequirements)(projectDir) : [];
|
|
154
167
|
const actions = await (0, core_1.syncRequirements)(reqs, map, client, { dryRun: opts.dryRun });
|
|
168
|
+
// REQ-305, REQ-307: the board follows each change with a ticket.
|
|
169
|
+
const changes = (0, phases_1.boardChanges)(projectDir);
|
|
170
|
+
const phases = (0, phases_1.readPhaseMap)(projectDir);
|
|
171
|
+
const moves = await (0, phases_1.syncPhases)(changes, phases, client, cfg, { dryRun: opts.dryRun });
|
|
172
|
+
const children = await (0, phases_1.syncSubIssues)(changes, phases, client, { dryRun: opts.dryRun });
|
|
173
|
+
(0, phases_1.writePhaseMap)(projectDir, phases, opts.dryRun);
|
|
174
|
+
for (const m of moves) {
|
|
175
|
+
if (m.action === "in-sync")
|
|
176
|
+
continue;
|
|
177
|
+
if (m.action === "phase-unsupported")
|
|
178
|
+
logWarn(`${m.change}: ${m.detail}`);
|
|
179
|
+
else
|
|
180
|
+
logInfo(`${m.action} ${m.change} ${m.issue} → ${m.state}`);
|
|
181
|
+
}
|
|
182
|
+
for (const c of children) {
|
|
183
|
+
if (c.detail)
|
|
184
|
+
logWarn(`${c.change}: ${c.detail}`);
|
|
185
|
+
else
|
|
186
|
+
logInfo(`${c.action} sub-issue ${c.change} ${c.repo}${c.issue ? ` → ${c.issue}` : ""}`);
|
|
187
|
+
}
|
|
155
188
|
let drift = 0;
|
|
156
189
|
for (const a of actions) {
|
|
157
190
|
if (a.action === "drift") {
|
|
@@ -162,7 +195,7 @@ async function main() {
|
|
|
162
195
|
logInfo(`${a.action} ${a.req}${a.issue ? ` → ${a.issue}` : ""}`);
|
|
163
196
|
}
|
|
164
197
|
}
|
|
165
|
-
if (!opts.dryRun)
|
|
198
|
+
if (!opts.dryRun && mirror)
|
|
166
199
|
(0, core_1.writeAlmMap)(projectDir, map, false);
|
|
167
200
|
const summary = actions.reduce((acc, a) => {
|
|
168
201
|
acc[a.action] = (acc[a.action] || 0) + 1;
|
|
@@ -186,6 +219,14 @@ async function main() {
|
|
|
186
219
|
await (0, PrCommand_1.main)(argv.slice(1));
|
|
187
220
|
return;
|
|
188
221
|
}
|
|
222
|
+
if (sub === "phase") {
|
|
223
|
+
await (0, PhaseCommand_1.phaseMain)(argv.slice(1));
|
|
224
|
+
return;
|
|
225
|
+
}
|
|
226
|
+
if (sub === "move") {
|
|
227
|
+
await (0, PhaseCommand_1.moveMain)(argv.slice(1));
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
189
230
|
if (sub === "pull") {
|
|
190
231
|
// Implemented outside `scripts/alm/` on purpose: ADR-0021 forbids this
|
|
191
232
|
// subsystem from writing the spec tree, and a pull has to produce files.
|
|
@@ -193,7 +234,7 @@ async function main() {
|
|
|
193
234
|
await (0, PullCommand_1.main)(argv.slice(1));
|
|
194
235
|
return;
|
|
195
236
|
}
|
|
196
|
-
logError(`Unknown alm sub-command: ${sub || "(none)"}. Expected: sync, link, status, pull, pr`);
|
|
237
|
+
logError(`Unknown alm sub-command: ${sub || "(none)"}. Expected: sync, link, status, pull, pr, phase, move`);
|
|
197
238
|
usage();
|
|
198
239
|
process.exit(2);
|
|
199
240
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../../scripts/alm/cli.ts"],"names":[],"mappings":";;AACA
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../../../scripts/alm/cli.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.githubClient = exports.azureClient = exports.jiraClient = void 0;
|
|
3
|
+
exports.linearClient = exports.githubClient = exports.azureClient = exports.jiraClient = void 0;
|
|
4
4
|
exports.makeClient = makeClient;
|
|
5
5
|
const providers_1 = require("./providers");
|
|
6
6
|
/**
|
|
@@ -27,4 +27,6 @@ const azureClient = (cfg, fetchImpl) => (0, providers_1.getProvider)("azure").cr
|
|
|
27
27
|
exports.azureClient = azureClient;
|
|
28
28
|
const githubClient = (cfg, fetchImpl) => (0, providers_1.getProvider)("github").create(cfg, fetchImpl);
|
|
29
29
|
exports.githubClient = githubClient;
|
|
30
|
+
const linearClient = (cfg, fetchImpl) => (0, providers_1.getProvider)("linear").create(cfg, fetchImpl);
|
|
31
|
+
exports.linearClient = linearClient;
|
|
30
32
|
//# sourceMappingURL=clients.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"clients.js","sourceRoot":"","sources":["../../../scripts/alm/clients.ts"],"names":[],"mappings":";;;AAeA,gCAEC;AAjBD,2CAA0C;AAG1C;;;;;;;;;;;GAWG;AACH,SAAgB,UAAU,CAAC,GAAc,EAAE,SAAqB,EAAE,UAAmB;IACnF,OAAO,IAAA,uBAAW,EAAC,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;AACtE,CAAC;AAED,6EAA6E;AAC7E,4EAA4E;AAC5E,oCAAoC;AAC7B,MAAM,UAAU,GAAG,CAAC,GAAc,EAAE,SAAqB,EAAa,EAAE,CAC7E,IAAA,uBAAW,EAAC,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;AADhC,QAAA,UAAU,cACsB;AAEtC,MAAM,WAAW,GAAG,CAAC,GAAc,EAAE,SAAqB,EAAa,EAAE,CAC9E,IAAA,uBAAW,EAAC,OAAO,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;AADjC,QAAA,WAAW,eACsB;AAEvC,MAAM,YAAY,GAAG,CAAC,GAAc,EAAE,SAAqB,EAAa,EAAE,CAC/E,IAAA,uBAAW,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;AADlC,QAAA,YAAY,gBACsB"}
|
|
1
|
+
{"version":3,"file":"clients.js","sourceRoot":"","sources":["../../../scripts/alm/clients.ts"],"names":[],"mappings":";;;AAeA,gCAEC;AAjBD,2CAA0C;AAG1C;;;;;;;;;;;GAWG;AACH,SAAgB,UAAU,CAAC,GAAc,EAAE,SAAqB,EAAE,UAAmB;IACnF,OAAO,IAAA,uBAAW,EAAC,GAAG,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;AACtE,CAAC;AAED,6EAA6E;AAC7E,4EAA4E;AAC5E,oCAAoC;AAC7B,MAAM,UAAU,GAAG,CAAC,GAAc,EAAE,SAAqB,EAAa,EAAE,CAC7E,IAAA,uBAAW,EAAC,MAAM,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;AADhC,QAAA,UAAU,cACsB;AAEtC,MAAM,WAAW,GAAG,CAAC,GAAc,EAAE,SAAqB,EAAa,EAAE,CAC9E,IAAA,uBAAW,EAAC,OAAO,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;AADjC,QAAA,WAAW,eACsB;AAEvC,MAAM,YAAY,GAAG,CAAC,GAAc,EAAE,SAAqB,EAAa,EAAE,CAC/E,IAAA,uBAAW,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;AADlC,QAAA,YAAY,gBACsB;AAExC,MAAM,YAAY,GAAG,CAAC,GAAc,EAAE,SAAqB,EAAa,EAAE,CAC/E,IAAA,uBAAW,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,GAAG,EAAE,SAAS,CAAC,CAAC;AADlC,QAAA,YAAY,gBACsB"}
|
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* The board follows the change (REQ-305, REQ-307).
|
|
4
|
+
*
|
|
5
|
+
* A change's phase is read from the repository, never from the board: open
|
|
6
|
+
* and not yet built, one of its requirements being built, or archived. The
|
|
7
|
+
* board is told; it is never asked what the change is (ADR-0021). What the
|
|
8
|
+
* sync has told the board is kept in `.specops/alm-phases.json`, beside the
|
|
9
|
+
* REQ ↔ issue mapping, so a move already made is not made again and a
|
|
10
|
+
* sub-issue is never created twice.
|
|
11
|
+
*/
|
|
12
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
13
|
+
if (k2 === undefined) k2 = k;
|
|
14
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
15
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
16
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
17
|
+
}
|
|
18
|
+
Object.defineProperty(o, k2, desc);
|
|
19
|
+
}) : (function(o, m, k, k2) {
|
|
20
|
+
if (k2 === undefined) k2 = k;
|
|
21
|
+
o[k2] = m[k];
|
|
22
|
+
}));
|
|
23
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
24
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
25
|
+
}) : function(o, v) {
|
|
26
|
+
o["default"] = v;
|
|
27
|
+
});
|
|
28
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
29
|
+
var ownKeys = function(o) {
|
|
30
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
31
|
+
var ar = [];
|
|
32
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
33
|
+
return ar;
|
|
34
|
+
};
|
|
35
|
+
return ownKeys(o);
|
|
36
|
+
};
|
|
37
|
+
return function (mod) {
|
|
38
|
+
if (mod && mod.__esModule) return mod;
|
|
39
|
+
var result = {};
|
|
40
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
41
|
+
__setModuleDefault(result, mod);
|
|
42
|
+
return result;
|
|
43
|
+
};
|
|
44
|
+
})();
|
|
45
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
46
|
+
exports.PHASES_RELPATH = void 0;
|
|
47
|
+
exports.readPhaseMap = readPhaseMap;
|
|
48
|
+
exports.writePhaseMap = writePhaseMap;
|
|
49
|
+
exports.changeTicket = changeTicket;
|
|
50
|
+
exports.boardChanges = boardChanges;
|
|
51
|
+
exports.namedState = namedState;
|
|
52
|
+
exports.movePhase = movePhase;
|
|
53
|
+
exports.syncPhases = syncPhases;
|
|
54
|
+
exports.syncSubIssues = syncSubIssues;
|
|
55
|
+
const fs = __importStar(require("node:fs"));
|
|
56
|
+
const path = __importStar(require("node:path"));
|
|
57
|
+
const node_child_process_1 = require("node:child_process");
|
|
58
|
+
const YamlLite_1 = require("../../packages/core/src/domain/YamlLite");
|
|
59
|
+
exports.PHASES_RELPATH = path.join(".specops", "alm-phases.json");
|
|
60
|
+
const CHANGES = path.join("docs", "specs", "changes");
|
|
61
|
+
// ── The map ───────────────────────────────────────────────────────────────────
|
|
62
|
+
function readPhaseMap(projectDir) {
|
|
63
|
+
const mapPath = path.join(projectDir, exports.PHASES_RELPATH);
|
|
64
|
+
if (!fs.existsSync(mapPath))
|
|
65
|
+
return {};
|
|
66
|
+
return JSON.parse(fs.readFileSync(mapPath, "utf8"));
|
|
67
|
+
}
|
|
68
|
+
function writePhaseMap(projectDir, map, dryRun) {
|
|
69
|
+
const mapPath = path.join(projectDir, exports.PHASES_RELPATH);
|
|
70
|
+
if (dryRun)
|
|
71
|
+
return mapPath;
|
|
72
|
+
fs.mkdirSync(path.dirname(mapPath), { recursive: true });
|
|
73
|
+
fs.writeFileSync(mapPath, `${JSON.stringify(map, null, 2)}\n`, "utf8");
|
|
74
|
+
return mapPath;
|
|
75
|
+
}
|
|
76
|
+
// ── Changes and their phase ───────────────────────────────────────────────────
|
|
77
|
+
/** The ticket a change carries: `ticket:`, or the issue `alm pull` opened it from. */
|
|
78
|
+
function changeTicket(yaml) {
|
|
79
|
+
const ticket = typeof yaml.ticket === "string" ? yaml.ticket.trim() : "";
|
|
80
|
+
if (ticket)
|
|
81
|
+
return ticket;
|
|
82
|
+
const origin = typeof yaml.origin === "string" ? /^alm:(\S+)$/.exec(yaml.origin.trim()) : null;
|
|
83
|
+
return origin ? origin[1] : null;
|
|
84
|
+
}
|
|
85
|
+
function readYaml(file) {
|
|
86
|
+
if (!fs.existsSync(file))
|
|
87
|
+
return {};
|
|
88
|
+
return ((0, YamlLite_1.parseYamlLite)(fs.readFileSync(file, "utf8")) || {});
|
|
89
|
+
}
|
|
90
|
+
function deltaRequirements(changeDir) {
|
|
91
|
+
const found = new Set();
|
|
92
|
+
const walk = (dir) => {
|
|
93
|
+
if (!fs.existsSync(dir))
|
|
94
|
+
return;
|
|
95
|
+
for (const e of fs.readdirSync(dir, { withFileTypes: true })) {
|
|
96
|
+
const full = path.join(dir, e.name);
|
|
97
|
+
if (e.isDirectory())
|
|
98
|
+
walk(full);
|
|
99
|
+
else if (e.name === "spec.md") {
|
|
100
|
+
for (const m of fs
|
|
101
|
+
.readFileSync(full, "utf8")
|
|
102
|
+
.matchAll(/^###\s+Requirement:\s+(REQ-\d+)/gm)) {
|
|
103
|
+
found.add(m[1]);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
walk(path.join(changeDir, "specs"));
|
|
109
|
+
return [...found];
|
|
110
|
+
}
|
|
111
|
+
/** The local `harness/REQ-NNN` branches: a requirement the harness has started. */
|
|
112
|
+
function harnessBranches(projectDir) {
|
|
113
|
+
const r = (0, node_child_process_1.spawnSync)("git", ["branch", "--list", "harness/REQ-*", "--format=%(refname:short)"], {
|
|
114
|
+
cwd: projectDir,
|
|
115
|
+
encoding: "utf8",
|
|
116
|
+
});
|
|
117
|
+
if (r.status !== 0)
|
|
118
|
+
return new Set();
|
|
119
|
+
return new Set(r.stdout
|
|
120
|
+
.split("\n")
|
|
121
|
+
.map((l) => l.trim().replace(/^harness\//, ""))
|
|
122
|
+
.filter(Boolean));
|
|
123
|
+
}
|
|
124
|
+
/** Requirements the matrix says are delivered. */
|
|
125
|
+
function implementedRequirements(projectDir) {
|
|
126
|
+
const file = path.join(projectDir, "docs", "specs", "traceability.md");
|
|
127
|
+
const done = new Set();
|
|
128
|
+
if (!fs.existsSync(file))
|
|
129
|
+
return done;
|
|
130
|
+
for (const line of fs.readFileSync(file, "utf8").split("\n")) {
|
|
131
|
+
const cells = line.split("|").map((c) => c.trim());
|
|
132
|
+
const req = cells.find((c) => /^REQ-\d+$/.test(c));
|
|
133
|
+
if (req && /^(Implemented|Verified|Released)$/.test(cells[cells.length - 2] || "")) {
|
|
134
|
+
done.add(req);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
return done;
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Every change, open or archived, with its phase. An archived change keeps its
|
|
141
|
+
* id after the date prefix the archive gives it (`2026-10-29-alerts`).
|
|
142
|
+
*/
|
|
143
|
+
function boardChanges(projectDir) {
|
|
144
|
+
const root = path.join(projectDir, CHANGES);
|
|
145
|
+
if (!fs.existsSync(root))
|
|
146
|
+
return [];
|
|
147
|
+
const branches = harnessBranches(projectDir);
|
|
148
|
+
const implemented = implementedRequirements(projectDir);
|
|
149
|
+
const out = [];
|
|
150
|
+
const add = (dir, id, archived) => {
|
|
151
|
+
const yaml = readYaml(path.join(dir, "change.yaml"));
|
|
152
|
+
const requirements = deltaRequirements(dir);
|
|
153
|
+
const building = requirements.some((r) => branches.has(r) || implemented.has(r));
|
|
154
|
+
const repositories = Array.isArray(yaml.repositories)
|
|
155
|
+
? yaml.repositories.map(String).filter(Boolean)
|
|
156
|
+
: [];
|
|
157
|
+
out.push({
|
|
158
|
+
id,
|
|
159
|
+
dir,
|
|
160
|
+
archived,
|
|
161
|
+
ticket: changeTicket(yaml),
|
|
162
|
+
repositories,
|
|
163
|
+
requirements,
|
|
164
|
+
phase: archived ? "archived" : building ? "building" : "proposed",
|
|
165
|
+
});
|
|
166
|
+
};
|
|
167
|
+
for (const e of fs.readdirSync(root, { withFileTypes: true })) {
|
|
168
|
+
if (!e.isDirectory() || e.name.startsWith("."))
|
|
169
|
+
continue;
|
|
170
|
+
if (e.name === "archive") {
|
|
171
|
+
const archive = path.join(root, "archive");
|
|
172
|
+
for (const a of fs.readdirSync(archive, { withFileTypes: true })) {
|
|
173
|
+
if (!a.isDirectory())
|
|
174
|
+
continue;
|
|
175
|
+
add(path.join(archive, a.name), a.name.replace(/^\d{4}-\d{2}-\d{2}-/, ""), true);
|
|
176
|
+
}
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
add(path.join(root, e.name), e.name, false);
|
|
180
|
+
}
|
|
181
|
+
return out;
|
|
182
|
+
}
|
|
183
|
+
// ── Moving the board ──────────────────────────────────────────────────────────
|
|
184
|
+
/** The state `phases:` names for a phase, or undefined for the provider's default. */
|
|
185
|
+
function namedState(cfg, phase) {
|
|
186
|
+
const phases = cfg.phases;
|
|
187
|
+
if (!phases || typeof phases !== "object")
|
|
188
|
+
return undefined;
|
|
189
|
+
const value = phases[phase];
|
|
190
|
+
return typeof value === "string" && value.trim() ? value.trim() : undefined;
|
|
191
|
+
}
|
|
192
|
+
/** Move one change's ticket to its phase, unless the board was already told. */
|
|
193
|
+
async function movePhase(change, map, client, cfg, opts = {}) {
|
|
194
|
+
const phase = opts.phase ?? change.phase;
|
|
195
|
+
const record = (map[change.id] ??= { ticket: change.ticket });
|
|
196
|
+
record.ticket = change.ticket;
|
|
197
|
+
const named = namedState(cfg, phase);
|
|
198
|
+
if (!opts.force && record.phase === phase) {
|
|
199
|
+
return {
|
|
200
|
+
change: change.id,
|
|
201
|
+
action: "in-sync",
|
|
202
|
+
issue: change.ticket,
|
|
203
|
+
phase,
|
|
204
|
+
state: record.state,
|
|
205
|
+
};
|
|
206
|
+
}
|
|
207
|
+
if (!client.capabilities.phase || typeof client.setPhase !== "function") {
|
|
208
|
+
return {
|
|
209
|
+
change: change.id,
|
|
210
|
+
action: "phase-unsupported",
|
|
211
|
+
issue: change.ticket,
|
|
212
|
+
phase,
|
|
213
|
+
detail: `${change.ticket} should be ${phase}, but provider '${cfg.provider}' cannot move an issue — move it by hand.`,
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
if (opts.dryRun) {
|
|
217
|
+
return {
|
|
218
|
+
change: change.id,
|
|
219
|
+
action: "would-move",
|
|
220
|
+
issue: change.ticket,
|
|
221
|
+
phase,
|
|
222
|
+
state: named ?? `the ${phase} state`,
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
const state = await client.setPhase(change.ticket, phase, named);
|
|
226
|
+
record.phase = phase;
|
|
227
|
+
record.state = state;
|
|
228
|
+
return { change: change.id, action: "moved", issue: change.ticket, phase, state };
|
|
229
|
+
}
|
|
230
|
+
/** REQ-305: every change with a ticket, moved to its phase. */
|
|
231
|
+
async function syncPhases(changes, map, client, cfg, opts = {}) {
|
|
232
|
+
const actions = [];
|
|
233
|
+
for (const change of changes) {
|
|
234
|
+
if (!change.ticket)
|
|
235
|
+
continue;
|
|
236
|
+
actions.push(await movePhase({ ...change, ticket: change.ticket }, map, client, cfg, opts));
|
|
237
|
+
}
|
|
238
|
+
return actions;
|
|
239
|
+
}
|
|
240
|
+
/** REQ-307: one sub-issue per repository a change names, created once. */
|
|
241
|
+
async function syncSubIssues(changes, map, client, opts = {}) {
|
|
242
|
+
const actions = [];
|
|
243
|
+
for (const change of changes) {
|
|
244
|
+
if (change.archived || change.repositories.length === 0)
|
|
245
|
+
continue;
|
|
246
|
+
if (!change.ticket) {
|
|
247
|
+
actions.push({
|
|
248
|
+
change: change.id,
|
|
249
|
+
action: "no-ticket",
|
|
250
|
+
detail: `${change.id} names repositories but no ticket to hang their sub-issues on — add ticket: <KEY> to its change.yaml.`,
|
|
251
|
+
});
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
const record = (map[change.id] ??= { ticket: change.ticket });
|
|
255
|
+
const children = (record.children ??= {});
|
|
256
|
+
for (const repo of change.repositories) {
|
|
257
|
+
if (children[repo])
|
|
258
|
+
continue;
|
|
259
|
+
if (!client.capabilities.subIssues || typeof client.createSubIssue !== "function") {
|
|
260
|
+
actions.push({
|
|
261
|
+
change: change.id,
|
|
262
|
+
action: "sub-issues-unsupported",
|
|
263
|
+
repo,
|
|
264
|
+
detail: `${change.ticket} needs a sub-issue for ${repo}, but this provider cannot create one — create it by hand.`,
|
|
265
|
+
});
|
|
266
|
+
continue;
|
|
267
|
+
}
|
|
268
|
+
if (opts.dryRun) {
|
|
269
|
+
actions.push({ change: change.id, action: "would-create", repo });
|
|
270
|
+
continue;
|
|
271
|
+
}
|
|
272
|
+
const created = await client.createSubIssue(change.ticket, `${change.ticket} — ${repo}: ${change.id}`);
|
|
273
|
+
children[repo] = created.key;
|
|
274
|
+
actions.push({ change: change.id, action: "created", repo, issue: created.key });
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
return actions;
|
|
278
|
+
}
|
|
279
|
+
//# sourceMappingURL=phases.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phases.js","sourceRoot":"","sources":["../../../scripts/alm/phases.ts"],"names":[],"mappings":"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"}
|
package/dist/scripts/alm/port.js
CHANGED
|
@@ -33,24 +33,46 @@
|
|
|
33
33
|
* implementation and its declaration disagree.
|
|
34
34
|
*/
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.CORE_CONFIG_KEYS = exports.CAPABILITY_METHOD = exports.CAPABILITIES = void 0;
|
|
36
|
+
exports.CORE_CONFIG_KEYS = exports.CAPABILITY_METHOD = exports.OPTIONAL_CAPABILITIES = exports.CAPABILITIES = exports.PHASES = void 0;
|
|
37
37
|
exports.checkProviderDeclaration = checkProviderDeclaration;
|
|
38
|
-
|
|
38
|
+
exports.PHASES = ["proposed", "building", "archived"];
|
|
39
|
+
/** Every capability a provider must declare, for the checks that iterate them. */
|
|
39
40
|
exports.CAPABILITIES = [
|
|
40
41
|
"create",
|
|
41
42
|
"readStatus",
|
|
42
43
|
"close",
|
|
43
44
|
"listIssues",
|
|
44
45
|
];
|
|
46
|
+
/** The capabilities a provider may declare (REQ-305..307). */
|
|
47
|
+
exports.OPTIONAL_CAPABILITIES = [
|
|
48
|
+
"phase",
|
|
49
|
+
"subIssues",
|
|
50
|
+
"comments",
|
|
51
|
+
"readText",
|
|
52
|
+
];
|
|
45
53
|
/** The client method each capability promises. */
|
|
46
54
|
exports.CAPABILITY_METHOD = {
|
|
47
55
|
create: "createIssue",
|
|
48
56
|
readStatus: "getIssueStatus",
|
|
49
57
|
close: "closeIssue",
|
|
50
58
|
listIssues: "listIssues",
|
|
59
|
+
phase: "setPhase",
|
|
60
|
+
subIssues: "createSubIssue",
|
|
61
|
+
comments: "listComments",
|
|
62
|
+
readText: "readIssueText",
|
|
51
63
|
};
|
|
52
|
-
/**
|
|
53
|
-
|
|
64
|
+
/**
|
|
65
|
+
* Config keys the core itself reads, whatever the provider. `phases` names the
|
|
66
|
+
* board state of each phase (REQ-305); `mirror: false` keeps `alm sync` from
|
|
67
|
+
* creating an issue per requirement on a project whose tickets are the source.
|
|
68
|
+
*/
|
|
69
|
+
exports.CORE_CONFIG_KEYS = [
|
|
70
|
+
"alm_version",
|
|
71
|
+
"provider",
|
|
72
|
+
"pr",
|
|
73
|
+
"phases",
|
|
74
|
+
"mirror",
|
|
75
|
+
];
|
|
54
76
|
/**
|
|
55
77
|
* Check a provider declaration is well formed.
|
|
56
78
|
*
|
|
@@ -107,7 +129,13 @@ function checkCapabilities(candidate) {
|
|
|
107
129
|
problems.push(`${label}: capability '${capability}' is not declared as a boolean`);
|
|
108
130
|
}
|
|
109
131
|
}
|
|
110
|
-
const
|
|
132
|
+
for (const capability of exports.OPTIONAL_CAPABILITIES) {
|
|
133
|
+
if (capability in caps && typeof caps[capability] !== "boolean") {
|
|
134
|
+
problems.push(`${label}: capability '${capability}' is not declared as a boolean`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
const known = [...exports.CAPABILITIES, ...exports.OPTIONAL_CAPABILITIES];
|
|
138
|
+
const extra = Object.keys(caps).filter((name) => !known.includes(name));
|
|
111
139
|
if (extra.length > 0) {
|
|
112
140
|
problems.push(`${label}: declares unknown capabilit(y/ies): ${extra.join(", ")}`);
|
|
113
141
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"port.js","sourceRoot":"","sources":["../../../scripts/alm/port.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;;;
|
|
1
|
+
{"version":3,"file":"port.js","sourceRoot":"","sources":["../../../scripts/alm/port.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,16 +13,7 @@ const API_VERSION = "api-version=7.1";
|
|
|
13
13
|
* which is why this provider, and only this one, declares `done_state`.
|
|
14
14
|
*/
|
|
15
15
|
class AzureClient extends http_client_1.HttpAlmClient {
|
|
16
|
-
capabilities =
|
|
17
|
-
create: true,
|
|
18
|
-
readStatus: true,
|
|
19
|
-
close: true,
|
|
20
|
-
// Azure searches with WIQL — a POST carrying a query language, then a
|
|
21
|
-
// second request to hydrate each id. That is a different shape from the
|
|
22
|
-
// other two, and declaring `false` degrades `alm pull` with a message
|
|
23
|
-
// rather than pretending and failing at the first request.
|
|
24
|
-
listIssues: false,
|
|
25
|
-
};
|
|
16
|
+
capabilities = AZURE_CAPABILITIES;
|
|
26
17
|
authorization;
|
|
27
18
|
projectKey;
|
|
28
19
|
issueType;
|
|
@@ -57,6 +48,55 @@ class AzureClient extends http_client_1.HttpAlmClient {
|
|
|
57
48
|
const state = item.fields?.["System.State"];
|
|
58
49
|
return state !== undefined && DONE_STATES.includes(state) ? "done" : "open";
|
|
59
50
|
}
|
|
51
|
+
/**
|
|
52
|
+
* REQ-305: Azure Boards' default process states — New, Active, and the
|
|
53
|
+
* configured done state — unless `phases:` names the project's own.
|
|
54
|
+
*/
|
|
55
|
+
async setPhase(issueKey, phase, state) {
|
|
56
|
+
const target = state ?? (phase === "proposed" ? "New" : phase === "building" ? "Active" : this.doneState);
|
|
57
|
+
await this.request(`/_apis/wit/workitems/${workItemId(issueKey)}?${API_VERSION}`, `Azure move work item ${issueKey} to ${target}`, {
|
|
58
|
+
method: "PATCH",
|
|
59
|
+
headers: this.patchHeaders(),
|
|
60
|
+
body: JSON.stringify([{ op: "add", path: "/fields/System.State", value: target }]),
|
|
61
|
+
});
|
|
62
|
+
return target;
|
|
63
|
+
}
|
|
64
|
+
/** REQ-307: a child work item, linked to its parent by the hierarchy relation. */
|
|
65
|
+
async createSubIssue(parentKey, title) {
|
|
66
|
+
const created = await this.requestJson(`/${this.projectKey}/_apis/wit/workitems/$${encodeURIComponent(this.issueType)}?${API_VERSION}`, `Azure create child of work item ${parentKey}`, {
|
|
67
|
+
method: "POST",
|
|
68
|
+
headers: this.patchHeaders(),
|
|
69
|
+
body: JSON.stringify([
|
|
70
|
+
{ op: "add", path: "/fields/System.Title", value: title },
|
|
71
|
+
{ op: "add", path: "/fields/System.Tags", value: "spec-driven" },
|
|
72
|
+
{
|
|
73
|
+
op: "add",
|
|
74
|
+
path: "/relations/-",
|
|
75
|
+
value: {
|
|
76
|
+
rel: "System.LinkTypes.Hierarchy-Reverse",
|
|
77
|
+
url: `${this.baseUrl}/_apis/wit/workItems/${workItemId(parentKey)}`,
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
]),
|
|
81
|
+
});
|
|
82
|
+
return { key: String(created.id), url: created._links?.html?.href ?? null };
|
|
83
|
+
}
|
|
84
|
+
/** REQ-306: the work item's title and description, its HTML flattened. */
|
|
85
|
+
async readIssueText(issueKey) {
|
|
86
|
+
const item = await this.requestJson(`/_apis/wit/workitems/${workItemId(issueKey)}?fields=System.Title,System.Description&${API_VERSION}`, `Azure read work item ${issueKey}`, { headers: { Authorization: this.authorization } });
|
|
87
|
+
const html = String(item.fields?.["System.Description"] ?? "");
|
|
88
|
+
return {
|
|
89
|
+
title: String(item.fields?.["System.Title"] ?? ""),
|
|
90
|
+
body: html
|
|
91
|
+
.replace(/<br\s*\/?>|<\/(?:p|div|li)>/gi, "\n")
|
|
92
|
+
.replace(/<[^>]+>/g, "")
|
|
93
|
+
.replace(/ /g, " ")
|
|
94
|
+
.replace(/&/g, "&")
|
|
95
|
+
.replace(/</g, "<")
|
|
96
|
+
.replace(/>/g, ">")
|
|
97
|
+
.trim(),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
60
100
|
async closeIssue(issueKey) {
|
|
61
101
|
await this.request(`/_apis/wit/workitems/${issueKey}?${API_VERSION}`, `Azure close work item ${issueKey}`, {
|
|
62
102
|
method: "PATCH",
|
|
@@ -65,6 +105,27 @@ class AzureClient extends http_client_1.HttpAlmClient {
|
|
|
65
105
|
});
|
|
66
106
|
}
|
|
67
107
|
}
|
|
108
|
+
/** A work item id as a path segment: digits, nothing a path could be walked with. */
|
|
109
|
+
function workItemId(key) {
|
|
110
|
+
if (!/^\d+$/.test(key))
|
|
111
|
+
throw new Error(`Azure: '${key}' is not a work item id.`);
|
|
112
|
+
return key;
|
|
113
|
+
}
|
|
114
|
+
/** Comments are a preview API on Azure Boards: not read, and `alm pull` says so. */
|
|
115
|
+
const AZURE_CAPABILITIES = {
|
|
116
|
+
create: true,
|
|
117
|
+
readStatus: true,
|
|
118
|
+
close: true,
|
|
119
|
+
// Azure searches with WIQL — a POST carrying a query language, then a
|
|
120
|
+
// second request to hydrate each id. That is a different shape from the
|
|
121
|
+
// other two, and declaring `false` degrades `alm pull` with a message
|
|
122
|
+
// rather than pretending and failing at the first request.
|
|
123
|
+
listIssues: false,
|
|
124
|
+
phase: true,
|
|
125
|
+
subIssues: true,
|
|
126
|
+
comments: false,
|
|
127
|
+
readText: true,
|
|
128
|
+
};
|
|
68
129
|
exports.azureProvider = {
|
|
69
130
|
id: "azure",
|
|
70
131
|
label: "Azure Boards",
|
|
@@ -72,7 +133,7 @@ exports.azureProvider = {
|
|
|
72
133
|
required: ["base_url", "project_key", "token_env"],
|
|
73
134
|
optional: ["issue_type", "done_state"],
|
|
74
135
|
},
|
|
75
|
-
capabilities:
|
|
136
|
+
capabilities: AZURE_CAPABILITIES,
|
|
76
137
|
create: (cfg, fetchImpl) => new AzureClient(cfg, fetchImpl),
|
|
77
138
|
};
|
|
78
139
|
exports.default = exports.azureProvider;
|