Skip to content

Commit efd1dfd

Browse files
authored
Add Safe Deployment of Versioned Workflow section (#238)
* add Safe Deployment of Versioned Workflow section * add tabs
1 parent c61fce3 commit efd1dfd

File tree

1 file changed

+66
-0
lines changed

1 file changed

+66
-0
lines changed

docs/05-go-client/15-workflow-versioning.md

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,72 @@ but you want to ensure new :workflow:workflows: are running on new logic, you ca
135135
new `WorkflowType`, and change your start path (calls to `StartWorkflow()`) to start the new :workflow:
136136
type.
137137

138+
## Safe Deployment of Versioned Workflows
139+
140+
When deploying workflow changes in production environments, you may want to separate the versioning
141+
of the workflow code from the activation of new logic to ensure ability to roll back changes safely.
142+
The `ExecuteWithVersion` and `ExecuteWithMinVersion` options provides this capability by allowing you
143+
to control which version is returned when `GetVersion()` is executed for the first time.
144+
145+
### Step 1: Deploy with Compatibility
146+
147+
Initially, your workflow has the following code:
148+
149+
```go
150+
err = workflow.ExecuteActivity(ctx, FooActivity).Get(ctx, nil)
151+
```
152+
153+
To safely roll out changes that replace `FooActivity` with `BarActivity`, you need both versions
154+
of your workflow code to be compatible with each other. Use `GetVersion` with the `ExecuteWithMinVersion` option:
155+
156+
```go
157+
v := workflow.GetVersion(ctx, "fooToBarChange", workflow.DefaultVersion, 1, workflow.ExecuteWithMinVersion())
158+
// equivalent to
159+
// v := workflow.GetVersion(ctx, "fooToBarChange", workflow.DefaultVersion, 1, workflow.ExecuteWithVersion(workflow.DefaultVersion))
160+
if v == workflow.DefaultVersion {
161+
err = workflow.ExecuteActivity(ctx, FooActivity).Get(ctx, nil)
162+
} else {
163+
err = workflow.ExecuteActivity(ctx, BarActivity).Get(ctx, nil)
164+
}
165+
```
166+
167+
At this step:
168+
- The previous version of the code supports only `DefaultVersion`
169+
- The new version of the code supports both `DefaultVersion` and `1`
170+
- The new version of the code is not yet activated, so workflows started on the new code will still execute the `FooActivity` (previous version)
171+
- This makes it possible to safely roll back your changes if needed, as the previous code supports `DefaultVersion` only
172+
173+
### Step 2: Activate New Logic
174+
175+
When the previous version of the code is no longer running, you can activate the new code by removing the `ExecuteWithMinVersion` option:
176+
177+
```go
178+
v := workflow.GetVersion(ctx, "fooToBarChange", workflow.DefaultVersion, 1)
179+
if v == workflow.DefaultVersion {
180+
err = workflow.ExecuteActivity(ctx, FooActivity).Get(ctx, nil)
181+
} else {
182+
err = workflow.ExecuteActivity(ctx, BarActivity).Get(ctx, nil)
183+
}
184+
```
185+
186+
At this step:
187+
- Both versions of the code support both `DefaultVersion` and `1`
188+
- The new version of the code is activated, so workflows started on the new code will execute the `BarActivity` (new version)
189+
- This still allows safe rollback because both versions of the code support both `DefaultVersion` and `1`
190+
191+
### Step 3: Clean Up Old Code
192+
193+
When there are no running workflows using `DefaultVersion`, you can remove the corresponding branch:
194+
195+
```go
196+
workflow.GetVersion(ctx, "fooToBarChange", 1, 1)
197+
err = workflow.ExecuteActivity(ctx, BarActivity).Get(ctx, nil)
198+
```
199+
200+
`ExecuteWithMinVersion` and `ExecuteWithVersion` options are particularly useful when you want to ensure that
201+
your changes can be safely rolled back if needed, as both versions of the workflow code remain compatible with
202+
each other throughout the deployment process.
203+
138204
## Sanity checking
139205

140206
The Cadence client SDK performs a sanity check to help prevent obvious incompatible changes.

0 commit comments

Comments
 (0)