Skip to content

Commit a1fc996

Browse files
docs: add comprehensive upgrade procedure to migration guide
Add missing sections to migration.md addressing all P0 documentation gaps: - Architecture note: clarify server/CLI are v2-only components - Upgrade procedure: * Pre-upgrade: database backup, staging testing checklist * Upgrade steps: composer update, migrations, config updates, worker restart * Post-upgrade: verification checklist (doctor, test workflow, monitoring) * Rollback procedure: full recovery steps if upgrade fails - Restructure: Code changes section now clearly separated from procedure This addresses the following gaps identified during migration validation: - Database backup step (#267) - Staging environment testing (#268) - Queue worker restart instructions (#262) - Config/env variable updates (#263) - Post-upgrade verification checklist (#265) - Rollback procedure (#264) - Server/CLI architecture clarification (#266) Fixes #262, #263, #264, #265, #266, #267, #268 Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 3476b9c commit a1fc996

File tree

1 file changed

+253
-14
lines changed

1 file changed

+253
-14
lines changed

docs/migration.md

Lines changed: 253 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,246 @@ sidebar_position: 3
66

77
This guide covers the key changes when upgrading from Durable Workflow v1 to v2.
88

9-
## Namespace change
9+
## Architecture note
10+
11+
**The standalone server, CLI, and Python SDK are v2-only components.** They did not exist in v1. This means:
12+
13+
- **PHP package upgrade**: Existing Laravel applications using v1 embedded execution upgrade to v2 embedded execution
14+
- **Server/CLI adoption**: If you want to use the standalone server or CLI, these are new v2-only capabilities (no v1→v2 migration path, just adoption)
15+
- **No server/CLI version skew**: Since server and CLI didn't exist in v1, all server/CLI instances are v2
16+
17+
This guide focuses on upgrading Laravel applications from v1 to v2 embedded execution. For server/CLI/Python SDK setup, see their respective installation guides.
18+
19+
## Upgrade procedure
20+
21+
### Before upgrading
22+
23+
**1. Back up your database**
24+
25+
Create a full database backup before upgrading:
26+
27+
```bash
28+
# MySQL/MariaDB
29+
mysqldump -u root -p your_database > backup-v1-$(date +%Y%m%d-%H%M%S).sql
30+
31+
# PostgreSQL
32+
pg_dump -U postgres your_database > backup-v1-$(date +%Y%m%d-%H%M%S).sql
33+
34+
# Laravel backup package (if installed)
35+
php artisan backup:run --only-db
36+
```
37+
38+
Store the backup in a safe location. You will need it if you need to roll back.
39+
40+
**2. Test in staging first**
41+
42+
**Do not upgrade production without testing in staging.** The upgrade includes:
43+
44+
- Database schema changes (19 new tables)
45+
- Namespace changes requiring code updates
46+
- Queue worker restart (brief interruption)
47+
- Backend capability validation
48+
49+
**Staging test checklist:**
50+
51+
- [ ] Deploy v2 code to staging environment
52+
- [ ] Run migrations against staging database
53+
- [ ] Restart queue workers
54+
- [ ] Run `php artisan workflow:v2:doctor --strict`
55+
- [ ] Start a new v2 workflow and verify it completes
56+
- [ ] Verify v1 workflows (if any) still complete
57+
- [ ] Check Waterline shows both v1 and v2 workflows
58+
- [ ] Run your application's test suite
59+
- [ ] Verify no errors in logs
60+
61+
Only proceed to production after staging validation passes.
62+
63+
### Upgrade steps
64+
65+
**1. Update composer dependency**
66+
67+
```bash
68+
composer require durable-workflow/workflow:^2.0
69+
```
70+
71+
This upgrades the package from `laravel-workflow/laravel-workflow` (v1) to `durable-workflow/workflow` (v2).
72+
73+
**2. Run database migrations**
74+
75+
```bash
76+
php artisan migrate
77+
```
78+
79+
v2 adds 19 new tables:
80+
81+
- Core: `workflow_instances`, `workflow_runs`, `workflow_history_events`, `workflow_tasks`, `workflow_commands`
82+
- Activity: `activity_executions`, `activity_attempts`
83+
- Features: `workflow_updates`, `workflow_signal_records`, `workflow_run_waits`, `workflow_run_timeline_entries`, `workflow_run_lineage_entries`, `workflow_schedules`
84+
- Observability: `workflow_run_summaries`, `workflow_failures`, `workflow_links`, `worker_compatibility_heartbeats`
85+
- Timers: `workflow_run_timers`, `workflow_run_timer_entries`
86+
87+
v1 tables (`workflows`, `workflow_logs`, `workflow_signals`, `workflow_timers`, `workflow_exceptions`) are preserved for finish-on-v1 execution.
88+
89+
**3. Update configuration (if needed)**
90+
91+
v2 configuration is backward compatible. If you published `config/workflow.php` in v1, it will continue to work. New v2 options include:
92+
93+
- `durable_types` — type aliases for language-agnostic workflow references
94+
- `task_repair_policy` — how to handle stuck tasks
95+
- `backend_capability_check` — strict vs. permissive validation
96+
- `projection_rebuild` — history rebuild strategies
97+
- `history_budget` — event count limits for continue-as-new
98+
99+
These have sensible defaults. Only configure them if you need non-default behavior. See [Configuration](/docs/2.0/configuration/options/) for details.
100+
101+
**Environment variables:**
102+
103+
v2 does not introduce new required environment variables. Existing `QUEUE_CONNECTION`, `CACHE_DRIVER`, and `DB_CONNECTION` continue to work.
104+
105+
**4. Restart queue workers**
106+
107+
Queue workers must be restarted to load v2 code:
108+
109+
```bash
110+
# If using Laravel queue workers
111+
php artisan queue:restart
112+
113+
# If using Supervisor
114+
sudo supervisorctl restart <your-worker-group>:*
115+
116+
# If using systemd
117+
sudo systemctl restart laravel-worker
118+
119+
# If using Horizon
120+
php artisan horizon:terminate
121+
```
122+
123+
Workers will:
124+
1. Finish their current job
125+
2. Exit gracefully
126+
3. Restart with v2 code loaded
127+
128+
**Workers must restart before processing v2 workflows.** v1 workflows can complete with old or new workers (finish-on-v1 compatibility).
129+
130+
### After upgrading
131+
132+
**1. Verify backend capability**
133+
134+
```bash
135+
php artisan workflow:v2:doctor --strict
136+
```
137+
138+
Expected output:
139+
140+
```
141+
✓ Database driver supports required features
142+
✓ Queue driver supports required features
143+
✓ Cache driver supports locks
144+
✓ All backend capabilities present
145+
```
146+
147+
If any check fails, see [Backend Requirements](/docs/2.0/installation/#requirements) for driver prerequisites.
148+
149+
**2. Verify v2 workflows start successfully**
150+
151+
Start a test workflow using v2 API:
152+
153+
```php
154+
use Workflow\V2\WorkflowStub;
155+
use Workflow\V2\StartOptions;
156+
157+
$workflow = WorkflowStub::make(TestWorkflow::class, 'test-upgrade');
158+
$runId = $workflow->start(['test' => true], StartOptions::new());
159+
```
160+
161+
Check that:
162+
163+
- Workflow appears in Waterline
164+
- `workflow_instances` table has a row with matching `instance_id`
165+
- `workflow_runs` table has a row with matching `run_id`
166+
- Workflow completes or progresses as expected
167+
168+
**3. Check v1 workflows (if any)**
169+
170+
If you have in-flight v1 workflows:
171+
172+
```bash
173+
php artisan workflow:v1:list
174+
```
175+
176+
Verify they continue to progress. v1 workflows should complete on the v1 engine without errors.
177+
178+
**4. Monitor logs for errors**
179+
180+
Watch application logs for workflow-related errors:
181+
182+
```bash
183+
tail -f storage/logs/laravel.log | grep -i workflow
184+
```
185+
186+
Common issues:
187+
188+
- Namespace errors: code still using `Workflow\Workflow` instead of `Workflow\V2\Workflow`
189+
- Method errors: code still using `execute()` without `handle()` fallback
190+
- Queue driver errors: using `sync` driver (not supported)
191+
192+
**5. Verify Waterline observability**
193+
194+
Open Waterline (default: `/waterline`) and verify:
195+
196+
- v1 workflows (if any) appear with their original data
197+
- v2 workflows appear with full run/history/activity detail
198+
- No errors in Waterline rendering
199+
200+
### Rollback procedure
201+
202+
If the upgrade fails in production, roll back:
203+
204+
**1. Stop queue workers**
205+
206+
```bash
207+
php artisan queue:restart # or appropriate restart command for your worker system
208+
```
209+
210+
**2. Restore database backup**
211+
212+
```bash
213+
# MySQL/MariaDB
214+
mysql -u root -p your_database < backup-v1-YYYYMMDD-HHMMSS.sql
215+
216+
# PostgreSQL
217+
psql -U postgres -d your_database < backup-v1-YYYYMMDD-HHMMSS.sql
218+
```
219+
220+
**3. Revert composer dependency**
221+
222+
```bash
223+
composer require laravel-workflow/laravel-workflow:^1.0
224+
```
225+
226+
**4. Restart queue workers**
227+
228+
```bash
229+
php artisan queue:restart # or appropriate restart command
230+
```
231+
232+
**5. Verify v1 operation**
233+
234+
- Check that v1 workflows appear in Waterline
235+
- Start a test v1 workflow to verify functionality
236+
- Monitor logs for errors
237+
238+
**Important rollback notes:**
239+
240+
- Rollback discards any v2 workflows started after upgrade (they exist only in v2 tables)
241+
- Rollback restores v1 workflows to their pre-upgrade state
242+
- If you must preserve v2 workflows started during the upgrade window, do not restore the database — instead fix the upgrade issue forward
243+
244+
## Code changes
245+
246+
The sections below detail the code-level changes needed when migrating from v1 to v2 APIs.
247+
248+
### Namespace change
10249

11250
All v2 classes live under `Workflow\V2`. Update your imports:
12251

@@ -22,7 +261,7 @@ use Workflow\V2\Activity;
22261
use Workflow\V2\WorkflowStub;
23262
```
24263

25-
## Entry method
264+
### Entry method
26265

27266
v2 workflows and activities use `handle()` as the entry method. If your v1 code uses `execute()`, it will still work through a compatibility path, but new code should use `handle()`:
28267

@@ -51,7 +290,7 @@ class MyWorkflow extends Workflow
51290

52291
Do not mix `handle()` and `execute()` in the same inheritance chain — the runtime rejects this.
53292

54-
## Activity calls
293+
### Activity calls
55294

56295
v2 replaces `ActivityStub::make()` and `yield` with direct function helpers:
57296

@@ -67,7 +306,7 @@ $result = activity(MyActivity::class, $arg1, $arg2);
67306

68307
Activities now have durable identity. Each scheduled activity gets an `activity_executions` row with a stable execution id, and each concrete attempt gets an `activity_attempts` row with typed history.
69308

70-
## Workflow identity
309+
### Workflow identity
71310

72311
v2 splits identity into instance id and run id:
73312

@@ -76,7 +315,7 @@ v2 splits identity into instance id and run id:
76315

77316
In v1, these were the same concept.
78317

79-
## Signals
318+
### Signals
80319

81320
v2 uses named signal waits instead of `#[SignalMethod]` attribute-based mutators:
82321

@@ -96,7 +335,7 @@ $approved = awaitSignal('approve');
96335

97336
Named signals support `awaitSignal('name')` for blocking waits and `signal()` / `attemptSignal()` for external input. Cancellation and termination are not modeled as signals — they remain explicit runtime commands.
98337

99-
## Queries
338+
### Queries
100339

101340
v2 uses replay-safe query methods instead of reading workflow properties directly:
102341

@@ -114,7 +353,7 @@ use function Workflow\V2\query;
114353
// Queries are defined as named, replay-safe accessors
115354
```
116355

117-
## Timers and side effects
356+
### Timers and side effects
118357

119358
The function-based helpers replace the v1 static methods:
120359

@@ -131,7 +370,7 @@ timer(60);
131370
$value = sideEffect(fn() => random_int(1, 100));
132371
```
133372

134-
## Timeouts
373+
### Timeouts
135374

136375
v2 adds workflow-level timeouts through `StartOptions`:
137376

@@ -152,7 +391,7 @@ $workflow->start(
152391
- **Execution timeout** spans the entire instance, including continue-as-new transitions.
153392
- **Run timeout** applies to a single run and resets on continue-as-new.
154393

155-
## Database migrations
394+
### Database migrations
156395

157396
v2 adds new tables and columns. The package auto-loads its migrations, so after updating:
158397

@@ -163,15 +402,15 @@ php artisan migrate
163402

164403
The 2.0.0 release includes 19 clean base table migrations. If you previously published migration files, you may need to publish the new ones or switch to auto-loaded migrations.
165404

166-
## Backend capability check
405+
### Backend capability check
167406

168407
v2 validates that your queue, database, and cache drivers meet its requirements. Run the doctor command after upgrading:
169408

170409
```bash
171410
php artisan workflow:v2:doctor --strict
172411
```
173412

174-
## Configuration
413+
### Configuration
175414

176415
v2 introduces several new configuration options. See the [Configuration](/docs/2.0/configuration/options/) section for details on:
177416

@@ -181,15 +420,15 @@ v2 introduces several new configuration options. See the [Configuration](/docs/2
181420
- Projection rebuilds
182421
- History budgets and export redaction
183422

184-
## Waterline
423+
### Waterline
185424

186425
Waterline (the monitoring UI) has been updated for v2 with:
187426

188427
- Run detail views showing timeout durations and deadlines
189428
- Activity attempt tracking with durable ids
190429
- Updated workflow status displays
191430

192-
## Continue-as-new
431+
### Continue-as-new
193432

194433
v2 adds history budgets that can automatically trigger continue-as-new when the event count exceeds a threshold. Metadata (memo, search attributes, timeouts) is carried forward across transitions.
195434

@@ -227,7 +466,7 @@ Sample output:
227466
+--------------------------------------+---------------------+-----------+------------+
228467
```
229468

230-
### Waterline visibility
469+
#### Waterline visibility
231470

232471
After upgrading to 2.0, Waterline automatically shows workflows from both engines:
233472

0 commit comments

Comments
 (0)