Skip to content

Commit f82bd6d

Browse files
authored
Export URLs on PRs (#268)
1 parent 34c856e commit f82bd6d

File tree

3 files changed

+263
-0
lines changed

3 files changed

+263
-0
lines changed

.github/workflows/build.yaml renamed to .github/workflows/build.yml

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,3 +722,91 @@ jobs:
722722
for i in {1..5}; do
723723
curl ${BASE_URL}/ping
724724
done
725+
726+
create-status-checks:
727+
needs: [deploy, smoke-test]
728+
runs-on: ubuntu-latest
729+
if: ${{ always() && needs.deploy.result != 'failed' && github.event_name == 'pull_request' }}
730+
steps:
731+
- name: Generate URLs
732+
id: generate-urls
733+
env:
734+
PR_NUMBER: ${{ github.event.pull_request.number }}
735+
run: |
736+
echo "alb_router=https://lambdadispatch-pr-${PR_NUMBER}.ghpublic.pwrdrvr.com" >> $GITHUB_OUTPUT
737+
echo "alb_demoapp=https://lambdadispatch-demoapp-pr-${PR_NUMBER}.ghpublic.pwrdrvr.com" >> $GITHUB_OUTPUT
738+
echo "nlb_router=https://lambdadispatch-nlb-pr-${PR_NUMBER}.ghpublic.pwrdrvr.com" >> $GITHUB_OUTPUT
739+
echo "nlb_demoapp=https://lambdadispatch-nlb-demoapp-pr-${PR_NUMBER}.ghpublic.pwrdrvr.com" >> $GITHUB_OUTPUT
740+
741+
- name: Find Deployment URLs Comment
742+
uses: peter-evans/find-comment@v3
743+
id: find-comment
744+
with:
745+
issue-number: ${{ github.event.pull_request.number }}
746+
comment-author: 'github-actions[bot]'
747+
body-includes: '### 🚀 Deployment URLs'
748+
749+
- name: Post Deployment URLs Comment
750+
uses: peter-evans/create-or-update-comment@v4
751+
with:
752+
comment-id: ${{ steps.find-comment.outputs.comment-id }}
753+
edit-mode: replace
754+
issue-number: ${{ github.event.pull_request.number }}
755+
body: |
756+
### 🚀 Deployment URLs
757+
758+
#### Application Load Balancer (ALB)
759+
- **Router**: [${{ steps.generate-urls.outputs.alb_router }}](${{ steps.generate-urls.outputs.alb_router }})
760+
- **Demo App**: [${{ steps.generate-urls.outputs.alb_demoapp }}](${{ steps.generate-urls.outputs.alb_demoapp }})
761+
762+
#### Network Load Balancer (NLB)
763+
- **Router (Port ${{ github.event.pull_request.number }})**: [${{ steps.generate-urls.outputs.nlb_router }}](${{ steps.generate-urls.outputs.nlb_router }})
764+
- **Demo App (Port ${{ github.event.pull_request.number }}+10000)**: [${{ steps.generate-urls.outputs.nlb_demoapp }}](${{ steps.generate-urls.outputs.nlb_demoapp }})
765+
766+
### 🧪 Test Endpoints
767+
768+
#### Basic Tests
769+
```bash
770+
# Simple ping test
771+
curl -v ${{ steps.generate-urls.outputs.alb_router }}/ping
772+
773+
# View request headers
774+
curl ${{ steps.generate-urls.outputs.alb_router }}/headers
775+
776+
# Delayed response (milliseconds)
777+
curl ${{ steps.generate-urls.outputs.alb_router }}/delay?delay=500
778+
```
779+
780+
#### Load/Performance Tests
781+
```bash
782+
# Ping test with 100 concurrent requests (Hey)
783+
hey -h2 -c 100 -n 10000 ${{ steps.generate-urls.outputs.alb_router }}/ping
784+
785+
# Ping test with controlled concurrency (oha)
786+
oha -c 20 -z 60s ${{ steps.generate-urls.outputs.alb_router }}/ping
787+
788+
# Post and echo data
789+
curl -X POST -H "Content-Type: text/plain" --data "Hello World" ${{ steps.generate-urls.outputs.alb_router }}/echo
790+
```
791+
792+
#### Advanced Features
793+
```bash
794+
# Chunked/streaming response
795+
curl ${{ steps.generate-urls.outputs.alb_router }}/chunked-response
796+
797+
# Read from S3
798+
curl ${{ steps.generate-urls.outputs.alb_router }}/read-s3
799+
800+
# Read from DynamoDB
801+
curl ${{ steps.generate-urls.outputs.alb_router }}/read
802+
```
803+
804+
*Deployment updated: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}*
805+
806+
# Create a single environment for the main deployment URL to show in PR checks
807+
- name: Update Main Environment
808+
env:
809+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
810+
run: |
811+
# This will update the environment URL that appears in the PR checks
812+
echo "Deployment URLs have been posted as a comment"
File renamed without changes.

