Skip to content

Commit 15983b9

Browse files
committed
Update protos to latest
1 parent 84c4291 commit 15983b9

File tree

5 files changed

+202
-25
lines changed

5 files changed

+202
-25
lines changed
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
---
2+
description: >-
3+
Update the protobuf generated Python files from the latest
4+
microsoft/durabletask-protobuf definitions. Use when the proto definitions
5+
need to be refreshed or regenerated.
6+
---
7+
8+
# Update Protobuf Definitions
9+
10+
This skill regenerates the Python protobuf files in `durabletask/internal/`
11+
from the latest proto source at
12+
<https://github.com/microsoft/durabletask-protobuf>.
13+
14+
## Prerequisites
15+
16+
- Python 3.11 must be available on the system. Verify with `py -3.11 --version`
17+
(Windows) or `python3.11 --version` (Linux/macOS). If it is not installed,
18+
stop and ask the user to install it — do **not** use a different version.
19+
- Internet access is required to download the proto file and query the GitHub
20+
API.
21+
22+
## Steps
23+
24+
### 1. Set up the `.proto_venv` environment (skip if it already exists)
25+
26+
Check whether `.proto_venv/` already exists at the repo root and whether
27+
`grpcio-tools==1.65.4` is installed in it:
28+
29+
```bash
30+
# Windows
31+
.proto_venv\Scripts\pip.exe list 2>$null | Select-String grpcio-tools
32+
33+
# Bash
34+
.proto_venv/bin/pip list 2>/dev/null | grep grpcio-tools
35+
```
36+
37+
If the venv **does not exist** or `grpcio-tools` is missing, create/recreate it:
38+
39+
```bash
40+
# Windows
41+
py -3.11 -m venv .proto_venv
42+
.proto_venv\Scripts\python.exe -m pip install grpcio-tools==1.65.4
43+
44+
# Bash
45+
python3.11 -m venv .proto_venv
46+
.proto_venv/bin/python -m pip install grpcio-tools==1.65.4
47+
```
48+
49+
> [!NOTE]
50+
> Do **not** delete `.proto_venv` after use. It is reused across runs to avoid
51+
> reinstalling `grpcio-tools` each time. The directory is already in
52+
> `.gitignore`.
53+
54+
### 2. Download the latest proto file
55+
56+
Download from the `main` branch of `microsoft/durabletask-protobuf`:
57+
58+
```bash
59+
# Windows (PowerShell)
60+
Invoke-WebRequest `
61+
-Uri "https://raw.githubusercontent.com/microsoft/durabletask-protobuf/refs/heads/main/protos/orchestrator_service.proto" `
62+
-OutFile "durabletask/internal/orchestrator_service.proto"
63+
64+
# Bash
65+
curl -o durabletask/internal/orchestrator_service.proto \
66+
https://raw.githubusercontent.com/microsoft/durabletask-protobuf/refs/heads/main/protos/orchestrator_service.proto
67+
```
68+
69+
### 3. Regenerate the Python files
70+
71+
Run `grpc_tools.protoc` from the **repo root**:
72+
73+
```bash
74+
# Windows
75+
.proto_venv\Scripts\python.exe -m grpc_tools.protoc --proto_path=. --python_out=. --pyi_out=. --grpc_python_out=. ./durabletask/internal/orchestrator_service.proto
76+
77+
# Bash
78+
.proto_venv/bin/python -m grpc_tools.protoc --proto_path=. --python_out=. --pyi_out=. --grpc_python_out=. ./durabletask/internal/orchestrator_service.proto
79+
```
80+
81+
This produces three files in `durabletask/internal/`:
82+
83+
- `orchestrator_service_pb2.py`
84+
- `orchestrator_service_pb2_grpc.py`
85+
- `orchestrator_service_pb2.pyi`
86+
87+
### 4. Update `PROTO_SOURCE_COMMIT_HASH`
88+
89+
Query the GitHub API for the latest commit that touched the proto file and
90+
**overwrite** `durabletask/internal/PROTO_SOURCE_COMMIT_HASH` with that single
91+
hash:
92+
93+
```bash
94+
# Windows (PowerShell)
95+
$response = Invoke-RestMethod `
96+
-Uri "https://api.github.com/repos/microsoft/durabletask-protobuf/commits?path=protos/orchestrator_service.proto&sha=main&per_page=1"
97+
$response[0].sha | Out-File -FilePath "durabletask/internal/PROTO_SOURCE_COMMIT_HASH" -NoNewline -Encoding ascii
98+
99+
# Bash
100+
curl -s -H "Accept: application/vnd.github.v3+json" \
101+
"https://api.github.com/repos/microsoft/durabletask-protobuf/commits?path=protos/orchestrator_service.proto&sha=main&per_page=1" \
102+
| jq -r '.[0].sha' > durabletask/internal/PROTO_SOURCE_COMMIT_HASH
103+
```
104+
105+
The file should contain exactly one commit hash with no trailing newline.
106+
107+
### 5. Clean up the downloaded proto file
108+
109+
Delete the `.proto` source file — only the generated Python files are kept in
110+
the repo:
111+
112+
```bash
113+
# Windows
114+
Remove-Item durabletask/internal/orchestrator_service.proto
115+
116+
# Bash
117+
rm durabletask/internal/orchestrator_service.proto
118+
```
119+
120+
### 6. Verify
121+
122+
Confirm the generated modules import successfully using the project's main
123+
venv:
124+
125+
```bash
126+
python -c "from durabletask.internal import orchestrator_service_pb2; print('pb2 OK'); from durabletask.internal import orchestrator_service_pb2_grpc; print('pb2_grpc OK')"
127+
```
128+
129+
## Generated files
130+
131+
| File | Description |
132+
|---|---|
133+
| `durabletask/internal/orchestrator_service_pb2.py` | Message classes |
134+
| `durabletask/internal/orchestrator_service_pb2_grpc.py` | gRPC stubs |
135+
| `durabletask/internal/orchestrator_service_pb2.pyi` | Type stubs |
136+
| `durabletask/internal/PROTO_SOURCE_COMMIT_HASH` | Source commit hash |

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@ celerybeat.pid
104104
# Environments
105105
.env
106106
.venv
107+
.proto_venv
107108
env/
108109
venv/
109110
ENV/
Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1 @@
1-
443b333f4f65a438dc9eb4f090560d232afec4b7
2-
fd9369c6a03d6af4e95285e432b7c4e943c06970
3-
026329c53fe6363985655857b9ca848ec7238bd2
1+
1caadbd7ecfdf5f2309acbeac28a3e36d16aa156

durabletask/internal/orchestrator_service_pb2.py

Lines changed: 28 additions & 20 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

durabletask/internal/orchestrator_service_pb2.pyi

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1250,16 +1250,50 @@ class SkipGracefulOrchestrationTerminationsResponse(_message.Message):
12501250
def __init__(self, unterminatedInstanceIds: _Optional[_Iterable[str]] = ...) -> None: ...
12511251

12521252
class GetWorkItemsRequest(_message.Message):
1253-
__slots__ = ("maxConcurrentOrchestrationWorkItems", "maxConcurrentActivityWorkItems", "maxConcurrentEntityWorkItems", "capabilities")
1253+
__slots__ = ("maxConcurrentOrchestrationWorkItems", "maxConcurrentActivityWorkItems", "maxConcurrentEntityWorkItems", "capabilities", "workItemFilters")
12541254
MAXCONCURRENTORCHESTRATIONWORKITEMS_FIELD_NUMBER: _ClassVar[int]
12551255
MAXCONCURRENTACTIVITYWORKITEMS_FIELD_NUMBER: _ClassVar[int]
12561256
MAXCONCURRENTENTITYWORKITEMS_FIELD_NUMBER: _ClassVar[int]
12571257
CAPABILITIES_FIELD_NUMBER: _ClassVar[int]
1258+
WORKITEMFILTERS_FIELD_NUMBER: _ClassVar[int]
12581259
maxConcurrentOrchestrationWorkItems: int
12591260
maxConcurrentActivityWorkItems: int
12601261
maxConcurrentEntityWorkItems: int
12611262
capabilities: _containers.RepeatedScalarFieldContainer[WorkerCapability]
1262-
def __init__(self, maxConcurrentOrchestrationWorkItems: _Optional[int] = ..., maxConcurrentActivityWorkItems: _Optional[int] = ..., maxConcurrentEntityWorkItems: _Optional[int] = ..., capabilities: _Optional[_Iterable[_Union[WorkerCapability, str]]] = ...) -> None: ...
1263+
workItemFilters: WorkItemFilters
1264+
def __init__(self, maxConcurrentOrchestrationWorkItems: _Optional[int] = ..., maxConcurrentActivityWorkItems: _Optional[int] = ..., maxConcurrentEntityWorkItems: _Optional[int] = ..., capabilities: _Optional[_Iterable[_Union[WorkerCapability, str]]] = ..., workItemFilters: _Optional[_Union[WorkItemFilters, _Mapping]] = ...) -> None: ...
1265+
1266+
class WorkItemFilters(_message.Message):
1267+
__slots__ = ("orchestrations", "activities", "entities")
1268+
ORCHESTRATIONS_FIELD_NUMBER: _ClassVar[int]
1269+
ACTIVITIES_FIELD_NUMBER: _ClassVar[int]
1270+
ENTITIES_FIELD_NUMBER: _ClassVar[int]
1271+
orchestrations: _containers.RepeatedCompositeFieldContainer[OrchestrationFilter]
1272+
activities: _containers.RepeatedCompositeFieldContainer[ActivityFilter]
1273+
entities: _containers.RepeatedCompositeFieldContainer[EntityFilter]
1274+
def __init__(self, orchestrations: _Optional[_Iterable[_Union[OrchestrationFilter, _Mapping]]] = ..., activities: _Optional[_Iterable[_Union[ActivityFilter, _Mapping]]] = ..., entities: _Optional[_Iterable[_Union[EntityFilter, _Mapping]]] = ...) -> None: ...
1275+
1276+
class OrchestrationFilter(_message.Message):
1277+
__slots__ = ("name", "versions")
1278+
NAME_FIELD_NUMBER: _ClassVar[int]
1279+
VERSIONS_FIELD_NUMBER: _ClassVar[int]
1280+
name: str
1281+
versions: _containers.RepeatedScalarFieldContainer[str]
1282+
def __init__(self, name: _Optional[str] = ..., versions: _Optional[_Iterable[str]] = ...) -> None: ...
1283+
1284+
class ActivityFilter(_message.Message):
1285+
__slots__ = ("name", "versions")
1286+
NAME_FIELD_NUMBER: _ClassVar[int]
1287+
VERSIONS_FIELD_NUMBER: _ClassVar[int]
1288+
name: str
1289+
versions: _containers.RepeatedScalarFieldContainer[str]
1290+
def __init__(self, name: _Optional[str] = ..., versions: _Optional[_Iterable[str]] = ...) -> None: ...
1291+
1292+
class EntityFilter(_message.Message):
1293+
__slots__ = ("name",)
1294+
NAME_FIELD_NUMBER: _ClassVar[int]
1295+
name: str
1296+
def __init__(self, name: _Optional[str] = ...) -> None: ...
12631297

12641298
class WorkItem(_message.Message):
12651299
__slots__ = ("orchestratorRequest", "activityRequest", "entityRequest", "healthPing", "entityRequestV2", "completionToken")

0 commit comments

Comments
 (0)