Skip to content

Commit 3bbee5c

Browse files
committed
Expand ELM migration docs and TSG guidance
1 parent c50b636 commit 3bbee5c

2 files changed

Lines changed: 100 additions & 14 deletions

File tree

doc/elm_migrations_tsg.md

Lines changed: 49 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,8 @@ This saves you from typing `--org` on every single command:
5151
az devops configure -d organization=https://dev.azure.com/<your-org>
5252
```
5353

54+
If your local git remote points to a different org, add `--detect false` to migration commands to prevent auto-detect from choosing the wrong org.
55+
5456
### 1.5 Verify your config
5557

5658
```powershell
@@ -83,7 +85,7 @@ And has one of these **statuses**:
8385
The safest approach is **validate first, then migrate**:
8486

8587
```
86-
Create (validate-only) → Check status → Pause → Resume (--migration) → Monitor → Schedule cutover → Done
88+
Create (validate-only) → Check status → Resume (--migration) → Monitor → Schedule cutover → Done
8789
```
8890

8991
---
@@ -180,18 +182,31 @@ az devops migrations status --detect false --repository-id b3e18946-5b39-40ca-8e
180182

181183
**When to do this:** After step 3.4 shows `status: Succeeded` (validation passed).
182184

183-
You need to pause first (because the migration may still be active), then resume in migration mode:
185+
Resume in migration mode:
184186

185187
```powershell
186-
# Step A: Pause the current migration
187-
az devops migrations pause --detect false --repository-id b3e18946-5b39-40ca-8e2f-d0eb683d8a85
188-
189-
# Step B: Resume as a full migration (this starts data movement)
188+
# Promote validate-only success to full migration (this starts data movement)
190189
az devops migrations resume --detect false --repository-id b3e18946-5b39-40ca-8e2f-d0eb683d8a85 --migration
191190
```
192191

193-
> **If you get:** `Migration is active (status: ..., stage: ...). Pause it before resuming or changing mode.`
194-
> Run the pause command first (Step A), then retry Step B.
192+
Under the hood, this updates the existing migration (PUT) with:
193+
194+
- `validateOnly=false`
195+
- `statusRequested=active`
196+
197+
No new migration is created.
198+
199+
> **If you get an active-state error:**
200+
>
201+
> `Migration is currently active (...). Pause it first using "az devops migrations pause --repository-id <guid>" before resuming or changing mode.`
202+
>
203+
> run:
204+
205+
```powershell
206+
az devops migrations pause --detect false --repository-id b3e18946-5b39-40ca-8e2f-d0eb683d8a85
207+
```
208+
209+
then retry `resume --migration`.
195210

196211
After this, monitor with step 3.4 until `stage: Synchronization` is running.
197212

