diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 914fbae..cf7f630 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -92,6 +92,10 @@ jobs: run: npm ci - name: Build worker with OpenNext + env: + # Match the production build mode so the / → /home redirect path + # and the rest of the (main) layout behavior is what gets smoked. + NEXT_PUBLIC_SHOW_FULL_SITE: 'true' run: npx opennextjs-cloudflare build - name: Start wrangler dev in background @@ -101,8 +105,9 @@ jobs: - name: Wait for worker readiness run: | + # Probe /home (always 200) instead of / (now 307 under SHOW_FULL_SITE=true). for i in {1..30}; do - if curl -sf -o /dev/null http://localhost:8787/; then + if curl -sf -o /dev/null http://localhost:8787/home; then echo "Worker ready after ${i} attempt(s)" exit 0 fi @@ -158,6 +163,63 @@ jobs: fi echo "GET /crisis smoke + headers smoke passed." + - name: GET / redirects to /home (production codepath) + run: | + HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" http://localhost:8787/) + if [ "$HTTP_CODE" != "307" ] && [ "$HTTP_CODE" != "308" ]; then + echo "Expected 307/308 redirect from /, got $HTTP_CODE" + exit 1 + fi + LOCATION=$(curl -sI http://localhost:8787/ | grep -i '^location:' | tr -d '\r' | awk '{print $2}') + if [ "$LOCATION" != "/home" ]; then + echo "Expected location: /home, got '$LOCATION'" + exit 1 + fi + echo "GET / redirect smoke passed." + + - name: GET /home renders + run: | + curl -s -i -o /tmp/home.txt http://localhost:8787/home + if ! head -1 /tmp/home.txt | grep -q " 200 "; then + echo "Expected HTTP 200 on /home" + exit 1 + fi + if ! grep -qi "Mindfulness with meaning" /tmp/home.txt; then + echo "Expected 'Mindfulness with meaning' in /home body" + exit 1 + fi + echo "GET /home smoke passed." + + - name: GET /download renders pre-launch waitlist + run: | + curl -s -i -o /tmp/download.txt http://localhost:8787/download + if ! head -1 /tmp/download.txt | grep -q " 200 "; then + echo "Expected HTTP 200 on /download" + exit 1 + fi + if ! grep -qi "Coming soon" /tmp/download.txt; then + echo "Expected 'Coming soon' in /download body (pre-launch waitlist marker)" + exit 1 + fi + if grep -qi "graphic needed" /tmp/download.txt; then + echo "Found 'graphic needed' placeholder text — /download regressed to old badges" + exit 1 + fi + echo "GET /download smoke passed." + + - name: GET /privacy/multi-state renders + run: | + curl -s -i -o /tmp/multistate.txt http://localhost:8787/privacy/multi-state + if ! head -1 /tmp/multistate.txt | grep -q " 200 "; then + echo "Expected HTTP 200 on /privacy/multi-state" + exit 1 + fi + if ! grep -qi "Multi-State" /tmp/multistate.txt; then + echo "Expected 'Multi-State' in /privacy/multi-state body" + exit 1 + fi + echo "GET /privacy/multi-state smoke passed." + - name: Stop wrangler dev if: always() run: | diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 9f32aa1..2540605 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -61,3 +61,30 @@ jobs: apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }} accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} command: deploy ${{ github.ref_name == 'preview' && '--env preview' || '' }} + + - name: Post-deploy smoke against live URL + run: | + URL="${{ github.ref_name == 'main' && 'https://being.fyi' || 'https://being-website-preview.palouselabs.workers.dev' }}" + echo "Smoke testing $URL ..." + # Brief wait for Cloudflare edge propagation after deploy + sleep 15 + # Cache-bust query param to avoid stale edge responses + CB="?cb=$(date +%s)" + # /home must return 200 + HOME_CODE=$(curl -s -o /dev/null -w "%{http_code}" "$URL/home$CB") + if [ "$HOME_CODE" != "200" ]; then + echo "FAIL: $URL/home returned $HOME_CODE (expected 200)" + exit 1 + fi + # /download must contain pre-launch marker (update at app launch) + if ! curl -sf "$URL/download$CB" | grep -q "Coming soon"; then + echo "FAIL: $URL/download body missing 'Coming soon' marker" + exit 1 + fi + # /privacy must serve security headers (HSTS proves the security + # headers pipeline is intact end-to-end through Cloudflare) + if ! curl -sI "$URL/privacy" | grep -qi "strict-transport-security"; then + echo "FAIL: $URL/privacy missing Strict-Transport-Security header" + exit 1 + fi + echo "Post-deploy smoke passed for $URL"