Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 46 additions & 4 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -1,19 +1,61 @@
name: CI

# ──────────────────────────────────────────────────────────────────────────────
# Runs on every pull request and on pushes to non-main branches.
# Purpose: Fast quality gate (syntax + tests + audit).
# The full deploy pipeline lives in deploy.yml (push to main only).
# ──────────────────────────────────────────────────────────────────────────────
on:
pull_request:
push:
branches: [ main ]
branches-ignore: [main]

jobs:
validate:
name: Validate
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'

- name: Install dependencies
run: npm ci

- name: Syntax check
run: npm run check

- name: Run tests
run: npm test

- name: Security audit (high+critical only)
run: npm audit --audit-level=high
continue-on-error: true # Warn but don't block PR for advisories

# Lightweight integration check (does the bot start without crashing?)
smoke:
name: Smoke
runs-on: ubuntu-latest
needs: validate

steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm run check
- run: npm run test

- name: Install dependencies
run: npm ci

- name: Check entrypoint can be required without errors
run: |
# We can't fully start the bot (no BOT_TOKEN), but we can check
# that the file is syntactically and structurally valid.
node --check index.js
echo "✅ index.js passes node --check"
375 changes: 375 additions & 0 deletions .github/workflows/deploy.yml

Large diffs are not rendered by default.

45 changes: 43 additions & 2 deletions health-check.sh
Original file line number Diff line number Diff line change
@@ -1,11 +1,52 @@
#!/usr/bin/env bash
# =============================================================================
# health-check.sh — Quick health check for the Runewager bot.
#
# Usage:
# ./health-check.sh # basic check (exits 0 if OK, 1 if not)
# ./health-check.sh --verbose # prints the full JSON response
# ./health-check.sh --status # also checks /status endpoint
# =============================================================================
set -euo pipefail

PORT="${PORT:-3000}"
VERBOSE="${1:-}"
BASE_URL="http://127.0.0.1:${PORT}"

if ! command -v curl >/dev/null 2>&1; then
echo "ERROR: curl is not available — install curl or use wget" >&2
echo "ERROR: curl is not available — install curl" >&2
exit 1
fi

curl -fsS "http://127.0.0.1:${PORT}/health" >/dev/null
# ── /health check ─────────────────────────────────────────────────────────────
HEALTH_BODY=$(curl -fsS --max-time 5 "${BASE_URL}/health" 2>/dev/null) || {
echo "❌ Health check FAILED — bot not responding on port ${PORT}" >&2
exit 1
}

HTTP_STATUS=$(echo "$HEALTH_BODY" | python3 -c "import sys,json; d=json.load(sys.stdin); print(d.get('status','unknown'))" 2>/dev/null || echo "parse_error")

if [[ "$HTTP_STATUS" == "ok" ]]; then
if [[ "$VERBOSE" == "--verbose" ]] || [[ "$VERBOSE" == "--status" ]]; then
echo "✅ Health check OK"
echo ""
echo "$HEALTH_BODY" | python3 -c "import sys,json; print(json.dumps(json.load(sys.stdin), indent=2))" 2>/dev/null || echo "$HEALTH_BODY"
else
echo "✅ Bot healthy"
fi
else
echo "❌ Health check returned status: $HTTP_STATUS" >&2
exit 1
fi

# ── /status check (optional) ──────────────────────────────────────────────────
if [[ "$VERBOSE" == "--status" ]]; then
echo ""
echo "── /status endpoint ──"
STATUS_BODY=$(curl -fsS --max-time 5 "${BASE_URL}/status" 2>/dev/null) || {
echo "⚠️ /status endpoint not responding" >&2
}
if [[ -n "${STATUS_BODY:-}" ]]; then
echo "$STATUS_BODY" | python3 -c "import sys,json; print(json.dumps(json.load(sys.stdin), indent=2))" 2>/dev/null || echo "$STATUS_BODY"
fi
fi
Loading