|
| 1 | +--- |
| 2 | +name: proto-codegen |
| 3 | +description: Locally regenerate @temporalio/proto TypeScript types from current temporalio/api protos, to unblock UI development against unreleased proto fields. Use when the published @temporalio/proto package lags the protos you're developing against (missing/renamed fields). The generated output is local-only and never committed. |
| 4 | +--- |
| 5 | + |
| 6 | +# Local @temporalio/proto codegen |
| 7 | + |
| 8 | +The published `@temporalio/proto` package often lags the protos we develop |
| 9 | +against. This tool regenerates a drop-in `@temporalio/proto` from current |
| 10 | +`temporalio/api` protos so you can build and preview the UI against unreleased |
| 11 | +fields **locally**. |
| 12 | + |
| 13 | +**This is a local dev unblock, not a shipped dependency.** The generated output, |
| 14 | +the pnpm override that activates it, and the ui-server `go.mod` bump are all |
| 15 | +**local-only** — none of them are committed. A feature must not merge to main |
| 16 | +relying on an unreleased proto; wait until the fields ship in a released |
| 17 | +`@temporalio/proto` (and `go.temporal.io/api` for the ui-server), then delete the |
| 18 | +local setup with `--reset`. |
| 19 | + |
| 20 | +Only the tooling is committed: `scripts/generate-temporal-proto.ts`, this skill, |
| 21 | +the `.gitignore` entry, and the `protobufjs-cli` devDep. `vendor/temporalio-proto/` |
| 22 | +is gitignored. |
| 23 | + |
| 24 | +## Commands |
| 25 | + |
| 26 | +```bash |
| 27 | +pnpm generate:proto --help # full option list |
| 28 | + |
| 29 | +pnpm generate:proto # generate from the latest temporalio/api main |
| 30 | +pnpm generate:proto --ref v1.63.3 # generate from a specific tag, branch, or commit SHA |
| 31 | +pnpm generate:proto --sync-ui-server # also bump server/go.mod + rebuild the ui-server to match |
| 32 | +pnpm generate:proto --sync-ui-server --ui-server-version v1.63.3 # pin the ui-server go module version |
| 33 | +pnpm generate:proto --reset # undo everything: remove override, delete vendor, revert go.mod, reinstall |
| 34 | +``` |
| 35 | + |
| 36 | +A normal run generates `vendor/temporalio-proto/`, injects the |
| 37 | +`@temporalio/proto` override into `package.json` (a **local, uncommitted** |
| 38 | +change), and runs `pnpm install`. Do not commit the override or the vendored |
| 39 | +output. When you're done previewing, `pnpm generate:proto --reset` returns the |
| 40 | +working tree to the clean, main-matching state. |
| 41 | + |
| 42 | +## The two-part bump |
| 43 | + |
| 44 | +Field names/values only line up if **two** things are on the same proto revision, |
| 45 | +because gRPC matches by field **number** — a mismatch silently drops values or |
| 46 | +renames fields: |
| 47 | + |
| 48 | +1. **UI TypeScript types** — the generated `@temporalio/proto` (this tool). |
| 49 | +2. **The ui-server** (`server/go.mod`) — the grpc-gateway that decodes gRPC into |
| 50 | + the JSON the UI receives; its baked-in descriptors decide the wire field names. |
| 51 | + |
| 52 | +`--sync-ui-server` does both: generate the types, then |
| 53 | +`go get go.temporal.io/api@<version>` + `make build` in `server/`. Restart |
| 54 | +`pnpm dev:local-temporal` afterward. Both changes are local-only; `--reset` |
| 55 | +reverts them. |
| 56 | + |
| 57 | +**Version-axis caveat:** the TS types come from a temporalio/api **git ref**, |
| 58 | +while the ui-server pins a `go.temporal.io/api` **release tag** — no exact 1:1 |
| 59 | +mapping, so `--sync-ui-server` defaults to `@latest` (the practical match for |
| 60 | +`main`). If a field still looks wrong, confirm the release tag contains the ref |
| 61 | +you generated from. |
| 62 | + |
| 63 | +## Consuming the generated types |
| 64 | + |
| 65 | +Import as usual — the local override makes these resolve to the generated |
| 66 | +package: |
| 67 | + |
| 68 | +```ts |
| 69 | +import type { temporal, google } from '@temporalio/proto'; |
| 70 | +``` |
| 71 | + |
| 72 | +Only `temporal.*` and `google.*` are generated (not `coresdk.*`, unused here). |
| 73 | +For enum fields that arrive over REST/JSON as SCREAMING_SNAKE strings, derive a |
| 74 | +string union from the proto enum so it can't drift: |
| 75 | + |
| 76 | +```ts |
| 77 | +type ActivityExecutionStatus = |
| 78 | + keyof typeof import('@temporalio/proto').temporal.api.enums.v1.ActivityExecutionStatus; |
| 79 | +``` |
| 80 | + |
| 81 | +Note: while previewing with the override active, these resolve to the unreleased |
| 82 | +shape. Committed code must still compile against the **published** package, so |
| 83 | +don't reference fields that only exist in the unreleased protos until they ship. |
0 commit comments