From 3d89028b23f571b098bc148a247818273f186c82 Mon Sep 17 00:00:00 2001 From: Brent Champion Date: Sat, 6 Sep 2025 14:24:58 -0400 Subject: [PATCH 01/10] wip: create GitHub action for deploying samples to AWS --- .github/workflows/{node.js.yml => ci.yml} | 2 +- .github/workflows/deploy.yml | 60 +++++++++++++++++++++ packages/examples/scripts/deploy-samples.sh | 43 +++++++++++++++ 3 files changed, 104 insertions(+), 1 deletion(-) rename .github/workflows/{node.js.yml => ci.yml} (98%) create mode 100644 .github/workflows/deploy.yml create mode 100644 packages/examples/scripts/deploy-samples.sh diff --git a/.github/workflows/node.js.yml b/.github/workflows/ci.yml similarity index 98% rename from .github/workflows/node.js.yml rename to .github/workflows/ci.yml index feb70829..a15bf8cd 100644 --- a/.github/workflows/node.js.yml +++ b/.github/workflows/ci.yml @@ -1,7 +1,7 @@ # This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs -name: Node.js CI +name: CI on: push: diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 00000000..2044f728 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,60 @@ +name: Deploy Lambda Functions + +on: + push: + branches: [ "main", "development" ] + paths: + - 'packages/lambda-durable-functions-sdk-js/**' + - 'packages/examples/**' + pull_request: + branches: [ "main", "development" ] + paths: + - 'packages/lambda-durable-functions-sdk-js/**' + - 'packages/examples/**' + workflow_dispatch: + +env: + AWS_REGION: us-east-1 + +jobs: + deploy: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '22.x' + cache: 'npm' + + - name: Configure AWS credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} + aws-region: ${{ env.AWS_REGION }} + + - name: Install AWS CLI + run: | + apt-get -y update + apt-get -y install python3-pip + pip3 install awscli + + - name: Install dependencies + run: npm run install-all + + - name: Build project + run: npm run build + + - name: Run tests + run: npm run test + + - name: Deploy Lambda functions + working-directory: ./packages/examples + env: + AWS_ACCOUNT_ID: ${{ secrets.AWS_ACCOUNT_ID }} + run: | + chmod +x scripts/deploy-samples.sh + ./scripts/deploy-samples.sh diff --git a/packages/examples/scripts/deploy-samples.sh b/packages/examples/scripts/deploy-samples.sh new file mode 100644 index 00000000..890026a5 --- /dev/null +++ b/packages/examples/scripts/deploy-samples.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +set -e + +REGION=${AWS_REGION:-us-east-1} +ROLE_ARN="arn:aws:iam::${AWS_ACCOUNT_ID}:role/lambda-execution-role" + +echo "Packaging Lambda functions..." +cd dist +zip -r ../lambda-functions.zip . +cd .. + +echo "Reading examples catalog..." +HANDLERS=$(jq -r '.examples[].handler' examples-catalog.json) + +for handler in $HANDLERS; do + FUNCTION_NAME=$(echo $handler | sed 's/\.handler$//' | sed 's/-/_/g') + FUNCTION_NAME="${FUNCTION_NAME}_TypeScript" + + echo "Deploying function: $FUNCTION_NAME with handler: $handler" + + # Try to update existing function, create if it doesn't exist + if aws lambda get-function --function-name "$FUNCTION_NAME" --region "$REGION" >/dev/null 2>&1; then + echo "Updating existing function: $FUNCTION_NAME" + aws lambda update-function-code \ + --function-name "$FUNCTION_NAME" \ + --zip-file fileb://lambda-functions.zip \ + --region "$REGION" + else + echo "Creating new function: $FUNCTION_NAME" + aws lambda create-function \ + --function-name "$FUNCTION_NAME" \ + --runtime nodejs22.x \ + --role "$ROLE_ARN" \ + --handler "$handler" \ + --zip-file fileb://lambda-functions.zip \ + --timeout 60 \ + --memory-size 128 \ + --region "$REGION" + fi +done + +echo "Deployment complete!" From 2f1a4c6d9b166a4aae668aadfd4573036916cc0e Mon Sep 17 00:00:00 2001 From: Brent Champion Date: Sat, 6 Sep 2025 14:28:20 -0400 Subject: [PATCH 02/10] remove AWS CLI setup step --- .github/workflows/deploy.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 2044f728..2a63df11 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -35,12 +35,6 @@ jobs: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: ${{ env.AWS_REGION }} - - - name: Install AWS CLI - run: | - apt-get -y update - apt-get -y install python3-pip - pip3 install awscli - name: Install dependencies run: npm run install-all From 591fb45d004b6dd448338fcc39bc8a38b4f009f1 Mon Sep 17 00:00:00 2001 From: Brent Champion Date: Sat, 6 Sep 2025 14:33:13 -0400 Subject: [PATCH 03/10] rename workflows and make deployment script executable --- .../{deploy.yml => integration-tests.yml} | 14 +++++--------- .github/workflows/{ci.yml => unit-tests.yml} | 2 +- packages/examples/scripts/deploy-samples.sh | 0 3 files changed, 6 insertions(+), 10 deletions(-) rename .github/workflows/{deploy.yml => integration-tests.yml} (82%) rename .github/workflows/{ci.yml => unit-tests.yml} (98%) mode change 100644 => 100755 packages/examples/scripts/deploy-samples.sh diff --git a/.github/workflows/deploy.yml b/.github/workflows/integration-tests.yml similarity index 82% rename from .github/workflows/deploy.yml rename to .github/workflows/integration-tests.yml index 2a63df11..18fab400 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/integration-tests.yml @@ -1,4 +1,4 @@ -name: Deploy Lambda Functions +name: Integration Tests on: push: @@ -36,19 +36,15 @@ jobs: aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: ${{ env.AWS_REGION }} - - name: Install dependencies + - name: Install Dependencies run: npm run install-all - - name: Build project + - name: Build Project run: npm run build - - - name: Run tests - run: npm run test - - - name: Deploy Lambda functions + + - name: Deploy Lambda Functions working-directory: ./packages/examples env: AWS_ACCOUNT_ID: ${{ secrets.AWS_ACCOUNT_ID }} run: | - chmod +x scripts/deploy-samples.sh ./scripts/deploy-samples.sh diff --git a/.github/workflows/ci.yml b/.github/workflows/unit-tests.yml similarity index 98% rename from .github/workflows/ci.yml rename to .github/workflows/unit-tests.yml index a15bf8cd..2d3b06a2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/unit-tests.yml @@ -1,7 +1,7 @@ # This workflow will do a clean installation of node dependencies, cache/restore them, build the source code and run tests across different versions of node # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-nodejs -name: CI +name: Unit Tests on: push: diff --git a/packages/examples/scripts/deploy-samples.sh b/packages/examples/scripts/deploy-samples.sh old mode 100644 new mode 100755 From ade238ba9ca2465925aca8eb44a08dc29acb6e7b Mon Sep 17 00:00:00 2001 From: Brent Champion Date: Sat, 6 Sep 2025 14:40:39 -0400 Subject: [PATCH 04/10] update IAM role for integration tests --- packages/examples/scripts/deploy-samples.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/examples/scripts/deploy-samples.sh b/packages/examples/scripts/deploy-samples.sh index 890026a5..b6e1fcd6 100755 --- a/packages/examples/scripts/deploy-samples.sh +++ b/packages/examples/scripts/deploy-samples.sh @@ -3,7 +3,7 @@ set -e REGION=${AWS_REGION:-us-east-1} -ROLE_ARN="arn:aws:iam::${AWS_ACCOUNT_ID}:role/lambda-execution-role" +ROLE_ARN="arn:aws:iam::${AWS_ACCOUNT_ID}:role/DurableFunctionsIntegrationTestRole" echo "Packaging Lambda functions..." cd dist From 6f58b24aadf412dbdb719f63a47f0cea78418d42 Mon Sep 17 00:00:00 2001 From: Brent Champion Date: Sat, 6 Sep 2025 14:52:45 -0400 Subject: [PATCH 05/10] use matrix strategy for integration tests workflow --- .github/workflows/integration-tests.yml | 72 ++++++++++++++++++--- packages/examples/scripts/deploy-samples.sh | 46 ++++--------- 2 files changed, 75 insertions(+), 43 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 18fab400..358366f8 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -14,11 +14,28 @@ on: workflow_dispatch: env: - AWS_REGION: us-east-1 + AWS_REGION: us-west-2 jobs: - deploy: + 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: ./packages/examples + run: | + echo "examples=$(jq -c '.examples' examples-catalog.json)" >> $GITHUB_OUTPUT + + deploy-test: + needs: setup + runs-on: ubuntu-latest + strategy: + matrix: + example: ${{ fromJson(needs.setup.outputs.examples) }} + fail-fast: false steps: - uses: actions/checkout@v4 @@ -35,16 +52,55 @@ jobs: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: ${{ env.AWS_REGION }} - - - name: Install Dependencies + + - name: Install AWS CLI + run: | + curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" + unzip awscliv2.zip + sudo ./aws/install + + - name: Install dependencies run: npm run install-all - - name: Build Project + - name: Build project run: npm run build - - - name: Deploy Lambda Functions + + - name: Deploy Lambda function - ${{ matrix.example.name }} working-directory: ./packages/examples env: AWS_ACCOUNT_ID: ${{ secrets.AWS_ACCOUNT_ID }} run: | - ./scripts/deploy-samples.sh + FUNCTION_NAME=$(echo "${{ matrix.example.name }}" | sed 's/ //g')-TypeScript + ROLE_ARN="arn:aws:iam::${AWS_ACCOUNT_ID}:role/DurableFunctionsIntegrationTestRole" + + echo "Packaging Lambda function..." + cd dist/examples + zip -r ../../lambda-function.zip . + cd ../.. + + echo "Deploying function: $FUNCTION_NAME with handler: ${{ matrix.example.handler }}" + + if aws lambda get-function --function-name "$FUNCTION_NAME" --region "${{ env.AWS_REGION }}" >/dev/null 2>&1; then + echo "Updating existing function: $FUNCTION_NAME" + aws lambda update-function-code \ + --function-name "$FUNCTION_NAME" \ + --zip-file fileb://lambda-function.zip \ + --region "${{ env.AWS_REGION }}" + else + echo "Creating new function: $FUNCTION_NAME" + aws lambda create-function \ + --function-name "$FUNCTION_NAME" \ + --runtime nodejs22.x \ + --role "$ROLE_ARN" \ + --handler "${{ matrix.example.handler }}" \ + --zip-file fileb://lambda-function.zip \ + --timeout 60 \ + --memory-size 128 \ + --region "${{ env.AWS_REGION }}" + fi + + - name: Test Lambda function - ${{ matrix.example.name }} + run: | + FUNCTION_NAME=$(echo "${{ matrix.example.name }}" | sed 's/ //g')-TypeScript + echo "Testing function: $FUNCTION_NAME" + # Add your test logic here diff --git a/packages/examples/scripts/deploy-samples.sh b/packages/examples/scripts/deploy-samples.sh index b6e1fcd6..511accf5 100755 --- a/packages/examples/scripts/deploy-samples.sh +++ b/packages/examples/scripts/deploy-samples.sh @@ -2,42 +2,18 @@ set -e -REGION=${AWS_REGION:-us-east-1} -ROLE_ARN="arn:aws:iam::${AWS_ACCOUNT_ID}:role/DurableFunctionsIntegrationTestRole" +echo "Reading examples catalog and dispatching individual workflows..." -echo "Packaging Lambda functions..." -cd dist -zip -r ../lambda-functions.zip . -cd .. - -echo "Reading examples catalog..." -HANDLERS=$(jq -r '.examples[].handler' examples-catalog.json) - -for handler in $HANDLERS; do - FUNCTION_NAME=$(echo $handler | sed 's/\.handler$//' | sed 's/-/_/g') - FUNCTION_NAME="${FUNCTION_NAME}_TypeScript" +while IFS= read -r line; do + name=$(echo "$line" | jq -r '.name') + handler=$(echo "$line" | jq -r '.handler') - echo "Deploying function: $FUNCTION_NAME with handler: $handler" + echo "Dispatching workflow for: $name" - # Try to update existing function, create if it doesn't exist - if aws lambda get-function --function-name "$FUNCTION_NAME" --region "$REGION" >/dev/null 2>&1; then - echo "Updating existing function: $FUNCTION_NAME" - aws lambda update-function-code \ - --function-name "$FUNCTION_NAME" \ - --zip-file fileb://lambda-functions.zip \ - --region "$REGION" - else - echo "Creating new function: $FUNCTION_NAME" - aws lambda create-function \ - --function-name "$FUNCTION_NAME" \ - --runtime nodejs22.x \ - --role "$ROLE_ARN" \ - --handler "$handler" \ - --zip-file fileb://lambda-functions.zip \ - --timeout 60 \ - --memory-size 128 \ - --region "$REGION" - fi -done + gh workflow run deploy-test-example.yml \ + -f example_name="$name" \ + -f handler="$handler" + +done < <(jq -c '.examples[]' examples-catalog.json) -echo "Deployment complete!" +echo "All workflows dispatched!" From 333b20311f22c8abbe9748f78b1b6b0eae78ed3e Mon Sep 17 00:00:00 2001 From: Brent Champion Date: Sat, 6 Sep 2025 14:56:16 -0400 Subject: [PATCH 06/10] do heavy lifting in setup, cosmetic changes around matrix test names --- .github/workflows/integration-tests.yml | 48 ++++++++++++++++--------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 358366f8..9978c116 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -23,15 +23,41 @@ jobs: examples: ${{ steps.get-examples.outputs.examples }} steps: - uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '22.x' + cache: 'npm' + + - name: Install AWS CLI + run: | + curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" + unzip awscliv2.zip + sudo ./aws/install + + - name: Install dependencies + run: npm run install-all + + - name: Build project + run: npm run build + + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + with: + name: built-examples + path: packages/examples/dist/ + - name: Get examples from catalog id: get-examples working-directory: ./packages/examples run: | echo "examples=$(jq -c '.examples' examples-catalog.json)" >> $GITHUB_OUTPUT - deploy-test: + integration-test: needs: setup runs-on: ubuntu-latest + name: ${{ matrix.example.name }} strategy: matrix: example: ${{ fromJson(needs.setup.outputs.examples) }} @@ -40,11 +66,11 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Setup Node.js - uses: actions/setup-node@v4 + - name: Download build artifacts + uses: actions/download-artifact@v4 with: - node-version: '22.x' - cache: 'npm' + name: built-examples + path: packages/examples/dist/ - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v4 @@ -53,18 +79,6 @@ jobs: aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} aws-region: ${{ env.AWS_REGION }} - - name: Install AWS CLI - run: | - curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" - unzip awscliv2.zip - sudo ./aws/install - - - name: Install dependencies - run: npm run install-all - - - name: Build project - run: npm run build - - name: Deploy Lambda function - ${{ matrix.example.name }} working-directory: ./packages/examples env: From e6b14e4d96f57c53396993605e520bba8ea1ee1e Mon Sep 17 00:00:00 2001 From: Brent Champion Date: Sat, 6 Sep 2025 14:58:52 -0400 Subject: [PATCH 07/10] skip AWS CLI --- .github/workflows/integration-tests.yml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 9978c116..ee6971be 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -30,12 +30,6 @@ jobs: node-version: '22.x' cache: 'npm' - - name: Install AWS CLI - run: | - curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip" - unzip awscliv2.zip - sudo ./aws/install - - name: Install dependencies run: npm run install-all From 2f29ffd00fb75c9b4c60558f0769f2a3a50c7b75 Mon Sep 17 00:00:00 2001 From: Brent Champion Date: Sat, 6 Sep 2025 15:09:06 -0400 Subject: [PATCH 08/10] update integration tests to create function names specific to the PR and delete after each run --- .github/workflows/integration-tests.yml | 39 +++++++++++++++++---- packages/examples/scripts/deploy-samples.sh | 19 ---------- 2 files changed, 33 insertions(+), 25 deletions(-) delete mode 100755 packages/examples/scripts/deploy-samples.sh diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index ee6971be..ce003880 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -78,13 +78,33 @@ jobs: env: AWS_ACCOUNT_ID: ${{ secrets.AWS_ACCOUNT_ID }} run: | - FUNCTION_NAME=$(echo "${{ matrix.example.name }}" | sed 's/ //g')-TypeScript + BASE_NAME=$(echo "${{ matrix.example.name }}" | sed 's/ //g')-TypeScript + if [ "${{ github.event_name }}" = "pull_request" ]; then + FUNCTION_NAME="${BASE_NAME}-PR-${{ github.event.number }}" + else + FUNCTION_NAME="${BASE_NAME}" + fi + echo "FUNCTION_NAME=$FUNCTION_NAME" >> $GITHUB_ENV + ROLE_ARN="arn:aws:iam::${AWS_ACCOUNT_ID}:role/DurableFunctionsIntegrationTestRole" echo "Packaging Lambda function..." - cd dist/examples - zip -r ../../lambda-function.zip . - cd ../.. + # Create a temporary directory for this specific function + mkdir -p temp-package + + # Copy the specific example file + HANDLER_FILE=$(echo "${{ matrix.example.handler }}" | sed 's/\.handler$//') + cp dist/examples/${HANDLER_FILE}.js temp-package/ + cp dist/examples/${HANDLER_FILE}.js.map temp-package/ 2>/dev/null || true + + # Copy node_modules + cp -r node_modules temp-package/ + + # Create zip from temp directory + cd temp-package + zip -r ../lambda-function.zip . + cd .. + rm -rf temp-package echo "Deploying function: $FUNCTION_NAME with handler: ${{ matrix.example.handler }}" @@ -109,6 +129,13 @@ jobs: - name: Test Lambda function - ${{ matrix.example.name }} run: | - FUNCTION_NAME=$(echo "${{ matrix.example.name }}" | sed 's/ //g')-TypeScript echo "Testing function: $FUNCTION_NAME" - # Add your test logic here + # TODO: Add testing logic here + + - name: Cleanup Lambda function + if: always() + run: | + echo "Deleting function: $FUNCTION_NAME" + aws lambda delete-function \ + --function-name "$FUNCTION_NAME" \ + --region "${{ env.AWS_REGION }}" || echo "Function already deleted or doesn't exist" diff --git a/packages/examples/scripts/deploy-samples.sh b/packages/examples/scripts/deploy-samples.sh deleted file mode 100755 index 511accf5..00000000 --- a/packages/examples/scripts/deploy-samples.sh +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/bash - -set -e - -echo "Reading examples catalog and dispatching individual workflows..." - -while IFS= read -r line; do - name=$(echo "$line" | jq -r '.name') - handler=$(echo "$line" | jq -r '.handler') - - echo "Dispatching workflow for: $name" - - gh workflow run deploy-test-example.yml \ - -f example_name="$name" \ - -f handler="$handler" - -done < <(jq -c '.examples[]' examples-catalog.json) - -echo "All workflows dispatched!" From 4d96973e44ebdc583da9dc8f6f7e7ec410c3e682 Mon Sep 17 00:00:00 2001 From: Brent Champion Date: Sat, 6 Sep 2025 15:10:20 -0400 Subject: [PATCH 09/10] run when workflow changes --- .github/workflows/integration-tests.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index ce003880..a736a6dc 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -6,11 +6,13 @@ on: paths: - 'packages/lambda-durable-functions-sdk-js/**' - 'packages/examples/**' + - '.github/workflows/integration-tests.yml' pull_request: branches: [ "main", "development" ] paths: - 'packages/lambda-durable-functions-sdk-js/**' - 'packages/examples/**' + - '.github/workflows/integration-tests.yml' workflow_dispatch: env: From 2aa81af958873346ce8e4ae65e0ae0379ad9b8d7 Mon Sep 17 00:00:00 2001 From: Brent Champion Date: Sat, 6 Sep 2025 15:12:45 -0400 Subject: [PATCH 10/10] update artifacts for examples --- .github/workflows/integration-tests.yml | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index a736a6dc..596a4864 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -42,7 +42,9 @@ jobs: uses: actions/upload-artifact@v4 with: name: built-examples - path: packages/examples/dist/ + path: | + packages/examples/dist/ + packages/examples/node_modules/ - name: Get examples from catalog id: get-examples @@ -66,7 +68,7 @@ jobs: uses: actions/download-artifact@v4 with: name: built-examples - path: packages/examples/dist/ + path: packages/examples/ - name: Configure AWS credentials uses: aws-actions/configure-aws-credentials@v4