Skip to content

Commit 411f190

Browse files
committed
use SAM to deploy examples
1 parent 5719ff9 commit 411f190

7 files changed

Lines changed: 2070 additions & 292 deletions

File tree

.github/workflows/deploy-examples.yml

Lines changed: 90 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -11,33 +11,16 @@ on:
1111

1212
env:
1313
AWS_REGION: us-west-2
14+
SAM_CLI_TELEMETRY: 0
1415

1516
permissions:
1617
id-token: write
1718
contents: read
1819

1920
jobs:
20-
setup:
21-
runs-on: ubuntu-latest
22-
outputs:
23-
examples: ${{ steps.get-examples.outputs.examples }}
24-
steps:
25-
- uses: actions/checkout@v6
26-
27-
- name: Get examples from catalog
28-
id: get-examples
29-
working-directory: ./packages/aws-durable-execution-sdk-python-examples
30-
run: |
31-
echo "examples=$(jq -c '.examples | map(select(.integration == true))' examples-catalog.json)" >> $GITHUB_OUTPUT
32-
3321
integration-test:
34-
needs: setup
3522
runs-on: ubuntu-latest
36-
name: ${{ matrix.example.name }}
37-
strategy:
38-
matrix:
39-
example: ${{ fromJson(needs.setup.outputs.examples) }}
40-
fail-fast: false
23+
name: Deploy and test examples
4124

4225
steps:
4326
- uses: actions/checkout@v6
@@ -57,80 +40,99 @@ jobs:
5740

5841
- name: Install Hatch
5942
run: pip install hatch
60-
- name: Build examples
61-
run: |
62-
hatch run -- examples:pip install -e packages/aws-durable-execution-sdk-python packages/aws-durable-execution-sdk-python-otel
63-
hatch run examples:build
6443

