signed-in-health #1688
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Hand-maintained (NOT generated by Upptime; update-template leaves it alone). | |
| # | |
| # Signed-in dashboard health. The checker's rows prove the sign-in page, the | |
| # docs, and the API answer; none of them holds a session. On 2026-09-22 | |
| # 22:55-23:20Z every SIGNED-IN page of platform.experientiallabs.ai | |
| # intermittently 502'd (an nginx TLS sidecar in the web pods rejected Next.js | |
| # responses whose Set-Cookie carried the chunked Supabase session cookies) | |
| # while this page stayed green. This workflow runs scripts/signed-in-probe.mjs | |
| # every 5 minutes: a dedicated monitor account (status-dashboard-monitor@, | |
| # its own personal org, no credits) signs in with the password grant, presents | |
| # the session as the browser cookies do, loads /overview through the public | |
| # hostname, then repeats with an expired token so the proxy refreshes the | |
| # session and writes the chunked Set-Cookie response. See the script header | |
| # for the verdict rules; the JSON lands in assets/status-ui/signed-in-health.json | |
| # and the status-ui overlay renders it as the "Dashboard (signed in)" row. | |
| # | |
| # Incidents: a non-ok verdict opens ONE issue labelled `status` + `dashboard` | |
| # with Upptime's title shape ("🟥 Dashboard (signed in) is down" / | |
| # "⚠️ Dashboard (signed in) has degraded performance"), so the page's Past | |
| # Incidents, the 90-day bars of the injected row, the Atom feed, and | |
| # slack-mention.yml (owner @mention on down, recovery line on close) all pick | |
| # it up through the paths they already have. Recovery closes it. The issue is | |
| # opened with GH_PAT on purpose: issues created by github.token do not fire the | |
| # `issues` event slack-mention.yml listens to. An `unknown` verdict (the monitor | |
| # itself could not sign in for a client-side reason) never touches issues; the | |
| # run fails red instead so the owner sees it. | |
| name: Signed-in Health | |
| on: | |
| # Fallback only: GitHub runs this cron when it has capacity (about every two | |
| # hours on this repo). The Vercel cron (vercel/api/cron/signed-in.js) fires | |
| # the repository_dispatch every 5 minutes, three minutes after the checker. | |
| schedule: | |
| - cron: "*/5 * * * *" | |
| repository_dispatch: | |
| types: [signed-in-health] | |
| workflow_dispatch: | |
| # Upptime's group: this workflow pushes to main, so it must serialize with the | |
| # checker (README "Anything that pushes to main must share Upptime's | |
| # concurrency group"). Never cancel-in-progress here. | |
| concurrency: | |
| group: ${{ github.repository }}-${{ github.head_ref || github.ref_name }}-upptime | |
| cancel-in-progress: false | |
| permissions: | |
| contents: write | |
| issues: write | |
| jobs: | |
| probe: | |
| name: Render the signed-in dashboard | |
| runs-on: ubuntu-latest | |
| timeout-minutes: 8 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| token: ${{ secrets.GH_PAT || github.token }} | |
| - name: Setup Node.js | |
| uses: actions/setup-node@v6 | |
| with: | |
| node-version: "22" | |
| - name: Sign in and render /overview | |
| id: probe | |
| env: | |
| STATUS_SUPABASE_URL: ${{ secrets.STATUS_SUPABASE_URL }} | |
| STATUS_SUPABASE_ANON_KEY: ${{ secrets.STATUS_SUPABASE_ANON_KEY }} | |
| STATUS_MONITOR_EMAIL: ${{ secrets.STATUS_MONITOR_EMAIL }} | |
| STATUS_MONITOR_PASSWORD: ${{ secrets.STATUS_MONITOR_PASSWORD }} | |
| run: node scripts/signed-in-probe.mjs --out assets/status-ui/signed-in-health.json | |
| - name: Commit if changed | |
| run: | | |
| git config user.name "Upptime Bot" | |
| git config user.email "73812536+upptime-bot@users.noreply.github.com" | |
| git add assets/status-ui/signed-in-health.json | |
| git diff --cached --quiet && { echo "No change."; exit 0; } | |
| git commit -m ":stethoscope: Refresh signed-in dashboard health [skip ci]" | |
| # Upptime's own bots commit to main every few minutes; rebase over | |
| # whatever landed while this job ran instead of failing the push. | |
| for _ in 1 2 3; do | |
| git push && exit 0 | |
| git pull --rebase --autostash && continue | |
| done | |
| exit 1 | |
| - name: Open, hold, or close the incident | |
| env: | |
| GH_TOKEN: ${{ secrets.GH_PAT || github.token }} | |
| VERDICT: ${{ steps.probe.outputs.verdict }} | |
| REASON: ${{ steps.probe.outputs.reason }} | |
| REPO: ${{ github.repository }} | |
| RUN_URL: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }} | |
| run: | | |
| set -euo pipefail | |
| name="Dashboard (signed in)" | |
| open_issue=$(gh issue list --repo "$REPO" --label status --label dashboard --state open --json number --jq '.[0].number // empty') | |
| case "$VERDICT" in | |
| down|degraded) | |
| if [ "$VERDICT" = down ]; then | |
| title="🟥 $name is down" | |
| else | |
| title="⚠️ $name has degraded performance" | |
| fi | |
| if [ -z "$open_issue" ]; then | |
| gh label create dashboard --repo "$REPO" --color 0e8a16 \ | |
| --description "Signed-in dashboard check (signed-in-health workflow)" 2>/dev/null || true | |
| gh issue create --repo "$REPO" --label status --label dashboard --assignee SilenNaihin \ | |
| --title "$title" \ | |
| --body "$(printf '%s\n\nSource: the signed-in dashboard check (a monitor account renders %s through the public hostname, including the session-refresh path that writes chunked Set-Cookie headers).\nVerdict: **%s**\n\nThis issue closes automatically when the next check renders the page cleanly. Run: %s' \ | |
| "$REASON" "https://platform.experientiallabs.ai/overview" "$VERDICT" "$RUN_URL")" | |
| else | |
| gh issue comment "$open_issue" --repo "$REPO" --body "Still **$VERDICT**: $REASON ($RUN_URL)" | |
| fi | |
| ;; | |
| ok) | |
| if [ -n "$open_issue" ]; then | |
| gh issue close "$open_issue" --repo "$REPO" \ | |
| --comment "Recovered: the signed-in dashboard renders again, including the session-refresh path ($RUN_URL)." | |
| fi | |
| ;; | |
| unknown) | |
| echo "::error::The monitor could not sign in: $REASON. Check STATUS_MONITOR_EMAIL / STATUS_MONITOR_PASSWORD / STATUS_SUPABASE_*; no incident opened." | |
| exit 1 | |
| ;; | |
| *) | |
| echo "::error::Unexpected verdict '$VERDICT'" | |
| exit 1 | |
| ;; | |
| esac |