src/demo-app/app.cjs

Lines changed: 175 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,181 @@ export async function performInit() {
9898
// Serve static files from the "public" directory
9999
app.use('/public', express.static(path.join(__dirname, 'public')));
100100

101+
app.get('/', (req, res) => {
102+
// HTML for the documentation page
103+
const html = `<!DOCTYPE html>
104+
<html lang="en">
105+
<head>
106+
<meta charset="UTF-8">
107+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
108+
<title>Lambda Dispatch Demo App</title>
109+
<style>
110+
body {
111+
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
112+
line-height: 1.6;
113+
color: #333;
114+
max-width: 900px;
115+
margin: 0 auto;
116+
padding: 20px;
117+
}
118+
h1, h2, h3 {
119+
color: #0066cc;
120+
}
121+
.endpoint {
122+
background: #f5f5f5;
123+
border-left: 4px solid #0066cc;
124+
padding: 10px 15px;
125+
margin-bottom: 20px;
126+
border-radius: 0 4px 4px 0;
127+
}
128+
.endpoint h3 {
129+
margin-top: 0;
130+
}
131+
code {
132+
background: #eee;
133+
padding: 2px 5px;
134+
border-radius: 3px;
135+
font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace;
136+
}
137+
pre {
138+
background: #f8f8f8;
139+
padding: 10px;
140+
border-radius: 5px;
141+
overflow-x: auto;
142+
border: 1px solid #ddd;
143+
}
144+
table {
145+
border-collapse: collapse;
146+
width: 100%;
147+
}
148+
th, td {
149+
text-align: left;
150+
padding: 8px;
151+
border-bottom: 1px solid #ddd;
152+
}
153+
th {
154+
background-color: #f2f2f2;
155+
}
156+
</style>
157+
</head>
158+
<body>
159+
<h1>Lambda Dispatch Demo App</h1>
160+
<p>This application demonstrates various features of the Lambda Dispatch system. Use the endpoints below to test different aspects of the service.</p>
161+
162+
<h2>Health and Status Endpoints</h2>
163+
164+
<div class="endpoint">
165+
<h3>GET /health-quick</h3>
166+
<p>Quick health check that doesn't wait for initialization.</p>
167+
<pre><code>curl ${req.protocol}://${req.headers.host}/health-quick</code></pre>
168+
</div>
169+
170+
<div class="endpoint">
171+
<h3>GET /health</h3>
172+
<p>Full health check that ensures initialization is complete (waits for ${initSleepMs}ms).</p>
173+
<pre><code>curl ${req.protocol}://${req.headers.host}/health</code></pre>
174+
</div>
175+
176+
<div class="endpoint">
177+
<h3>GET /ping</h3>
178+
<p>Simple ping endpoint that returns "pong".</p>
179+
<pre><code>curl ${req.protocol}://${req.headers.host}/ping</code></pre>
180+
<p>Load test with hey:</p>
181+
<pre><code>hey -h2 -c 100 -n 10000 ${req.protocol}://${req.headers.host}/ping</code></pre>
182+
</div>
183+
184+
<div class="endpoint">
185+
<h3>GET /headers</h3>
186+
<p>Returns all HTTP headers from the incoming request as JSON.</p>
187+
<pre><code>curl ${req.protocol}://${req.headers.host}/headers</code></pre>
188+
</div>
189+
190+
<h2>Delay and Streaming Endpoints</h2>
191+
192+
<div class="endpoint">
193+
<h3>GET /delay</h3>
194+
<p>Delays the response by the specified number of milliseconds.</p>
195+
<pre><code>curl ${req.protocol}://${req.headers.host}/delay?delay=500</code></pre>
196+
</div>
197+
198+
<div class="endpoint">
199+
<h3>GET /chunked-response</h3>
200+
<p>Returns a chunked response with an initial payload, 5 second delay, then final payload.</p>
201+
<pre><code>curl ${req.protocol}://${req.headers.host}/chunked-response</code></pre>
202+
</div>
203+
204+
<h2>Echo Endpoints</h2>
205+
206+
<div class="endpoint">
207+
<h3>POST /echo</h3>
208+
<p>Streams the request body directly to the response with back pressure.</p>
209+
<pre><code>curl -X POST -H "Content-Type: text/plain" --data "Hello World" ${req.protocol}://${req.headers.host}/echo</code></pre>
210+
<p>Debug mode:</p>
211+
<pre><code>curl -X POST -H "Content-Type: text/plain" -H "X-Lambda-Dispatch-Debug: true" --data "Hello World" ${req.protocol}://${req.headers.host}/echo</code></pre>
212+
</div>
213+
214+
<div class="endpoint">
215+
<h3>POST /echo-slow</h3>
216+
<p>Reads the entire request body into memory before sending the response.</p>
217+
<pre><code>curl -X POST -H "Content-Type: text/plain" --data "Hello World" ${req.protocol}://${req.headers.host}/echo-slow</code></pre>
218+
</div>
219+
220+
<div class="endpoint">
221+
<h3>POST /double-echo</h3>
222+
<p>Echoes each chunk of the request body twice, doubling the response size.</p>
223+
<pre><code>curl -X POST -H "Content-Type: text/plain" --data "Hello World" ${req.protocol}://${req.headers.host}/double-echo</code></pre>
224+
</div>
225+
226+
<div class="endpoint">
227+
<h3>POST /half-echo</h3>
228+
<p>Echoes half of each chunk of the request body, halving the response size.</p>
229+
<pre><code>curl -X POST -H "Content-Type: text/plain" --data "Hello World" ${req.protocol}://${req.headers.host}/half-echo</code></pre>
230+
</div>
231+
232+
<div class="endpoint">
233+
<h3>ALL /debug</h3>
234+
<p>Returns the request line, headers, and body. Works with any HTTP method.</p>
235+
<pre><code>curl -X POST -H "Content-Type: text/plain" --data "Hello World" ${req.protocol}://${req.headers.host}/debug</code></pre>
236+
</div>
237+
238+
<h2>AWS Service Endpoints</h2>
239+
240+
<div class="endpoint">
241+
<h3>GET /read-s3</h3>
242+
<p>Reads an image file from S3 and returns it. Good for testing larger payloads.</p>
243+
<pre><code>curl -o image.jpg ${req.protocol}://${req.headers.host}/read-s3</code></pre>
244+
<p>Load test with hey:</p>
245+
<pre><code>hey -h2 -c 100 -n 1000 ${req.protocol}://${req.headers.host}/read-s3</code></pre>
246+
</div>
247+
248+
<div class="endpoint">
249+
<h3>GET /read</h3>
250+
<p>Reads a random item from DynamoDB.</p>
251+
<pre><code>curl ${req.protocol}://${req.headers.host}/read</code></pre>
252+
<p>Load test with k6:</p>
253+
<pre><code>k6 run k6/read-dynamodb-constant.js</code></pre>
254+
</div>
255+
256+
<div class="endpoint">
257+
<h3>GET /odd-status</h3>
258+
<p>Returns an unusual HTTP status code (519).</p>
259+
<pre><code>curl -i ${req.protocol}://${req.headers.host}/odd-status</code></pre>
260+
</div>
261+
262+
<h2>Static Files</h2>
263+
264+
<div class="endpoint">
265+
<h3>GET /public/silly-test-image.jpg</h3>
266+
<p>Serves a static image file stored in the application.</p>
267+
<pre><code>curl -o local-image.jpg ${req.protocol}://${req.headers.host}/public/silly-test-image.jpg</code></pre>
268+
</div>
269+
270+
</body>
271+
</html>`;
272+
273+
res.send(html);
274+
});
275+
101276
app.get('/health-quick', async (req, res) => {
102277
res.send('OK');
103278
});

0 commit comments

Comments
 (0)