65-
- name: Deploy Lambda function - ${{ matrix.example.name }}
66-
id: deploy
44+
- name: Set up SAM CLI
45+
uses: aws-actions/setup-sam@v2
46+
47+
- name: Deploy and test integration examples
6748
env:
6849
AWS_ACCOUNT_ID: ${{ secrets.AWS_ACCOUNT_ID }}
6950
LAMBDA_ENDPOINT: "https://lambda.us-west-2.amazonaws.com"
7051
KMS_KEY_ARN: ${{ secrets.KMS_KEY_ARN }}
7152
run: |
72-
# Build function name
73-
EXAMPLE_NAME_CLEAN=$(echo "${{ matrix.example.name }}" | sed 's/ //g')
74-
if [ "${{ github.event_name }}" = "pull_request" ]; then
75-
FUNCTION_NAME="${EXAMPLE_NAME_CLEAN}-Python-PR-${{ github.event.number }}"
76-
else
77-
FUNCTION_NAME="${EXAMPLE_NAME_CLEAN}-Python"
78-
fi
79-
80-
# Clean up existing function if present to avoid conflicts
81-
echo "Cleaning up existing function if present..."
82-
aws lambda delete-function \
83-
--function-name "$FUNCTION_NAME" \
84-
--endpoint-url "$LAMBDA_ENDPOINT" \
85-
--region "$AWS_REGION" 2>/dev/null || echo "No existing function to clean up"
86-
87-
# Give AWS time to process the deletion
88-
sleep 5
89-
90-
echo "Deploying ${{ matrix.example.name }} as $FUNCTION_NAME"
91-
hatch run examples:deploy "${{ matrix.example.name }}" --function-name "$FUNCTION_NAME"
92-
93-
# $LATEST is also a qualified version
94-
QUALIFIED_FUNCTION_NAME="${FUNCTION_NAME}:\$LATEST"
95-
96-
# Store both names for later steps
97-
echo "FUNCTION_NAME=$FUNCTION_NAME" >> $GITHUB_ENV
98-
echo "QUALIFIED_FUNCTION_NAME=$QUALIFIED_FUNCTION_NAME" >> $GITHUB_ENV
99-
echo "VERSION=$VERSION" >> $GITHUB_ENV
100-
echo "DEPLOYED_FUNCTION_NAME=$FUNCTION_NAME" >> $GITHUB_OUTPUT
101-
echo "QUALIFIED_FUNCTION_NAME=$QUALIFIED_FUNCTION_NAME" >> $GITHUB_OUTPUT
102-
103-
- name: Run Integration Tests - ${{ matrix.example.name }}
104-
env:
105-
AWS_REGION: ${{ env.AWS_REGION }}
106-
LAMBDA_ENDPOINT: "https://lambda.us-west-2.amazonaws.com"
107-
QUALIFIED_FUNCTION_NAME: ${{ env.QUALIFIED_FUNCTION_NAME }}
108-
LAMBDA_FUNCTION_TEST_NAME: ${{ matrix.example.name }}
109-
run: |
110-
echo "Running integration tests for ${{ matrix.example.name }}"
111-
echo "Function name: ${{ steps.deploy.outputs.DEPLOYED_FUNCTION_NAME }}"
112-
echo "Qualified function name: ${QUALIFIED_FUNCTION_NAME}"
113-
echo "AWS Region: ${AWS_REGION}"
114-
echo "Lambda Endpoint: ${LAMBDA_ENDPOINT}"
115-
116-
# Convert example name to test name: "Hello World" -> "test_hello_world"
117-
TEST_NAME="test_$(echo "${{ matrix.example.name }}" | tr '[:upper:]' '[:lower:]' | tr ' ' '_')"
118-
echo "Test name: ${TEST_NAME}"
119-
120-
# Run integration tests from repo root
121-
hatch run test:examples-integration
122-
123-
# Wait for function to be ready
124-
echo "Waiting for function to be active..."
125-
aws lambda wait function-active --function-name "$QUALIFIED_FUNCTION_NAME" --endpoint-url "$LAMBDA_ENDPOINT" --region "$AWS_REGION"
126-
127-
# - name: Cleanup Lambda function
53+
while IFS= read -r EXAMPLE; do
54+
EXAMPLE_NAME="$(echo "$EXAMPLE" | jq -r '.name')"
55+
EXAMPLE_NAME_CLEAN="$(echo "$EXAMPLE_NAME" | sed 's/ //g')"
56+
57+
if [ "${{ github.event_name }}" = "pull_request" ]; then
58+
FUNCTION_NAME="${EXAMPLE_NAME_CLEAN}-Python-PR-${{ github.event.number }}"
59+
else
60+
FUNCTION_NAME="${EXAMPLE_NAME_CLEAN}-Python"
61+
fi
62+
STACK_NAME="${FUNCTION_NAME}-stack"
63+
QUALIFIED_FUNCTION_NAME="${FUNCTION_NAME}:\$LATEST"
64+
SOURCE_DIR="$PWD/packages/aws-durable-execution-sdk-python-examples/.aws-sam/source"
65+
TEMPLATE_FILE="$PWD/packages/aws-durable-execution-sdk-python-examples/.aws-sam/template.generated.json"
66+
BUILD_DIR="$PWD/packages/aws-durable-execution-sdk-python-examples/.aws-sam/build"
67+
68+
echo "::group::Deploy $EXAMPLE_NAME"
69+
70+
# Remove a legacy directly-created Lambda only when no SAM stack owns it.
71+
if ! aws cloudformation describe-stacks --stack-name "$STACK_NAME" --region "$AWS_REGION" >/dev/null 2>&1; then
72+
echo "Cleaning up legacy function if present..."
73+
aws lambda delete-function \
74+
--function-name "$FUNCTION_NAME" \
75+
--endpoint-url "$LAMBDA_ENDPOINT" \
76+
--region "$AWS_REGION" 2>/dev/null || echo "No legacy function to clean up"
77+
sleep 5
78+
fi
79+
80+
echo "Deploying $EXAMPLE_NAME as $FUNCTION_NAME"
81+
python packages/aws-durable-execution-sdk-python-examples/scripts/build_deployment_artifacts.py "$SOURCE_DIR"
82+
python packages/aws-durable-execution-sdk-python-examples/scripts/generate_sam_template.py \
83+
--example-name "$EXAMPLE_NAME" \
84+
--function-name "$FUNCTION_NAME" \
85+
--code-uri "$SOURCE_DIR" \
86+
--output "$TEMPLATE_FILE"
87+
88+
sam build \
89+
--template-file "$TEMPLATE_FILE" \
90+
--build-dir "$BUILD_DIR" \
91+
--use-container
92+
93+
PARAMETER_OVERRIDES=("LambdaEndpoint=$LAMBDA_ENDPOINT")
94+
if [ -n "${KMS_KEY_ARN:-}" ]; then
95+
PARAMETER_OVERRIDES+=("KmsKeyArn=$KMS_KEY_ARN")
96+
fi
97+
98+
sam deploy \
99+
--template-file "$BUILD_DIR/template.yaml" \
100+
--stack-name "$STACK_NAME" \
101+
--capabilities CAPABILITY_IAM \
102+
--resolve-s3 \
103+
--no-confirm-changeset \
104+
--no-fail-on-empty-changeset \
105+
--region "$AWS_REGION" \
106+
--parameter-overrides "${PARAMETER_OVERRIDES[@]}"
107+
108+
echo "Waiting for function to be active..."
109+
aws lambda wait function-active \
110+
--function-name "$QUALIFIED_FUNCTION_NAME" \
111+
--endpoint-url "$LAMBDA_ENDPOINT" \
112+
--region "$AWS_REGION"
113+
114+
echo "::endgroup::"
115+
echo "::group::Test $EXAMPLE_NAME"
116+
117+
echo "Function name: $FUNCTION_NAME"
118+
echo "Qualified function name: $QUALIFIED_FUNCTION_NAME"
119+
echo "AWS Region: $AWS_REGION"
120+
echo "Lambda Endpoint: $LAMBDA_ENDPOINT"
121+
122+
TEST_NAME="test_$(echo "$EXAMPLE_NAME" | tr '[:upper:]' '[:lower:]' | tr ' ' '_')"
123+
echo "Test name: $TEST_NAME"
124+
125+
QUALIFIED_FUNCTION_NAME="$QUALIFIED_FUNCTION_NAME" \
126+
LAMBDA_FUNCTION_TEST_NAME="$EXAMPLE_NAME" \
127+
hatch run test:examples-integration
128+
129+
echo "::endgroup::"
130+
done < <(jq -c '.examples[] | select(.integration == true)' packages/aws-durable-execution-sdk-python-examples/examples-catalog.json)
131+
132+
# - name: Cleanup SAM stack
128133
# if: always()
129-
# env:
130-
# LAMBDA_ENDPOINT: ${{ secrets.LAMBDA_ENDPOINT_BETA }}
131134
# run: |
132-
# echo "Deleting function: $FUNCTION_NAME"
133-
# aws lambda delete-function \
134-
# --function-name "$FUNCTION_NAME" \
135-
# --endpoint-url "$LAMBDA_ENDPOINT" \
136-
# --region "${{ env.AWS_REGION }}" || echo "Function already deleted or doesn't exist"
135+
# sam delete \
136+
# --stack-name "$STACK_NAME" \
137+
# --region "${{ env.AWS_REGION }}" \
138+
# --no-prompts || echo "Stack cleanup failed or already deleted"

