Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
134 changes: 134 additions & 0 deletions .github/workflows/deploy-examples.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
name: Deploy Python Examples

on:
pull_request:
branches: [ "main", "development"]
paths:
- 'src/aws_durable_execution_sdk_python/**'
- 'examples/**'
- '.github/workflows/deploy-examples.yml'
workflow_dispatch:

env:
AWS_REGION: us-west-2

permissions:
id-token: write
contents: read

jobs:
setup:
runs-on: ubuntu-latest
outputs:
examples: ${{ steps.get-examples.outputs.examples }}
steps:
- uses: actions/checkout@v4

- name: Get examples from catalog
id: get-examples
working-directory: ./examples
run: |
echo "examples=$(jq -c '.examples | map(select(.integration == true))' examples-catalog.json)" >> $GITHUB_OUTPUT

integration-test:
needs: setup
runs-on: ubuntu-latest
name: ${{ matrix.example.name }}
strategy:
matrix:
example: ${{ fromJson(needs.setup.outputs.examples) }}
fail-fast: false

steps:
- uses: actions/checkout@v4

- name: Setup Python
uses: actions/setup-python@v4
with:
python-version: '3.13'

- name: Configure AWS credentials
if: github.event_name != 'workflow_dispatch' || github.actor != 'nektos/act'
uses: aws-actions/configure-aws-credentials@v4
with:
role-to-assume: "${{ secrets.ACTIONS_INTEGRATION_ROLE_NAME }}"
role-session-name: pythonTestingLibraryGitHubIntegrationTest
aws-region: ${{ env.AWS_REGION }}

- name: Install Hatch
run: pip install hatch
- name: Build examples
run: hatch run examples:build

- name: Deploy Lambda function - ${{ matrix.example.name }}
id: deploy
env:
AWS_ACCOUNT_ID: ${{ secrets.AWS_ACCOUNT_ID }}
LAMBDA_ENDPOINT: "https://lambda.us-west-2.amazonaws.com"
KMS_KEY_ARN: ${{ secrets.KMS_KEY_ARN }}
run: |
# Build function name
EXAMPLE_NAME_CLEAN=$(echo "${{ matrix.example.name }}" | sed 's/ //g')
if [ "${{ github.event_name }}" = "pull_request" ]; then
FUNCTION_NAME="${EXAMPLE_NAME_CLEAN}-Python-PR-${{ github.event.number }}"
else
FUNCTION_NAME="${EXAMPLE_NAME_CLEAN}-Python"
fi

# Clean up existing function if present to avoid conflicts
echo "Cleaning up existing function if present..."
aws lambda delete-function \
--function-name "$FUNCTION_NAME" \
--endpoint-url "$LAMBDA_ENDPOINT" \
--region "$AWS_REGION" 2>/dev/null || echo "No existing function to clean up"

# Give AWS time to process the deletion
sleep 5

echo "Deploying ${{ matrix.example.name }} as $FUNCTION_NAME"
hatch run examples:deploy "${{ matrix.example.name }}" --function-name "$FUNCTION_NAME"

# $LATEST is also a qualified version
QUALIFIED_FUNCTION_NAME="${FUNCTION_NAME}:\$LATEST"

# Store both names for later steps
echo "FUNCTION_NAME=$FUNCTION_NAME" >> $GITHUB_ENV
echo "QUALIFIED_FUNCTION_NAME=$QUALIFIED_FUNCTION_NAME" >> $GITHUB_ENV
echo "VERSION=$VERSION" >> $GITHUB_ENV
echo "DEPLOYED_FUNCTION_NAME=$FUNCTION_NAME" >> $GITHUB_OUTPUT
echo "QUALIFIED_FUNCTION_NAME=$QUALIFIED_FUNCTION_NAME" >> $GITHUB_OUTPUT

- name: Run Integration Tests - ${{ matrix.example.name }}
env:
AWS_REGION: ${{ env.AWS_REGION }}
LAMBDA_ENDPOINT: "https://lambda.us-west-2.amazonaws.com"
QUALIFIED_FUNCTION_NAME: ${{ env.QUALIFIED_FUNCTION_NAME }}
LAMBDA_FUNCTION_TEST_NAME: ${{ matrix.example.name }}
run: |
echo "Running integration tests for ${{ matrix.example.name }}"
echo "Function name: ${{ steps.deploy.outputs.DEPLOYED_FUNCTION_NAME }}"
echo "Qualified function name: ${QUALIFIED_FUNCTION_NAME}"
echo "AWS Region: ${AWS_REGION}"
echo "Lambda Endpoint: ${LAMBDA_ENDPOINT}"

# Convert example name to test name: "Hello World" -> "test_hello_world"
TEST_NAME="test_$(echo "${{ matrix.example.name }}" | tr '[:upper:]' '[:lower:]' | tr ' ' '_')"
echo "Test name: ${TEST_NAME}"

# Run integration tests
hatch run test:examples-integration

# Wait for function to be ready
echo "Waiting for function to be active..."
aws lambda wait function-active --function-name "$QUALIFIED_FUNCTION_NAME" --endpoint-url "$LAMBDA_ENDPOINT" --region "$AWS_REGION"

# - name: Cleanup Lambda function
# if: always()
# env:
# LAMBDA_ENDPOINT: ${{ secrets.LAMBDA_ENDPOINT_BETA }}
# run: |
# echo "Deleting function: $FUNCTION_NAME"
# aws lambda delete-function \
# --function-name "$FUNCTION_NAME" \
# --endpoint-url "$LAMBDA_ENDPOINT" \
# --region "${{ env.AWS_REGION }}" || echo "Function already deleted or doesn't exist"
52 changes: 9 additions & 43 deletions .github/workflows/integration-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,19 +22,6 @@ jobs:
with:
path: language-sdk

