@chris1807/claude-kit 2.1.59 → 2.2.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/package.json +1 -1
- package/templates/agents/project/deployer.md +1 -1
- package/templates/commands/cherry-pick.md +43 -4
- package/templates/commands/deploy-release.md +43 -4
- package/templates/commands/implement.md +1 -1
- package/templates/commands/promote.md +44 -5
- package/templates/commands/track.md +2 -2
- package/templates/commands/where.md +1 -1
- package/templates/infrastructure/CLAUDE-WORKFLOW.md +14 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chris1807/claude-kit",
|
|
3
|
-
"version": "2.1
|
|
3
|
+
"version": "2.2.1",
|
|
4
4
|
"description": "Claude Code starter kit for Azure DevOps teams — agents, hooks, MCP servers, slash commands, and end-to-end work item → PR → release → deploy workflow automation",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|
|
@@ -73,7 +73,7 @@ When asked to promote code from one environment to the next:
|
|
|
73
73
|
1. Create a PR from the source branch to the next branch in the chain (`main` → `dev`, `dev` → `test`, `test` → `staging`, `staging` → `prod`)
|
|
74
74
|
2. Include a summary of all changes being promoted and the work items they carry
|
|
75
75
|
3. After PR is merged, the CD pipeline for the target environment triggers automatically
|
|
76
|
-
4. Once the user confirms the merge, advance the carried User Stories / Bugs / Hot Fixes to the environment's state (`
|
|
76
|
+
4. Once the user confirms the merge, advance the carried User Stories / Bugs / Hot Fixes to the environment's state (`test` → `Testing`, `staging` → `Staging`, `prod` → `Deployed`; **`dev` sets no state** — items stay at `Code Review` and the developer sets `Ready for Testing` by hand) — never backward, never a Feature or Task. The `/promote` command documents the full gate-check and state rules
|
|
77
77
|
|
|
78
78
|
### Deploy Release
|
|
79
79
|
|
|
@@ -11,12 +11,12 @@ Resolve branch names from the project's `CLAUDE.md` **Pipeline Configuration** t
|
|
|
11
11
|
| Branch | Environment | Gate — items should already be in… | State set after the PR merges |
|
|
12
12
|
|---|---|---|---|
|
|
13
13
|
| `main` | — (compare branch) | — | *(no change)* |
|
|
14
|
-
| `dev` | Dev | `Code Review` (merged to `main`) |
|
|
14
|
+
| `dev` | Dev | `Code Review` (merged to `main`) | *(no change — stays `Code Review`)* |
|
|
15
15
|
| `test` | Test | `Ready for Testing` | `Testing` |
|
|
16
16
|
| `staging` | Staging | `Ready for Staging` | `Staging` |
|
|
17
17
|
| `prod` | Production | `Ready to Deploy` | `Deployed` |
|
|
18
18
|
|
|
19
|
-
`Ready for Staging` and `Ready to Deploy` are set by QA and stakeholders — **never by this command**.
|
|
19
|
+
`Ready for Testing`, `Ready for Staging` and `Ready to Deploy` are set by the developer, QA, and stakeholders — **never by this command**. A `main → dev` deploy therefore sets **no state**: items stay at `Code Review` until the developer has checked the change on Dev and moves it to `Ready for Testing` by hand.
|
|
20
20
|
|
|
21
21
|
## Step 1: Read the Work Items and Gate-Check Them
|
|
22
22
|
|
|
@@ -33,6 +33,37 @@ Fetch each work item from Azure DevOps via MCP. Compare each one's `System.State
|
|
|
33
33
|
Cherry-pick {count} work items to {environment}? Items behind the gate: include / drop / cancel
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
+
### Step 1b: Scripts That Have to Be Run
|
|
37
|
+
|
|
38
|
+
A deployment script — a SQL migration, a data backfill, a PowerShell step — is attached to the work item it belongs to, and it has to run in **every** environment that item's code lands in. A promotion carries the code; it does not carry the script, and nothing in the PR says one exists. That is how an environment ends up half-deployed.
|
|
39
|
+
|
|
40
|
+
Fetch each carried work item with its attachments — `wit_work_item` `action: get`, `expand: "Relations"`, one call per item (`get_batch` has no `expand`) — and keep every relation whose `rel` is `AttachedFile` and whose filename extension is **not** a document, image or video:
|
|
41
|
+
|
|
42
|
+
```
|
|
43
|
+
.xlsx .xls .xlsm .xlsb .csv .docx .doc .docm .pdf
|
|
44
|
+
.png .jpg .jpeg .gif .bmp .ico .svg .webp .tiff .tif
|
|
45
|
+
.mp4 .mov .avi .webm .mkv .wmv .flv .m4v
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Everything else counts, extensionless files included. The rule is deliberately loose, because the two mistakes do not cost the same: a filename someone glances at and dismisses costs seconds, a migration nobody ran costs an environment.
|
|
49
|
+
|
|
50
|
+
Show them with the table above, before the confirmation:
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
📜 Scripts to run with this promotion:
|
|
54
|
+
|
|
55
|
+
| Work Item | Script |
|
|
56
|
+
|-----------|--------|
|
|
57
|
+
| AB#1234 | 2026-09-11_add_delivery_index.sql |
|
|
58
|
+
| AB#1240 | backfill-tenant-flags.ps1 |
|
|
59
|
+
|
|
60
|
+
Download them from the work items. This command does not run them.
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
If nothing carries an attachment, say `No deployment scripts attached` on one line and move on.
|
|
64
|
+
|
|
65
|
+
**Reported, never enforced.** A script does not block the promotion and does not change the gate check: the attachment may already have been run, may be a reference copy, may not be a script at all. Listing it is the whole job — the person deploying decides.
|
|
66
|
+
|
|
36
67
|
Wait for confirmation. `drop` removes flagged items from this cherry-pick only.
|
|
37
68
|
|
|
38
69
|
## Step 2: Find Commits
|
|
@@ -91,7 +122,7 @@ Cherry-picking:
|
|
|
91
122
|
- **sourceRefName**: `refs/heads/cherry-pick/<date>-to-<environment>`
|
|
92
123
|
- **targetRefName**: `refs/heads/<target-environment-branch>`
|
|
93
124
|
- **title**: `Cherry-pick AB#1234, AB#1235 → {Environment}`
|
|
94
|
-
- **description**: List all work items with IDs and titles
|
|
125
|
+
- **description**: List all work items with IDs and titles, and — under a `Scripts to run` heading — any deployment scripts found in Step 1b, so whoever merges sees them without opening the work items
|
|
95
126
|
3. Link all work items to the PR via `wit_link_work_item_to_pull_request`
|
|
96
127
|
|
|
97
128
|
## Step 6: Pick Who Verifies Each Group (before the merge)
|
|
@@ -296,7 +327,8 @@ This step runs **by itself** the moment the pipeline reports success — do not
|
|
|
296
327
|
|
|
297
328
|
For every cherry-picked work item of type **User Story**, **Bug**, or **Hot Fix**, one `wit_work_item_write` update per item setting both fields:
|
|
298
329
|
|
|
299
|
-
1. `System.State` → the target's state (`
|
|
330
|
+
1. `System.State` → the target's state (`Testing` / `Staging` / `Deployed`).
|
|
331
|
+
- **A cherry-pick to `dev` sets no state.** Items stay at `Code Review`; the developer sets `Ready for Testing` by hand. Update the assignee only.
|
|
300
332
|
- **Never move backward** — an item already past the target state keeps it; note it.
|
|
301
333
|
- Skipped (conflict) or dropped items are not on the branch — leave them alone.
|
|
302
334
|
- An invalid-state error means this project's template differs — confirm with `get_type`, report the item, continue. Don't silently swallow it.
|
|
@@ -319,3 +351,10 @@ Next: {the human step — "QA tests on Test and sets Ready for Staging" / "stake
|
|
|
319
351
|
```
|
|
320
352
|
|
|
321
353
|
If the user said `stop watching`, or an update fails, leave the rest alone, say exactly which items were and were not updated, and note that `/track` will flag the lag later.
|
|
354
|
+
|
|
355
|
+
If any carried item had a deployment script (Step 1b), repeat it here — this is the moment it has to run, and the list is stale in the scroll-back by now:
|
|
356
|
+
|
|
357
|
+
```
|
|
358
|
+
📜 Still to run on {environment}: AB#1234 2026-09-11_add_delivery_index.sql, AB#1240 backfill-tenant-flags.ps1
|
|
359
|
+
```
|
|
360
|
+
|
|
@@ -11,12 +11,12 @@ Resolve branch names from the project's `CLAUDE.md` **Pipeline Configuration** t
|
|
|
11
11
|
| Branch | Environment | Gate — items should already be in… | State set after the PR merges |
|
|
12
12
|
|---|---|---|---|
|
|
13
13
|
| `main` | — (compare branch) | — | — |
|
|
14
|
-
| `dev` | Dev | `Code Review` (merged to `main`) |
|
|
14
|
+
| `dev` | Dev | `Code Review` (merged to `main`) | *(no change — stays `Code Review`)* |
|
|
15
15
|
| `test` | Test | `Ready for Testing` | `Testing` |
|
|
16
16
|
| `staging` | Staging | `Ready for Staging` | `Staging` |
|
|
17
17
|
| `prod` | Production | `Ready to Deploy` | `Deployed` |
|
|
18
18
|
|
|
19
|
-
`Ready for Staging` and `Ready to Deploy` are set by QA and stakeholders — **never by this command**. If the project's table has different environments, confirm the type's states with `mcp__azure-devops__wit_work_item` (`action: get_type`) and map them the same way: a "Ready for X" gate → an "in X" state.
|
|
19
|
+
`Ready for Testing`, `Ready for Staging` and `Ready to Deploy` are set by the developer, QA, and stakeholders — **never by this command**. A `main → dev` deploy therefore sets **no state**: items stay at `Code Review` until the developer has checked the change on Dev and moves it to `Ready for Testing` by hand. If the project's table has different environments, confirm the type's states with `mcp__azure-devops__wit_work_item` (`action: get_type`) and map them the same way: a "Ready for X" gate → an "in X" state.
|
|
20
20
|
|
|
21
21
|
## Step 1: Read the Release
|
|
22
22
|
|
|
@@ -74,6 +74,37 @@ Include them anyway, or drop them from this deploy? (include / drop / cancel)
|
|
|
74
74
|
|
|
75
75
|
Wait for the answer. `drop` removes them from **this deploy only** — they stay in the release.
|
|
76
76
|
|
|
77
|
+
## Step 3b: Scripts That Have to Be Run
|
|
78
|
+
|
|
79
|
+
A deployment script — a SQL migration, a data backfill, a PowerShell step — is attached to the work item it belongs to, and it has to run in **every** environment that item's code lands in. A promotion carries the code; it does not carry the script, and nothing in the PR says one exists. That is how an environment ends up half-deployed.
|
|
80
|
+
|
|
81
|
+
Fetch each carried work item with its attachments — `wit_work_item` `action: get`, `expand: "Relations"`, one call per item (`get_batch` has no `expand`) — and keep every relation whose `rel` is `AttachedFile` and whose filename extension is **not** a document, image or video:
|
|
82
|
+
|
|
83
|
+
```
|
|
84
|
+
.xlsx .xls .xlsm .xlsb .csv .docx .doc .docm .pdf
|
|
85
|
+
.png .jpg .jpeg .gif .bmp .ico .svg .webp .tiff .tif
|
|
86
|
+
.mp4 .mov .avi .webm .mkv .wmv .flv .m4v
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Everything else counts, extensionless files included. The rule is deliberately loose, because the two mistakes do not cost the same: a filename someone glances at and dismisses costs seconds, a migration nobody ran costs an environment.
|
|
90
|
+
|
|
91
|
+
Show them with the gate check, before Step 4's confirmation:
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
📜 Scripts to run with this promotion:
|
|
95
|
+
|
|
96
|
+
| Work Item | Script |
|
|
97
|
+
|-----------|--------|
|
|
98
|
+
| AB#1234 | 2026-09-11_add_delivery_index.sql |
|
|
99
|
+
| AB#1240 | backfill-tenant-flags.ps1 |
|
|
100
|
+
|
|
101
|
+
Download them from the work items. This command does not run them.
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
If nothing carries an attachment, say `No deployment scripts attached` on one line and move on.
|
|
105
|
+
|
|
106
|
+
**Reported, never enforced.** A script does not block the promotion and does not change the gate check: the attachment may already have been run, may be a reference copy, may not be a script at all. Listing it is the whole job — the person deploying decides.
|
|
107
|
+
|
|
77
108
|
## Step 4: Confirm
|
|
78
109
|
|
|
79
110
|
```
|
|
@@ -147,7 +178,7 @@ Cherry-picking commits for Release #{N}:
|
|
|
147
178
|
- **sourceRefName**: `refs/heads/release/{N}-to-<environment>`
|
|
148
179
|
- **targetRefName**: `refs/heads/<target-environment-branch>`
|
|
149
180
|
- **title**: `Release #{N} → {Environment}`
|
|
150
|
-
- **description**: List all work items included with their IDs and titles
|
|
181
|
+
- **description**: List all work items included with their IDs and titles, and — under a `Scripts to run` heading — any deployment scripts found in Step 3b, so whoever merges sees them without opening the work items
|
|
151
182
|
3. Link all work items to the PR via `wit_link_work_item_to_pull_request`
|
|
152
183
|
|
|
153
184
|
## Step 8: Pick Who Verifies Each Group (before the merge)
|
|
@@ -356,7 +387,8 @@ This step runs **by itself** the moment the pipeline reports success — do not
|
|
|
356
387
|
|
|
357
388
|
For every carried work item of type **User Story**, **Bug**, or **Hot Fix**, one `wit_work_item_write` update per item (or the batch variant) setting both fields:
|
|
358
389
|
|
|
359
|
-
1. `System.State` → the target environment's state (`
|
|
390
|
+
1. `System.State` → the target environment's state (`Testing` / `Staging` / `Deployed`).
|
|
391
|
+
- **A deploy to `dev` sets no state.** Items stay at `Code Review`; the developer sets `Ready for Testing` by hand. Update the assignee only.
|
|
360
392
|
- **Never move backward.** An item already past the target state (e.g. `Deployed` when deploying to `staging`) keeps its state; note it.
|
|
361
393
|
- Items skipped in Step 6 (conflict) or dropped in Step 3 are not on the branch — leave them alone.
|
|
362
394
|
- An invalid-state error means this project's template differs — confirm with `get_type`, report the item, continue with the rest. Don't silently swallow it.
|
|
@@ -381,6 +413,13 @@ Next: {the human step — "QA tests on Test and sets Ready for Staging" / "stake
|
|
|
381
413
|
|
|
382
414
|
If the user said `stop watching`, or an update fails, leave the rest alone, say exactly which items were and were not updated, and note that `/track release {N}` will flag the lag later.
|
|
383
415
|
|
|
416
|
+
If any carried item had a deployment script (Step 3b), repeat it here — this is the moment it has to run, and the list is stale in the scroll-back by now:
|
|
417
|
+
|
|
418
|
+
```
|
|
419
|
+
📜 Still to run on {environment}: AB#1234 2026-09-11_add_delivery_index.sql, AB#1240 backfill-tenant-flags.ps1
|
|
420
|
+
```
|
|
421
|
+
|
|
422
|
+
|
|
384
423
|
## Step 11: Notify Team (if Teams MCP is configured)
|
|
385
424
|
|
|
386
425
|
Send a notification to the project's Teams channel via the Microsoft Teams MCP server — once when the PR is created:
|
|
@@ -362,7 +362,7 @@ Wait for the user's response before proceeding. Do NOT create a PR until confirm
|
|
|
362
362
|
|
|
363
363
|
If the project's process template does not have a `Code Review` state (the update call returns an invalid-state error), fall back in this order: `Resolved` → `In Review` → leave the current state and warn the user that the state could not be advanced automatically. Do not silently swallow the error.
|
|
364
364
|
|
|
365
|
-
> **Only the Task ever gets closed — never the parent.** The child Task is closed here, at PR creation (step 4 above). When the PR is later completed/merged, do **not** enable Azure DevOps's "Complete associated work items" option: it transitions *every* linked work item, including the parent this PR is linked to. The parent User Story or Bug stays in `Code Review
|
|
365
|
+
> **Only the Task ever gets closed — never the parent.** The child Task is closed here, at PR creation (step 4 above). When the PR is later completed/merged, do **not** enable Azure DevOps's "Complete associated work items" option: it transitions *every* linked work item, including the parent this PR is linked to. The parent User Story or Bug stays in `Code Review`: merging this PR into `main` deploys nothing, and promoting to `dev` deploys the code but **leaves the state alone** — the developer moves it to `Ready for Testing` once they have checked it on Dev. From there `/promote` and `/deploy-release` advance it to `Testing` → `Staging` → `Deployed` across `test → staging → prod` (see **Work Item States ↔ Environments** in CLAUDE.md).
|
|
366
366
|
|
|
367
367
|
### Closing Related Tasks
|
|
368
368
|
|
|
@@ -11,12 +11,12 @@ Resolve branch names from the project's `CLAUDE.md` **Pipeline Configuration** t
|
|
|
11
11
|
| Branch | Environment | Gate — items should already be in… | State set after the PR merges |
|
|
12
12
|
|---|---|---|---|
|
|
13
13
|
| `main` | — (compare branch) | — | — |
|
|
14
|
-
| `dev` | Dev | `Code Review` (merged to `main`) |
|
|
14
|
+
| `dev` | Dev | `Code Review` (merged to `main`) | *(no change — stays `Code Review`)* |
|
|
15
15
|
| `test` | Test | `Ready for Testing` | `Testing` |
|
|
16
16
|
| `staging` | Staging | `Ready for Staging` | `Staging` |
|
|
17
17
|
| `prod` | Production | `Ready to Deploy` | `Deployed` |
|
|
18
18
|
|
|
19
|
-
`Ready for Staging` and `Ready to Deploy` are set by QA and stakeholders — **never by this command**.
|
|
19
|
+
`Ready for Testing`, `Ready for Staging` and `Ready to Deploy` are set by the developer, QA, and stakeholders — **never by this command**. A `main → dev` deploy therefore sets **no state**: items stay at `Code Review` until the developer has checked the change on Dev and moves it to `Ready for Testing` by hand.
|
|
20
20
|
|
|
21
21
|
## Step 1: Determine Source and Target
|
|
22
22
|
|
|
@@ -79,6 +79,37 @@ Which? (1 / 2)
|
|
|
79
79
|
|
|
80
80
|
For `main → dev` the gate is `Code Review`: an item still at `Code Review` whose commits are on `main` has had its PR merged, which is exactly right — not a warning. Features and Tasks are skipped. Items *ahead* of the gate are reported and left alone.
|
|
81
81
|
|
|
82
|
+
## Step 3b: Scripts That Have to Be Run
|
|
83
|
+
|
|
84
|
+
A deployment script — a SQL migration, a data backfill, a PowerShell step — is attached to the work item it belongs to, and it has to run in **every** environment that item's code lands in. A promotion carries the code; it does not carry the script, and nothing in the PR says one exists. That is how an environment ends up half-deployed.
|
|
85
|
+
|
|
86
|
+
Fetch each carried work item with its attachments — `wit_work_item` `action: get`, `expand: "Relations"`, one call per item (`get_batch` has no `expand`) — and keep every relation whose `rel` is `AttachedFile` and whose filename extension is **not** a document, image or video:
|
|
87
|
+
|
|
88
|
+
```
|
|
89
|
+
.xlsx .xls .xlsm .xlsb .csv .docx .doc .docm .pdf
|
|
90
|
+
.png .jpg .jpeg .gif .bmp .ico .svg .webp .tiff .tif
|
|
91
|
+
.mp4 .mov .avi .webm .mkv .wmv .flv .m4v
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
Everything else counts, extensionless files included. The rule is deliberately loose, because the two mistakes do not cost the same: a filename someone glances at and dismisses costs seconds, a migration nobody ran costs an environment.
|
|
95
|
+
|
|
96
|
+
Show them with the gate check, before the confirmation:
|
|
97
|
+
|
|
98
|
+
```
|
|
99
|
+
📜 Scripts to run with this promotion:
|
|
100
|
+
|
|
101
|
+
| Work Item | Script |
|
|
102
|
+
|-----------|--------|
|
|
103
|
+
| AB#1234 | 2026-09-11_add_delivery_index.sql |
|
|
104
|
+
| AB#1240 | backfill-tenant-flags.ps1 |
|
|
105
|
+
|
|
106
|
+
Download them from the work items. This command does not run them.
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
If nothing carries an attachment, say `No deployment scripts attached` on one line and move on.
|
|
110
|
+
|
|
111
|
+
**Reported, never enforced.** A script does not block the promotion and does not change the gate check: the attachment may already have been run, may be a reference copy, may not be a script at all. Listing it is the whole job — the person deploying decides.
|
|
112
|
+
|
|
82
113
|
Then confirm: `Promote {count} commits from {source} to {target}? (yes/no)` — and wait.
|
|
83
114
|
|
|
84
115
|
## Step 4: Create PR
|
|
@@ -88,7 +119,7 @@ Create a PR directly from the source branch to the target branch via Azure DevOp
|
|
|
88
119
|
- **sourceRefName**: `refs/heads/<source-branch>`
|
|
89
120
|
- **targetRefName**: `refs/heads/<target-branch>`
|
|
90
121
|
- **title**: `Promote {source} → {target}`
|
|
91
|
-
- **description**: List all commits and associated work items being promoted
|
|
122
|
+
- **description**: List all commits and associated work items being promoted, and — under a `Scripts to run` heading — any deployment scripts found in Step 3b, so whoever merges sees them without opening the work items
|
|
92
123
|
|
|
93
124
|
Link the associated work items to the PR.
|
|
94
125
|
|
|
@@ -290,7 +321,8 @@ This step runs **by itself** the moment the pipeline reports success — do not
|
|
|
290
321
|
|
|
291
322
|
For every carried work item of type **User Story**, **Bug**, or **Hot Fix**, one `wit_work_item_write` update per item setting both fields:
|
|
292
323
|
|
|
293
|
-
1. `System.State` → the target's state (`
|
|
324
|
+
1. `System.State` → the target's state (`Testing` / `Staging` / `Deployed`).
|
|
325
|
+
- **`main → dev` sets no state.** Items stay at `Code Review` — the developer sets `Ready for Testing` by hand once they have checked it on Dev. Update the assignee only, and show the state as `Code Review (unchanged — developer sets Ready for Testing)`.
|
|
294
326
|
- **Never move backward** — an item already past the target state keeps it; note it.
|
|
295
327
|
- An invalid-state error means this project's template differs — confirm with `get_type`, report the item, continue with the rest. Don't silently swallow it.
|
|
296
328
|
2. `System.AssignedTo` → the person approved for that item's prefix group. Pass the identity's `uniqueName` / email, not the display name; if the update rejects it, resolve with `core_get_identity_ids` and retry once. A `Leave the current assignee alone` group keeps its assignee — never clear a field the user didn't ask you to clear.
|
|
@@ -308,7 +340,14 @@ Report both fields, so a wrong assignment is easy to put back:
|
|
|
308
340
|
| AB#1240 | Ready for Staging → Staging | Chris Waters → Pat Ruiz |
|
|
309
341
|
| AB#1250 | Deployed (unchanged — already ahead) | unchanged |
|
|
310
342
|
|
|
311
|
-
Next: {the human step — "QA tests on Test and sets Ready for Staging" / "stakeholders verify on Staging and set Ready to Deploy" / "verify in production, then Close"}.
|
|
343
|
+
Next: {the human step — "the developer checks it on Dev and sets Ready for Testing" / "QA tests on Test and sets Ready for Staging" / "stakeholders verify on Staging and set Ready to Deploy" / "verify in production, then Close"}.
|
|
312
344
|
```
|
|
313
345
|
|
|
314
346
|
If the user said `stop watching`, or an update fails, leave the rest alone, say exactly which items were and were not updated, and note that `/track` will flag the lag later.
|
|
347
|
+
|
|
348
|
+
If any carried item had a deployment script (Step 3b), repeat it here — this is the moment it has to run, and the list is stale in the scroll-back by now:
|
|
349
|
+
|
|
350
|
+
```
|
|
351
|
+
📜 Still to run on {target}: AB#1234 2026-09-11_add_delivery_index.sql, AB#1240 backfill-tenant-flags.ps1
|
|
352
|
+
```
|
|
353
|
+
|
|
@@ -16,12 +16,12 @@ Work item states track environments. Use this to spot **state lag** — an item
|
|
|
16
16
|
| Commits are on… | State should be at least… |
|
|
17
17
|
|---|---|
|
|
18
18
|
| `main` | `Code Review` |
|
|
19
|
-
| `dev` | `
|
|
19
|
+
| `dev` | `Code Review` |
|
|
20
20
|
| `test` | `Testing` |
|
|
21
21
|
| `staging` | `Staging` |
|
|
22
22
|
| `prod` | `Deployed` |
|
|
23
23
|
|
|
24
|
-
`Ready for Staging` and `Ready to Deploy` are human sign-offs and are never "lag". Only User Stories, Bugs, and Hot Fixes are checked — Features and Tasks have no environment state.
|
|
24
|
+
`Ready for Testing`, `Ready for Staging` and `Ready to Deploy` are human sign-offs and are never "lag" — an item sitting at `Code Review` with commits on `dev` is waiting on the developer, not behind. Only User Stories, Bugs, and Hot Fixes are checked — Features and Tasks have no environment state.
|
|
25
25
|
|
|
26
26
|
## If Release (e.g., `/track release 24`):
|
|
27
27
|
|
|
@@ -88,6 +88,6 @@ Open PRs:
|
|
|
88
88
|
- PR #<n> → <target branch> (<status>)
|
|
89
89
|
```
|
|
90
90
|
|
|
91
|
-
Finally, compare the work item's state with its furthest environment (`dev` → `
|
|
91
|
+
Finally, compare the work item's state with its furthest environment (`dev` → `Code Review`, `test` → `Testing`, `staging` → `Staging`, `prod` → `Deployed`). If the state lags — e.g. commits on `staging` but the item is still `Testing` — add one line: `⚠ State lags environment: Testing, expected at least Staging — /track AB#<id> can catch it up.`
|
|
92
92
|
|
|
93
93
|
That's it — read-only. Do not modify branches, push, create PRs, or change states.
|
|
@@ -161,19 +161,19 @@ feature/AB#1234-... ──PR──▸ main ──PR──▸ dev ──PR
|
|
|
161
161
|
|
|
162
162
|
#### Work Item States ↔ Environments
|
|
163
163
|
|
|
164
|
-
Every environment in the chain has a work item state, so the board shows where each story physically is. The **"Ready for …" states are human gates** — QA or stakeholders set them when something passes; the slash commands never do. The **environment states** (`Testing`, `Staging`, `Deployed`) are set by the promotion commands once the PR into that branch has merged and its CD pipeline has come back green.
|
|
164
|
+
Every environment in the chain has a work item state, so the board shows where each story physically is. The **"Ready for …" states are human gates** — the developer, QA, or stakeholders set them when something passes; the slash commands never do. The **environment states** (`Testing`, `Staging`, `Deployed`) are set by the promotion commands once the PR into that branch has merged and its CD pipeline has come back green.
|
|
165
165
|
|
|
166
166
|
| Branch | Environment | Gate — items should already be in… | Set once the PR into this branch merges |
|
|
167
167
|
|---|---|---|---|
|
|
168
168
|
| `main` | — | `Code Review` (the `/implement` PR is open) | *(no change — nothing deployed)* |
|
|
169
|
-
| `dev` | Dev | `Code Review` (merged to `main`) |
|
|
169
|
+
| `dev` | Dev | `Code Review` (merged to `main`) | *(no change — stays `Code Review`)* |
|
|
170
170
|
| `test` | Test | `Ready for Testing` | `Testing` |
|
|
171
171
|
| `staging` | Staging | `Ready for Staging` | `Staging` |
|
|
172
172
|
| `prod` | Production | `Ready to Deploy` | `Deployed` |
|
|
173
173
|
|
|
174
174
|
`/qa` is the exception that proves the rule: it tests a work item in a browser and posts a pass/fail comment, but it **never writes a state** — not even `Ready for Testing`.
|
|
175
175
|
|
|
176
|
-
Human-only transitions — no slash command ever makes these: `Testing → Ready for Staging` (QA sign-off), `Staging → Ready to Deploy` (stakeholder / UAT sign-off), `Deployed → Closed` (verified in production).
|
|
176
|
+
Human-only transitions — no slash command ever makes these: `Code Review → Ready for Testing` (the developer confirms the change on Dev), `Testing → Ready for Staging` (QA sign-off), `Staging → Ready to Deploy` (stakeholder / UAT sign-off), `Deployed → Closed` (verified in production).
|
|
177
177
|
|
|
178
178
|
How the commands use this table:
|
|
179
179
|
|
|
@@ -183,6 +183,14 @@ How the commands use this table:
|
|
|
183
183
|
- **Assign the verifier at the same time.** The state change hands the item to a person, so the same three commands ask **before the merge** who each group of items should go to, then apply the assignee alongside the state once the pipeline is green. See **Verifier Assignment** below.
|
|
184
184
|
- **Never assume the state list.** Confirm with `mcp__azure-devops__wit_work_item` (`action: get_type`) on an unfamiliar project before writing a state name — a bad name is accepted silently by a query and rejected only at write time.
|
|
185
185
|
|
|
186
|
+
#### Deployment Scripts
|
|
187
|
+
|
|
188
|
+
A SQL migration or a backfill script is attached to the work item it belongs to, and it has to run in **every** environment that item's code lands in — test, then staging, then prod. The promotion carries the code, never the script.
|
|
189
|
+
|
|
190
|
+
`/promote`, `/cherry-pick` and `/deploy-release` therefore read the carried items' attachments (`wit_work_item` `action: get`, `expand: "Relations"`) and list any that look like something to run: an `AttachedFile` whose extension is **not** a document, image or video (`.docx .xlsx .csv .pdf .png .jpg .mp4` and friends). Everything else counts — the rule is loose on purpose, because a filename glanced at and dismissed costs seconds while a migration nobody ran costs an environment. The list appears before the confirmation, in the PR description, and again once the pipeline is green, which is when it actually has to be run.
|
|
191
|
+
|
|
192
|
+
**Reported, never enforced.** A script never blocks a promotion and never changes the gate check — it may already have been run, or be a reference copy. The person deploying decides; the commands only make sure nobody finds out afterwards.
|
|
193
|
+
|
|
186
194
|
#### Verifier Assignment
|
|
187
195
|
|
|
188
196
|
Moving an item to `Testing`, `Staging`, or `Deployed` puts it on someone's plate, so `/promote`, `/cherry-pick`, and `/deploy-release` also change who owns it. The developer implemented it; from here on it belongs to whoever checks it in that environment.
|
|
@@ -303,10 +311,10 @@ All deployment and release operations are available as slash commands:
|
|
|
303
311
|
| `/resolve-feedback` | `/resolve-feedback 142` | Address unresolved PR comment threads, push fixes, reply + resolve threads |
|
|
304
312
|
| `/deploy` | `/deploy "commit message"` | Commit, push, trigger pipeline (only on `dev`/`test`/`staging`/`prod` — never on `main`) |
|
|
305
313
|
| `/create-release` | `/create-release 23` | Group work items into Release #23 |
|
|
306
|
-
| `/deploy-release` | `/deploy-release 23 staging` | Gate-check → cherry-pick release to environment → PR → ask who verifies → merge on Serena's approval (below prod) → advance + assign on a green pipeline |
|
|
314
|
+
| `/deploy-release` | `/deploy-release 23 staging` | Gate-check → list deployment scripts → cherry-pick release to environment → PR → ask who verifies → merge on Serena's approval (below prod) → advance + assign on a green pipeline |
|
|
307
315
|
| `/add-to-release` | `/add-to-release 24 AB#4599` | Add work items to existing release |
|
|
308
|
-
| `/cherry-pick` | `/cherry-pick AB#1234 AB#1235 prod` | Gate-check → cherry-pick specific work items → PR → ask who verifies → merge on Serena's approval (below prod) → advance + assign on a green pipeline |
|
|
309
|
-
| `/promote` | `/promote main dev` | Promote all code between environments (`main → dev → test → staging → prod`) → ask who verifies → merge on Serena's approval (below prod) → advance + assign on a green pipeline |
|
|
316
|
+
| `/cherry-pick` | `/cherry-pick AB#1234 AB#1235 prod` | Gate-check → list deployment scripts → cherry-pick specific work items → PR → ask who verifies → merge on Serena's approval (below prod) → advance + assign on a green pipeline |
|
|
317
|
+
| `/promote` | `/promote main dev` | Promote all code between environments (`main → dev → test → staging → prod`) → list deployment scripts → ask who verifies → merge on Serena's approval (below prod) → advance + assign on a green pipeline |
|
|
310
318
|
| `/rollback` | `/rollback AB#1234 prod` | Revert commits on an environment |
|
|
311
319
|
| `/track` | `/track release 24` | Check release, pipeline, environment, or work item status; flags work items whose state lags their environment |
|
|
312
320
|
| `/where` | `/where AB#1234` | Show which environment branches contain a work item's commits |
|