name: Deploy to Fly.io
on:
push:
tags:
- 'v[0-9]+.[0-9]+.[0-9]+'
workflow_dispatch:
jobs:
deploy:
name: Deploy to Fly.io
runs-on: ubuntu-latest
if: github.repository == 'joshrotenberg/cratesio-mcp'
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Setup Fly CLI
uses: superfly/flyctl-actions/setup-flyctl@master
- name: Deploy to Fly.io
run: flyctl deploy --remote-only --strategy immediate
env:
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
- name: Reap stale machines
run: |
echo "Destroying any stopped/suspended machines left from the deploy..."
flyctl machines list --json | jq -r '.[] | select(.state != "started") | .id' | xargs -I{} flyctl machines destroy {} --force || true
echo "Active machines after reap:"
flyctl machines list
env:
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
- name: Verify deployment (health check)
run: |
echo "Waiting for server to be ready..."
MAX_RETRIES=6
RETRY_DELAY=10
for attempt in $(seq 1 $MAX_RETRIES); do
# Tolerate transient connect/TLS errors while the machine comes up
# (a single early curl false-failed the v0.2.0 release run).
HTTP_STATUS=$(curl -s -o /dev/null -w "%{http_code}" --max-time 10 https://cratesio-mcp.fly.dev/health || echo "000")
echo "Attempt $attempt/$MAX_RETRIES: HTTP $HTTP_STATUS"
if [ "$HTTP_STATUS" = "200" ]; then
echo "Health check passed!"
exit 0
fi
sleep $RETRY_DELAY
done
echo "Health check failed after $MAX_RETRIES attempts"
exit 1
- name: Verify deployment (MCP protocol)
run: |
MAX_RETRIES=3
RETRY_DELAY=5
for attempt in $(seq 1 $MAX_RETRIES); do
echo "=== Attempt $attempt of $MAX_RETRIES ==="
echo "Sending initialize request..."
INIT_RESPONSE=$(curl -s -D /tmp/headers.txt -X POST https://cratesio-mcp.fly.dev/ \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"deploy-check","version":"1.0"}}}')
echo "Init response: $INIT_RESPONSE"
SESSION_ID=$(grep -i "mcp-session-id" /tmp/headers.txt | cut -d' ' -f2 | tr -d '\r')
echo "Session ID: $SESSION_ID"
if [ -z "$SESSION_ID" ]; then
echo "Failed to get session ID"
if [ $attempt -lt $MAX_RETRIES ]; then
echo "Retrying in ${RETRY_DELAY}s..."
sleep $RETRY_DELAY
continue
fi
exit 1
fi
sleep 1
echo "Sending initialized notification..."
curl -s -X POST https://cratesio-mcp.fly.dev/ \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "MCP-Session-Id: $SESSION_ID" \
-d '{"jsonrpc":"2.0","method":"notifications/initialized"}'
sleep 1
echo "Sending test tool call..."
TOOL_RESPONSE=$(curl -s -X POST https://cratesio-mcp.fly.dev/ \
-H "Content-Type: application/json" \
-H "Accept: application/json" \
-H "MCP-Session-Id: $SESSION_ID" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"search_crates","arguments":{"query":"tower"}}}')
echo "Tool response: $TOOL_RESPONSE"
if echo "$TOOL_RESPONSE" | grep -q '"result"'; then
echo "MCP protocol verification successful!"
exit 0
else
echo "MCP protocol verification failed - unexpected response"
if [ $attempt -lt $MAX_RETRIES ]; then
echo "Retrying in ${RETRY_DELAY}s..."
sleep $RETRY_DELAY
continue
fi
exit 1
fi
done