diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 8bca71f62..326d8dcf5 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -117,7 +117,9 @@ jobs: set -euo pipefail base_url=$(node -e 'const u = new URL(process.env.WEBHOOK_URL); console.log(`${u.protocol}//${u.host}`)') - health_url="${base_url}/api/health/auth-config" + auth_health_url="${base_url}/api/health/auth-config" + generic_health_url="${base_url}/api/health" + health_url="$auth_health_url" echo "==> Running deploy smoke check: $health_url" @@ -127,41 +129,52 @@ jobs: http_code=$(echo "$response" | tail -1) body=$(echo "$response" | sed '$d') + if [ "$http_code" = "404" ] && [ "$health_url" = "$auth_health_url" ]; then + echo "Auth-config health endpoint not available. Falling back to generic health check." + health_url="$generic_health_url" + continue + fi + if [ "$http_code" = "200" ]; then - HEALTH_BODY="$body" node - <<'NODE' - const body = process.env.HEALTH_BODY ?? ''; - let parsed; - try { - parsed = JSON.parse(body); - } catch { - console.error('::error::auth-config returned invalid JSON'); - process.exit(1); - } - - const status = parsed?.status ?? 'unknown'; - const hasLegacyDomain = Boolean(parsed?.auth?.hasLegacyDomain); - const warnings = Array.isArray(parsed?.warnings) ? parsed.warnings : []; - - if (status !== 'ok' || hasLegacyDomain || warnings.length > 0) { - console.error( - `::error::OAuth auth-config smoke check failed (status=${status}, hasLegacyDomain=${hasLegacyDomain}, warnings=${warnings.length})`, - ); - if (warnings.length > 0) { - console.error(`::error::Warnings: ${warnings.join(' | ')}`); + if [ "$health_url" = "$generic_health_url" ]; then + echo "==> Generic health check passed" + exit 0 + fi + + HEALTH_BODY="$body" node -e ' + const body = process.env.HEALTH_BODY ?? ""; + let parsed; + try { + parsed = JSON.parse(body); + } catch { + console.error("::error::auth-config returned invalid JSON"); + process.exit(1); + } + + const status = parsed?.status ?? "unknown"; + const hasLegacyDomain = Boolean(parsed?.auth?.hasLegacyDomain); + const warnings = Array.isArray(parsed?.warnings) ? parsed.warnings : []; + + if (status !== "ok" || hasLegacyDomain || warnings.length > 0) { + console.error( + `::error::OAuth auth-config smoke check failed (status=${status}, hasLegacyDomain=${hasLegacyDomain}, warnings=${warnings.length})`, + ); + if (warnings.length > 0) { + console.error(`::error::Warnings: ${warnings.join(" | ")}`); + } + process.exit(1); } - process.exit(1); - } - console.log('==> OAuth auth-config smoke check passed'); - NODE + console.log("==> OAuth auth-config smoke check passed"); + ' exit 0 fi - echo "Service not ready yet (HTTP $http_code). Waiting 10s..." + echo "Service not ready yet at $health_url (HTTP $http_code). Waiting 10s..." sleep 10 done - echo "::error::Timed out waiting for /api/health/auth-config to become available" + echo "::error::Timed out waiting for health endpoint to become available" exit 1 - name: Notify failure diff --git a/CHANGELOG.md b/CHANGELOG.md index 637cda5bd..e82436c9c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,7 +17,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - Backend CORS now accepts configured origins plus `*.lucassantana.tech` and `*.luk-homeserver.com.br` hosts for dashboard/API split-domain setups -- Frontend API client now auto-resolves hosted API base to `api.lucassantana.tech` or `api.luk-homeserver.com.br` when `VITE_API_BASE_URL` is not set +- Frontend API client now auto-resolves hosted API base to `lucky-api.lucassantana.tech` or `api.luk-homeserver.com.br` when `VITE_API_BASE_URL` is not set +- Deploy smoke check now falls back to `/api/health` when `/api/health/auth-config` is unavailable - Vercel routing no longer rewrites `/api/*` back to the same Lucky host, preventing `508 INFINITE_LOOP` on OAuth login - Frontend API base URL now supports `VITE_API_BASE_URL` for hosted deployments that use a separate backend origin - Deploy webhook trigger now uses strict curl connect/request timeouts to avoid long hangs in CI deploy jobs diff --git a/README.md b/README.md index ecb6c21fa..062f41d5e 100644 --- a/README.md +++ b/README.md @@ -130,7 +130,7 @@ Triggers the GitHub `Deploy to Homelab` workflow, waits for completion, and show Vercel note: `vercel.json` runs `npm run db:generate` before `build:shared` and `build:frontend` to ensure Prisma generated client files are present during cloud builds. For hosted frontend deployments, set `VITE_API_BASE_URL` to your backend API origin (example: `https://api.yourdomain.com/api`) to avoid auth/API loop misrouting. -Without `VITE_API_BASE_URL`, frontend now auto-targets `api.lucassantana.tech` for +Without `VITE_API_BASE_URL`, frontend now auto-targets `lucky-api.lucassantana.tech` for `*.lucassantana.tech` hosts and `api.luk-homeserver.com.br` for `*.luk-homeserver.com.br`. ## Environment Variables diff --git a/packages/frontend/src/services/api.ts b/packages/frontend/src/services/api.ts index cb0028041..289f5df2d 100644 --- a/packages/frontend/src/services/api.ts +++ b/packages/frontend/src/services/api.ts @@ -30,7 +30,7 @@ const inferApiBase = (): string => { hostname === 'lucassantana.tech' || hostname.endsWith('.lucassantana.tech') ) { - return `${protocol}//api.lucassantana.tech/api` + return `${protocol}//lucky-api.lucassantana.tech/api` } if (