aws-durable-execution-sdk-python 1.0.0__tar.gz → 1.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- aws_durable_execution_sdk_python-1.1.0/.github/CODEOWNERS +1 -0
- aws_durable_execution_sdk_python-1.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +91 -0
- aws_durable_execution_sdk_python-1.1.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
- aws_durable_execution_sdk_python-1.1.0/.github/ISSUE_TEMPLATE/documentation.yml +36 -0
- aws_durable_execution_sdk_python-1.1.0/.github/ISSUE_TEMPLATE/feature_request.yml +57 -0
- aws_durable_execution_sdk_python-1.1.0/.github/dependabot.yml +14 -0
- aws_durable_execution_sdk_python-1.1.0/.github/workflows/ci.yml +53 -0
- aws_durable_execution_sdk_python-1.1.0/.github/workflows/integration-tests.yml +184 -0
- aws_durable_execution_sdk_python-1.1.0/.github/workflows/lintcommit.js +178 -0
- aws_durable_execution_sdk_python-1.1.0/.github/workflows/pypi-publish.yml +71 -0
- aws_durable_execution_sdk_python-1.1.0/.github/workflows/scorecard.yml +80 -0
- aws_durable_execution_sdk_python-1.1.0/.github/workflows/sync-package.yml +84 -0
- aws_durable_execution_sdk_python-1.1.0/.github/workflows/test-parser.yml +24 -0
- aws_durable_execution_sdk_python-1.1.0/CODE_OF_CONDUCT.md +4 -0
- aws_durable_execution_sdk_python-1.1.0/CONTRIBUTING.md +324 -0
- {aws_durable_execution_sdk_python-1.0.0 → aws_durable_execution_sdk_python-1.1.0}/PKG-INFO +5 -3
- {aws_durable_execution_sdk_python-1.0.0 → aws_durable_execution_sdk_python-1.1.0}/README.md +2 -0
- aws_durable_execution_sdk_python-1.1.0/docs/advanced/error-handling.md +955 -0
- aws_durable_execution_sdk_python-1.1.0/docs/advanced/serialization.md +771 -0
- aws_durable_execution_sdk_python-1.1.0/docs/advanced/testing-modes.md +496 -0
- aws_durable_execution_sdk_python-1.1.0/docs/api-reference/.gitkeep +1 -0
- aws_durable_execution_sdk_python-1.1.0/docs/best-practices.md +850 -0
- aws_durable_execution_sdk_python-1.1.0/docs/core/callbacks.md +877 -0
- aws_durable_execution_sdk_python-1.1.0/docs/core/child-contexts.md +701 -0
- aws_durable_execution_sdk_python-1.1.0/docs/core/invoke.md +774 -0
- aws_durable_execution_sdk_python-1.1.0/docs/core/logger.md +663 -0
- aws_durable_execution_sdk_python-1.1.0/docs/core/map.md +638 -0
- aws_durable_execution_sdk_python-1.1.0/docs/core/parallel.md +900 -0
- aws_durable_execution_sdk_python-1.1.0/docs/core/steps.md +597 -0
- aws_durable_execution_sdk_python-1.1.0/docs/core/wait.md +450 -0
- aws_durable_execution_sdk_python-1.1.0/docs/getting-started.md +291 -0
- aws_durable_execution_sdk_python-1.1.0/docs/index.md +234 -0
- aws_durable_execution_sdk_python-1.1.0/docs/testing-patterns/.gitkeep +1 -0
- aws_durable_execution_sdk_python-1.1.0/docs/testing-patterns/basic-tests.md +701 -0
- aws_durable_execution_sdk_python-1.1.0/docs/testing-patterns/complex-workflows.md +675 -0
- aws_durable_execution_sdk_python-1.1.0/docs/testing-patterns/stores.md +263 -0
- aws_durable_execution_sdk_python-1.1.0/ops/__tests__/test_parse_sdk_branch.py +84 -0
- aws_durable_execution_sdk_python-1.1.0/ops/ci-checks.sh +15 -0
- aws_durable_execution_sdk_python-1.1.0/ops/parse_sdk_branch.py +31 -0
- {aws_durable_execution_sdk_python-1.0.0 → aws_durable_execution_sdk_python-1.1.0}/pyproject.toml +2 -5
- {aws_durable_execution_sdk_python-1.0.0 → aws_durable_execution_sdk_python-1.1.0/src}/aws_durable_execution_sdk_python/__about__.py +1 -1
- {aws_durable_execution_sdk_python-1.0.0 → aws_durable_execution_sdk_python-1.1.0/src}/aws_durable_execution_sdk_python/__init__.py +2 -0
- {aws_durable_execution_sdk_python-1.0.0 → aws_durable_execution_sdk_python-1.1.0/src}/aws_durable_execution_sdk_python/concurrency/executor.py +45 -30
- {aws_durable_execution_sdk_python-1.0.0 → aws_durable_execution_sdk_python-1.1.0/src}/aws_durable_execution_sdk_python/context.py +85 -22
- {aws_durable_execution_sdk_python-1.0.0 → aws_durable_execution_sdk_python-1.1.0/src}/aws_durable_execution_sdk_python/exceptions.py +29 -0
- {aws_durable_execution_sdk_python-1.0.0 → aws_durable_execution_sdk_python-1.1.0/src}/aws_durable_execution_sdk_python/execution.py +1 -1
- {aws_durable_execution_sdk_python-1.0.0 → aws_durable_execution_sdk_python-1.1.0/src}/aws_durable_execution_sdk_python/lambda_service.py +8 -37
- aws_durable_execution_sdk_python-1.1.0/src/aws_durable_execution_sdk_python/operation/base.py +187 -0
- aws_durable_execution_sdk_python-1.1.0/src/aws_durable_execution_sdk_python/operation/callback.py +182 -0
- aws_durable_execution_sdk_python-1.1.0/src/aws_durable_execution_sdk_python/operation/child.py +277 -0
- aws_durable_execution_sdk_python-1.1.0/src/aws_durable_execution_sdk_python/operation/invoke.py +172 -0
- aws_durable_execution_sdk_python-1.1.0/src/aws_durable_execution_sdk_python/operation/step.py +358 -0
- aws_durable_execution_sdk_python-1.1.0/src/aws_durable_execution_sdk_python/operation/wait.py +111 -0
- aws_durable_execution_sdk_python-1.1.0/src/aws_durable_execution_sdk_python/operation/wait_for_condition.py +282 -0
- {aws_durable_execution_sdk_python-1.0.0 → aws_durable_execution_sdk_python-1.1.0/src}/aws_durable_execution_sdk_python/state.py +8 -1
- aws_durable_execution_sdk_python-1.1.0/tests/__init__.py +0 -0
- aws_durable_execution_sdk_python-1.1.0/tests/concurrency_test.py +3033 -0
- aws_durable_execution_sdk_python-1.1.0/tests/config_test.py +291 -0
- aws_durable_execution_sdk_python-1.1.0/tests/context_test.py +1853 -0
- aws_durable_execution_sdk_python-1.1.0/tests/durable_executions_python_language_sdk_test.py +6 -0
- aws_durable_execution_sdk_python-1.1.0/tests/e2e/__init__.py +0 -0
- aws_durable_execution_sdk_python-1.1.0/tests/e2e/checkpoint_response_int_test.py +768 -0
- aws_durable_execution_sdk_python-1.1.0/tests/e2e/execution_int_test.py +623 -0
- aws_durable_execution_sdk_python-1.1.0/tests/exceptions_test.py +376 -0
- aws_durable_execution_sdk_python-1.1.0/tests/execution_test.py +2039 -0
- aws_durable_execution_sdk_python-1.1.0/tests/lambda_service_test.py +2044 -0
- aws_durable_execution_sdk_python-1.1.0/tests/logger_test.py +418 -0
- aws_durable_execution_sdk_python-1.1.0/tests/operation/__init__.py +0 -0
- aws_durable_execution_sdk_python-1.1.0/tests/operation/base_test.py +314 -0
- aws_durable_execution_sdk_python-1.1.0/tests/operation/callback_test.py +1533 -0
- aws_durable_execution_sdk_python-1.1.0/tests/operation/child_test.py +686 -0
- aws_durable_execution_sdk_python-1.1.0/tests/operation/invoke_test.py +1187 -0
- aws_durable_execution_sdk_python-1.1.0/tests/operation/map_test.py +1093 -0
- aws_durable_execution_sdk_python-1.1.0/tests/operation/parallel_test.py +1085 -0
- aws_durable_execution_sdk_python-1.1.0/tests/operation/step_test.py +896 -0
- aws_durable_execution_sdk_python-1.1.0/tests/operation/wait_for_condition_test.py +1201 -0
- aws_durable_execution_sdk_python-1.1.0/tests/operation/wait_test.py +419 -0
- aws_durable_execution_sdk_python-1.1.0/tests/retries_test.py +576 -0
- aws_durable_execution_sdk_python-1.1.0/tests/serdes_test.py +995 -0
- aws_durable_execution_sdk_python-1.1.0/tests/state_test.py +3267 -0
- aws_durable_execution_sdk_python-1.1.0/tests/suspend_test.py +65 -0
- aws_durable_execution_sdk_python-1.1.0/tests/test_helpers.py +17 -0
- aws_durable_execution_sdk_python-1.1.0/tests/threading_test.py +954 -0
- aws_durable_execution_sdk_python-1.1.0/tests/types_test.py +198 -0
- aws_durable_execution_sdk_python-1.1.0/tests/waits_test.py +415 -0
- aws_durable_execution_sdk_python-1.0.0/aws_durable_execution_sdk_python/botocore/data/lambdainternal/2015-03-31/service-2.json +0 -7864
- aws_durable_execution_sdk_python-1.0.0/aws_durable_execution_sdk_python/operation/callback.py +0 -123
- aws_durable_execution_sdk_python-1.0.0/aws_durable_execution_sdk_python/operation/child.py +0 -162
- aws_durable_execution_sdk_python-1.0.0/aws_durable_execution_sdk_python/operation/invoke.py +0 -119
- aws_durable_execution_sdk_python-1.0.0/aws_durable_execution_sdk_python/operation/step.py +0 -269
- aws_durable_execution_sdk_python-1.0.0/aws_durable_execution_sdk_python/operation/wait.py +0 -53
- aws_durable_execution_sdk_python-1.0.0/aws_durable_execution_sdk_python/operation/wait_for_condition.py +0 -235
- {aws_durable_execution_sdk_python-1.0.0 → aws_durable_execution_sdk_python-1.1.0}/.gitignore +0 -0
- {aws_durable_execution_sdk_python-1.0.0 → aws_durable_execution_sdk_python-1.1.0}/LICENSE +0 -0
- {aws_durable_execution_sdk_python-1.0.0 → aws_durable_execution_sdk_python-1.1.0}/NOTICE +0 -0
- {aws_durable_execution_sdk_python-1.0.0 → aws_durable_execution_sdk_python-1.1.0/src}/aws_durable_execution_sdk_python/.gitignore +0 -0
- {aws_durable_execution_sdk_python-1.0.0 → aws_durable_execution_sdk_python-1.1.0/src}/aws_durable_execution_sdk_python/concurrency/__init__.py +0 -0
- {aws_durable_execution_sdk_python-1.0.0 → aws_durable_execution_sdk_python-1.1.0/src}/aws_durable_execution_sdk_python/concurrency/models.py +0 -0
- {aws_durable_execution_sdk_python-1.0.0 → aws_durable_execution_sdk_python-1.1.0/src}/aws_durable_execution_sdk_python/config.py +0 -0
- {aws_durable_execution_sdk_python-1.0.0 → aws_durable_execution_sdk_python-1.1.0/src}/aws_durable_execution_sdk_python/identifier.py +0 -0
- {aws_durable_execution_sdk_python-1.0.0 → aws_durable_execution_sdk_python-1.1.0/src}/aws_durable_execution_sdk_python/logger.py +0 -0
- {aws_durable_execution_sdk_python-1.0.0 → aws_durable_execution_sdk_python-1.1.0/src}/aws_durable_execution_sdk_python/operation/__init__.py +0 -0
- {aws_durable_execution_sdk_python-1.0.0 → aws_durable_execution_sdk_python-1.1.0/src}/aws_durable_execution_sdk_python/operation/map.py +0 -0
- {aws_durable_execution_sdk_python-1.0.0 → aws_durable_execution_sdk_python-1.1.0/src}/aws_durable_execution_sdk_python/operation/parallel.py +0 -0
- {aws_durable_execution_sdk_python-1.0.0 → aws_durable_execution_sdk_python-1.1.0/src}/aws_durable_execution_sdk_python/py.typed +0 -0
- {aws_durable_execution_sdk_python-1.0.0 → aws_durable_execution_sdk_python-1.1.0/src}/aws_durable_execution_sdk_python/retries.py +0 -0
- {aws_durable_execution_sdk_python-1.0.0 → aws_durable_execution_sdk_python-1.1.0/src}/aws_durable_execution_sdk_python/serdes.py +0 -0
- {aws_durable_execution_sdk_python-1.0.0 → aws_durable_execution_sdk_python-1.1.0/src}/aws_durable_execution_sdk_python/suspend.py +0 -0
- {aws_durable_execution_sdk_python-1.0.0 → aws_durable_execution_sdk_python-1.1.0/src}/aws_durable_execution_sdk_python/threading.py +0 -0
- {aws_durable_execution_sdk_python-1.0.0 → aws_durable_execution_sdk_python-1.1.0/src}/aws_durable_execution_sdk_python/types.py +0 -0
- {aws_durable_execution_sdk_python-1.0.0 → aws_durable_execution_sdk_python-1.1.0/src}/aws_durable_execution_sdk_python/waits.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
* @yaythomas @wangyb-A
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
name: 🐛 Bug Report
|
|
2
|
+
description: Report a bug or unexpected behavior
|
|
3
|
+
title: "[Bug]: "
|
|
4
|
+
labels: ["bug"]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Thanks for reporting a bug! Please fill out the information below.
|
|
10
|
+
|
|
11
|
+
- type: textarea
|
|
12
|
+
id: expected
|
|
13
|
+
attributes:
|
|
14
|
+
label: Expected Behavior
|
|
15
|
+
description: What did you expect to happen?
|
|
16
|
+
placeholder: I expected...
|
|
17
|
+
validations:
|
|
18
|
+
required: true
|
|
19
|
+
|
|
20
|
+
- type: textarea
|
|
21
|
+
id: actual
|
|
22
|
+
attributes:
|
|
23
|
+
label: Actual Behavior
|
|
24
|
+
description: What actually happened?
|
|
25
|
+
placeholder: Instead, what happened was...
|
|
26
|
+
validations:
|
|
27
|
+
required: true
|
|
28
|
+
|
|
29
|
+
- type: textarea
|
|
30
|
+
id: reproduce
|
|
31
|
+
attributes:
|
|
32
|
+
label: Steps to Reproduce
|
|
33
|
+
description: Provide steps to reproduce the issue
|
|
34
|
+
placeholder: |
|
|
35
|
+
1.
|
|
36
|
+
2.
|
|
37
|
+
3.
|
|
38
|
+
validations:
|
|
39
|
+
required: true
|
|
40
|
+
|
|
41
|
+
- type: input
|
|
42
|
+
id: sdk-version
|
|
43
|
+
attributes:
|
|
44
|
+
label: SDK Version
|
|
45
|
+
description: What version of the SDK are you using?
|
|
46
|
+
placeholder: e.g., 1.0.0
|
|
47
|
+
validations:
|
|
48
|
+
required: true
|
|
49
|
+
|
|
50
|
+
- type: dropdown
|
|
51
|
+
id: python-version
|
|
52
|
+
attributes:
|
|
53
|
+
label: Python Version
|
|
54
|
+
description: What version of Python are you using?
|
|
55
|
+
options:
|
|
56
|
+
- "3.14"
|
|
57
|
+
- "3.13"
|
|
58
|
+
- "3.12"
|
|
59
|
+
- "3.11"
|
|
60
|
+
- Other (specify in additional context)
|
|
61
|
+
validations:
|
|
62
|
+
required: true
|
|
63
|
+
|
|
64
|
+
- type: dropdown
|
|
65
|
+
id: regression
|
|
66
|
+
attributes:
|
|
67
|
+
label: Is this a regression?
|
|
68
|
+
description: Did this work in a previous version?
|
|
69
|
+
options:
|
|
70
|
+
- "No"
|
|
71
|
+
- "Yes"
|
|
72
|
+
validations:
|
|
73
|
+
required: true
|
|
74
|
+
|
|
75
|
+
- type: input
|
|
76
|
+
id: worked-version
|
|
77
|
+
attributes:
|
|
78
|
+
label: Last Working Version
|
|
79
|
+
description: If this is a regression, what version did this work in?
|
|
80
|
+
placeholder: e.g., 0.9.0
|
|
81
|
+
validations:
|
|
82
|
+
required: false
|
|
83
|
+
|
|
84
|
+
- type: textarea
|
|
85
|
+
id: context
|
|
86
|
+
attributes:
|
|
87
|
+
label: Additional Context
|
|
88
|
+
description: Add any other context, logs, or screenshots
|
|
89
|
+
placeholder: Additional information...
|
|
90
|
+
validations:
|
|
91
|
+
required: false
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
name: 📚 Documentation Issue
|
|
2
|
+
description: Report an issue with documentation
|
|
3
|
+
title: "[Docs]: "
|
|
4
|
+
labels: ["documentation"]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Thanks for helping improve our documentation!
|
|
10
|
+
|
|
11
|
+
- type: textarea
|
|
12
|
+
id: issue
|
|
13
|
+
attributes:
|
|
14
|
+
label: Issue
|
|
15
|
+
description: Describe the documentation issue
|
|
16
|
+
placeholder: The documentation says... but it should say...
|
|
17
|
+
validations:
|
|
18
|
+
required: true
|
|
19
|
+
|
|
20
|
+
- type: input
|
|
21
|
+
id: page
|
|
22
|
+
attributes:
|
|
23
|
+
label: Page/Location
|
|
24
|
+
description: Link to the page or specify where in the docs this occurs
|
|
25
|
+
placeholder: https://... or README.md section "..."
|
|
26
|
+
validations:
|
|
27
|
+
required: true
|
|
28
|
+
|
|
29
|
+
- type: textarea
|
|
30
|
+
id: fix
|
|
31
|
+
attributes:
|
|
32
|
+
label: Suggested Fix
|
|
33
|
+
description: How should this be corrected?
|
|
34
|
+
placeholder: This could be fixed by...
|
|
35
|
+
validations:
|
|
36
|
+
required: false
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
name: ✨ Feature Request
|
|
2
|
+
description: Suggest a new feature or enhancement
|
|
3
|
+
title: "[Feature]: "
|
|
4
|
+
labels: ["enhancement"]
|
|
5
|
+
body:
|
|
6
|
+
- type: markdown
|
|
7
|
+
attributes:
|
|
8
|
+
value: |
|
|
9
|
+
Thanks for taking the time to suggest a new feature!
|
|
10
|
+
|
|
11
|
+
- type: textarea
|
|
12
|
+
id: what
|
|
13
|
+
attributes:
|
|
14
|
+
label: What would you like?
|
|
15
|
+
description: Describe the feature you'd like to see
|
|
16
|
+
placeholder: I would like to...
|
|
17
|
+
validations:
|
|
18
|
+
required: true
|
|
19
|
+
|
|
20
|
+
- type: textarea
|
|
21
|
+
id: implementation
|
|
22
|
+
attributes:
|
|
23
|
+
label: Possible Implementation
|
|
24
|
+
description: Suggest how this could be implemented
|
|
25
|
+
placeholder: This could be implemented by...
|
|
26
|
+
validations:
|
|
27
|
+
required: false
|
|
28
|
+
|
|
29
|
+
- type: dropdown
|
|
30
|
+
id: breaking-change
|
|
31
|
+
attributes:
|
|
32
|
+
label: Is this a breaking change?
|
|
33
|
+
options:
|
|
34
|
+
- "No"
|
|
35
|
+
- "Yes"
|
|
36
|
+
validations:
|
|
37
|
+
required: true
|
|
38
|
+
|
|
39
|
+
- type: dropdown
|
|
40
|
+
id: rfc
|
|
41
|
+
attributes:
|
|
42
|
+
label: Does this require an RFC?
|
|
43
|
+
description: RFC is required when changing existing behavior or for new features that require research
|
|
44
|
+
options:
|
|
45
|
+
- "No"
|
|
46
|
+
- "Yes"
|
|
47
|
+
validations:
|
|
48
|
+
required: true
|
|
49
|
+
|
|
50
|
+
- type: textarea
|
|
51
|
+
id: context
|
|
52
|
+
attributes:
|
|
53
|
+
label: Additional Context
|
|
54
|
+
description: Add any other context, examples, or screenshots
|
|
55
|
+
placeholder: Additional information...
|
|
56
|
+
validations:
|
|
57
|
+
required: false
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# Reference: https://docs.github.com/en/github/administering-a-repository/configuration-options-for-dependency-updates
|
|
2
|
+
version: 2
|
|
3
|
+
updates:
|
|
4
|
+
- package-ecosystem: "github-actions"
|
|
5
|
+
directory: "/"
|
|
6
|
+
schedule:
|
|
7
|
+
interval: "weekly"
|
|
8
|
+
groups:
|
|
9
|
+
# Group updates together, so that they are all applied in a single PR.
|
|
10
|
+
# Grouped updates are currently in beta and is subject to change.
|
|
11
|
+
# xref: https://docs.github.com/en/code-security/dependabot/dependabot-version-updates/configuration-options-for-the-dependabot.yml-file#groups
|
|
12
|
+
actions-deps:
|
|
13
|
+
patterns:
|
|
14
|
+
- "*"
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions
|
|
2
|
+
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python
|
|
3
|
+
|
|
4
|
+
name: Python package
|
|
5
|
+
permissions:
|
|
6
|
+
contents: read
|
|
7
|
+
|
|
8
|
+
on:
|
|
9
|
+
push:
|
|
10
|
+
|
|
11
|
+
pull_request:
|
|
12
|
+
branches: [ main ]
|
|
13
|
+
|
|
14
|
+
jobs:
|
|
15
|
+
lint-commits:
|
|
16
|
+
# Note: To re-run `lint-commits` after fixing the PR title, close-and-reopen the PR.
|
|
17
|
+
runs-on: ubuntu-latest
|
|
18
|
+
steps:
|
|
19
|
+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
|
20
|
+
- name: Use Node.js
|
|
21
|
+
uses: actions/setup-node@395ad3262231945c25e8478fd5baf05154b1d79f # v6.1.0
|
|
22
|
+
with:
|
|
23
|
+
node-version: 22.x
|
|
24
|
+
- name: Check PR title
|
|
25
|
+
run: |
|
|
26
|
+
node "$GITHUB_WORKSPACE/.github/workflows/lintcommit.js"
|
|
27
|
+
|
|
28
|
+
build:
|
|
29
|
+
needs: lint-commits
|
|
30
|
+
|
|
31
|
+
runs-on: ubuntu-latest
|
|
32
|
+
strategy:
|
|
33
|
+
fail-fast: false
|
|
34
|
+
matrix:
|
|
35
|
+
python-version: ["3.11","3.12","3.13","3.14"]
|
|
36
|
+
|
|
37
|
+
steps:
|
|
38
|
+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
|
39
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
40
|
+
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
|
|
41
|
+
with:
|
|
42
|
+
python-version: ${{ matrix.python-version }}
|
|
43
|
+
- name: Install Hatch
|
|
44
|
+
run: |
|
|
45
|
+
python -m pip install hatch==1.15.0
|
|
46
|
+
- name: static analysis
|
|
47
|
+
run: hatch fmt --check
|
|
48
|
+
- name: type checking
|
|
49
|
+
run: hatch run types:check
|
|
50
|
+
- name: Run tests + coverage
|
|
51
|
+
run: hatch run test:cov
|
|
52
|
+
- name: Build distribution
|
|
53
|
+
run: hatch build
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
name: Integration Tests
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request:
|
|
5
|
+
branches: [ main ]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
contents: read
|
|
9
|
+
id-token: write
|
|
10
|
+
|
|
11
|
+
jobs:
|
|
12
|
+
integration-tests:
|
|
13
|
+
runs-on: ubuntu-latest
|
|
14
|
+
strategy:
|
|
15
|
+
fail-fast: false
|
|
16
|
+
matrix:
|
|
17
|
+
python-version: ["3.13"]
|
|
18
|
+
|
|
19
|
+
steps:
|
|
20
|
+
- name: Checkout Language SDK (this PR)
|
|
21
|
+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
|
22
|
+
with:
|
|
23
|
+
path: language-sdk
|
|
24
|
+
|
|
25
|
+
- name: Parse testing SDK branch from PR body
|
|
26
|
+
id: parse
|
|
27
|
+
run: python language-sdk/ops/parse_sdk_branch.py
|
|
28
|
+
env:
|
|
29
|
+
PR_BODY: ${{ github.event.pull_request.body }}
|
|
30
|
+
|
|
31
|
+
- name: Checkout Testing SDK
|
|
32
|
+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
|
33
|
+
with:
|
|
34
|
+
repository: aws/aws-durable-execution-sdk-python-testing
|
|
35
|
+
ref: ${{ steps.parse.outputs.testing_ref }}
|
|
36
|
+
token: ${{ secrets.CROSS_REPO_PAT }}
|
|
37
|
+
path: testing-sdk
|
|
38
|
+
|
|
39
|
+
- name: Set up Python ${{ matrix.python-version }}
|
|
40
|
+
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
|
|
41
|
+
with:
|
|
42
|
+
python-version: ${{ matrix.python-version }}
|
|
43
|
+
|
|
44
|
+
- name: Install Hatch
|
|
45
|
+
run: python -m pip install hatch==1.15.0
|
|
46
|
+
|
|
47
|
+
- name: Setup and run Testing SDK
|
|
48
|
+
working-directory: testing-sdk
|
|
49
|
+
env:
|
|
50
|
+
AWS_DURABLE_SDK_URL: file://${{ github.workspace }}/language-sdk
|
|
51
|
+
run: |
|
|
52
|
+
echo "Running Testing SDK tests against Language SDK PR changes..."
|
|
53
|
+
echo "Using Language SDK from: $AWS_DURABLE_SDK_URL"
|
|
54
|
+
python -m pip install -e .
|
|
55
|
+
hatch fmt --check
|
|
56
|
+
hatch run types:check
|
|
57
|
+
hatch run test:cov
|
|
58
|
+
hatch run test:examples
|
|
59
|
+
hatch build
|
|
60
|
+
|
|
61
|
+
e2e-tests:
|
|
62
|
+
needs: integration-tests
|
|
63
|
+
runs-on: ubuntu-latest
|
|
64
|
+
if: github.event_name == 'pull_request'
|
|
65
|
+
env:
|
|
66
|
+
AWS_REGION: us-west-2
|
|
67
|
+
|
|
68
|
+
steps:
|
|
69
|
+
- name: Checkout Language SDK (this PR)
|
|
70
|
+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
|
71
|
+
with:
|
|
72
|
+
path: language-sdk
|
|
73
|
+
|
|
74
|
+
- name: Parse testing SDK branch from PR body
|
|
75
|
+
id: parse
|
|
76
|
+
run: python language-sdk/ops/parse_sdk_branch.py
|
|
77
|
+
env:
|
|
78
|
+
PR_BODY: ${{ github.event.pull_request.body }}
|
|
79
|
+
|
|
80
|
+
- name: Checkout Testing SDK
|
|
81
|
+
uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
|
82
|
+
with:
|
|
83
|
+
repository: aws/aws-durable-execution-sdk-python-testing
|
|
84
|
+
ref: ${{ steps.parse.outputs.testing_ref }}
|
|
85
|
+
token: ${{ secrets.CROSS_REPO_PAT }}
|
|
86
|
+
path: testing-sdk
|
|
87
|
+
|
|
88
|
+
- name: Set up Python 3.13
|
|
89
|
+
uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
|
|
90
|
+
with:
|
|
91
|
+
python-version: '3.13'
|
|
92
|
+
|
|
93
|
+
- name: Configure AWS credentials
|
|
94
|
+
uses: aws-actions/configure-aws-credentials@61815dcd50bd041e203e49132bacad1fd04d2708 # v5.1.1
|
|
95
|
+
with:
|
|
96
|
+
role-to-assume: "${{ secrets.ACTIONS_INTEGRATION_ROLE_NAME }}"
|
|
97
|
+
role-session-name: languageSDKIntegrationTest
|
|
98
|
+
aws-region: ${{ env.AWS_REGION }}
|
|
99
|
+
|
|
100
|
+
- name: Install Hatch and setup Testing SDK
|
|
101
|
+
working-directory: testing-sdk
|
|
102
|
+
env:
|
|
103
|
+
AWS_DURABLE_SDK_URL: file://${{ github.workspace }}/language-sdk
|
|
104
|
+
run: |
|
|
105
|
+
pip install hatch==1.15.0
|
|
106
|
+
python -m pip install -e .
|
|
107
|
+
|
|
108
|
+
- name: Get integration examples
|
|
109
|
+
id: get-examples
|
|
110
|
+
working-directory: testing-sdk/examples
|
|
111
|
+
run: |
|
|
112
|
+
echo "examples=$(jq -c '.examples | map(select(.integration == true)) | .[0:2]' examples-catalog.json)" >> $GITHUB_OUTPUT
|
|
113
|
+
|
|
114
|
+
- name: Install AWS CLI v2
|
|
115
|
+
run: |
|
|
116
|
+
curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "/tmp/awscliv2.zip"
|
|
117
|
+
unzip -q /tmp/awscliv2.zip -d /tmp
|
|
118
|
+
rm /tmp/awscliv2.zip
|
|
119
|
+
sudo /tmp/aws/install --update
|
|
120
|
+
rm -rf /tmp/aws/
|
|
121
|
+
- name: Deploy and test examples
|
|
122
|
+
working-directory: testing-sdk
|
|
123
|
+
env:
|
|
124
|
+
AWS_DURABLE_SDK_URL: file://${{ github.workspace }}/language-sdk
|
|
125
|
+
AWS_ACCOUNT_ID: ${{ secrets.AWS_ACCOUNT_ID }}
|
|
126
|
+
LAMBDA_ENDPOINT: ${{ secrets.LAMBDA_ENDPOINT }}
|
|
127
|
+
INVOKE_ACCOUNT_ID: ${{ secrets.INVOKE_ACCOUNT_ID }}
|
|
128
|
+
KMS_KEY_ARN: ${{ secrets.KMS_KEY_ARN }}
|
|
129
|
+
run: |
|
|
130
|
+
echo "Building examples..."
|
|
131
|
+
hatch run examples:build
|
|
132
|
+
|
|
133
|
+
# Get first integration example for testing
|
|
134
|
+
EXAMPLE_NAME=$(echo '${{ steps.get-examples.outputs.examples }}' | jq -r '.[0].name')
|
|
135
|
+
EXAMPLE_NAME_CLEAN=$(echo "$EXAMPLE_NAME" | sed 's/ //g')
|
|
136
|
+
FUNCTION_NAME="${EXAMPLE_NAME_CLEAN}-LanguageSDK-PR-${{ github.event.number }}"
|
|
137
|
+
|
|
138
|
+
echo "Deploying example: $EXAMPLE_NAME as $FUNCTION_NAME"
|
|
139
|
+
hatch run examples:deploy "$EXAMPLE_NAME" --function-name "$FUNCTION_NAME"
|
|
140
|
+
|
|
141
|
+
QUALIFIED_FUNCTION_NAME="$FUNCTION_NAME:\$LATEST"
|
|
142
|
+
|
|
143
|
+
echo "Waiting for function to be ready..."
|
|
144
|
+
aws lambda wait function-active --function-name "$FUNCTION_NAME" --endpoint-url "$LAMBDA_ENDPOINT" --region "${{ env.AWS_REGION }}"
|
|
145
|
+
|
|
146
|
+
echo "Invoking Lambda function: $QUALIFIED_FUNCTION_NAME"
|
|
147
|
+
aws lambda invoke \
|
|
148
|
+
--function-name "$QUALIFIED_FUNCTION_NAME" \
|
|
149
|
+
--cli-binary-format raw-in-base64-out \
|
|
150
|
+
--payload '{"name": "World"}' \
|
|
151
|
+
--region "${{ env.AWS_REGION }}" \
|
|
152
|
+
--endpoint-url "$LAMBDA_ENDPOINT" \
|
|
153
|
+
/tmp/response.json \
|
|
154
|
+
> /tmp/invoke_response.json
|
|
155
|
+
|
|
156
|
+
echo "Response:"
|
|
157
|
+
cat /tmp/response.json
|
|
158
|
+
|
|
159
|
+
# Check for function errors
|
|
160
|
+
FUNCTION_ERROR=$(jq -r '.FunctionError // empty' /tmp/invoke_response.json)
|
|
161
|
+
if [ -n "$FUNCTION_ERROR" ]; then
|
|
162
|
+
echo "ERROR: Lambda function failed with error: $FUNCTION_ERROR"
|
|
163
|
+
cat /tmp/response.json
|
|
164
|
+
exit 1
|
|
165
|
+
fi
|
|
166
|
+
|
|
167
|
+
echo "Getting durable executions..."
|
|
168
|
+
aws lambda list-durable-executions-by-function \
|
|
169
|
+
--function-name "$QUALIFIED_FUNCTION_NAME" \
|
|
170
|
+
--statuses SUCCEEDED \
|
|
171
|
+
--region "${{ env.AWS_REGION }}" \
|
|
172
|
+
--endpoint-url "$LAMBDA_ENDPOINT" \
|
|
173
|
+
--cli-binary-format raw-in-base64-out \
|
|
174
|
+
> /tmp/executions.json
|
|
175
|
+
|
|
176
|
+
echo "Durable Executions:"
|
|
177
|
+
cat /tmp/executions.json
|
|
178
|
+
|
|
179
|
+
# Cleanup
|
|
180
|
+
echo "Cleaning up function: $FUNCTION_NAME"
|
|
181
|
+
aws lambda delete-function \
|
|
182
|
+
--function-name "$FUNCTION_NAME" \
|
|
183
|
+
--endpoint-url "$LAMBDA_ENDPOINT" \
|
|
184
|
+
--region "${{ env.AWS_REGION }}" || echo "Function cleanup failed or already deleted"
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
// Checks that a PR title conforms to conventional commits
|
|
2
|
+
// (https://www.conventionalcommits.org/).
|
|
3
|
+
//
|
|
4
|
+
// To run self-tests, run this script:
|
|
5
|
+
//
|
|
6
|
+
// node lintcommit.js test
|
|
7
|
+
|
|
8
|
+
import { readFileSync, appendFileSync } from "fs";
|
|
9
|
+
|
|
10
|
+
const types = new Set([
|
|
11
|
+
"build",
|
|
12
|
+
"chore",
|
|
13
|
+
"ci",
|
|
14
|
+
"config",
|
|
15
|
+
"deps",
|
|
16
|
+
"docs",
|
|
17
|
+
"feat",
|
|
18
|
+
"fix",
|
|
19
|
+
"perf",
|
|
20
|
+
"refactor",
|
|
21
|
+
"revert",
|
|
22
|
+
"style",
|
|
23
|
+
"test",
|
|
24
|
+
"types",
|
|
25
|
+
]);
|
|
26
|
+
|
|
27
|
+
const scopes = new Set(["sdk", "examples"]);
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* Checks that a pull request title, or commit message subject, follows the expected format:
|
|
31
|
+
*
|
|
32
|
+
* type(scope): message
|
|
33
|
+
*
|
|
34
|
+
* Returns undefined if `title` is valid, else an error message.
|
|
35
|
+
*/
|
|
36
|
+
function validateTitle(title) {
|
|
37
|
+
const parts = title.split(":");
|
|
38
|
+
const subject = parts.slice(1).join(":").trim();
|
|
39
|
+
|
|
40
|
+
if (title.startsWith("Merge")) {
|
|
41
|
+
return undefined;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (parts.length < 2) {
|
|
45
|
+
return "missing colon (:) char";
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const typeScope = parts[0];
|
|
49
|
+
|
|
50
|
+
const [type, scope] = typeScope.split(/\(([^)]+)\)$/);
|
|
51
|
+
|
|
52
|
+
if (/\s+/.test(type)) {
|
|
53
|
+
return `type contains whitespace: "${type}"`;
|
|
54
|
+
} else if (!types.has(type)) {
|
|
55
|
+
return `invalid type "${type}"`;
|
|
56
|
+
} else if (!scope && typeScope.includes("(")) {
|
|
57
|
+
return `must be formatted like type(scope):`;
|
|
58
|
+
} else if (scope && scope.length > 30) {
|
|
59
|
+
return "invalid scope (must be <=30 chars)";
|
|
60
|
+
} else if (scope && /[^- a-z0-9]+/.test(scope)) {
|
|
61
|
+
return `invalid scope (must be lowercase, ascii only): "${scope}"`;
|
|
62
|
+
} else if (scope && !scopes.has(scope)) {
|
|
63
|
+
return `invalid scope "${scope}" (valid scopes are ${Array.from(scopes).join(", ")})`;
|
|
64
|
+
} else if (subject.length === 0) {
|
|
65
|
+
return "empty subject";
|
|
66
|
+
} else if (subject.length > 50) {
|
|
67
|
+
return "invalid subject (must be <=50 chars)";
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function run() {
|
|
74
|
+
const eventData = JSON.parse(
|
|
75
|
+
readFileSync(process.env.GITHUB_EVENT_PATH, "utf8"),
|
|
76
|
+
);
|
|
77
|
+
const pullRequest = eventData.pull_request;
|
|
78
|
+
|
|
79
|
+
// console.log(eventData)
|
|
80
|
+
|
|
81
|
+
if (!pullRequest) {
|
|
82
|
+
console.info("No pull request found in the context");
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const title = pullRequest.title;
|
|
87
|
+
|
|
88
|
+
const failReason = validateTitle(title);
|
|
89
|
+
const msg = failReason
|
|
90
|
+
? `
|
|
91
|
+
Invalid pull request title: \`${title}\`
|
|
92
|
+
|
|
93
|
+
* Problem: ${failReason}
|
|
94
|
+
* Expected format: \`type(scope): subject...\`
|
|
95
|
+
* type: one of (${Array.from(types).join(", ")})
|
|
96
|
+
* scope: optional, lowercase, <30 chars
|
|
97
|
+
* subject: must be <50 chars
|
|
98
|
+
* Hint: *close and re-open the PR* to re-trigger CI (after fixing the PR title).
|
|
99
|
+
`
|
|
100
|
+
: `Pull request title matches the expected format`;
|
|
101
|
+
|
|
102
|
+
if (process.env.GITHUB_STEP_SUMMARY) {
|
|
103
|
+
appendFileSync(process.env.GITHUB_STEP_SUMMARY, msg);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (failReason) {
|
|
107
|
+
console.error(msg);
|
|
108
|
+
process.exit(1);
|
|
109
|
+
} else {
|
|
110
|
+
console.info(msg);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function _test() {
|
|
115
|
+
const tests = {
|
|
116
|
+
" foo(scope): bar": 'type contains whitespace: " foo"',
|
|
117
|
+
"build: update build process": undefined,
|
|
118
|
+
"chore: update dependencies": undefined,
|
|
119
|
+
"ci: configure CI/CD": undefined,
|
|
120
|
+
"config: update configuration files": undefined,
|
|
121
|
+
"deps: bump aws-sdk group with 5 updates": undefined,
|
|
122
|
+
"docs: update documentation": undefined,
|
|
123
|
+
"feat(sdk): add new feature": undefined,
|
|
124
|
+
"feat(sdk):": "empty subject",
|
|
125
|
+
"feat foo):": 'type contains whitespace: "feat foo)"',
|
|
126
|
+
"feat(foo)): sujet": 'invalid type "feat(foo))"',
|
|
127
|
+
"feat(foo: sujet": 'invalid type "feat(foo"',
|
|
128
|
+
"feat(Q Foo Bar): bar":
|
|
129
|
+
'invalid scope (must be lowercase, ascii only): "Q Foo Bar"',
|
|
130
|
+
"feat(sdk): bar": undefined,
|
|
131
|
+
"feat(sdk): x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x x ":
|
|
132
|
+
"invalid subject (must be <=50 chars)",
|
|
133
|
+
"feat: foo": undefined,
|
|
134
|
+
"fix: foo": undefined,
|
|
135
|
+
"fix(sdk): resolve issue": undefined,
|
|
136
|
+
"foo (scope): bar": 'type contains whitespace: "foo "',
|
|
137
|
+
"invalid title": "missing colon (:) char",
|
|
138
|
+
"perf: optimize performance": undefined,
|
|
139
|
+
"refactor: improve code structure": undefined,
|
|
140
|
+
"revert: feat: add new feature": undefined,
|
|
141
|
+
"style: format code": undefined,
|
|
142
|
+
"test: add new tests": undefined,
|
|
143
|
+
"types: add type definitions": undefined,
|
|
144
|
+
"Merge staging into feature/lambda-get-started": undefined,
|
|
145
|
+
"feat(foo): fix the types":
|
|
146
|
+
'invalid scope "foo" (valid scopes are sdk, examples)',
|
|
147
|
+
};
|
|
148
|
+
|
|
149
|
+
let passed = 0;
|
|
150
|
+
let failed = 0;
|
|
151
|
+
|
|
152
|
+
for (const [title, expected] of Object.entries(tests)) {
|
|
153
|
+
const result = validateTitle(title);
|
|
154
|
+
if (result === expected) {
|
|
155
|
+
console.log(`✅ Test passed for "${title}"`);
|
|
156
|
+
passed++;
|
|
157
|
+
} else {
|
|
158
|
+
console.log(
|
|
159
|
+
`❌ Test failed for "${title}" (expected "${expected}", got "${result}")`,
|
|
160
|
+
);
|
|
161
|
+
failed++;
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
console.log(`\n${passed} tests passed, ${failed} tests failed`);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
function main() {
|
|
169
|
+
const mode = process.argv[2];
|
|
170
|
+
|
|
171
|
+
if (mode === "test") {
|
|
172
|
+
_test();
|
|
173
|
+
} else {
|
|
174
|
+
run();
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
main();
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
# This workflow will upload a Python Package to PyPI when a release is created
|
|
2
|
+
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python#publishing-to-package-registries
|
|
3
|
+
|
|
4
|
+
# This workflow uses actions that are not certified by GitHub.
|
|
5
|
+
# They are provided by a third-party and are governed by
|
|
6
|
+
# separate terms of service, privacy policy, and support
|
|
7
|
+
# documentation.
|
|
8
|
+
|
|
9
|
+
name: Upload PyPI Package
|
|
10
|
+
|
|
11
|
+
on:
|
|
12
|
+
release:
|
|
13
|
+
types: [published]
|
|
14
|
+
|
|
15
|
+
permissions:
|
|
16
|
+
contents: read
|
|
17
|
+
|
|
18
|
+
jobs:
|
|
19
|
+
release-build:
|
|
20
|
+
runs-on: ubuntu-latest
|
|
21
|
+
|
|
22
|
+
steps:
|
|
23
|
+
- uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # v6.0.1
|
|
24
|
+
|
|
25
|
+
- uses: actions/setup-python@83679a892e2d95755f2dac6acb0bfd1e9ac5d548 # v6.1.0
|
|
26
|
+
with:
|
|
27
|
+
python-version: "3.11"
|
|
28
|
+
- name: Install Hatch
|
|
29
|
+
run: |
|
|
30
|
+
python -m pip install --upgrade hatch==1.15.0
|
|
31
|
+
- name: Build release distributions
|
|
32
|
+
run: |
|
|
33
|
+
# NOTE: put your own distribution build steps here.
|
|
34
|
+
hatch build
|
|
35
|
+
|
|
36
|
+
- name: Upload distributions
|
|
37
|
+
uses: actions/upload-artifact@330a01c490aca151604b8cf639adc76d48f6c5d4 # v5.0.0
|
|
38
|
+
with:
|
|
39
|
+
name: release-dists
|
|
40
|
+
path: dist/
|
|
41
|
+
|
|
42
|
+
pypi-publish:
|
|
43
|
+
runs-on: ubuntu-latest
|
|
44
|
+
needs:
|
|
45
|
+
- release-build
|
|
46
|
+
permissions:
|
|
47
|
+
# IMPORTANT: this permission is mandatory for trusted publishing
|
|
48
|
+
id-token: write
|
|
49
|
+
|
|
50
|
+
# Dedicated environments with protections for publishing are strongly recommended.
|
|
51
|
+
# For more information, see: https://docs.github.com/en/actions/deployment/targeting-different-environments/using-environments-for-deployment#deployment-protection-rules
|
|
52
|
+
environment:
|
|
53
|
+
name: pypi
|
|
54
|
+
# OPTIONAL: uncomment and update to include your PyPI project URL in the deployment status:
|
|
55
|
+
# url: https://pypi.org/p/aws-durable-execution-sdk-python
|
|
56
|
+
#
|
|
57
|
+
# ALTERNATIVE: if your GitHub Release name is the PyPI project version string
|
|
58
|
+
# ALTERNATIVE: exactly, uncomment the following line instead:
|
|
59
|
+
url: https://pypi.org/project/aws-durable-execution-sdk-python/${{ github.event.release.name }}
|
|
60
|
+
|
|
61
|
+
steps:
|
|
62
|
+
- name: Retrieve release distributions
|
|
63
|
+
uses: actions/download-artifact@018cc2cf5baa6db3ef3c5f8a56943fffe632ef53 # v6.0.0
|
|
64
|
+
with:
|
|
65
|
+
name: release-dists
|
|
66
|
+
path: dist/
|
|
67
|
+
|
|
68
|
+
- name: Publish release distributions to PyPI
|
|
69
|
+
uses: pypa/gh-action-pypi-publish@ed0c53931b1dc9bd32cbe73a98c7f6766f8a527e # v1.13.0
|
|
70
|
+
with:
|
|
71
|
+
packages-dir: dist/
|