- name: Parse testing SDK branch from PR body
id: parse
run: python language-sdk/ops/parse_sdk_branch.py
env:
PR_BODY: ${{ github.event.pull_request.body }}

- name: Checkout Testing SDK
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
repository: aws/aws-durable-execution-sdk-python-testing
ref: ${{ steps.parse.outputs.testing_ref }}
path: testing-sdk

- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
Expand All @@ -43,13 +30,10 @@ jobs:
- name: Install Hatch
run: python -m pip install hatch==1.16.5

- name: Setup and run Testing SDK
working-directory: testing-sdk
env:
AWS_DURABLE_SDK_URL: file://${{ github.workspace }}/language-sdk
- name: Setup and run tests
working-directory: language-sdk
run: |
echo "Running Testing SDK tests against Language SDK PR changes..."
echo "Using Language SDK from: $AWS_DURABLE_SDK_URL"
echo "Running SDK tests..."
hatch run -- test:pip install -e ../language-sdk
hatch fmt --check
hatch run types:check
Expand All @@ -70,19 +54,6 @@ jobs:
with:
path: language-sdk

- name: Parse testing SDK branch from PR body
id: parse
run: python language-sdk/ops/parse_sdk_branch.py
env:
PR_BODY: ${{ github.event.pull_request.body }}

- name: Checkout Testing SDK
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
repository: aws/aws-durable-execution-sdk-python-testing
ref: ${{ steps.parse.outputs.testing_ref }}
path: testing-sdk

- name: Set up Python 3.13
uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
Expand All @@ -95,17 +66,12 @@ jobs:
role-session-name: languageSDKIntegrationTest
aws-region: ${{ env.AWS_REGION }}

- name: Install Hatch and setup Testing SDK
working-directory: testing-sdk
env:
AWS_DURABLE_SDK_URL: file://${{ github.workspace }}/language-sdk
run: |
pip install hatch==1.16.5
python -m pip install -e .
- name: Install Hatch
run: python -m pip install hatch==1.16.5

- name: Get integration examples
id: get-examples
working-directory: testing-sdk/examples
working-directory: language-sdk/examples
run: |
echo "examples=$(jq -c '.examples | map(select(.integration == true)) | .[0:2]' examples-catalog.json)" >> $GITHUB_OUTPUT

Expand All @@ -116,12 +82,12 @@ jobs:
rm /tmp/awscliv2.zip
sudo /tmp/aws/install --update
rm -rf /tmp/aws/

- name: Deploy and test examples
working-directory: testing-sdk
working-directory: language-sdk
env:
AWS_DURABLE_SDK_URL: file://${{ github.workspace }}/language-sdk
AWS_ACCOUNT_ID: ${{ secrets.AWS_ACCOUNT_ID }}
LAMBDA_ENDPOINT: ${{ secrets.LAMBDA_ENDPOINT }}
LAMBDA_ENDPOINT: "https://lambda.us-west-2.amazonaws.com"
INVOKE_ACCOUNT_ID: ${{ secrets.INVOKE_ACCOUNT_ID }}
KMS_KEY_ARN: ${{ secrets.KMS_KEY_ARN }}
run: |
Expand Down
42 changes: 42 additions & 0 deletions .github/workflows/update-sam-template.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
name: Update SAM Template

on:
pull_request:
paths:
- "examples/**"

permissions:
contents: write

concurrency:
group: ${{ github.head_ref }}-${{ github.run_id}}-sam-template
cancel-in-progress: true

jobs:
update-template:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
ref: ${{ github.head_ref }}

- name: Set up Python 3.13
uses: actions/setup-python@v5
with:
python-version: "3.13"

- name: Generate SAM template
run: python examples/scripts/generate_sam_template.py

- name: Commit and push changes
run: |
git config --local user.email "action@github.com"
git config --local user.name "GitHub Action"
git add .
if git diff --staged --quiet; then
echo "No changes to commit"
else
git commit -m "chore: update SAM template" --no-verify
git push
fi
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,7 @@ dist/

.idea

.kiro/
.kiro/

/examples/build/*
/examples/*.zip
41 changes: 41 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -203,6 +203,47 @@ Mimic the package structure in the src/aws_durable_execution_sdk_python director
Name your module so that src/mypackage/mymodule.py has a dedicated unit test file
tests/mypackage/mymodule_test.py

## Examples and Deployment

The project includes a unified CLI tool for managing examples, deployment, and AWS account setup:

### Bootstrap AWS Account
```bash
# Set up IAM role and KMS key for durable functions
export AWS_ACCOUNT_ID=your-account-id
hatch run examples:bootstrap
```

### Build and Deploy Examples
```bash
# Build all examples with dependencies
hatch run examples:build

# Generate SAM template for all examples
hatch run examples:generate-sam-template

# List available examples
hatch run examples:list

# Deploy specific example (when durable functions are available)
hatch run examples:deploy "Hello World"
```

### Other CLI Commands
```bash
# Invoke deployed function
hatch run examples:invoke function-name --payload '{}'

# Get execution details
hatch run examples:get execution-arn

# Get execution history
hatch run examples:history execution-arn

# Clean build artifacts
hatch run examples:clean
```

## Coverage
```
hatch run test:cov
Expand Down
Loading
Loading