This repository demos how to set up Temporal Python project that uses worker versioning.
It includes:
- A simple workflow and activity
- A worker that's set up to use versioning
- A client to signal all running workflows
- GitHub Actions workflows to build a worker docker image and run release validation
- Build scripts
- Python >= 3.7
- Temporal CLI
temporal server start-dev --dynamic-config-value frontend.workerVersioningDataAPIs=true --dynamic-config-value frontend.workerVersioningWorkflowAPIs=true --dynamic-config-value worker.buildIdScavengerEnabled=true
poetry install
These environment variables are supported by the worker and client of the provided application as well as Temporal CLI unless mentioned otherwise.
BUILD_ID
- Build ID for the worker to use (required)
TEMPORAL_ADDRESS
- Address of Temporal Server (optional)
TEMPORAL_NAMESPACE
- Namespace to use (optional)
TEMPORAL_TLS_CERT
- Path to TLS Certificate (optional)
TEMPORAL_TLS_KEY
- Path to TLS private key (optional)
TEMPORAL_TASK_QUEUE
- Task queue to use (optional) (not supported in CLI)
Includes the "first" workflow version, which we'll call V1.
Based on main
and contains a modified, incompatible version of the V1 workflow (V2).
based on workflow-v2
and contains a modified, compatible version of the V2 workflow.
-
Export any environment variables required to connect to your namespace.
-
Run the first version of the workflow code, either directly with
npm run worker
or using a prebuilt docker image (either via GitHub actions or locally. Make sure to set theBUILD_ID
environment if run outside of docker. -
Set your enviroment to communicate with the server:
temporal env set prod.namespace YOUR_NAMESPACE.a2dd6 temporal env set prod.address YOUR_NAMESPACE.a2dd6.tmprl.cloud:7233 temporal env set prod.tls-cert-path ca.pem temporal env set prod.tls-key-path ca.key
-
Add the build ID as default for the task queue:
temporal task-queue update-build-ids add-new-default \ --task-queue versioned-queue \ --build-id $MY_V1_BUILD_ID \ --env prod
-
Start a couple of workflows:
temporal workflow start \ --task-queue versioned-queue \ --type VersioningExample \ --workflow-id wf-1 \ --env prod temporal workflow start \ --task-queue versioned-queue \ --type VersioningExample \ --workflow-id wf-2 \ --env prod
-
Check your worker logs and ensure it picks up those workflows. They will continue running on this worker for the duration of this demo.
-
Inspect these workflows in the Temporal web UI and see the added versioning information.
-
Run the second version of the workflow. This can be done either by switching to the
workflow-v2
branch and runningnpm run worker
or by running a container with an image built from that branch. Make sure to set a newBUILD_ID
for this worker if run outside of docker. -
Add the new incompatible build ID as default for the task queue:
temporal task-queue update-build-ids add-new-default \ --task-queue versioned-queue \ --build-id $MY_V2_BUILD_ID \ --env prod
-
Run another workflow:
temporal workflow start \ --task-queue versioned-queue \ --type VersioningExample \ --workflow-id wf-3 \ --env prod
-
Check the second worker's logs and ensure it picks up the workflow.
-
Inspect the workflow in the Temporal web UI.
-
Signal all workflows and inspect worker logs an UI. You should see wf-1 and wf-2 signals processed on the first worker and wf-3 on the second.
poetry run python run_workflow.py go
-
Run the third version of the workflow. This can be done either by switching to the
workflow-v2.1
branch and runningnpm run worker
or by running a container with an image built from that branch. Make sure to set a newBUILD_ID
for this worker if run outside of docker. -
Add the new compatible build ID as default for the task queue. As soon as the versioning propagate, polls from the second worker will start failing because there's a newer compatible build ID.
temporal task-queue update-build-ids add-new-compatible \
--task-queue versioned-queue \
--build-id $MY_V2_1_BUILD_ID \
--existing-compatible-build-id $MY_V2_BUILD_ID \
--env prod
- Run another workflow:
temporal workflow start \
--task-queue versioned-queue \
--type VersioningExample \
--workflow-id wf-4 \
--env prod
-
Check the third worker's logs and ensure it picks up the workflow.
-
Inspect the workflow in the Temporal web UI.
-
Signal all workflows to finish and inspect worker logs an UI. You should see wf-1 and wf-2 signals processed on the first worker and wf-3 and wf-4 on the third.
poetry run python run_workflow.py finish
- Check the reachability of the build IDs to see which workers can be retired:
temporal task-queue get-build-id-reachability \
--build-id $MY_V1_BUILD_ID \
--build-id $MY_V2_BUILD_ID \
--build-id $MY_V2_1_BUILD_ID \
--env prod
docker build --tag $MY_IMAGE_TAG --build-arg BUILD_ID=$MY_BUILD_ID .
- Modify the
IMAGE_NAME
environment variable to push to an authorized docker registry. - Paste your docker credentials as
DOCKER_USERNAME
andDOCKER_PASSWORD
(or use a token instead) as GitHub Actions secrets on your forked repository. - Modify the
TEMPORAL_ADDRESS
andTEMPORAL_NAMESPACE
environment variables inci.yml
so they're directed at your server and namespace. - Paste your TLS certificate and private key as
TEMPORAL_CLIENT_CERT
andTEMPORAL_CLIENT_KEY
GitHub Actions secrets on your forked repository.
The release validation process uses existing workflow histories from a given compatible version set and replays them with the current version of the workflows to verify that the code was modified in a backwards compatible way.
The process is triggered on a GitHub pull request if the pull request title contains a [compatible-BUILD_ID]
prefix.
For example to verify that a commit is compatible with build ID foo
, prefix your pull request title with
[compatible-foo]
.