@@ -280,7 +295,7 @@ az devops migrations resume --detect false --repository-id <GUID> --validate-onl
280295
|---|---|---|---|---|
281296
| `list` | `--org` | `--include-inactive`, `--detect` | GET | List migrations. By default only active ones. |
282297
| `status` | `--org`, `--repository-id` | `--detect` | GET | Get detailed status for one migration. |
283-
| `create` | `--org`, `--repository-id`, `--target-repository`, `--target-owner-user-id`, `--agent-pool` | `--validate-only`, `--cutover-date`, `--skip-validation`, `--detect` | POST | Create a new migration. |
298+
| `create` | `--org`, `--repository-id`, `--target-repository`, `--target-owner-user-id` | `--agent-pool`, `--validate-only`, `--cutover-date`, `--skip-validation`, `--detect` | POST | Create a new migration. |
284299
| `pause` | `--org`, `--repository-id` | `--detect` | PUT | Pause an active migration. |
285300
| `resume` | `--org`, `--repository-id` | `--validate-only`, `--migration`, `--detect` | PUT | Resume a stopped migration. |
286301
| `cutover set` | `--org`, `--repository-id`, `--date` | `--detect` | PUT | Schedule a cutover date/time. |
@@ -293,11 +308,11 @@ az devops migrations resume --detect false --repository-id <GUID> --validate-onl
293308
|---|---|---|---|
294309
| `--org` | URL | All | Azure DevOps org URL (e.g., `https://dev.azure.com/myorg`). Can be set as default. |
295310
| `--repository-id` | GUID | All except `list` | Azure Repos repository GUID. Get from `az repos show --query id`. |
296-
| `--target-repository` | URL | `create` | Target repository URL (e.g., `https://example.ghe.com/OrgName/RepoName`). Validated by the server. |
311+
| `--target-repository` | URL | `create` | Target repository URL (e.g., `https://example.ghe.com/OrgName/RepoName`). Must start with `http://` or `https://`. |
297312
| `--target-owner-user-id` | string | `create` | Target repository owner user ID. |
298-
| `--agent-pool` | string | `create` | Agent pool name for migration work. Required. |
313+
| `--agent-pool` | string | `create` | Agent pool name for migration work. Optional. |
299314
| `--validate-only` | flag | `create`, `resume` | On `create`: run pre-migration checks only. On `resume`: switch to validate-only mode. |
300-
| `--migration` | flag | `resume` | Switch to full migration mode (clears validate-only). Mutually exclusive with `--validate-only`. |
315+
| `--migration` | flag | `resume` | Promote succeeded validate-only to full migration (`validateOnly=false`, `statusRequested=active`). Mutually exclusive with `--validate-only`. |
301316
| `--cutover-date` | ISO 8601 | `create` | Pre-schedule cutover at creation time. E.g., `2030-12-31T11:59:00Z`. |
302317
| `--date` | ISO 8601 | `cutover set` | Schedule cutover date/time. E.g., `2030-12-31T11:59:00Z`. |
303318
| `--skip-validation` | string | `create` | Comma-separated list of validation policies to skip. |
@@ -312,7 +327,8 @@ az devops migrations resume --detect false --repository-id <GUID> --validate-onl
312327
| **Stale default org in config** | Requests go to old/dev URL (e.g., `codedev.ms`) | Run `az devops configure -d organization=https://dev.azure.com/<your-org>` to update |
313328
| **Resume on an active migration** | Error: "Migration is active..." | Pause first with `az devops migrations pause`, then resume |
314329
| **Both `--validate-only` and `--migration` on resume** | Error: "Please specify only one..." | Use only one flag at a time |
315-
| **Missing `--agent-pool` on create** | Error: "--agent-pool must be specified." | Always provide `--agent-pool <PoolName>` |
330+
| **Missing `--target-repository` on create** | Error: "--target-repository must be specified." | Provide `--target-repository <URL>` |
331+
| **Invalid `--target-repository` format** | Error: "--target-repository must be a valid URL..." | Use a fully qualified URL starting with `http://` or `https://` |
316332
| **Invalid `--repository-id`** | Error: "--repository-id must be a valid GUID." | Use `az repos show --query id` to get the correct GUID |
317333
| **Bad date format** | Error: "must be a valid date or datetime string" | Use ISO 8601 format, e.g., `2030-12-31T11:59:00Z` |
318334

@@ -344,6 +360,26 @@ az devops migrations resume --detect false --repository-id <GUID> --validate-onl
344360
2. Ensure `--target-repository` is a valid URL.
345361
3. Ensure `--agent-pool` matches a pool name the service recognizes.
346362

363+
### Promote validate-only does not start
364+
365+
**Symptom:** `resume --migration` does not proceed, or returns a state error.
366+
367+
**Fix:**
368+
1. Confirm current state first:
369+
370+
```powershell
371+
az devops migrations status --detect false --repository-id <GUID> -o json
372+
```
373+
374+
2. If migration is active, pause then retry:
375+
376+
```powershell
377+
az devops migrations pause --detect false --repository-id <GUID>
378+
az devops migrations resume --detect false --repository-id <GUID> --migration
379+
```
380+
381+
3. If migration already succeeded as full migration, abandon and recreate if needed.
382+
347383
### 406 Not Acceptable
348384

