diff --git a/.github/scripts/release_verify.py b/.github/scripts/release_verify.py index 7f69f2408..dcfbd5ad5 100644 --- a/.github/scripts/release_verify.py +++ b/.github/scripts/release_verify.py @@ -108,6 +108,42 @@ def verify_dist(args: argparse.Namespace) -> None: print(f" {name}") +def changelog_notes(args: argparse.Namespace) -> None: + changelog_path = pathlib.Path(args.changelog) + lines = changelog_path.read_text(encoding="utf-8").splitlines() + heading = re.compile(r"^## \[(?P[^\]]+)\](?:\s+-\s+.*)?\s*$") + + start = None + for index, line in enumerate(lines): + match = heading.match(line) + if match and match.group("version") == args.version: + start = index + 1 + break + + if start is None: + raise RuntimeError( + f"Could not find changelog section for version {args.version!r}" + ) + + end = len(lines) + for index in range(start, len(lines)): + if lines[index].startswith("## "): + end = index + break + + section_lines = lines[start:end] + while section_lines and not section_lines[0].strip(): + section_lines.pop(0) + while section_lines and not section_lines[-1].strip(): + section_lines.pop() + + if not section_lines: + raise RuntimeError(f"Changelog section for {args.version!r} is empty") + + notes = "## Changelog\n\n" + "\n".join(section_lines) + "\n" + pathlib.Path(args.output).write_text(notes, encoding="utf-8") + + def main(argv: Sequence[str] | None = None) -> None: parser = argparse.ArgumentParser() subparsers = parser.add_subparsers(required=True) @@ -122,6 +158,12 @@ def main(argv: Sequence[str] | None = None) -> None: verify_parser.add_argument("--dist-dir", default="dist") verify_parser.set_defaults(func=verify_dist) + changelog_parser = subparsers.add_parser("changelog-notes") + changelog_parser.add_argument("--version", required=True) + changelog_parser.add_argument("--changelog", default="CHANGELOG.md") + changelog_parser.add_argument("--output", required=True) + changelog_parser.set_defaults(func=changelog_notes) + args = parser.parse_args(argv) args.func(args) diff --git a/.github/workflows/release-publish.yml b/.github/workflows/release-publish.yml index 5c8d54196..5f4cdfc74 100644 --- a/.github/workflows/release-publish.yml +++ b/.github/workflows/release-publish.yml @@ -111,6 +111,12 @@ jobs: python .github/scripts/release_verify.py validate-version \ --sha "$(git rev-parse HEAD)" \ --github-output "$GITHUB_OUTPUT" + - name: Validate changelog release notes + run: | + set -euo pipefail + python .github/scripts/release_verify.py changelog-notes \ + --version "${{ steps.validate_versions.outputs.version }}" \ + --output /tmp/release-notes.md - name: Download and flatten artifacts env: GH_TOKEN: ${{ github.token }} @@ -249,6 +255,17 @@ jobs: permissions: contents: write steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + with: + ref: ${{ needs.verify_artifacts.outputs.release_sha }} + - name: Build changelog release notes + env: + VERSION: ${{ needs.verify_artifacts.outputs.version }} + run: | + set -euo pipefail + python3 .github/scripts/release_verify.py changelog-notes \ + --version "$VERSION" \ + --output release-notes.md - name: Create draft release with generated notes env: GH_TOKEN: ${{ github.token }} @@ -261,4 +278,5 @@ jobs: --target "$RELEASE_SHA" \ --title "$VERSION" \ --draft \ + --notes-file release-notes.md \ --generate-notes diff --git a/CHANGELOG.md b/CHANGELOG.md index 346a0bcb3..9c975cfec 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,8 +19,41 @@ to docs, or any other relevant information. ## [Unreleased] +## [1.29.0] - 2026-06-17 + +### Added + +- Added experimental `temporalio.workflow.signal_with_start_workflow`, backed by + generated system Nexus bindings for + `WorkflowService.SignalWithStartWorkflowExecution`. +- Added OpenAI Agents plugin support for `CustomTool` dispatch, including lazy + tool discovery through `defer_loading`. + +### Changed + +- Client connections now use gzip transport-level gRPC compression by default. + Pass `grpc_compression=GrpcCompression.NONE` to `Client.connect` or + `CloudOperationsClient.connect` to disable it. + +### Breaking Changes + +- `StartWorkflowUpdateWithStartInput` now owns the authoritative + `rpc_metadata` and `rpc_timeout` fields for + `OutboundInterceptor.start_update_with_start_workflow`. These fields were + removed from the nested update-with-start input objects, so custom + interceptors that accessed them there should read or update the top-level + fields instead. + ### Fixed +- Fixed `breakpoint()` and `pdb.set_trace()` inside workflow code when a worker + runs with `debug_mode=True` or `TEMPORAL_DEBUG=1`; sandboxed workflows without + debug mode now get a clearer error pointing to `debug_mode=True`. +- Fixed `start_update_with_start_workflow` interceptor handling so RPC metadata + and timeouts are forwarded to the underlying `execute_multi_operation` call. +- Fixed OpenAI Agents plugin streamed event serialization when pydantic had not + yet built deferred schemas, and fixed terminal sandbox errors retrying + forever. - Removed the lazy-connect lock from the per-RPC hot path. It was previously acquired on every RPC, putting an event-loop-bound primitive on the hot path; it is now skipped once the client is connected. This reduces the client's diff --git a/pyproject.toml b/pyproject.toml index 943e56018..299c03df9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "temporalio" -version = "1.28.0" +version = "1.29.0" description = "Temporal.io Python SDK" authors = [{ name = "Temporal Technologies Inc", email = "sdk@temporal.io" }] requires-python = ">=3.10" diff --git a/temporalio/service.py b/temporalio/service.py index 3d8702ed1..2d3829c08 100644 --- a/temporalio/service.py +++ b/temporalio/service.py @@ -24,7 +24,7 @@ import temporalio.runtime from temporalio.bridge.client import RPCError as BridgeRPCError -__version__ = "1.28.0" +__version__ = "1.29.0" ServiceRequest = TypeVar("ServiceRequest", bound=google.protobuf.message.Message) ServiceResponse = TypeVar("ServiceResponse", bound=google.protobuf.message.Message) diff --git a/uv.lock b/uv.lock index 15a79011a..3e48e3df7 100644 --- a/uv.lock +++ b/uv.lock @@ -5412,7 +5412,7 @@ wheels = [ [[package]] name = "temporalio" -version = "1.28.0" +version = "1.29.0" source = { virtual = "." } dependencies = [ { name = "nexus-rpc" },