1111
1212env :
1313 AWS_REGION : us-west-2
14+ SAM_CLI_TELEMETRY : 0
1415
1516permissions :
1617 id-token : write
1718 contents : read
1819
1920jobs :
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"
0 commit comments