Skip to content

Commit fb30838

Browse files
Oba-Onecodex
andcommitted
ci(shared): verify Fly API deploy workflow
Pin actions to Node 24-compatible runtimes and smoke-test the production API after deploy. Co-Authored-By: Codex (automated) <noreply@openai.com>
1 parent f135657 commit fb30838

1 file changed

Lines changed: 47 additions & 2 deletions

File tree

.github/workflows/deploy-api.yml

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,61 @@ jobs:
1818
runs-on: ubuntu-latest
1919
permissions:
2020
contents: read
21+
env:
22+
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
23+
API_HTTP_URL: https://api.coop.town
24+
API_WS_URL: wss://api.coop.town
2125

2226
steps:
2327
- name: Checkout
24-
uses: actions/checkout@v4
28+
uses: actions/checkout@v5
2529

2630
- name: Setup flyctl
27-
uses: superfly/flyctl-actions/setup-flyctl@master
31+
uses: superfly/flyctl-actions/setup-flyctl@v1.5
2832

2933
- name: Deploy
3034
working-directory: packages/api
3135
run: flyctl deploy --remote-only
3236
env:
3337
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
38+
39+
- name: Verify health endpoint
40+
run: |
41+
body="$(curl -fsS --retry 5 --retry-delay 2 "${API_HTTP_URL}/health")"
42+
test "${body}" = '{"status":"ok"}'
43+
44+
- name: Verify WebSocket endpoints
45+
run: |
46+
python3 -m venv .venv-smoke
47+
. .venv-smoke/bin/activate
48+
python -m pip install --disable-pip-version-check --quiet websockets
49+
python - <<'PY'
50+
import asyncio
51+
import json
52+
import os
53+
import time
54+
import uuid
55+
56+
import websockets
57+
58+
API_WS_URL = os.environ["API_WS_URL"]
59+
60+
async def verify_signaling():
61+
async with websockets.connect(API_WS_URL) as ws:
62+
await ws.send(json.dumps({"type": "ping"}))
63+
response = await asyncio.wait_for(ws.recv(), timeout=10)
64+
if response != '{"type":"pong"}':
65+
raise AssertionError(f"unexpected signaling response: {response!r}")
66+
67+
async def verify_yjs():
68+
room = f"gha-smoke-{int(time.time())}-{uuid.uuid4().hex[:8]}"
69+
async with websockets.connect(f"{API_WS_URL}/yws/{room}") as ws:
70+
response = await asyncio.wait_for(ws.recv(), timeout=10)
71+
if not isinstance(response, bytes):
72+
raise AssertionError(f"expected binary Yjs frame, got: {type(response).__name__}")
73+
if len(response) < 4:
74+
raise AssertionError(f"expected non-empty Yjs sync frame, got {len(response)} bytes")
75+
76+
asyncio.run(verify_signaling())
77+
asyncio.run(verify_yjs())
78+
PY

0 commit comments

Comments
 (0)