Skip to content

Commit 2071a6d

Browse files
authored
revamp the sample application (#83)
1 parent e58fed5 commit 2071a6d

27 files changed

+3201
-326
lines changed

.circleci/config.yml

Lines changed: 0 additions & 33 deletions
This file was deleted.
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
name: Integration Test
2+
3+
on:
4+
push:
5+
paths-ignore:
6+
- 'README.md'
7+
branches:
8+
- master
9+
pull_request:
10+
branches:
11+
- master
12+
schedule:
13+
# "At 00:00 on Sunday."
14+
- cron: "0 0 * * 0"
15+
workflow_dispatch:
16+
17+
jobs:
18+
test:
19+
name: Run Integration Tests
20+
runs-on: ubuntu-latest
21+
timeout-minutes: 30
22+
23+
steps:
24+
- name: Checkout
25+
uses: actions/checkout@v4
26+
27+
- name: Setup Node.js
28+
uses: actions/setup-node@v4
29+
with:
30+
node-version: '22'
31+
32+
- name: Setup Ruby
33+
uses: ruby/setup-ruby@v1
34+
with:
35+
ruby-version: '3.3'
36+
working-directory: demo/lambdas/ruby
37+
38+
- name: Setup LocalStack
39+
uses: localstack/setup-localstack@main
40+
with:
41+
image-tag: 'latest'
42+
use-pro: 'true'
43+
configuration: LS_LOG=trace
44+
install-awslocal: 'true'
45+
env:
46+
LOCALSTACK_AUTH_TOKEN: ${{ secrets.LOCALSTACK_AUTH_TOKEN }}
47+
48+
- name: Install CDK dependencies
49+
run: cd cdk && npm ci
50+
51+
- name: Bundle Ruby Lambda gems
52+
working-directory: demo/lambdas/ruby
53+
run: |
54+
bundle config set --local path vendor/bundle
55+
bundle install
56+
57+
- name: Install Node.js Lambda dependencies
58+
run: cd demo/lambdas/nodejs && npm install --omit=dev
59+
60+
- name: Bootstrap CDK
61+
working-directory: cdk
62+
env:
63+
AWS_ACCESS_KEY_ID: test
64+
AWS_SECRET_ACCESS_KEY: test
65+
AWS_DEFAULT_REGION: us-east-1
66+
run: npx cdklocal bootstrap
67+
68+
- name: Deploy CDK stack
69+
working-directory: cdk
70+
env:
71+
AWS_ACCESS_KEY_ID: test
72+
AWS_SECRET_ACCESS_KEY: test
73+
AWS_DEFAULT_REGION: us-east-1
74+
run: npx cdklocal deploy LocalstackDemoStack --require-approval never
75+
76+
- name: Upload frontend to S3
77+
env:
78+
AWS_ACCESS_KEY_ID: test
79+
AWS_SECRET_ACCESS_KEY: test
80+
AWS_DEFAULT_REGION: us-east-1
81+
AWS_ENDPOINT_URL: http://localhost.localstack.cloud:4566
82+
run: awslocal s3 sync demo/web/ s3://archive-bucket/
83+
84+
- name: Run end-to-end test
85+
env:
86+
AWS_ACCESS_KEY_ID: test
87+
AWS_SECRET_ACCESS_KEY: test
88+
AWS_DEFAULT_REGION: us-east-1
89+
AWS_ENDPOINT_URL: http://localhost.localstack.cloud:4566
90+
run: |
91+
echo "Discovering REST API ID..."
92+
apiId=$(awslocal apigateway get-rest-apis --output json \
93+
| jq -r '.items[] | select(.name=="localstack-demo") | .id')
94+
echo "API ID: $apiId"
95+
96+
echo "Sending new request..."
97+
reqID=$(curl -sf -d '{}' \
98+
"http://localhost:4566/_aws/execute-api/$apiId/local/requests" \
99+
| jq -r .requestID)
100+
echo "Request ID: $reqID"
101+
102+
echo "Polling for QUEUED -> PROCESSING -> FINISHED..."
103+
for i in $(seq 1 25); do
104+
cur=$(curl -sf \
105+
"http://localhost:4566/_aws/execute-api/$apiId/local/requests" \
106+
| jq -r "[.result[] | select(.requestID==\"$reqID\") | .status] | sort | last")
107+
echo " attempt $i: $cur"
108+
[ "$cur" = "FINISHED" ] && break
109+
sleep 3
110+
done
111+
112+
echo "Verifying S3 result file..."
113+
awslocal s3 cp "s3://archive-bucket/$reqID/result.txt" - | grep -q "Archive result" \
114+
&& echo "✅ End-to-end test passed!" \
115+
|| (echo "❌ S3 result not found" && exit 1)
116+
117+
- name: LocalStack logs (on failure)
118+
if: failure()
119+
run: localstack logs

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
*.pyc
2-
.serverless/
32
node_modules
43
.idea/
4+
cdk.out
5+
.DS_Store
6+
vendor/

Makefile

Lines changed: 102 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,103 @@
1-
export AWS_ACCESS_KEY_ID ?= test
1+
SHELL := /bin/bash
2+
3+
-include .env-gdc-local
4+
5+
CDIR = cd cdk
6+
7+
export AWS_ACCESS_KEY_ID ?= test
28
export AWS_SECRET_ACCESS_KEY ?= test
3-
export AWS_DEFAULT_REGION = us-east-1
4-
5-
usage: ## Show this help
6-
@fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/\\$$//' | sed -e 's/##//'
7-
8-
install: ## Install dependencies
9-
npm install
10-
which serverless || npm install -g serverless
11-
which localstack || pip install localstack
12-
13-
deploy: ## Deploy the app
14-
@make install; \
15-
echo "Deploying Serverless app to local environment"; \
16-
SLS_DEBUG=1 serverless deploy --stage local
17-
18-
send-request: ## Send a test request to the deployed application
19-
@which jq || (echo "jq was not found. Please install it (https://jqlang.github.io/jq/download/) and try again." && exit 1)
20-
@echo Looking up API ID from deployed API Gateway REST APIs ...; \
21-
apiId=$$(awslocal apigateway get-rest-apis --output json | jq -r '.items[] | select(.name="local-localstack-demo") | .id'); \
22-
echo Sending request to API Gateway REST APIs ID "$$apiId" ...; \
23-
requestID=$$(curl -s -d '{}' http://$$apiId.execute-api.localhost.localstack.cloud:4566/local/requests | jq -r .requestID); \
24-
echo "Received request ID '$$requestID'"; \
25-
for i in 1 2 3 4 5 6 7 8 9 10; do echo "Polling for processing result to appear in s3://archive-bucket/..."; awslocal s3 ls s3://archive-bucket/ | grep $$requestID && exit; sleep 3; done
26-
27-
lint: ## Run code linter
28-
@npm run lint
29-
@flake8 demo
30-
31-
.PHONY: usage install deploy send-request lint
9+
export AWS_DEFAULT_REGION ?= us-east-1
10+
export AWS_ENDPOINT_URL ?= http://localhost.localstack.cloud:4566
11+
12+
usage: ## Show this help in table format
13+
@echo "| Target | Description |"
14+
@echo "|------------------------|-------------------------------------------------------------------|"
15+
@fgrep -h "##" $(MAKEFILE_LIST) | fgrep -v fgrep | sed -e 's/:.*##\s*/##/g' | awk -F'##' '{ printf "| %-22s | %-65s |\n", $$1, $$2 }'
16+
17+
check: ## Check if all required prerequisites are installed
18+
@command -v docker > /dev/null 2>&1 || { echo "Docker is not installed. Please install Docker and try again."; exit 1; }
19+
@command -v node > /dev/null 2>&1 || { echo "Node.js is not installed. Please install Node.js and try again."; exit 1; }
20+
@command -v aws > /dev/null 2>&1 || { echo "AWS CLI is not installed. Please install AWS CLI and try again."; exit 1; }
21+
@command -v awslocal > /dev/null 2>&1 || { echo "awslocal is not installed. Run: pip install awscli-local"; exit 1; }
22+
@command -v localstack > /dev/null 2>&1 || { echo "LocalStack CLI is not installed. Run: pip install localstack"; exit 1; }
23+
@command -v jq > /dev/null 2>&1 || { echo "jq is not installed. See https://jqlang.github.io/jq/download/"; exit 1; }
24+
@test -n "$(LOCALSTACK_AUTH_TOKEN)" || { echo "LOCALSTACK_AUTH_TOKEN is not set. Find your token at https://app.localstack.cloud/workspace/auth-token"; exit 1; }
25+
@echo "All required prerequisites are available."
26+
27+
install: ## Install CDK and Lambda dependencies
28+
@$(CDIR); if [ ! -d "node_modules" ]; then \
29+
echo "Installing CDK dependencies..."; \
30+
npm install; \
31+
else \
32+
echo "CDK dependencies already installed."; \
33+
fi
34+
35+
bundle-ruby: ## Bundle Ruby 3.3 Lambda gems (requires Docker)
36+
docker run --rm \
37+
-v "$(shell pwd)/demo/lambdas/ruby:/var/task" \
38+
-w /var/task \
39+
ruby:3.3 \
40+
sh -c "bundle config set --local path vendor/bundle && bundle install"
41+
42+
bundle-node: ## Install Node.js Lambda production dependencies
43+
cd demo/lambdas/nodejs && npm install --omit=dev
44+
45+
build: ## Build the CDK TypeScript app
46+
$(CDIR) && npm run build
47+
48+
bootstrap: ## Bootstrap CDK for LocalStack
49+
$(CDIR) && npm run build && npx cdklocal bootstrap
50+
51+
deploy: ## Build, deploy CDK stack to LocalStack, and upload frontend
52+
$(MAKE) bundle-ruby bundle-node
53+
$(MAKE) bootstrap
54+
$(CDIR) && npx cdklocal deploy LocalstackDemoStack --require-approval never
55+
@echo "Uploading frontend to s3://archive-bucket/ ..."
56+
awslocal s3 sync demo/web/ s3://archive-bucket/
57+
@echo ""
58+
@echo "Done! Open http://localhost:4566/archive-bucket/index.html in your browser."
59+
60+
destroy: ## Destroy the deployed CDK stack on LocalStack
61+
$(CDIR) && npx cdklocal destroy LocalstackDemoStack
62+
63+
send-request: ## Send a test request and poll S3 for the result
64+
@command -v jq > /dev/null 2>&1 || { echo "jq is not installed. See https://jqlang.github.io/jq/download/"; exit 1; }
65+
@echo "Looking up REST API ID..."
66+
@apiId=$$(awslocal apigateway get-rest-apis --output json | jq -r '.items[] | select(.name=="localstack-demo") | .id'); \
67+
echo "Sending request to API ID '$$apiId' ..."; \
68+
reqID=$$(curl -s -d '{}' "http://localhost:4566/_aws/execute-api/$$apiId/local/requests" | jq -r .requestID); \
69+
echo "Received request ID '$$reqID'"; \
70+
for i in 1 2 3 4 5 6 7 8 9 10; do \
71+
echo "Polling s3://archive-bucket/ for result ..."; \
72+
awslocal s3 ls s3://archive-bucket/ | grep "$$reqID" && exit 0; \
73+
sleep 3; \
74+
done; \
75+
echo "Timed out waiting for result."
76+
77+
start: ## Start LocalStack in detached mode
78+
@echo "Starting LocalStack..."
79+
@test -n "$(LOCALSTACK_AUTH_TOKEN)" || { echo "LOCALSTACK_AUTH_TOKEN is not set. Find your token at https://app.localstack.cloud/workspace/auth-token"; exit 1; }
80+
@LOCALSTACK_AUTH_TOKEN=$(LOCALSTACK_AUTH_TOKEN) localstack start -d
81+
@echo "LocalStack started successfully."
82+
83+
stop: ## Stop LocalStack
84+
@echo "Stopping LocalStack..."
85+
@localstack stop
86+
@echo "LocalStack stopped successfully."
87+
88+
ready: ## Wait until the LocalStack container is ready
89+
@echo "Waiting on the LocalStack container..."
90+
@localstack wait -t 30 && echo "LocalStack is ready to use!" || { echo "Gave up waiting on LocalStack, exiting."; exit 1; }
91+
92+
logs: ## Save LocalStack logs to logs.txt
93+
@localstack logs > logs.txt
94+
95+
PKG_SUB_DIRS := $(dir $(shell find . -type d -name node_modules -prune -o -type d -name "vendor" -prune -o -type f -name package.json -print))
96+
97+
update-deps: ## Update npm dependencies in all sub-projects
98+
for i in $(PKG_SUB_DIRS); do \
99+
pushd $$i && ncu -u && npm install && popd; \
100+
done
101+
102+
.PHONY: usage check install bundle-ruby bundle-node build bootstrap deploy deploy-aws \
103+
destroy destroy-aws send-request start stop ready logs update-deps

0 commit comments

Comments
 (0)