.github/workflows/integration-tests.yml

Lines changed: 49 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ jobs:
5454
if: github.event_name == 'pull_request'
5555
env:
5656
AWS_REGION: us-west-2
57+
SAM_CLI_TELEMETRY: 0
5758

5859
steps:
5960
- name: Checkout Language SDK (this PR)
@@ -82,6 +83,9 @@ jobs:
8283
- name: Install Hatch
8384
run: python -m pip install hatch==1.16.5
8485

86+
- name: Set up SAM CLI
87+
uses: aws-actions/setup-sam@v2
88+
8589
- name: Get integration examples
8690
id: get-examples
8791
working-directory: language-sdk/packages/aws-durable-execution-sdk-python-examples
@@ -104,17 +108,54 @@ jobs:
104108
INVOKE_ACCOUNT_ID: ${{ secrets.INVOKE_ACCOUNT_ID }}
105109
KMS_KEY_ARN: ${{ secrets.KMS_KEY_ARN }}
106110
run: |
107-
echo "Building examples..."
108111
hatch run -- examples:pip install -e packages/testing-sdk
109-
hatch run examples:build
110112
111113
# Get first integration example for testing
112114
EXAMPLE_NAME=$(echo '${{ steps.get-examples.outputs.examples }}' | jq -r '.[0].name')
113115
EXAMPLE_NAME_CLEAN=$(echo "$EXAMPLE_NAME" | sed 's/ //g')
114116
FUNCTION_NAME="${EXAMPLE_NAME_CLEAN}-LanguageSDK-PR-${{ github.event.number }}"
117+
STACK_NAME="${FUNCTION_NAME}-stack"
118+
SOURCE_DIR="$PWD/packages/aws-durable-execution-sdk-python-examples/.aws-sam/source"
119+
TEMPLATE_FILE="$PWD/packages/aws-durable-execution-sdk-python-examples/.aws-sam/template.generated.json"
120+
BUILD_DIR="$PWD/packages/aws-durable-execution-sdk-python-examples/.aws-sam/build"
121+
122+
# Remove a legacy directly-created Lambda only when no SAM stack owns it.
123+
if ! aws cloudformation describe-stacks --stack-name "$STACK_NAME" --region "${{ env.AWS_REGION }}" >/dev/null 2>&1; then
124+
echo "Cleaning up legacy function if present..."
125+
aws lambda delete-function \
126+
--function-name "$FUNCTION_NAME" \
127+
--endpoint-url "$LAMBDA_ENDPOINT" \
128+
--region "${{ env.AWS_REGION }}" 2>/dev/null || echo "No legacy function to clean up"
129+
sleep 5
130+
fi
115131
116132
echo "Deploying example: $EXAMPLE_NAME as $FUNCTION_NAME"
117-
hatch run examples:deploy "$EXAMPLE_NAME" --function-name "$FUNCTION_NAME"
133+
python packages/aws-durable-execution-sdk-python-examples/scripts/build_deployment_artifacts.py "$SOURCE_DIR"
134+
python packages/aws-durable-execution-sdk-python-examples/scripts/generate_sam_template.py \
135+
--example-name "$EXAMPLE_NAME" \
136+
--function-name "$FUNCTION_NAME" \
137+
--code-uri "$SOURCE_DIR" \
138+
--output "$TEMPLATE_FILE"
139+
140+
sam build \
141+
--template-file "$TEMPLATE_FILE" \
142+
--build-dir "$BUILD_DIR" \
143+
--use-container
144+
145+
PARAMETER_OVERRIDES=("LambdaEndpoint=$LAMBDA_ENDPOINT")
146+
if [ -n "${KMS_KEY_ARN:-}" ]; then
147+
PARAMETER_OVERRIDES+=("KmsKeyArn=$KMS_KEY_ARN")
148+
fi
149+
150+
sam deploy \
151+
--template-file "$BUILD_DIR/template.yaml" \
152+
--stack-name "$STACK_NAME" \
153+
--capabilities CAPABILITY_IAM \
154+
--resolve-s3 \
155+
--no-confirm-changeset \
156+
--no-fail-on-empty-changeset \
157+
--region "${{ env.AWS_REGION }}" \
158+
--parameter-overrides "${PARAMETER_OVERRIDES[@]}"
118159
119160
QUALIFIED_FUNCTION_NAME="$FUNCTION_NAME:\$LATEST"
120161
@@ -155,8 +196,8 @@ jobs:
155196
cat /tmp/executions.json
156197
157198
# Cleanup
158-
echo "Cleaning up function: $FUNCTION_NAME"
159-
aws lambda delete-function \
160-
--function-name "$FUNCTION_NAME" \
161-
--endpoint-url "$LAMBDA_ENDPOINT" \
162-
--region "${{ env.AWS_REGION }}" || echo "Function cleanup failed or already deleted"
199+
echo "Cleaning up stack: $STACK_NAME"
200+
sam delete \
201+
--stack-name "$STACK_NAME" \
202+
--region "${{ env.AWS_REGION }}" \
203+
--no-prompts || echo "Stack cleanup failed or already deleted"

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ dist/
3232
.kiro/
3333

3434
**/build/
35+
**/.aws-sam/
3536
**/*.zip
3637

37-
.env
38+
.env

0 commit comments

Comments
 (0)