This document describes how to cut a release for packages in this monorepo and how the automated PyPI publishing workflow is triggered.
This monorepo contains the following packages:
| Package | Path | Tag Prefix |
|---|---|---|
aws-durable-execution-sdk-python |
packages/aws-durable-execution-sdk-python |
sdk |
aws-durable-execution-sdk-python-otel |
packages/aws-durable-execution-sdk-python-otel |
otel |
aws-durable-execution-sdk-python-testing |
packages/aws-durable-execution-sdk-python-testing |
testing |
Each package maintains its own version in its respective __about__.py file:
- SDK:
packages/aws-durable-execution-sdk-python/src/aws_durable_execution_sdk_python/__about__.py - OTel:
packages/aws-durable-execution-sdk-python-otel/src/aws_durable_execution_sdk_python_otel/__about__.py - Testing:
packages/aws-durable-execution-sdk-python-testing/src/aws_durable_execution_sdk_python_testing/__about__.py
Bump the version in the appropriate __about__.py file(s) and merge to main before creating a release.
Update the __version__ string in the relevant __about__.py file(s). Commit and merge to main.
- Go to the Releases page on GitHub.
- Click Draft a new release.
- Create a new tag following the tagging convention below.
- Set the release title (typically the same as the tag).
- Write release notes following the format described in Release Notes Format.
- Click Publish release.
The tag should be the version of the package being bumped, prepended with a descriptive prefix:
- SDK only:
sdk-v<version>(e.g.,sdk-v1.6.0) - OTel only:
otel-v<version>(e.g.,otel-v0.3.0) - Testing only:
testing-v<version>(e.g.,testing-v1.2.1) - Multiple packages in a single release: comma-separate the sub-tags (e.g.,
sdk-v1.6.0,otel-v0.3.0)
Examples:
sdk-v1.6.0
otel-v0.3.0
testing-v1.2.1
sdk-v1.6.0,otel-v0.3.0
If additional packages are added to the monorepo in the future, follow the same pattern: choose a short descriptive prefix for the package and use <prefix>-<version>.
Creating a GitHub Release triggers the pypi-publish.yml workflow automatically. The workflow:
- Builds all packages using Hatch (
hatch build). - Uploads the built distributions as artifacts.
- Publishes each package to PyPI using trusted publishing (OIDC-based, no API tokens required).
The workflow runs on the release: [published] event, so it fires whenever a release is published on GitHub — no manual intervention is needed beyond creating the release.
Note: The workflow builds and publishes all packages in the matrix. Ensure the version in each package's
__about__.pyis correct before publishing. If only one package has a version bump, PyPI will reject the re-upload of the unchanged package (which is expected and harmless sincefail-fast: falseis set).
Releases containing an otel-v tag also trigger the
lambda-layer-publish.yml
workflow. It builds the SDK and OTel plugin into Lambda layers for each
supported Python runtime and architecture, then publishes public versions of the
aws-durable-execution-sdk-python-otel-plugin layer.
For OTel-only releases, the workflow downloads the exact SDK version pinned by
layer.sdk-version in .github/lambda-layer-publish.toml; that version must
already be published to PyPI. Combined SDK and OTel releases require the pin to
match the new SDK version and build both distributions from the tagged source.
The publishing job uses the lambda-layer-publish GitHub environment and its
LAYER_PUBLISH_ROLE_ARN secret. Set the optional LAYER_PUBLISH_REGIONS
environment variable to a comma-separated list of AWS Regions. When unset, the
workflow publishes to every commercial AWS Region supported by Lambda.
The workflow can also be run manually from the Actions tab on main; its
optional regions input overrides LAYER_PUBLISH_REGIONS for that run.
Each runtime and architecture layer archive is built once and retained as a
workflow artifact so retries publish the exact same resolved dependencies. Its
SHA-256 is included in the layer description and verified before reuse.
The publishing role must allow lambda:PublishLayerVersion and
lambda:AddLayerVersionPermission, as well as lambda:ListLayerVersions and
lambda:GetLayerVersion for identity-checked, idempotent release retries.
Release notes should maintain separate timelines for each package. Use the following structure:
## aws-durable-execution-sdk-python v1.6.0
### Features
- Added support for X
- New `context.foo()` API
### Bug Fixes
- Fixed issue with Y under Z conditions
### Breaking Changes
- Removed deprecated `bar()` method
---
## aws-durable-execution-sdk-python-otel v0.3.0
### Features
- Added tracing for `map` operations
### Bug Fixes
- Fixed span context propagation in child contexts
---
## aws-durable-execution-sdk-python-testing v1.2.1
### Bug Fixes
- Fixed issue with test runner under condition ZIf only one package is being released, include only that package's section. Each package's changelog should be self-contained so users can follow the history of the package they depend on independently.
Before publishing a release:
- Version bumped in the relevant
__about__.pyfile(s) - OTel layer SDK pin identifies a compatible published SDK, or matches the SDK version included in a combined release
- Changes merged to
main - CI checks pass on
main - Release notes written with separate sections per package
- Tag follows the naming convention (
sdk-vX.Y.Z,otel-vX.Y.Z,testing-vX.Y.Z, or comma-separated)