Repository navigation
Require a temporal-resource-id annotation or exemption on every RPC - #897
Merged
jiechenz merged 2 commits intoOct 27, 2026
Merged
Conversation
Add protoc-gen-resource-id-lint, run by `make` as part of the grpc lint step. It fails when an RPC has neither a temporal-resource-id request_header annotation nor an entry in cmd/protoc-gen-resource-id-lint/exemptions.go, when an exempted RPC has the annotation, or when an exemption names an RPC that does not exist. Exempt the RPCs that have no single resource to route by, and annotate the worker deployment and task queue RPCs that were missing it, using the same values as their sibling RPCs.
jiechenz
force-pushed
the
jiechenz/enforce-resource-id
branch
from
October 27, 2026 01:08
0e0f781 to
ce9db57
Compare
S15
approved these changes
Oct 27, 2026
| @@ -0,0 +1,5 @@ | |||
| module github.com/temporalio/api/cmd/protoc-gen-resource-id-lint | |||
|
|
|||
| go 1.25.4 | |||
Contributor
Author
There was a problem hiding this comment.
Not needed but I used 1.25.4 to match the other two plugins in cmd/.
yuandrew
approved these changes
Oct 27, 2026
yuandrew
left a comment
Contributor
There was a problem hiding this comment.
I'd say a test validating the test successfully rejects a missing annotation would be good, but looks like none of our other cmd/ tools have one.. 🤷
Cover an RPC with neither the annotation nor an exemption, an annotation for a different header, an exempted RPC that has the annotation, and an exemption for an RPC that does not exist, plus a passing service. Run the test before installing the plugin, so `make` and CI run it.
Contributor
Author
Added a test |
3 of 5 tasks
jiechenz
added a commit
to temporalio/temporal
that referenced
this pull request
Oct 28, 2026
## What changed? - Bump `go.temporal.io/api` to `v1.64.1-0.20261027235544-fa71e29e58da` (root and `tests/mixedbrain`) to pick up the `temporal-resource-id` annotations from temporalio/api#877 and temporalio/api#897. - Regenerate `common/rpc/interceptor/routing_key_extractor_gen.go`. 15 RPCs gain a routing key: - by `operation_id`: `StartNexusOperationExecution`, `DescribeNexusOperationExecution`, `PollNexusOperationExecution`, `RequestCancelNexusOperationExecution`, `TerminateNexusOperationExecution`, `DeleteNexusOperationExecution` - by `activity_id`: `DeleteActivityExecution` - by deployment name: `CreateWorkerDeployment`, `CreateWorkerDeploymentVersion`, `UpdateWorkerDeploymentVersionComputeConfig`, `ValidateWorkerDeploymentVersionComputeConfig` - by task queue: `UpdateWorkerVersioningRules`, `GetWorkerVersioningRules`, `UpdateWorkerBuildIdCompatibility`, `GetWorkerBuildIdCompatibility` - Add the 15 RPCs to `TestRoutingKeyInterceptor_AllMethods`. ## Why? Make sure Nexus operations have routingKey associated. ## How did you test it? - [x] built - [ ] run locally and tested manually - [x] covered by existing tests - [x] added new unit test(s) - [ ] added new functional test(s) <details><summary>go test -tags test_dep -count=1 ./common/rpc/interceptor/...</summary> ``` ok go.temporal.io/server/common/rpc/interceptor 4.919s ok go.temporal.io/server/common/rpc/interceptor/logtags 0.929s ``` </details> <details><summary>Same test with routing_key_extractor_gen.go from main</summary> ``` --- FAIL: TestRoutingKeyInterceptor_AllMethods --- FAIL: TestRoutingKeyInterceptor_AllMethods/ValidateWorkerDeploymentVersionComputeConfig --- FAIL: TestRoutingKeyInterceptor_AllMethods/UpdateWorkerVersioningRules --- FAIL: TestRoutingKeyInterceptor_AllMethods/UpdateWorkerDeploymentVersionComputeConfig --- FAIL: TestRoutingKeyInterceptor_AllMethods/UpdateWorkerBuildIdCompatibility --- FAIL: TestRoutingKeyInterceptor_AllMethods/TerminateNexusOperationExecution --- FAIL: TestRoutingKeyInterceptor_AllMethods/StartNexusOperationExecution --- FAIL: TestRoutingKeyInterceptor_AllMethods/RequestCancelNexusOperationExecution --- FAIL: TestRoutingKeyInterceptor_AllMethods/PollNexusOperationExecution --- FAIL: TestRoutingKeyInterceptor_AllMethods/GetWorkerVersioningRules --- FAIL: TestRoutingKeyInterceptor_AllMethods/GetWorkerBuildIdCompatibility --- FAIL: TestRoutingKeyInterceptor_AllMethods/DescribeNexusOperationExecution --- FAIL: TestRoutingKeyInterceptor_AllMethods/DeleteNexusOperationExecution --- FAIL: TestRoutingKeyInterceptor_AllMethods/DeleteActivityExecution --- FAIL: TestRoutingKeyInterceptor_AllMethods/CreateWorkerDeploymentVersion --- FAIL: TestRoutingKeyInterceptor_AllMethods/CreateWorkerDeployment ``` </details> <details><summary>make lint-code GOLANGCI_LINT_BASE_REV=origin/main LINT_CODE_TARGETS=./common/rpc/interceptor/...</summary> ``` 0 issues. ``` </details>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Stacked on #877.
What changed?
protoc-gen-resource-id-lint, a protoc plugin thatmakeruns in thegrpclint step (so CI runs it too). It checks every RPC in every service and fails when:temporal-resource-idrequest_headerannotation nor an entry incmd/protoc-gen-resource-id-lint/exemptions.go;ShutdownWorker, deprecated deployment APIs, and allOperatorServiceRPCs.temporal-resource-idannotations to RPCs that were missing them, using the same values as their sibling RPCs:CreateWorkerDeployment:deployment:{deployment_name}CreateWorkerDeploymentVersion,UpdateWorkerDeploymentVersionComputeConfig,ValidateWorkerDeploymentVersionComputeConfig:deployment:{deployment_version.deployment_name}UpdateWorkerVersioningRules,GetWorkerVersioningRules,UpdateWorkerBuildIdCompatibility,GetWorkerBuildIdCompatibility:taskqueue:{task_queue}The check only requires that the annotation is present. It does not validate the annotation value.
To exempt a new RPC, add
"<Service>.<Method>": {}toexemptions.go.Why?
New RPCs have shipped without a
temporal-resource-idannotation, for example the standalone Nexus operation RPCs fixed in #877. Requiring the annotation, or an explicit exemption, makes that decision part of every API review.Breaking changes
None at the wire or code level. The eight new annotations change the request headers SDKs send for those RPCs once they pick up the new protos.
Server PR
None required. After the api-go bump, regenerate
common/rpc/interceptor/routing_key_extractor_gen.go(make proto-codegen) to pick up the eight new annotations.