azdo-cli 0.2.0-develop.137 → 0.2.0-develop.141
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 +18 -7
- package/dist/index.js +27 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -12,7 +12,7 @@ Azure DevOps CLI focused on work item read/write workflows.
|
|
|
12
12
|
- Update work item state (`set-state`)
|
|
13
13
|
- Assign and unassign work items (`assign`)
|
|
14
14
|
- Set any work item field by reference name (`set-field`)
|
|
15
|
-
- Create or update
|
|
15
|
+
- Create or update work items from markdown documents (`upsert`)
|
|
16
16
|
- Read rich-text fields as markdown (`get-md-field`)
|
|
17
17
|
- Set rich-text fields as markdown from inline text, file, or stdin (`set-md-field`)
|
|
18
18
|
- Check branch pull request status, open PRs to `develop`, and review active comments (`pr`)
|
|
@@ -65,8 +65,8 @@ azdo get-item 12345
|
|
|
65
65
|
# 3) Update state
|
|
66
66
|
azdo set-state 12345 "Active"
|
|
67
67
|
|
|
68
|
-
# 4) Create or update a
|
|
69
|
-
azdo upsert --content $'---\nTitle: Improve markdown import UX\nState: New\n---'
|
|
68
|
+
# 4) Create or update a work item from markdown
|
|
69
|
+
azdo upsert --type "User Story" --content $'---\nTitle: Improve markdown import UX\nState: New\n---'
|
|
70
70
|
```
|
|
71
71
|
|
|
72
72
|
## Command Cheat Sheet
|
|
@@ -77,7 +77,7 @@ azdo upsert --content $'---\nTitle: Improve markdown import UX\nState: New\n---'
|
|
|
77
77
|
| `azdo set-state <id> <state>` | Change work item state | `--json`, `--org`, `--project` |
|
|
78
78
|
| `azdo assign <id> [name]` | Assign or unassign owner | `--unassign`, `--json`, `--org`, `--project` |
|
|
79
79
|
| `azdo set-field <id> <field> <value>` | Update any field | `--json`, `--org`, `--project` |
|
|
80
|
-
| `azdo upsert [id]` | Create or update a
|
|
80
|
+
| `azdo upsert [id]` | Create or update a work item from markdown | `--content`, `--file`, `--type`, `--json`, `--org`, `--project` |
|
|
81
81
|
| `azdo get-md-field <id> <field>` | Get field as markdown | `--org`, `--project` |
|
|
82
82
|
| `azdo set-md-field <id> <field> [content]` | Set markdown field | `--file`, `--json`, `--org`, `--project` |
|
|
83
83
|
| `azdo list-fields <id>` | List all fields of a work item | `--json`, `--org`, `--project` |
|
|
@@ -189,11 +189,14 @@ azdo pr comments
|
|
|
189
189
|
|
|
190
190
|
## azdo upsert
|
|
191
191
|
|
|
192
|
-
`azdo upsert` accepts a single markdown
|
|
192
|
+
`azdo upsert` accepts a single markdown work-item document and either creates a new Azure DevOps work item or updates an existing one. Omit `[id]` to create; pass `[id]` to update that work item in place. Create mode defaults to `Task`, and `--type <work item type>` lets you create `Bug`, `User Story`, `Feature`, `Epic`, and other Azure DevOps work item types.
|
|
193
193
|
|
|
194
194
|
```bash
|
|
195
|
-
# Create from inline content
|
|
196
|
-
azdo upsert --content $'---\nTitle: Improve markdown import UX\nAssigned To: user@example.com\nState: New\n---'
|
|
195
|
+
# Create a Bug from inline content
|
|
196
|
+
azdo upsert --type Bug --content $'---\nTitle: Improve markdown import UX\nAssigned To: user@example.com\nState: New\n---'
|
|
197
|
+
|
|
198
|
+
# Preserve the default Task create behavior
|
|
199
|
+
azdo upsert --content $'---\nTitle: Follow-up task\nAssigned To: user@example.com\nState: New\n---'
|
|
197
200
|
|
|
198
201
|
# Update from a file
|
|
199
202
|
azdo upsert 12345 --file ./task-import.md
|
|
@@ -206,9 +209,16 @@ The command requires exactly one source flag:
|
|
|
206
209
|
|
|
207
210
|
- `azdo upsert [id] --content <markdown>`
|
|
208
211
|
- `azdo upsert [id] --file <path>`
|
|
212
|
+
- `azdo upsert --type <work-item-type> --content <markdown>`
|
|
209
213
|
|
|
210
214
|
If `--file` succeeds, the source file is deleted after the Azure DevOps write completes. If parsing, validation, or the API call fails, the file is preserved. If deletion fails after a successful write, the command still succeeds and prints a warning.
|
|
211
215
|
|
|
216
|
+
Type rules:
|
|
217
|
+
|
|
218
|
+
- `--type` is optional for create and defaults to `Task`.
|
|
219
|
+
- `--type` is only valid when creating a new work item.
|
|
220
|
+
- Human-readable and JSON success output include the resulting work item type.
|
|
221
|
+
|
|
212
222
|
### Task Document Format
|
|
213
223
|
|
|
214
224
|
The document starts with YAML front matter for scalar fields, followed by optional `##` heading sections for markdown rich-text fields.
|
|
@@ -257,6 +267,7 @@ Clear semantics:
|
|
|
257
267
|
{
|
|
258
268
|
"action": "created",
|
|
259
269
|
"id": 12345,
|
|
270
|
+
"workItemType": "User Story",
|
|
260
271
|
"fields": {
|
|
261
272
|
"System.Title": "Improve markdown import UX",
|
|
262
273
|
"System.Description": "Implement a single-command task import flow."
|
package/dist/index.js
CHANGED
|
@@ -1391,7 +1391,7 @@ function buildAppliedFields(fields) {
|
|
|
1391
1391
|
function ensureTitleForCreate(fields) {
|
|
1392
1392
|
const titleField = fields.find((field) => field.refName === "System.Title");
|
|
1393
1393
|
if (!titleField || titleField.op === "clear" || titleField.value === null || titleField.value.trim() === "") {
|
|
1394
|
-
fail2("Title is required when creating a
|
|
1394
|
+
fail2("Title is required when creating a work item.");
|
|
1395
1395
|
}
|
|
1396
1396
|
}
|
|
1397
1397
|
function writeSuccess(result, options) {
|
|
@@ -1403,7 +1403,7 @@ function writeSuccess(result, options) {
|
|
|
1403
1403
|
const verb = result.action === "created" ? "Created" : "Updated";
|
|
1404
1404
|
const fields = Object.keys(result.fields).join(", ");
|
|
1405
1405
|
const suffix = fields ? ` (${fields})` : "";
|
|
1406
|
-
process.stdout.write(`${verb}
|
|
1406
|
+
process.stdout.write(`${verb} ${result.workItemType} #${result.id}${suffix}
|
|
1407
1407
|
`);
|
|
1408
1408
|
}
|
|
1409
1409
|
function cleanupSourceFile(sourceFile) {
|
|
@@ -1417,11 +1417,26 @@ function cleanupSourceFile(sourceFile) {
|
|
|
1417
1417
|
`);
|
|
1418
1418
|
}
|
|
1419
1419
|
}
|
|
1420
|
-
function
|
|
1420
|
+
function resolveCreateType(id, options) {
|
|
1421
|
+
if (options.type === void 0) {
|
|
1422
|
+
return "Task";
|
|
1423
|
+
}
|
|
1424
|
+
if (id !== void 0) {
|
|
1425
|
+
fail2("--type can only be used when creating a work item.");
|
|
1426
|
+
}
|
|
1427
|
+
const trimmedType = options.type.trim();
|
|
1428
|
+
if (trimmedType === "") {
|
|
1429
|
+
fail2("--type must be a non-empty work item type.");
|
|
1430
|
+
}
|
|
1431
|
+
return trimmedType;
|
|
1432
|
+
}
|
|
1433
|
+
function buildUpsertResult(action, writeResult, fields, fallbackWorkItemType) {
|
|
1421
1434
|
const appliedFields = buildAppliedFields(fields);
|
|
1435
|
+
const workItemType = writeResult.fields["System.WorkItemType"];
|
|
1422
1436
|
return {
|
|
1423
1437
|
action,
|
|
1424
1438
|
id: writeResult.id,
|
|
1439
|
+
workItemType: typeof workItemType === "string" && workItemType.trim() !== "" ? workItemType : fallbackWorkItemType,
|
|
1425
1440
|
fields: appliedFields
|
|
1426
1441
|
};
|
|
1427
1442
|
}
|
|
@@ -1456,10 +1471,11 @@ function handleUpsertError(err, id, context) {
|
|
|
1456
1471
|
}
|
|
1457
1472
|
function createUpsertCommand() {
|
|
1458
1473
|
const command = new Command9("upsert");
|
|
1459
|
-
command.description("Create or update a
|
|
1474
|
+
command.description("Create or update a work item from a markdown document").argument("[id]", "work item ID to update; omit to create a new work item").option("--content <markdown>", "task document content").option("--file <path>", "read task document from file").option("--type <workItemType>", "create mode work item type (defaults to Task)").option("--json", "output result as JSON").option("--org <org>", "Azure DevOps organization").option("--project <project>", "Azure DevOps project").action(async (idStr, options) => {
|
|
1460
1475
|
validateOrgProjectPair(options);
|
|
1461
1476
|
const id = idStr === void 0 ? void 0 : parseWorkItemId(idStr);
|
|
1462
1477
|
const { content, sourceFile } = loadSourceContent(options);
|
|
1478
|
+
const createType = resolveCreateType(id, options);
|
|
1463
1479
|
let context;
|
|
1464
1480
|
try {
|
|
1465
1481
|
context = resolveContext(options);
|
|
@@ -1472,14 +1488,19 @@ function createUpsertCommand() {
|
|
|
1472
1488
|
const credential = await resolvePat();
|
|
1473
1489
|
let writeResult;
|
|
1474
1490
|
if (action === "created") {
|
|
1475
|
-
writeResult = await createWorkItem(context,
|
|
1491
|
+
writeResult = await createWorkItem(context, createType, credential.pat, operations);
|
|
1476
1492
|
} else {
|
|
1477
1493
|
if (id === void 0) {
|
|
1478
1494
|
fail2("Work item ID is required for updates.");
|
|
1479
1495
|
}
|
|
1480
1496
|
writeResult = await applyWorkItemPatch(context, id, credential.pat, operations);
|
|
1481
1497
|
}
|
|
1482
|
-
const result = buildUpsertResult(
|
|
1498
|
+
const result = buildUpsertResult(
|
|
1499
|
+
action,
|
|
1500
|
+
writeResult,
|
|
1501
|
+
document.fields,
|
|
1502
|
+
action === "created" ? createType : "Work item"
|
|
1503
|
+
);
|
|
1483
1504
|
writeSuccess(result, options);
|
|
1484
1505
|
cleanupSourceFile(sourceFile);
|
|
1485
1506
|
} catch (err) {
|