diff --git a/dockerfiles/php.Dockerfile b/dockerfiles/php.Dockerfile index f938d6cf..297ea7c1 100644 --- a/dockerfiles/php.Dockerfile +++ b/dockerfiles/php.Dockerfile @@ -1,5 +1,5 @@ # Build in a full featured container -FROM php:8.2-cli as build +FROM php:8.2-cli-bookworm as build # Install protobuf compiler RUN apt-get update \ diff --git a/dockerfiles/py.Dockerfile b/dockerfiles/py.Dockerfile index 6ea75c0b..8a2f19d8 100644 --- a/dockerfiles/py.Dockerfile +++ b/dockerfiles/py.Dockerfile @@ -1,5 +1,5 @@ # Build in a full featured container -FROM python:3.11-bullseye as build +FROM python:3.11-bookworm as build # Install protobuf compiler RUN apt-get update \ @@ -48,7 +48,7 @@ COPY ./${REPO_DIR_OR_PLACEHOLDER} ./${REPO_DIR_OR_PLACEHOLDER} RUN CGO_ENABLED=0 ./temporal-features prepare --lang py --dir prepared --version "$SDK_VERSION" # Copy the CLI and prepared feature to a smaller container for running -FROM python:3.11-slim-bullseye +FROM python:3.11-slim-bookworm COPY --from=build /app/temporal-features /app/temporal-features COPY --from=build /app/dockerfiles/dynamicconfig /app/dockerfiles/dynamicconfig diff --git a/dockerfiles/ts.Dockerfile b/dockerfiles/ts.Dockerfile index 1f2ac621..a7172e7f 100644 --- a/dockerfiles/ts.Dockerfile +++ b/dockerfiles/ts.Dockerfile @@ -1,5 +1,5 @@ # Build in a full featured container -FROM node:22-bullseye AS build +FROM node:22-bookworm AS build RUN apt-get update \ && DEBIAN_FRONTEND=noninteractive \ @@ -44,7 +44,7 @@ RUN CGO_ENABLED=0 ./temporal-features prepare --lang ts --dir prepared --version ################################################################################ # Copy the CLI and prepared feature to a distroless "run" container -FROM node:22-bullseye +FROM node:22-bookworm COPY --from=build /app/temporal-features /app/temporal-features COPY --from=build /app/dockerfiles/dynamicconfig /app/dockerfiles/dynamicconfig diff --git a/features/data_converter/binary_protobuf/feature.ts b/features/data_converter/binary_protobuf/feature.ts index e431c9d2..5f3482f6 100644 --- a/features/data_converter/binary_protobuf/feature.ts +++ b/features/data_converter/binary_protobuf/feature.ts @@ -2,15 +2,16 @@ import * as assert from 'assert'; import { Feature } from '@temporalio/harness'; import * as proto from '@temporalio/proto'; -// Inject Buffer and Uint8Array from the node context to the workflow context to workaround SDK bug -// TODO(antlai-temporal) Remove when SDK bug is fixed -const g = globalThis as any; -g.Uint8Array = g.constructor.constructor('return globalThis.Uint8Array')(); - const expectedResult = proto.temporal.api.common.v1.DataBlob.create({ data: new Uint8Array([0xde, 0xad, 0xbe, 0xef]), }); +// Do an encode/decode roundtrip to make sure our test expectations match exactly +// what protobufjs 8 will produce (e.g. default values are omitted, etc.) +const expectedResultOnWire = proto.temporal.api.common.v1.DataBlob.decode( + proto.temporal.api.common.v1.DataBlob.encode(expectedResult).finish(), +); + // An "echo" workflow export async function workflow( res: proto.temporal.api.common.v1.DataBlob, @@ -29,7 +30,7 @@ export const feature = new Feature({ async checkResult(runner, handle) { // verify client result is DataBlob `0xdeadbeef` const result = await handle.result(); - assert.deepEqual(result, expectedResult); + assert.deepEqual(result, expectedResultOnWire); // get result payload of WorkflowExecutionCompleted event from workflow history const payload = await runner.getWorkflowResultPayload(handle); @@ -44,7 +45,7 @@ export const feature = new Feature({ assert.ok(payload.data); const resultInHistory = proto.temporal.api.common.v1.DataBlob.decode(payload.data); - assert.deepEqual(resultInHistory, expectedResult); + assert.deepEqual(resultInHistory, expectedResultOnWire); // get argument payload of WorkflowExecutionStarted event from workflow history const payloadArg = await runner.getWorkflowArgumentPayload(handle); diff --git a/features/data_converter/json_protobuf/feature.ts b/features/data_converter/json_protobuf/feature.ts index 9b7da3dd..8c2a53d1 100644 --- a/features/data_converter/json_protobuf/feature.ts +++ b/features/data_converter/json_protobuf/feature.ts @@ -1,5 +1,5 @@ import * as assert from 'assert'; -import { fromProto3JSON } from 'proto3-json-serializer'; +import * as protojson from 'protobufjs/ext/protojson'; import { Feature } from '@temporalio/harness'; import * as proto from '@temporalio/proto'; import { patchProtobufRoot } from '@temporalio/proto/lib/patch-protobuf-root'; @@ -9,15 +9,16 @@ import { decode } from '@temporalio/common/lib/encoding'; const patched = patchProtobufRoot(proto) as any; const dataBlobType = patched.lookupType('temporal.api.common.v1.DataBlob'); -// Inject Buffer and Uint8Array from the node context to the workflow context to workaround SDK bug -// TODO(antlai-temporal) Remove workaround when SDK bug is fixed -const g = globalThis as any; -g.Buffer = g.constructor.constructor('return globalThis.Buffer')(); - const expectedResult = proto.temporal.api.common.v1.DataBlob.create({ data: new Uint8Array([0xde, 0xad, 0xbe, 0xef]), }); +// Do an encode/decode roundtrip to make sure our test expectations match exactly +// what protobufjs 8 will produce (e.g. default values are omitted, etc.) +const expectedResultOnWire = proto.temporal.api.common.v1.DataBlob.decode( + proto.temporal.api.common.v1.DataBlob.encode(expectedResult).finish(), +); + // An "echo" workflow export async function workflow( res: proto.temporal.api.common.v1.DataBlob, @@ -36,7 +37,7 @@ export const feature = new Feature({ async checkResult(runner, handle) { // verify client result is DataBlob `0xdeadbeef` const result = await handle.result(); - assert.deepEqual(result, expectedResult); + assert.deepEqual(result, expectedResultOnWire); // get result payload of WorkflowExecutionCompleted event from workflow history const payload = await runner.getWorkflowResultPayload(handle); @@ -49,9 +50,9 @@ export const feature = new Feature({ assert.equal(Buffer.from(payload.metadata.messageType).toString(), 'temporal.api.common.v1.DataBlob'); assert.ok(payload.data); - const resultInHistory = fromProto3JSON(dataBlobType, JSON.parse(decode(payload.data))); + const resultInHistory = protojson.fromJson(dataBlobType, JSON.parse(decode(payload.data))); assert.ok(resultInHistory); - assert.deepEqual(resultInHistory, expectedResult); + assert.deepEqual(resultInHistory, expectedResultOnWire); // get argument payload of WorkflowExecutionStarted event from workflow history const payloadArg = await runner.getWorkflowArgumentPayload(handle); @@ -64,7 +65,7 @@ export const feature = new Feature({ assert.equal(Buffer.from(payloadArg.metadata.messageType).toString(), 'temporal.api.common.v1.DataBlob'); assert.ok(payloadArg.data); - const resultArgInHistory = fromProto3JSON(dataBlobType, JSON.parse(decode(payloadArg.data))); + const resultArgInHistory = protojson.fromJson(dataBlobType, JSON.parse(decode(payloadArg.data))); assert.ok(resultArgInHistory); assert.deepEqual(resultInHistory, resultArgInHistory); }, diff --git a/package-lock.json b/package-lock.json index abd93d05..a7b3187e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -24,7 +24,6 @@ "commander": "^8.3.0", "ms": "^3.0.0-canary.1", "nexus-rpc": "^0.0.1", - "proto3-json-serializer": "^1.1.1", "protobufjs": "^8.7.1" }, "devDependencies": { @@ -1745,9 +1744,9 @@ } }, "node_modules/@temporalio/common/node_modules/protobufjs": { - "version": "7.6.6", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.6.6.tgz", - "integrity": "sha512-dYDWdjSl5RNb7SgPxGQcRU+GtvP7s2fpkrY0r432PcOIaZ0/rBcxEZnQN67iJhFuQiVw754JDoPruPCNdGsbjg==", + "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": { @@ -6093,45 +6092,10 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, - "node_modules/proto3-json-serializer": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/proto3-json-serializer/-/proto3-json-serializer-1.1.1.tgz", - "integrity": "sha512-AwAuY4g9nxx0u52DnSMkqqgyLHaW/XaPLtaAo3y/ZCfeaQB/g4YDH4kb8Wc/mWzWvu0YjOznVnfn373MVZZrgw==", - "license": "Apache-2.0", - "dependencies": { - "protobufjs": "^7.0.0" - }, - "engines": { - "node": ">=12.0.0" - } - }, - "node_modules/proto3-json-serializer/node_modules/protobufjs": { - "version": "7.6.6", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.6.6.tgz", - "integrity": "sha512-dYDWdjSl5RNb7SgPxGQcRU+GtvP7s2fpkrY0r432PcOIaZ0/rBcxEZnQN67iJhFuQiVw754JDoPruPCNdGsbjg==", - "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/protobufjs": { - "version": "8.8.0", - "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-8.8.0.tgz", - "integrity": "sha512-N3xhQ5yyBx3vQq4gubBfASzYhJGNzeDbjqBpu61g7UVylsN/qyffU96TKWD3GbbLOKF82VGNRNvv1+BFgE31Eg==", + "version": "8.7.1", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-8.7.1.tgz", + "integrity": "sha512-agdGHrXNTv0IrYscJPDou/PlEJk1c/hBZ9o/B5NH2i/nSPtPqacNxzgwf1CebXxFMjMrZH5sqv9uQuw96aGt/A==", "license": "BSD-3-Clause", "dependencies": { "long": "^5.3.2" diff --git a/package.json b/package.json index 1528f6f0..7688bb92 100644 --- a/package.json +++ b/package.json @@ -26,7 +26,6 @@ "commander": "^8.3.0", "ms": "^3.0.0-canary.1", "nexus-rpc": "^0.0.1", - "proto3-json-serializer": "^1.1.1", "protobufjs": "^8.7.1" }, "devDependencies": { diff --git a/sdkbuild/typescript.go b/sdkbuild/typescript.go index a76cb0a3..3133a3b3 100644 --- a/sdkbuild/typescript.go +++ b/sdkbuild/typescript.go @@ -141,18 +141,13 @@ func BuildTypeScriptProgram(ctx context.Context, options BuildTypeScriptProgramO "commander": "^8.3.0", "ms": "^3.0.0-canary.1", "nexus-rpc": "^0.0.1", - "proto3-json-serializer": "^1.1.1" + "protobufjs": "^8.7.1" }, "devDependencies": { "@tsconfig/node24": "^24.0.4", "@types/node": "^24.1.0", "tsconfig-paths": "^3.12.0", "typescript": "^5.9.3" - }, - "pnpm": { - "overrides": { - "protobufjs": "^8.7.1" - } } }` if err := os.WriteFile(filepath.Join(dir, "package.json"), []byte(packageJSON), 0644); err != nil {