@chris1807/claude-kit 2.1.58 → 2.1.59
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
CHANGED
|
@@ -331,7 +331,8 @@ Claude automatically:
|
|
|
331
331
|
3. Creates a PR targeting the `staging` branch — merging it triggers the Staging pipeline
|
|
332
332
|
4. Links all work items to the PR
|
|
333
333
|
5. Asks who verifies each product group on Staging (`COM`, `PAY`, …) — candidates are the non-developer names already on those work items
|
|
334
|
-
6.
|
|
334
|
+
6. Waits for Serena (the AI reviewer) to approve the PR, then completes it — for `dev`, `test`, and `staging` only; a `prod` PR you merge yourself
|
|
335
|
+
7. Watches the Staging pipeline; once it's green, moves the work items to `Staging` and assigns them to the approved verifiers
|
|
335
336
|
|
|
336
337
|
The same command walks a release through `test` → `staging` → `prod`; with no environment given it picks the next one.
|
|
337
338
|
|
|
@@ -341,7 +342,7 @@ The same command walks a release through `test` → `staging` → `prod`; with n
|
|
|
341
342
|
/cherry-pick AB#1234 AB#1235 prod
|
|
342
343
|
```
|
|
343
344
|
|
|
344
|
-
Cherry-picks specific work items to an environment without a formal release. Same gate check, same verifier question, and the same automatic state advance + assignment once the pipeline is green as `/deploy-release`. `main` is also a valid target — that's how a hot fix that went straight to `prod` is brought back into the compare branch.
|
|
345
|
+
Cherry-picks specific work items to an environment without a formal release. Same gate check, same verifier question, and the same automatic state advance + assignment once the pipeline is green as `/deploy-release`. Targeting `dev`, `test`, or `staging` it also merges the PR itself once Serena approves it; a `prod` PR waits for a person. `main` is also a valid target — that's how a hot fix that went straight to `prod` is brought back into the compare branch.
|
|
345
346
|
|
|
346
347
|
### Promote an Environment
|
|
347
348
|
|
|
@@ -351,7 +352,7 @@ Cherry-picks specific work items to an environment without a formal release. Sam
|
|
|
351
352
|
/promote ← auto-detects from the current branch
|
|
352
353
|
```
|
|
353
354
|
|
|
354
|
-
Creates a PR to promote all code from one branch to the next in the chain (`main → dev → test → staging → prod`). Shows every commit and work item before confirming, gate-checks the work items, asks who verifies each product group, and advances and assigns them once the merge's pipeline is green. `main → dev` is the usual first hop after feature PRs merge — nothing has deployed before that.
|
|
355
|
+
Creates a PR to promote all code from one branch to the next in the chain (`main → dev → test → staging → prod`). Shows every commit and work item before confirming, gate-checks the work items, asks who verifies each product group, and advances and assigns them once the merge's pipeline is green. Below production it also **merges the PR for you**: it polls until Serena (the AI reviewer) approves, then completes it with autocomplete — a PR into `prod` is always merged by a person. `main → dev` is the usual first hop after feature PRs merge — nothing has deployed before that.
|
|
355
356
|
|
|
356
357
|
### Rollback a Deployment
|
|
357
358
|
|
|
@@ -509,7 +510,7 @@ The PR merges into `main`. **That merge deploys nothing** — `main` is the comp
|
|
|
509
510
|
/promote main dev
|
|
510
511
|
```
|
|
511
512
|
|
|
512
|
-
|
|
513
|
+
Claude asks who verifies each product group on Dev, waits for Serena to approve the PR and merges it, watches the Dev pipeline, and once it's green moves the work items to `Ready for Testing` and assigns them to those people. (Dev, Test, and Staging merge themselves this way; a production PR you merge yourself.)
|
|
513
514
|
|
|
514
515
|
### Step 2: Deploy Changes (Quick Commits)
|
|
515
516
|
|
|
@@ -569,7 +570,7 @@ When stakeholders have verified on Staging and set the items to `Ready to Deploy
|
|
|
569
570
|
/deploy-release 23 prod
|
|
570
571
|
```
|
|
571
572
|
|
|
572
|
-
Same process — gate `Ready to Deploy`, cherry-picks from `staging` into a PR targeting `prod`. After merge the Production CD pipeline triggers; when it comes back green the items move to `Deployed` and are assigned to whoever you named for each product group.
|
|
573
|
+
Same process — gate `Ready to Deploy`, cherry-picks from `staging` into a PR targeting `prod`. **You merge this one** — Claude auto-merges only into `dev`, `test`, and `staging`. After merge the Production CD pipeline triggers; when it comes back green the items move to `Deployed` and are assigned to whoever you named for each product group.
|
|
573
574
|
|
|
574
575
|
### Selective Deployment
|
|
575
576
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@chris1807/claude-kit",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.59",
|
|
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": {
|
|
@@ -162,9 +162,19 @@ Approve? (yes / change)
|
|
|
162
162
|
|
|
163
163
|
`change` re-asks 6c. Only after `yes` do you move on — if the PR merges before the user answers, keep waiting for the answer, then run Step 8.
|
|
164
164
|
|
|
165
|
-
## Step 7:
|
|
165
|
+
## Step 7: Get the PR Merged, Then Watch the Pipeline
|
|
166
166
|
|
|
167
|
-
|
|
167
|
+
### 7a. Who completes the PR depends on the target
|
|
168
|
+
|
|
169
|
+
| Target | Who merges |
|
|
170
|
+
|---|---|
|
|
171
|
+
| `dev`, `test`, `staging` | **You do** — poll until Serena approves, then complete the PR (7b–7c) |
|
|
172
|
+
| `prod` | A human. **Never auto-merge into production.** |
|
|
173
|
+
| `main` | A human. No pipeline and no state change either — report the PR and stop. |
|
|
174
|
+
|
|
175
|
+
Resolve the target through the Pipeline Configuration table, not by the spelling of the branch — a project whose staging branch is named `Staging` or `release/staging` is still staging, and a project with no `test` row simply has no test hop.
|
|
176
|
+
|
|
177
|
+
Report the PR either way:
|
|
168
178
|
|
|
169
179
|
```
|
|
170
180
|
Cherry-pick PR created for {environment}.
|
|
@@ -174,13 +184,88 @@ Work items:
|
|
|
174
184
|
- AB#1234: COM - Add payment export
|
|
175
185
|
- AB#1240: PAY - Fix login redirect
|
|
176
186
|
|
|
177
|
-
|
|
178
|
-
and that pipeline — when it comes back green I'll set these {count} items to
|
|
179
|
-
`{state after merge}` and assign them as approved above. Nothing is written
|
|
180
|
-
until then. Say `stop watching` to leave the states alone.
|
|
187
|
+
{merge line}
|
|
181
188
|
```
|
|
182
189
|
|
|
183
|
-
|
|
190
|
+
`{merge line}` for `dev` / `test` / `staging`:
|
|
191
|
+
|
|
192
|
+
```
|
|
193
|
+
Waiting on Serena's review. When she approves I'll complete the PR, which
|
|
194
|
+
triggers the {environment} CD pipeline; when that comes back green I'll set
|
|
195
|
+
these {count} items to `{state after merge}` and assign them as approved
|
|
196
|
+
above. Say `don't merge` to stop before the merge, or `stop watching` to
|
|
197
|
+
leave the work item states alone.
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
`{merge line}` for `prod` / `main`:
|
|
201
|
+
|
|
202
|
+
```
|
|
203
|
+
A reviewer approves and completes this one — I don't merge into {environment}.
|
|
204
|
+
I'm watching the PR and that pipeline: when it comes back green I'll set these
|
|
205
|
+
{count} items to `{state after merge}` and assign them as approved above.
|
|
206
|
+
Nothing is written until then. Say `stop watching` to leave the states alone.
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
### 7b. Wait for Serena's approval (`dev` / `test` / `staging` only)
|
|
210
|
+
|
|
211
|
+
Serena is the AI reviewer on this org's pull requests. Find her among the PR's reviewers by matching `serena` case-insensitively against `displayName` / `uniqueName` — never hardcode an identity id, and never count another reviewer's approval as hers.
|
|
212
|
+
|
|
213
|
+
Reviewer votes: `10` approved · `5` approved with suggestions · `0` no vote yet · `-5` waiting for author · `-10` rejected.
|
|
214
|
+
|
|
215
|
+
- `10` or `5` → approved. Go to 7c.
|
|
216
|
+
- `-5` or `-10` → **do not merge.** List her threads (`repo_pull_request_thread` `action: list`), report what she flagged, and stop. `/resolve-feedback {pr-id}` addresses them; her vote is re-evaluated after the next push.
|
|
217
|
+
- `0`, or she is not on the reviewer list yet → keep polling.
|
|
218
|
+
|
|
219
|
+
**Never cast a vote on the PR yourself** to satisfy an approval policy, and never add yourself as a reviewer to do it.
|
|
220
|
+
|
|
221
|
+
Poll in the background — never a foreground `sleep`:
|
|
222
|
+
|
|
223
|
+
```bash
|
|
224
|
+
ORG=<org-url>; PR=<pr-id>; TRIES=0
|
|
225
|
+
while [ $TRIES -lt 120 ]; do
|
|
226
|
+
VOTE=$(az repos pr show --id "$PR" --org "$ORG" \
|
|
227
|
+
--query "reviewers[].[displayName,vote]" -o tsv \
|
|
228
|
+
| grep -i serena | cut -f2 | head -1)
|
|
229
|
+
case "$VOTE" in
|
|
230
|
+
10|5) echo "APPROVED vote=$VOTE"; break ;;
|
|
231
|
+
-5|-10) echo "BLOCKED vote=$VOTE"; break ;;
|
|
232
|
+
*) TRIES=$((TRIES + 1)); sleep 30 ;;
|
|
233
|
+
esac
|
|
234
|
+
done
|
|
235
|
+
[ $TRIES -ge 120 ] && echo "TIMEOUT - no Serena vote after 60 minutes"
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
Run it with `Monitor` (or Bash `run_in_background`). An empty `VOTE` means she isn't a reviewer yet, which is why the loop keeps going rather than treating it as a decision. Without the Azure CLI, poll `repo_pull_request` `action: get` on the same ~30-second cadence and read `reviewers[]`.
|
|
239
|
+
|
|
240
|
+
If the loop times out, leave the PR open and ask whether to keep waiting or merge without her. **If she was never added as a reviewer at all, say exactly that** — it usually means the PR was never picked up for review, not that it sailed through.
|
|
241
|
+
|
|
242
|
+
### 7c. Complete the PR
|
|
243
|
+
|
|
244
|
+
Merge with `repo_pull_request_write` `action: update`:
|
|
245
|
+
|
|
246
|
+
| Field | Value | Why |
|
|
247
|
+
|---|---|---|
|
|
248
|
+
| `autoComplete` | `true` | ADO completes it the moment the remaining branch policies pass — a required build still gates the merge |
|
|
249
|
+
| `mergeStrategy` | `NoFastForward` | one merge commit, cherry-pick history intact |
|
|
250
|
+
| `transitionWorkItems` | `false` | **required.** This command owns the work item states (Step 8); ADO's own transition moves parents too |
|
|
251
|
+
| `deleteSourceBranch` | `true` | the `cherry-pick/...` branch is disposable |
|
|
252
|
+
| `bypassPolicy` | **never set it** | a policy that isn't passing is a stop, not an obstacle |
|
|
253
|
+
|
|
254
|
+
Then poll `repo_pull_request` `action: get` until `status` is `completed`. If it stays `Active` with autocomplete queued, a branch policy is unmet — report which one and stop; do not bypass it and do not push to the source branch to force it.
|
|
255
|
+
|
|
256
|
+
CLI fallback if the MCP update fails:
|
|
257
|
+
|
|
258
|
+
```bash
|
|
259
|
+
az repos pr update --id <pr-id> --org <org-url> \
|
|
260
|
+
--auto-complete true --transition-work-items false --delete-source-branch true \
|
|
261
|
+
--merge-commit-message "Cherry-pick AB#1234, AB#1240 -> {Environment}"
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
If the user said `don't merge`, leave the PR open, say so, and skip to 7d — a human merging it later still gets the pipeline watch and the state changes.
|
|
265
|
+
|
|
266
|
+
### 7d. Watch the CD pipeline
|
|
267
|
+
|
|
268
|
+
1. **Confirm the PR completed.** Poll `repo_pull_request` until `status` is `completed`; note the merge commit and completion time. `abandoned` → stop, change nothing, report it.
|
|
184
269
|
2. **Find the CD run.** Look up the target branch's pipeline ID(s) in the Pipeline Configuration table, then poll `pipelines_build` for runs on `refs/heads/<target-branch>` queued at or after the merge time — match the merge commit when the run exposes it — and **capture each run's id**. A run that was already completed before the merge is not this deployment; ignore it. A branch with more than one pipeline (API + Client) must have **all** of them green.
|
|
185
270
|
3. **Wait for a terminal result** on each run: `succeeded`, `partiallySucceeded`, `failed`, or `canceled`.
|
|
186
271
|
|
|
@@ -217,9 +217,20 @@ Approve? (yes / change)
|
|
|
217
217
|
|
|
218
218
|
`change` re-asks 8c. Only after `yes` do you move on — if the PR merges before the user answers, keep waiting for the answer, then run Step 10.
|
|
219
219
|
|
|
220
|
-
## Step 9:
|
|
220
|
+
## Step 9: Get the PR Merged, Then Watch the Pipeline
|
|
221
221
|
|
|
222
|
-
|
|
222
|
+
Never trigger the CD pipeline by hand — it triggers on the merge.
|
|
223
|
+
|
|
224
|
+
### 9a. Who completes the PR depends on the target
|
|
225
|
+
|
|
226
|
+
| Target | Who merges |
|
|
227
|
+
|---|---|
|
|
228
|
+
| `dev`, `test`, `staging` | **You do** — poll until Serena approves, then complete the PR (9b–9c) |
|
|
229
|
+
| `prod` | A human. **Never auto-merge into production.** |
|
|
230
|
+
|
|
231
|
+
Resolve the target through the Pipeline Configuration table, not by the spelling of the branch — a project whose staging branch is named `Staging` or `release/staging` is still staging, and a project with no `test` row simply has no test hop.
|
|
232
|
+
|
|
233
|
+
Report the PR either way:
|
|
223
234
|
|
|
224
235
|
```
|
|
225
236
|
Release #{N} PR created for {environment}.
|
|
@@ -232,13 +243,89 @@ Work items included:
|
|
|
232
243
|
- AB#1236: COM - View history
|
|
233
244
|
- AB#1240: PAY - Fix login redirect
|
|
234
245
|
|
|
235
|
-
|
|
236
|
-
|
|
246
|
+
{merge line}
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
`{merge line}` for `dev` / `test` / `staging`:
|
|
250
|
+
|
|
251
|
+
```
|
|
252
|
+
Waiting on Serena's review. When she approves I'll complete the PR, which
|
|
253
|
+
triggers the {environment} CD pipeline; when that comes back green I'll set
|
|
254
|
+
these {count} items to `{state after merge}` and assign them as approved
|
|
255
|
+
above. Say `don't merge` to stop before the merge, or `stop watching` to
|
|
256
|
+
leave the work item states alone.
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
`{merge line}` for `prod`:
|
|
260
|
+
|
|
261
|
+
```
|
|
262
|
+
Review and approve the PR — a person merges this one; I don't merge into
|
|
263
|
+
production. Merging it triggers the CD pipeline for {environment}. I'm
|
|
264
|
+
watching the PR and that pipeline; when it comes back green I'll set these
|
|
237
265
|
{count} items to `{state after merge}` and assign them as approved above.
|
|
238
266
|
Nothing is written until then. Say `stop watching` to leave the states alone.
|
|
239
267
|
```
|
|
240
268
|
|
|
241
|
-
|
|
269
|
+
### 9b. Wait for Serena's approval (`dev` / `test` / `staging` only)
|
|
270
|
+
|
|
271
|
+
Serena is the AI reviewer on this org's pull requests. Find her among the PR's reviewers by matching `serena` case-insensitively against `displayName` / `uniqueName` — never hardcode an identity id, and never count another reviewer's approval as hers.
|
|
272
|
+
|
|
273
|
+
Reviewer votes: `10` approved · `5` approved with suggestions · `0` no vote yet · `-5` waiting for author · `-10` rejected.
|
|
274
|
+
|
|
275
|
+
- `10` or `5` → approved. Go to 9c.
|
|
276
|
+
- `-5` or `-10` → **do not merge.** List her threads (`repo_pull_request_thread` `action: list`), report what she flagged, and stop. A release branch is a cherry-pick of commits that already merged upstream, so the fix usually belongs on the source branch and comes forward in the next release — not as a patch commit on `release/{N}-to-{environment}`.
|
|
277
|
+
- `0`, or she is not on the reviewer list yet → keep polling.
|
|
278
|
+
|
|
279
|
+
**Never cast a vote on the PR yourself** to satisfy an approval policy, and never add yourself as a reviewer to do it.
|
|
280
|
+
|
|
281
|
+
Poll in the background — never a foreground `sleep`:
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
ORG=<org-url>; PR=<pr-id>; TRIES=0
|
|
285
|
+
while [ $TRIES -lt 120 ]; do
|
|
286
|
+
VOTE=$(az repos pr show --id "$PR" --org "$ORG" \
|
|
287
|
+
--query "reviewers[].[displayName,vote]" -o tsv \
|
|
288
|
+
| grep -i serena | cut -f2 | head -1)
|
|
289
|
+
case "$VOTE" in
|
|
290
|
+
10|5) echo "APPROVED vote=$VOTE"; break ;;
|
|
291
|
+
-5|-10) echo "BLOCKED vote=$VOTE"; break ;;
|
|
292
|
+
*) TRIES=$((TRIES + 1)); sleep 30 ;;
|
|
293
|
+
esac
|
|
294
|
+
done
|
|
295
|
+
[ $TRIES -ge 120 ] && echo "TIMEOUT - no Serena vote after 60 minutes"
|
|
296
|
+
```
|
|
297
|
+
|
|
298
|
+
Run it with `Monitor` (or Bash `run_in_background`). An empty `VOTE` means she isn't a reviewer yet, which is why the loop keeps going rather than treating it as a decision. Without the Azure CLI, poll `repo_pull_request` `action: get` on the same ~30-second cadence and read `reviewers[]`.
|
|
299
|
+
|
|
300
|
+
If the loop times out, leave the PR open and ask whether to keep waiting or merge without her. **If she was never added as a reviewer at all, say exactly that** — it usually means the PR was never picked up for review, not that it sailed through.
|
|
301
|
+
|
|
302
|
+
### 9c. Complete the PR
|
|
303
|
+
|
|
304
|
+
Merge with `repo_pull_request_write` `action: update`:
|
|
305
|
+
|
|
306
|
+
| Field | Value | Why |
|
|
307
|
+
|---|---|---|
|
|
308
|
+
| `autoComplete` | `true` | ADO completes it the moment the remaining branch policies pass — a required build still gates the merge |
|
|
309
|
+
| `mergeStrategy` | `NoFastForward` | one merge commit, cherry-pick history intact |
|
|
310
|
+
| `transitionWorkItems` | `false` | **required.** This command owns the work item states (Step 10); ADO's own transition moves parents too |
|
|
311
|
+
| `deleteSourceBranch` | `true` | the `release/{N}-to-{environment}` branch is disposable — the release itself lives in the iteration and the `release-{N}` tags |
|
|
312
|
+
| `bypassPolicy` | **never set it** | a policy that isn't passing is a stop, not an obstacle |
|
|
313
|
+
|
|
314
|
+
Then poll `repo_pull_request` `action: get` until `status` is `completed`. If it stays `Active` with autocomplete queued, a branch policy is unmet — report which one and stop; do not bypass it and do not push to the source branch to force it.
|
|
315
|
+
|
|
316
|
+
CLI fallback if the MCP update fails:
|
|
317
|
+
|
|
318
|
+
```bash
|
|
319
|
+
az repos pr update --id <pr-id> --org <org-url> \
|
|
320
|
+
--auto-complete true --transition-work-items false --delete-source-branch true \
|
|
321
|
+
--merge-commit-message "Release #{N} -> {Environment}"
|
|
322
|
+
```
|
|
323
|
+
|
|
324
|
+
If the user said `don't merge`, leave the PR open, say so, and skip to 9d — a human merging it later still gets the pipeline watch and the state changes.
|
|
325
|
+
|
|
326
|
+
### 9d. Watch the CD pipeline
|
|
327
|
+
|
|
328
|
+
1. **Confirm the PR completed.** Poll `repo_pull_request` until `status` is `completed`; note the merge commit and completion time. `abandoned` → stop, change nothing, report it.
|
|
242
329
|
2. **Find the CD run.** Look up the target branch's pipeline ID(s) in the Pipeline Configuration table, then poll `pipelines_build` for runs on `refs/heads/<target-branch>` queued at or after the merge time — match the merge commit when the run exposes it — and **capture each run's id**. A run that was already completed before the merge is not this deployment; ignore it. A branch with more than one pipeline (API + Client) must have **all** of them green.
|
|
243
330
|
3. **Wait for a terminal result** on each run: `succeeded`, `partiallySucceeded`, `failed`, or `canceled`.
|
|
244
331
|
|
|
@@ -159,9 +159,18 @@ Approve? (yes / change)
|
|
|
159
159
|
|
|
160
160
|
`change` re-asks 5c. Only after `yes` do you move on — if the PR merges before the user answers, keep waiting for the answer, then run Step 7.
|
|
161
161
|
|
|
162
|
-
## Step 6:
|
|
162
|
+
## Step 6: Get the PR Merged, Then Watch the Pipeline
|
|
163
163
|
|
|
164
|
-
|
|
164
|
+
### 6a. Who completes the PR depends on the target
|
|
165
|
+
|
|
166
|
+
| Target | Who merges |
|
|
167
|
+
|---|---|
|
|
168
|
+
| `dev`, `test`, `staging` | **You do** — poll until Serena approves, then complete the PR (6b–6c) |
|
|
169
|
+
| `prod` | A human. **Never auto-merge into production.** |
|
|
170
|
+
|
|
171
|
+
Resolve the target through the Pipeline Configuration table, not by the spelling of the branch — a project whose staging branch is named `Staging` or `release/staging` is still staging, and a project with no `test` row simply has no test hop.
|
|
172
|
+
|
|
173
|
+
Report the PR either way:
|
|
165
174
|
|
|
166
175
|
```
|
|
167
176
|
Promotion PR created: {source} → {target}
|
|
@@ -169,13 +178,88 @@ Promotion PR created: {source} → {target}
|
|
|
169
178
|
PR: {pr-url}
|
|
170
179
|
|
|
171
180
|
{count} commits, {n} work items included.
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
181
|
+
{merge line}
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
`{merge line}` for `dev` / `test` / `staging`:
|
|
185
|
+
|
|
186
|
+
```
|
|
187
|
+
Waiting on Serena's review. When she approves I'll complete the PR, which
|
|
188
|
+
triggers the {target} CD pipeline; when that comes back green I'll set the
|
|
189
|
+
{n} work items to `{state after merge}` and assign them as approved above.
|
|
190
|
+
Say `don't merge` to stop before the merge, or `stop watching` to leave the
|
|
191
|
+
work item states alone.
|
|
192
|
+
```
|
|
193
|
+
|
|
194
|
+
`{merge line}` for `prod`:
|
|
195
|
+
|
|
196
|
+
```
|
|
197
|
+
A reviewer approves and completes this one — I don't merge into production.
|
|
198
|
+
I'm watching the PR and that pipeline: when it comes back green I'll set the
|
|
199
|
+
{n} work items to `{state after merge}` and assign them as approved above.
|
|
200
|
+
Nothing is written until then. Say `stop watching` to leave the states alone.
|
|
201
|
+
```
|
|
202
|
+
|
|
203
|
+
### 6b. Wait for Serena's approval (`dev` / `test` / `staging` only)
|
|
204
|
+
|
|
205
|
+
Serena is the AI reviewer on this org's pull requests. Find her among the PR's reviewers by matching `serena` case-insensitively against `displayName` / `uniqueName` — never hardcode an identity id, and never count another reviewer's approval as hers.
|
|
206
|
+
|
|
207
|
+
Reviewer votes: `10` approved · `5` approved with suggestions · `0` no vote yet · `-5` waiting for author · `-10` rejected.
|
|
208
|
+
|
|
209
|
+
- `10` or `5` → approved. Go to 6c.
|
|
210
|
+
- `-5` or `-10` → **do not merge.** List her threads (`repo_pull_request_thread` `action: list`), report what she flagged, and stop. On a promotion the fix belongs on the source branch, not on the PR — a promotion PR has no branch of its own to push to.
|
|
211
|
+
- `0`, or she is not on the reviewer list yet → keep polling.
|
|
212
|
+
|
|
213
|
+
**Never cast a vote on the PR yourself** to satisfy an approval policy, and never add yourself as a reviewer to do it.
|
|
214
|
+
|
|
215
|
+
Poll in the background — never a foreground `sleep`:
|
|
216
|
+
|
|
217
|
+
```bash
|
|
218
|
+
ORG=<org-url>; PR=<pr-id>; TRIES=0
|
|
219
|
+
while [ $TRIES -lt 120 ]; do
|
|
220
|
+
VOTE=$(az repos pr show --id "$PR" --org "$ORG" \
|
|
221
|
+
--query "reviewers[].[displayName,vote]" -o tsv \
|
|
222
|
+
| grep -i serena | cut -f2 | head -1)
|
|
223
|
+
case "$VOTE" in
|
|
224
|
+
10|5) echo "APPROVED vote=$VOTE"; break ;;
|
|
225
|
+
-5|-10) echo "BLOCKED vote=$VOTE"; break ;;
|
|
226
|
+
*) TRIES=$((TRIES + 1)); sleep 30 ;;
|
|
227
|
+
esac
|
|
228
|
+
done
|
|
229
|
+
[ $TRIES -ge 120 ] && echo "TIMEOUT - no Serena vote after 60 minutes"
|
|
176
230
|
```
|
|
177
231
|
|
|
178
|
-
|
|
232
|
+
Run it with `Monitor` (or Bash `run_in_background`). An empty `VOTE` means she isn't a reviewer yet, which is why the loop keeps going rather than treating it as a decision. Without the Azure CLI, poll `repo_pull_request` `action: get` on the same ~30-second cadence and read `reviewers[]`.
|
|
233
|
+
|
|
234
|
+
If the loop times out, leave the PR open and ask whether to keep waiting or merge without her. **If she was never added as a reviewer at all, say exactly that** — it usually means the PR was never picked up for review, not that it sailed through.
|
|
235
|
+
|
|
236
|
+
### 6c. Complete the PR
|
|
237
|
+
|
|
238
|
+
Merge with `repo_pull_request_write` `action: update`:
|
|
239
|
+
|
|
240
|
+
| Field | Value | Why |
|
|
241
|
+
|---|---|---|
|
|
242
|
+
| `autoComplete` | `true` | ADO completes it the moment the remaining branch policies pass — a required build still gates the merge |
|
|
243
|
+
| `mergeStrategy` | `NoFastForward` | one merge commit; never squash a promotion — it rewrites the commit ids the next hop cherry-picks by |
|
|
244
|
+
| `transitionWorkItems` | `false` | **required.** This command owns the work item states (Step 7); ADO's own transition moves parents too |
|
|
245
|
+
| `deleteSourceBranch` | **`false`** | the source is a long-lived environment branch (`main`, `dev`, `test`, `staging`) — deleting it would destroy the promotion chain |
|
|
246
|
+
| `bypassPolicy` | **never set it** | a policy that isn't passing is a stop, not an obstacle |
|
|
247
|
+
|
|
248
|
+
Then poll `repo_pull_request` `action: get` until `status` is `completed`. If it stays `Active` with autocomplete queued, a branch policy is unmet — report which one and stop; do not bypass it and do not push to the source branch to force it.
|
|
249
|
+
|
|
250
|
+
CLI fallback if the MCP update fails:
|
|
251
|
+
|
|
252
|
+
```bash
|
|
253
|
+
az repos pr update --id <pr-id> --org <org-url> \
|
|
254
|
+
--auto-complete true --transition-work-items false --delete-source-branch false \
|
|
255
|
+
--merge-commit-message "Promote {source} -> {target}"
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
If the user said `don't merge`, leave the PR open, say so, and skip to 6d — a human merging it later still gets the pipeline watch and the state changes.
|
|
259
|
+
|
|
260
|
+
### 6d. Watch the CD pipeline
|
|
261
|
+
|
|
262
|
+
1. **Confirm the PR completed.** Poll `repo_pull_request` until `status` is `completed`; note the merge commit and the completion time. `abandoned` → stop, change nothing, report it.
|
|
179
263
|
2. **Find the CD run.** Look up the target branch's pipeline ID(s) in the Pipeline Configuration table, then poll `pipelines_build` for runs on `refs/heads/<target-branch>` queued at or after the merge time — match the merge commit when the run exposes it — and **capture each run's id**. A run that was already completed before the merge is not this deployment; ignore it. A branch with more than one pipeline (API + Client) must have **all** of them green.
|
|
180
264
|
3. **Wait for a terminal result** on each run: `succeeded`, `partiallySucceeded`, `failed`, or `canceled`.
|
|
181
265
|
|
|
@@ -102,7 +102,7 @@ Claude maintains persistent memory across sessions in `~/.claude/projects/.../me
|
|
|
102
102
|
4. **PR merges** into `main` — the compare branch. **Nothing deploys yet.** The work item stays in `Code Review` until it is promoted
|
|
103
103
|
5. **Promote or release** — `/promote main dev` carries everything on `main` to Dev; `/create-release <N>` groups work items so `/deploy-release <N> test` → `staging` → `prod` can carry just those
|
|
104
104
|
6. **Say who verifies** — before the merge, the command asks who each product group (`COM`, `PAY`, …) should be assigned to in the target environment, offering the non-developer names already on those work items
|
|
105
|
-
7. **
|
|
105
|
+
7. **The promotion PR merges** — for `dev`, `test`, and `staging`, the deploy commands wait for Serena to approve and then complete the PR themselves; a `prod` PR is always merged by a person. That merge triggers the environment's CD pipeline. The command watches it and, once it's green, sets the work items to `Testing`, `Staging`, or `Deployed` **and** assigns them to the approved verifiers — automatically, no reply needed
|
|
106
106
|
8. **Test** using Playwright MCP for browser testing
|
|
107
107
|
9. **Track** work items via the Azure DevOps MCP server
|
|
108
108
|
10. **Learn** — Claude saves what worked for next time
|
|
@@ -179,6 +179,7 @@ How the commands use this table:
|
|
|
179
179
|
|
|
180
180
|
- **Gate check before the PR.** `/deploy-release`, `/cherry-pick`, and `/promote` compare each carried work item's state against the gate for the target environment. Anything behind the gate (e.g. still `Testing` when deploying to `staging`) is flagged and the user decides whether to include it. Items *ahead* of the gate (e.g. already `Deployed` on a cherry-pick to `prod`) are reported and left alone.
|
|
181
181
|
- **Advance on a green pipeline, automatically.** `/promote`, `/cherry-pick`, and `/deploy-release` do not stop at the PR. They poll it until it is `completed`, then poll the target branch's CD pipeline until every run finishes. Only on `succeeded` do they write the new state — for every carried User Story, Bug, and Hot Fix, never a Feature or Task, and never backward. A failed or canceled run changes **nothing** and is reported with the log link. `/track` reports items whose state lags the branch their commits are on and offers to catch them up.
|
|
182
|
+
- **Auto-merge below production.** When the target is `dev`, `test`, or `staging`, all three commands poll the PR until **Serena** (the AI reviewer) votes, then complete it with autocomplete — remaining branch policies still gate the merge, work item transitions are left off so the command's own state logic owns them, and a branch policy that isn't passing is a stop, never a bypass. A rejection or *waiting for author* vote stops the merge and reports her threads. A PR into `prod` (or into `main`) is **always** merged by a person.
|
|
182
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.
|
|
183
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.
|
|
184
185
|
|
|
@@ -207,7 +208,7 @@ This creates a `Release #23` iteration, assigns the selected work items to it, a
|
|
|
207
208
|
/deploy-release 23 staging
|
|
208
209
|
/deploy-release 23 prod
|
|
209
210
|
```
|
|
210
|
-
This finds all work items in Release #23, checks each one against the target environment's gate state, cherry-picks their commits into a release branch (`release/23-to-staging`), creates a PR targeting the environment branch, links all work items, asks who verifies each product group, and — once the merge's CD pipeline comes back green — advances them to the environment's state (`Testing`, `Staging`, `Deployed`) and assigns them to those verifiers.
|
|
211
|
+
This finds all work items in Release #23, checks each one against the target environment's gate state, cherry-picks their commits into a release branch (`release/23-to-staging`), creates a PR targeting the environment branch, links all work items, asks who verifies each product group, merges the PR once Serena approves it (`dev`/`test`/`staging` only — a `prod` PR waits for a person), and — once the merge's CD pipeline comes back green — advances them to the environment's state (`Testing`, `Staging`, `Deployed`) and assigns them to those verifiers.
|
|
211
212
|
|
|
212
213
|
**Selective deployment:** Since releases are deployed via cherry-pick, you can deploy a full release or a subset. If staging has 5 user stories but only 3 are `Ready to Deploy`, create a release with just those 3 and deploy it.
|
|
213
214
|
|
|
@@ -227,7 +228,7 @@ Cherry-pick specific work items to an environment without a formal release:
|
|
|
227
228
|
```
|
|
228
229
|
/cherry-pick AB#1234 AB#1235 prod
|
|
229
230
|
```
|
|
230
|
-
This finds commits for the specified work items, checks them against the target's gate state, cherry-picks them into a branch (`cherry-pick/<date>-to-<environment>`), creates a PR, asks who verifies each product group, and — once the merge's CD pipeline is green — advances and assigns the work items.
|
|
231
|
+
This finds commits for the specified work items, checks them against the target's gate state, cherry-picks them into a branch (`cherry-pick/<date>-to-<environment>`), creates a PR, asks who verifies each product group, merges the PR once Serena approves it (`dev`/`test`/`staging` only — a `prod` PR waits for a person), and — once the merge's CD pipeline is green — advances and assigns the work items.
|
|
231
232
|
|
|
232
233
|
#### Promoting Environments
|
|
233
234
|
|
|
@@ -237,7 +238,7 @@ Promote all code from one environment to the next:
|
|
|
237
238
|
/promote staging prod
|
|
238
239
|
/promote ← auto-detects source and target from current branch
|
|
239
240
|
```
|
|
240
|
-
This creates a PR from the source branch to the target branch with a summary of all included commits and their work items, checks the work items against the target's gate state, asks who verifies each product group, and — once the merge's CD pipeline is green — advances and assigns them. `main → dev` is the usual first hop after feature PRs merge.
|
|
241
|
+
This creates a PR from the source branch to the target branch with a summary of all included commits and their work items, checks the work items against the target's gate state, asks who verifies each product group, merges the PR once Serena approves it (`dev`/`test`/`staging` only — a `prod` PR waits for a person), and — once the merge's CD pipeline is green — advances and assigns them. `main → dev` is the usual first hop after feature PRs merge.
|
|
241
242
|
|
|
242
243
|
#### Rollbacks
|
|
243
244
|
|
|
@@ -302,10 +303,10 @@ All deployment and release operations are available as slash commands:
|
|
|
302
303
|
| `/resolve-feedback` | `/resolve-feedback 142` | Address unresolved PR comment threads, push fixes, reply + resolve threads |
|
|
303
304
|
| `/deploy` | `/deploy "commit message"` | Commit, push, trigger pipeline (only on `dev`/`test`/`staging`/`prod` — never on `main`) |
|
|
304
305
|
| `/create-release` | `/create-release 23` | Group work items into Release #23 |
|
|
305
|
-
| `/deploy-release` | `/deploy-release 23 staging` | Gate-check → cherry-pick release to environment → PR → ask who verifies → advance + assign on a green pipeline |
|
|
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 |
|
|
306
307
|
| `/add-to-release` | `/add-to-release 24 AB#4599` | Add work items to existing release |
|
|
307
|
-
| `/cherry-pick` | `/cherry-pick AB#1234 AB#1235 prod` | Gate-check → cherry-pick specific work items → PR → ask who verifies → advance + assign on a green pipeline |
|
|
308
|
-
| `/promote` | `/promote main dev` | Promote all code between environments (`main → dev → test → staging → prod`) → ask who verifies → advance + assign on a green pipeline |
|
|
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 |
|
|
309
310
|
| `/rollback` | `/rollback AB#1234 prod` | Revert commits on an environment |
|
|
310
311
|
| `/track` | `/track release 24` | Check release, pipeline, environment, or work item status; flags work items whose state lags their environment |
|
|
311
312
|
| `/where` | `/where AB#1234` | Show which environment branches contain a work item's commits |
|