349385
**Symptom:** `Request failed with status 406`.

doc/migrations.md

Lines changed: 51 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,21 @@ az devops configure --defaults organization=https://dev.azure.com/myorg
1313
```
1414

1515
- You can still override per command with `--org`.
16+
- If your current git remote points to another org, add `--detect false` to avoid auto-detect choosing the wrong organization.
17+
18+
## Migration lifecycle model
19+
20+
Typical active stages:
21+
22+
`queued -> validation -> synchronization -> cutover`
23+
24+
Key fields in `status` output:
25+
26+
- `statusRequested`: Desired state requested by the CLI (for example, `active`, `suspended`).
27+
- `status`: Service-reported status (for example, `succeeded`, `failed`).
28+
- `stage`: Current running stage while active.
29+
30+
Use all three fields together when troubleshooting state transitions.
1631

1732
## Required inputs
1833

@@ -22,6 +37,11 @@ az devops configure --defaults organization=https://dev.azure.com/myorg
2237
- `--agent-pool` is optional for create.
2338
- `--cutover-date` / `--date` must be ISO 8601, for example: `2030-12-31T11:59:00Z`.
2439

40+
Validation enforced by the CLI:
41+
42+
- `--target-repository` must start with `http://` or `https://`.
43+
- `--repository-id` must be a valid GUID.
44+
2545
### How to find `--repository-id`
2646

2747
```bash
@@ -38,7 +58,7 @@ az repos show --repository MyRepo --project MyProject --query id -o tsv
3858
- `--validate-only`: Resume in validate-only mode.
3959
- `--migration`: Promote a succeeded validate-only migration to full migration.
4060
This updates the existing migration by setting `validateOnly=false` and `statusRequested=active`.
41-
If a migration is active, pause it before resuming.
61+
If a migration is currently active, pause it before resuming or switching mode.
4262
- `cutover set` / `cutover cancel`: Schedule or cancel cutover.
4363
- `abandon`: Abandon and delete a migration.
4464

@@ -50,6 +70,23 @@ az repos show --repository MyRepo --project MyProject --query id -o tsv
5070

5171
If a command is blocked, inspect all three fields from `status` output to understand whether the migration is active, terminal, or promotable.
5272

73+
## Promotion semantics
74+
75+
When validation succeeds in validate-only mode, promotion does not create a new migration.
76+
77+
Promotion command:
78+
79+
```bash
80+
az devops migrations resume --org https://dev.azure.com/myorg \
81+
--repository-id 00000000-0000-0000-0000-000000000000 --migration
82+
```
83+
84+
What this does:
85+
86+
- Sends an update (PUT) to the existing migration.
87+
- Sets `validateOnly=false`.
88+
- Sets `statusRequested=active`.
89+
5390
## Common workflows
5491

5592
### List migrations
@@ -119,6 +156,13 @@ az devops migrations resume --org https://dev.azure.com/myorg \
119156

120157
This promotes the same migration record (no new migration is created).
121158

159+
If you receive an active-state error, pause first and retry:
160+
161+
```bash
162+
az devops migrations pause --org https://dev.azure.com/myorg \
163+
--repository-id 00000000-0000-0000-0000-000000000000
164+
```
165+
122166
### Schedule or cancel cutover
123167

124168
```bash
@@ -152,3 +196,9 @@ az devops migrations pause --org https://dev.azure.com/myorg \
152196

153197
- Error: `--target-repository` must be valid.
154198
Ensure it is a fully qualified URL starting with `http://` or `https://`.
199+
200+
- Error: requests are sent to the wrong org.
201+
Use `--org <url> --detect false`, and verify defaults via `az devops configure -l`.
202+
203+
- Error: migration already succeeded.
204+
Use `abandon` to reset before creating a new migration.

0 commit comments

Comments
 (0)