From 48775d5f9262e76590eb8665a30739e4de3f87ea Mon Sep 17 00:00:00 2001 From: Lenny Chen Date: Thu, 30 Jul 2026 17:30:22 -0700 Subject: [PATCH 1/4] Add Worker snippets for Java, .NET, and Ruby The Go, Python, and TypeScript Worker docs pages pull their create-worker and versioned-worker snippets from this directory. Java, .NET, and Ruby had only a max-cached-workflows snippet, so their docs pages carried hand-written code instead. Adds create-worker, versioned-worker, and graceful-shutdown snippets to each, matching the naming already used by the Go, Python, and TypeScript files. Each versioned Worker registers a Workflow that declares a versioning behavior, and the unversioned Workers register one that does not. The server rejects a Workflow that declares a versioning behavior when the Worker has not enabled versioning, so the two cases need separate Workflow types. Verified against a local dev server: every Worker polls its Task Queue and completes a Workflow. worker.java compiles with javac against temporal-sdk 1.30.1, worker.cs builds with dotnet.csproj, and worker.rb loads and passes rubocop. --- features/snippets/worker/worker.cs | 86 +++++++++++++++++++++++++ features/snippets/worker/worker.java | 95 ++++++++++++++++++++++++++++ features/snippets/worker/worker.rb | 83 +++++++++++++++++++++++- 3 files changed, 261 insertions(+), 3 deletions(-) diff --git a/features/snippets/worker/worker.cs b/features/snippets/worker/worker.cs index 5d0f77a4..aed43382 100644 --- a/features/snippets/worker/worker.cs +++ b/features/snippets/worker/worker.cs @@ -1,5 +1,8 @@ +using Temporalio.Activities; using Temporalio.Client; +using Temporalio.Common; using Temporalio.Worker; +using Temporalio.Workflows; public class WorkerSnippet { @@ -16,4 +19,87 @@ public static async Task Run() }); // @@@SNIPEND } + + public static async Task CreateWorker() + { + var client = await TemporalClient.ConnectAsync(new("localhost:7233")); + + // @@@SNIPSTART dotnet-create-worker + var options = new TemporalWorkerOptions("my-task-queue"); + options.AddWorkflow(); + options.AddAllActivities(typeof(GreetingActivities), null); + + using var worker = new TemporalWorker(client, options); + await worker.ExecuteAsync(CancellationToken.None); + // @@@SNIPEND + } + + public static async Task CreateVersionedWorker() + { + var client = await TemporalClient.ConnectAsync(new("localhost:7233")); + + // @@@SNIPSTART dotnet-versioned-worker + var options = new TemporalWorkerOptions("my-task-queue") + { + DeploymentOptions = new WorkerDeploymentOptions( + new WorkerDeploymentVersion("my-app", "1.0"), + useWorkerVersioning: true), + }; + options.AddWorkflow(); + options.AddAllActivities(typeof(GreetingActivities), null); + + using var worker = new TemporalWorker(client, options); + // @@@SNIPEND + await Task.CompletedTask; + } + + public static async Task ShutdownWorker() + { + var client = await TemporalClient.ConnectAsync(new("localhost:7233")); + + // @@@SNIPSTART dotnet-worker-graceful-shutdown + using var tokenSource = new CancellationTokenSource(); + Console.CancelKeyPress += (_, eventArgs) => + { + tokenSource.Cancel(); + eventArgs.Cancel = true; + }; + + var options = new TemporalWorkerOptions("my-task-queue") + { + GracefulShutdownTimeout = TimeSpan.FromSeconds(30), + }; + options.AddWorkflow(); + + using var worker = new TemporalWorker(client, options); + await worker.ExecuteAsync(tokenSource.Token); + // @@@SNIPEND + } + + public static class GreetingActivities + { + [Activity] + public static string SayHello(string name) => $"Hello, {name}!"; + } + + [Workflow] + public class GreetingWorkflow + { + [WorkflowRun] + public async Task RunAsync(string name) => + await Workflow.ExecuteActivityAsync( + () => GreetingActivities.SayHello(name), + new() { StartToCloseTimeout = TimeSpan.FromSeconds(10) }); + } + + // A versioning behavior is only valid on a Worker that has versioning enabled. + [Workflow(VersioningBehavior = VersioningBehavior.Pinned)] + public class VersionedGreetingWorkflow + { + [WorkflowRun] + public async Task RunAsync(string name) => + await Workflow.ExecuteActivityAsync( + () => GreetingActivities.SayHello(name), + new() { StartToCloseTimeout = TimeSpan.FromSeconds(10) }); + } } diff --git a/features/snippets/worker/worker.java b/features/snippets/worker/worker.java index 3a3ee8c4..d6ff4995 100644 --- a/features/snippets/worker/worker.java +++ b/features/snippets/worker/worker.java @@ -1,10 +1,61 @@ +import io.temporal.activity.ActivityInterface; +import io.temporal.activity.ActivityMethod; import io.temporal.client.WorkflowClient; +import io.temporal.common.VersioningBehavior; +import io.temporal.common.WorkerDeploymentVersion; import io.temporal.serviceclient.WorkflowServiceStubs; import io.temporal.worker.Worker; +import io.temporal.worker.WorkerDeploymentOptions; import io.temporal.worker.WorkerFactory; import io.temporal.worker.WorkerFactoryOptions; +import io.temporal.worker.WorkerOptions; +import io.temporal.workflow.WorkflowInterface; +import io.temporal.workflow.WorkflowMethod; +import io.temporal.workflow.WorkflowVersioningBehavior; +import java.util.concurrent.TimeUnit; class WorkerSnippet { + @ActivityInterface + public interface GreetingActivities { + @ActivityMethod + String sayHello(String name); + } + + public static class GreetingActivitiesImpl implements GreetingActivities { + @Override + public String sayHello(String name) { + return "Hello, " + name + "!"; + } + } + + @WorkflowInterface + public interface GreetingWorkflow { + @WorkflowMethod + String greet(String name); + } + + public static class GreetingWorkflowImpl implements GreetingWorkflow { + @Override + public String greet(String name) { + return "Hello, " + name + "!"; + } + } + + @WorkflowInterface + public interface VersionedGreetingWorkflow { + @WorkflowMethod + String greet(String name); + } + + // A versioning behavior is only valid on a Worker that has versioning enabled. + public static class VersionedGreetingWorkflowImpl implements VersionedGreetingWorkflow { + @Override + @WorkflowVersioningBehavior(VersioningBehavior.PINNED) + public String greet(String name) { + return "Hello, " + name + "!"; + } + } + public static void main(String[] args) { WorkflowServiceStubs service = WorkflowServiceStubs.newLocalServiceStubs(); WorkflowClient client = WorkflowClient.newInstance(service); @@ -18,4 +69,48 @@ public static void main(String[] args) { factory.start(); } + + static void createWorker(WorkflowClient client) { + // @@@SNIPSTART java-create-worker + WorkerFactory factory = WorkerFactory.newInstance(client); + + Worker worker = factory.newWorker("my-task-queue"); + worker.registerWorkflowImplementationTypes(GreetingWorkflowImpl.class); + worker.registerActivitiesImplementations(new GreetingActivitiesImpl()); + + factory.start(); + // @@@SNIPEND + } + + static void createVersionedWorker(WorkflowClient client) { + WorkerFactory factory = WorkerFactory.newInstance(client); + + // @@@SNIPSTART java-versioned-worker + WorkerOptions options = + WorkerOptions.newBuilder() + .setDeploymentOptions( + WorkerDeploymentOptions.newBuilder() + .setVersion(new WorkerDeploymentVersion("my-app", "1.0")) + .setUseVersioning(true) + .build()) + .build(); + + Worker worker = factory.newWorker("my-task-queue", options); + worker.registerWorkflowImplementationTypes(VersionedGreetingWorkflowImpl.class); + worker.registerActivitiesImplementations(new GreetingActivitiesImpl()); + // @@@SNIPEND + + factory.start(); + } + + static void shutdownWorker(WorkflowClient client) { + WorkerFactory factory = WorkerFactory.newInstance(client); + factory.newWorker("my-task-queue"); + factory.start(); + + // @@@SNIPSTART java-worker-graceful-shutdown + factory.shutdown(); + factory.awaitTermination(30, TimeUnit.SECONDS); + // @@@SNIPEND + } } diff --git a/features/snippets/worker/worker.rb b/features/snippets/worker/worker.rb index f4ab1f5e..0e1c3549 100644 --- a/features/snippets/worker/worker.rb +++ b/features/snippets/worker/worker.rb @@ -1,14 +1,39 @@ # frozen_string_literal: true +require 'temporalio/activity' require 'temporalio/client' +require 'temporalio/common_enums' require 'temporalio/worker' +require 'temporalio/worker_deployment_version' +require 'temporalio/workflow' + +class SayHello < Temporalio::Activity::Definition + def execute(name) + "Hello, #{name}!" + end +end + +class GreetingWorkflow < Temporalio::Workflow::Definition + def execute(name) + Temporalio::Workflow.execute_activity(SayHello, name, start_to_close_timeout: 10) + end +end + +# A versioning behavior is only valid on a Worker that has versioning enabled. +class VersionedGreetingWorkflow < Temporalio::Workflow::Definition + workflow_versioning_behavior Temporalio::VersioningBehavior::PINNED + + def execute(name) + Temporalio::Workflow.execute_activity(SayHello, name, start_to_close_timeout: 10) + end +end def run client = Temporalio::Client.connect( 'localhost:7233', 'default' ) - + # @@@SNIPSTART ruby-worker-max-cached-workflows worker = Temporalio::Worker.new( client: client, @@ -16,6 +41,58 @@ def run max_cached_workflows: 0 ) # @@@SNIPEND - + worker.run -end \ No newline at end of file +end + +def run_worker + client = Temporalio::Client.connect('localhost:7233', 'default') + + # @@@SNIPSTART ruby-create-worker + worker = Temporalio::Worker.new( + client: client, + task_queue: 'my-task-queue', + workflows: [GreetingWorkflow], + activities: [SayHello] + ) + + worker.run + # @@@SNIPEND +end + +def run_versioned_worker + client = Temporalio::Client.connect('localhost:7233', 'default') + + # @@@SNIPSTART ruby-versioned-worker + worker = Temporalio::Worker.new( + client: client, + task_queue: 'my-task-queue', + workflows: [VersionedGreetingWorkflow], + activities: [SayHello], + deployment_options: Temporalio::Worker::DeploymentOptions.new( + version: Temporalio::WorkerDeploymentVersion.new( + deployment_name: 'my-app', + build_id: '1.0' + ), + use_worker_versioning: true + ) + ) + # @@@SNIPEND + + worker.run +end + +def run_worker_until_interrupted + client = Temporalio::Client.connect('localhost:7233', 'default') + + worker = Temporalio::Worker.new( + client: client, + task_queue: 'my-task-queue', + workflows: [GreetingWorkflow], + activities: [SayHello] + ) + + # @@@SNIPSTART ruby-worker-graceful-shutdown + worker.run(shutdown_signals: %w[SIGINT SIGTERM]) + # @@@SNIPEND +end From 0d5866df572cbf96fcac1408f6901af4a315e82d Mon Sep 17 00:00:00 2001 From: Lenny Chen Date: Fri, 14 Aug 2026 14:15:36 -0700 Subject: [PATCH 2/4] Add Cloud Run Worker snippets for Java, .NET, TypeScript, and Ruby The Cloud Run Serverless Worker docs pages carry hand-written Worker code that nothing compiles. Add a cloud-run-worker snippet per language so those pages can pull compiled code instead. Each snippet is a standard long-lived Worker that reads its connection settings from the environment and enables Worker Versioning, which Serverless Workers require. Unlike the versioned-worker snippets, these set the versioning behavior on the Worker rather than per Workflow, so they register the plain GreetingWorkflow and reuse the Workflow and Activity types already in each file. Rust has no harness in this repo, so its Cloud Run page stays hand-written. --- features/snippets/worker/worker.cs | 29 ++++++++++++++++++ features/snippets/worker/worker.java | 44 ++++++++++++++++++++++++++++ features/snippets/worker/worker.rb | 30 +++++++++++++++++++ features/snippets/worker/worker.ts | 26 ++++++++++++++++ 4 files changed, 129 insertions(+) diff --git a/features/snippets/worker/worker.cs b/features/snippets/worker/worker.cs index aed43382..b1759025 100644 --- a/features/snippets/worker/worker.cs +++ b/features/snippets/worker/worker.cs @@ -53,6 +53,35 @@ public static async Task CreateVersionedWorker() await Task.CompletedTask; } + // A Serverless Worker on GCP Cloud Run is a standard long-lived Worker that reads its + // connection settings from the environment and enables Worker Versioning. + public static async Task CloudRunWorker() + { + // @@@SNIPSTART dotnet-cloud-run-worker + var client = await TemporalClient.ConnectAsync( + new(Environment.GetEnvironmentVariable("TEMPORAL_ADDRESS")!) + { + Namespace = Environment.GetEnvironmentVariable("TEMPORAL_NAMESPACE")!, + ApiKey = Environment.GetEnvironmentVariable("TEMPORAL_API_KEY"), + Tls = new(), + }); + + var options = new TemporalWorkerOptions( + Environment.GetEnvironmentVariable("TEMPORAL_TASK_QUEUE")!) + { + DeploymentOptions = new(new("my-app", "build-1"), useWorkerVersioning: true) + { + DefaultVersioningBehavior = VersioningBehavior.Pinned, + }, + }; + options.AddWorkflow(); + options.AddAllActivities(typeof(GreetingActivities), null); + + using var worker = new TemporalWorker(client, options); + await worker.ExecuteAsync(CancellationToken.None); + // @@@SNIPEND + } + public static async Task ShutdownWorker() { var client = await TemporalClient.ConnectAsync(new("localhost:7233")); diff --git a/features/snippets/worker/worker.java b/features/snippets/worker/worker.java index d6ff4995..1489bf07 100644 --- a/features/snippets/worker/worker.java +++ b/features/snippets/worker/worker.java @@ -1,9 +1,11 @@ import io.temporal.activity.ActivityInterface; import io.temporal.activity.ActivityMethod; import io.temporal.client.WorkflowClient; +import io.temporal.client.WorkflowClientOptions; import io.temporal.common.VersioningBehavior; import io.temporal.common.WorkerDeploymentVersion; import io.temporal.serviceclient.WorkflowServiceStubs; +import io.temporal.serviceclient.WorkflowServiceStubsOptions; import io.temporal.worker.Worker; import io.temporal.worker.WorkerDeploymentOptions; import io.temporal.worker.WorkerFactory; @@ -103,6 +105,48 @@ static void createVersionedWorker(WorkflowClient client) { factory.start(); } + // A Serverless Worker on GCP Cloud Run is a standard long-lived Worker that reads its + // connection settings from the environment and enables Worker Versioning. + static void cloudRunWorker() { + // @@@SNIPSTART java-cloud-run-worker + String apiKey = System.getenv("TEMPORAL_API_KEY"); + + WorkflowServiceStubs service = + WorkflowServiceStubs.newServiceStubs( + WorkflowServiceStubsOptions.newBuilder() + .setTarget(System.getenv("TEMPORAL_ADDRESS")) + .setEnableHttps(true) + .addApiKey(() -> apiKey) + .build()); + + WorkflowClient client = + WorkflowClient.newInstance( + service, + WorkflowClientOptions.newBuilder() + .setNamespace(System.getenv("TEMPORAL_NAMESPACE")) + .build()); + + WorkerFactory factory = WorkerFactory.newInstance(client); + + Worker worker = + factory.newWorker( + System.getenv("TEMPORAL_TASK_QUEUE"), + WorkerOptions.newBuilder() + .setDeploymentOptions( + WorkerDeploymentOptions.newBuilder() + .setUseVersioning(true) + .setVersion(new WorkerDeploymentVersion("my-app", "build-1")) + .setDefaultVersioningBehavior(VersioningBehavior.PINNED) + .build()) + .build()); + + worker.registerWorkflowImplementationTypes(GreetingWorkflowImpl.class); + worker.registerActivitiesImplementations(new GreetingActivitiesImpl()); + + factory.start(); + // @@@SNIPEND + } + static void shutdownWorker(WorkflowClient client) { WorkerFactory factory = WorkerFactory.newInstance(client); factory.newWorker("my-task-queue"); diff --git a/features/snippets/worker/worker.rb b/features/snippets/worker/worker.rb index 0e1c3549..31faee7a 100644 --- a/features/snippets/worker/worker.rb +++ b/features/snippets/worker/worker.rb @@ -82,6 +82,36 @@ def run_versioned_worker worker.run end +# A Serverless Worker on GCP Cloud Run is a standard long-lived Worker that reads its +# connection settings from the environment and enables Worker Versioning. +def run_cloud_run_worker + # @@@SNIPSTART ruby-cloud-run-worker + client = Temporalio::Client.connect( + ENV.fetch('TEMPORAL_ADDRESS'), + ENV.fetch('TEMPORAL_NAMESPACE'), + api_key: ENV.fetch('TEMPORAL_API_KEY'), + tls: true + ) + + worker = Temporalio::Worker.new( + client:, + task_queue: ENV.fetch('TEMPORAL_TASK_QUEUE'), + workflows: [GreetingWorkflow], + activities: [SayHello], + deployment_options: Temporalio::Worker::DeploymentOptions.new( + version: Temporalio::WorkerDeploymentVersion.new( + deployment_name: 'my-app', + build_id: 'build-1' + ), + use_worker_versioning: true, + default_versioning_behavior: Temporalio::VersioningBehavior::PINNED + ) + ) + + worker.run + # @@@SNIPEND +end + def run_worker_until_interrupted client = Temporalio::Client.connect('localhost:7233', 'default') diff --git a/features/snippets/worker/worker.ts b/features/snippets/worker/worker.ts index b294c9b3..fb838d12 100644 --- a/features/snippets/worker/worker.ts +++ b/features/snippets/worker/worker.ts @@ -34,6 +34,32 @@ async function _runVersioned() { // @@@SNIPEND } +// A Serverless Worker on GCP Cloud Run is a standard long-lived Worker that reads its +// connection settings from the environment and enables Worker Versioning. +async function _runCloudRunWorker() { + // @@@SNIPSTART typescript-cloud-run-worker + const connection = await NativeConnection.connect({ + address: process.env.TEMPORAL_ADDRESS, + apiKey: process.env.TEMPORAL_API_KEY, + tls: true, + }); + + const worker = await Worker.create({ + connection, + namespace: process.env.TEMPORAL_NAMESPACE!, + taskQueue: process.env.TEMPORAL_TASK_QUEUE!, + workflowsPath: require.resolve('./workflows'), + workerDeploymentOptions: { + version: { deploymentName: 'my-app', buildId: 'build-1' }, + useWorkerVersioning: true, + defaultVersioningBehavior: 'PINNED', + }, + }); + + await worker.run(); + // @@@SNIPEND +} + async function _runWithGracefulShutdown() { const connection = await NativeConnection.connect({ address: 'localhost:7233', From 992b21bc4ec5c4a6988f8cd0e4808bdbf07b4d73 Mon Sep 17 00:00:00 2001 From: Lenny Chen Date: Wed, 19 Aug 2026 16:29:22 -0700 Subject: [PATCH 3/4] Use envconfig in the TypeScript Cloud Run Worker snippet The docs page and the Cloud Run deployment guide both show the TypeScript Worker loading its connection settings through @temporalio/envconfig, so the snippet should match rather than reading the variables by hand. Adds @temporalio/envconfig to package.json, which the repo did not depend on. --- features/snippets/worker/worker.ts | 10 ++- package-lock.json | 108 +++++++++++++++++++++++++++++ package.json | 1 + 3 files changed, 113 insertions(+), 6 deletions(-) diff --git a/features/snippets/worker/worker.ts b/features/snippets/worker/worker.ts index fb838d12..ccb39636 100644 --- a/features/snippets/worker/worker.ts +++ b/features/snippets/worker/worker.ts @@ -1,3 +1,4 @@ +import { loadClientConnectConfig } from '@temporalio/envconfig'; import { NativeConnection, Worker } from '@temporalio/worker'; /* eslint-disable @typescript-eslint/no-unused-vars */ @@ -38,15 +39,12 @@ async function _runVersioned() { // connection settings from the environment and enables Worker Versioning. async function _runCloudRunWorker() { // @@@SNIPSTART typescript-cloud-run-worker - const connection = await NativeConnection.connect({ - address: process.env.TEMPORAL_ADDRESS, - apiKey: process.env.TEMPORAL_API_KEY, - tls: true, - }); + const config = loadClientConnectConfig(); + const connection = await NativeConnection.connect(config.connectionOptions); const worker = await Worker.create({ connection, - namespace: process.env.TEMPORAL_NAMESPACE!, + namespace: config.namespace, taskQueue: process.env.TEMPORAL_TASK_QUEUE!, workflowsPath: require.resolve('./workflows'), workerDeploymentOptions: { diff --git a/package-lock.json b/package-lock.json index 01544086..66d779e2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,6 +11,7 @@ "@temporalio/activity": "^1.18.1", "@temporalio/client": "^1.18.1", "@temporalio/common": "^1.18.1", + "@temporalio/envconfig": "^1.18.1", "@temporalio/plugin": "^1.18.1", "@temporalio/proto": "^1.18.1", "@temporalio/worker": "^1.18.1", @@ -1294,6 +1295,101 @@ "node": ">= 20.0.0" } }, + "node_modules/@temporalio/envconfig": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@temporalio/envconfig/-/envconfig-1.22.0.tgz", + "integrity": "sha512-7ZfLINqHBtkL+9ZqfD0T9ONl0RpFo8N5/DxGLRACC1MwaNta2ZJNr4E3fz3uKcd6Fz32WZPxAfTNbKiSy6JJlA==", + "license": "MIT", + "dependencies": { + "@temporalio/common": "1.22.0", + "smol-toml": "^1.6.1" + }, + "engines": { + "node": ">= 20.3.0" + } + }, + "node_modules/@temporalio/envconfig/node_modules/@temporalio/common": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@temporalio/common/-/common-1.22.0.tgz", + "integrity": "sha512-1NpQpo/y6XU1ULbo/bXgBEhl6qQnOeB79NrsSJdjI38/hfXPom2IYGJcIxOFfsQICQ0zePEKzB9Yyo31KNpIxA==", + "license": "MIT", + "dependencies": { + "@temporalio/proto": "1.22.0", + "long": "^5.2.3", + "ms": "3.0.0-canary.1", + "nexus-rpc": "^0.0.2", + "proto3-json-serializer": "^2.0.0" + }, + "engines": { + "node": ">= 20.3.0" + } + }, + "node_modules/@temporalio/envconfig/node_modules/@temporalio/proto": { + "version": "1.22.0", + "resolved": "https://registry.npmjs.org/@temporalio/proto/-/proto-1.22.0.tgz", + "integrity": "sha512-X7NVa0Z6HK3l9irZR48FKwZ9w9YXetCdF2z2KCIRr0W7Kul64Wt9o5hwvSXShAtrZuCEEHH8WO/ffHTXxJieLg==", + "license": "MIT", + "dependencies": { + "long": "^5.2.3", + "protobufjs": "^7.6.4" + }, + "engines": { + "node": ">= 20.3.0" + } + }, + "node_modules/@temporalio/envconfig/node_modules/ms": { + "version": "3.0.0-canary.1", + "resolved": "https://registry.npmjs.org/ms/-/ms-3.0.0-canary.1.tgz", + "integrity": "sha512-kh8ARjh8rMN7Du2igDRO9QJnqCb2xYTJxyQYK7vJJS4TvLLmsbyhiKpSW+t+y26gyOyMd0riphX0GeWKU3ky5g==", + "license": "MIT", + "engines": { + "node": ">=12.13" + } + }, + "node_modules/@temporalio/envconfig/node_modules/nexus-rpc": { + "version": "0.0.2", + "resolved": "https://registry.npmjs.org/nexus-rpc/-/nexus-rpc-0.0.2.tgz", + "integrity": "sha512-IWjIExdVYlmwXuzHdY/Q3lXCv1gbqoAXPazQhy2w4Xgtgha3H0OOujEESVPQcFUFMWm+pAk2gKnb57g8S41JZg==", + "license": "MIT", + "engines": { + "node": ">= 20.0.0" + } + }, + "node_modules/@temporalio/envconfig/node_modules/proto3-json-serializer": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-2.0.2.tgz", + "integrity": "sha512-SAzp/O4Yh02jGdRc+uIrGoe87dkN/XtwxfZ4ZyafJHymd79ozp5VG5nyZ7ygqPM5+cpLDjjGnYFUkngonyDPOQ==", + "license": "Apache-2.0", + "dependencies": { + "protobufjs": "^7.2.5" + }, + "engines": { + "node": ">=14.0.0" + } + }, + "node_modules/@temporalio/envconfig/node_modules/protobufjs": { + "version": "7.6.5", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.6.5.tgz", + "integrity": "sha512-/FPD0nUc9jH6rfFjji9IBqOz4pcSE3CsT1m7Ep6Mdb0LxSUMj8hgl6GomOvZzpNpAqqGaXA0P3VSrZLFzIhQrw==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.5", + "@protobufjs/eventemitter": "^1.1.1", + "@protobufjs/fetch": "^1.1.1", + "@protobufjs/float": "^1.0.2", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.1", + "@types/node": ">=13.7.0", + "long": "^5.3.2" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/@temporalio/nexus": { "version": "1.18.1", "resolved": "https://registry.npmjs.org/@temporalio/nexus/-/nexus-1.18.1.tgz", @@ -5457,6 +5553,18 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/smol-toml": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.8.0.tgz", + "integrity": "sha512-kCZr2V3ch9i00x8zXRhjUNVcjG9ijES5dDudkXvUVCT5QlJNQWElSJdZqyPemffHoLNUYwOcou0Fy+ojN0uHSQ==", + "license": "BSD-3-Clause", + "engines": { + "node": ">= 18" + }, + "funding": { + "url": "https://github.com/sponsors/cyyynthia" + } + }, "node_modules/source-map": { "version": "0.7.6", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", diff --git a/package.json b/package.json index 9edd2c25..880fe89a 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,7 @@ "@temporalio/activity": "^1.18.1", "@temporalio/client": "^1.18.1", "@temporalio/common": "^1.18.1", + "@temporalio/envconfig": "^1.18.1", "@temporalio/plugin": "^1.18.1", "@temporalio/proto": "^1.18.1", "@temporalio/worker": "^1.18.1", From 299c93a3215f2bc986af5feb939d5d311ddd44ed Mon Sep 17 00:00:00 2001 From: Lenny Chen Date: Wed, 19 Aug 2026 16:35:42 -0700 Subject: [PATCH 4/4] Revert envconfig in the TypeScript Cloud Run snippet The harness generates its own package.json from a fixed package list in sdkbuild/typescript.go, so adding @temporalio/envconfig to the root package.json did not reach the build and CI failed with TS2307. Adding envconfig to that list is not safe either: it is only published from 1.13.2, and the harness builds against whatever SDK version it is given, so older-version runs would fail to resolve it. The snippet reads the connection settings from the environment instead. --- features/snippets/worker/worker.ts | 10 +-- package-lock.json | 108 ----------------------------- package.json | 1 - 3 files changed, 6 insertions(+), 113 deletions(-) diff --git a/features/snippets/worker/worker.ts b/features/snippets/worker/worker.ts index ccb39636..fb838d12 100644 --- a/features/snippets/worker/worker.ts +++ b/features/snippets/worker/worker.ts @@ -1,4 +1,3 @@ -import { loadClientConnectConfig } from '@temporalio/envconfig'; import { NativeConnection, Worker } from '@temporalio/worker'; /* eslint-disable @typescript-eslint/no-unused-vars */ @@ -39,12 +38,15 @@ async function _runVersioned() { // connection settings from the environment and enables Worker Versioning. async function _runCloudRunWorker() { // @@@SNIPSTART typescript-cloud-run-worker - const config = loadClientConnectConfig(); - const connection = await NativeConnection.connect(config.connectionOptions); + const connection = await NativeConnection.connect({ + address: process.env.TEMPORAL_ADDRESS, + apiKey: process.env.TEMPORAL_API_KEY, + tls: true, + }); const worker = await Worker.create({ connection, - namespace: config.namespace, + namespace: process.env.TEMPORAL_NAMESPACE!, taskQueue: process.env.TEMPORAL_TASK_QUEUE!, workflowsPath: require.resolve('./workflows'), workerDeploymentOptions: { diff --git a/package-lock.json b/package-lock.json index 66d779e2..01544086 100644 --- a/package-lock.json +++ b/package-lock.json @@ -11,7 +11,6 @@ "@temporalio/activity": "^1.18.1", "@temporalio/client": "^1.18.1", "@temporalio/common": "^1.18.1", - "@temporalio/envconfig": "^1.18.1", "@temporalio/plugin": "^1.18.1", "@temporalio/proto": "^1.18.1", "@temporalio/worker": "^1.18.1", @@ -1295,101 +1294,6 @@ "node": ">= 20.0.0" } }, - "node_modules/@temporalio/envconfig": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/@temporalio/envconfig/-/envconfig-1.22.0.tgz", - "integrity": "sha512-7ZfLINqHBtkL+9ZqfD0T9ONl0RpFo8N5/DxGLRACC1MwaNta2ZJNr4E3fz3uKcd6Fz32WZPxAfTNbKiSy6JJlA==", - "license": "MIT", - "dependencies": { - "@temporalio/common": "1.22.0", - "smol-toml": "^1.6.1" - }, - "engines": { - "node": ">= 20.3.0" - } - }, - "node_modules/@temporalio/envconfig/node_modules/@temporalio/common": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/@temporalio/common/-/common-1.22.0.tgz", - "integrity": "sha512-1NpQpo/y6XU1ULbo/bXgBEhl6qQnOeB79NrsSJdjI38/hfXPom2IYGJcIxOFfsQICQ0zePEKzB9Yyo31KNpIxA==", - "license": "MIT", - "dependencies": { - "@temporalio/proto": "1.22.0", - "long": "^5.2.3", - "ms": "3.0.0-canary.1", - "nexus-rpc": "^0.0.2", - "proto3-json-serializer": "^2.0.0" - }, - "engines": { - "node": ">= 20.3.0" - } - }, - "node_modules/@temporalio/envconfig/node_modules/@temporalio/proto": { - "version": "1.22.0", - "resolved": "https://registry.npmjs.org/@temporalio/proto/-/proto-1.22.0.tgz", - "integrity": "sha512-X7NVa0Z6HK3l9irZR48FKwZ9w9YXetCdF2z2KCIRr0W7Kul64Wt9o5hwvSXShAtrZuCEEHH8WO/ffHTXxJieLg==", - "license": "MIT", - "dependencies": { - "long": "^5.2.3", - "protobufjs": "^7.6.4" - }, - "engines": { - "node": ">= 20.3.0" - } - }, - "node_modules/@temporalio/envconfig/node_modules/ms": { - "version": "3.0.0-canary.1", - "resolved": "https://registry.npmjs.org/ms/-/ms-3.0.0-canary.1.tgz", - "integrity": "sha512-kh8ARjh8rMN7Du2igDRO9QJnqCb2xYTJxyQYK7vJJS4TvLLmsbyhiKpSW+t+y26gyOyMd0riphX0GeWKU3ky5g==", - "license": "MIT", - "engines": { - "node": ">=12.13" - } - }, - "node_modules/@temporalio/envconfig/node_modules/nexus-rpc": { - "version": "0.0.2", - "resolved": "https://registry.npmjs.org/nexus-rpc/-/nexus-rpc-0.0.2.tgz", - "integrity": "sha512-IWjIExdVYlmwXuzHdY/Q3lXCv1gbqoAXPazQhy2w4Xgtgha3H0OOujEESVPQcFUFMWm+pAk2gKnb57g8S41JZg==", - "license": "MIT", - "engines": { - "node": ">= 20.0.0" - } - }, - "node_modules/@temporalio/envconfig/node_modules/proto3-json-serializer": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-2.0.2.tgz", - "integrity": "sha512-SAzp/O4Yh02jGdRc+uIrGoe87dkN/XtwxfZ4ZyafJHymd79ozp5VG5nyZ7ygqPM5+cpLDjjGnYFUkngonyDPOQ==", - "license": "Apache-2.0", - "dependencies": { - "protobufjs": "^7.2.5" - }, - "engines": { - "node": ">=14.0.0" - } - }, - "node_modules/@temporalio/envconfig/node_modules/protobufjs": { - "version": "7.6.5", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.6.5.tgz", - "integrity": "sha512-/FPD0nUc9jH6rfFjji9IBqOz4pcSE3CsT1m7Ep6Mdb0LxSUMj8hgl6GomOvZzpNpAqqGaXA0P3VSrZLFzIhQrw==", - "hasInstallScript": true, - "license": "BSD-3-Clause", - "dependencies": { - "@protobufjs/aspromise": "^1.1.2", - "@protobufjs/base64": "^1.1.2", - "@protobufjs/codegen": "^2.0.5", - "@protobufjs/eventemitter": "^1.1.1", - "@protobufjs/fetch": "^1.1.1", - "@protobufjs/float": "^1.0.2", - "@protobufjs/path": "^1.1.2", - "@protobufjs/pool": "^1.1.0", - "@protobufjs/utf8": "^1.1.1", - "@types/node": ">=13.7.0", - "long": "^5.3.2" - }, - "engines": { - "node": ">=12.0.0" - } - }, "node_modules/@temporalio/nexus": { "version": "1.18.1", "resolved": "https://registry.npmjs.org/@temporalio/nexus/-/nexus-1.18.1.tgz", @@ -5553,18 +5457,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/smol-toml": { - "version": "1.8.0", - "resolved": "https://registry.npmjs.org/smol-toml/-/smol-toml-1.8.0.tgz", - "integrity": "sha512-kCZr2V3ch9i00x8zXRhjUNVcjG9ijES5dDudkXvUVCT5QlJNQWElSJdZqyPemffHoLNUYwOcou0Fy+ojN0uHSQ==", - "license": "BSD-3-Clause", - "engines": { - "node": ">= 18" - }, - "funding": { - "url": "https://github.com/sponsors/cyyynthia" - } - }, "node_modules/source-map": { "version": "0.7.6", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.6.tgz", diff --git a/package.json b/package.json index 880fe89a..9edd2c25 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,6 @@ "@temporalio/activity": "^1.18.1", "@temporalio/client": "^1.18.1", "@temporalio/common": "^1.18.1", - "@temporalio/envconfig": "^1.18.1", "@temporalio/plugin": "^1.18.1", "@temporalio/proto": "^1.18.1", "@temporalio/worker": "^1.18.1",