# ROBOTS ON PAYROLL / THE VAULT
# What this is: a GitHub Actions cron workflow that pings your homepage and one key API route and alerts your webhook on anything but a 200.
# How to use it: download this file and give it to your AI (Claude, ChatGPT,
# Cursor, Lovable chat) as a reference. Say: "Use this as my playbook for
# setting up my uptime monitor."
# Latest version + full guide: https://robotsonpayroll.com/resources/github-actions-runbooks
#
# uptime-and-errors.yml
# Poor man's uptime monitor: every 10-ish minutes, hit your homepage and one
# key API route. Anything but a 200 fires your Slack/Discord webhook.
#
# HONEST FRAMING: GitHub's cron is best-effort. Expect 5-30 min delays at
# busy hours and occasional silently skipped runs. This is a free safety net,
# not a pager. If your SaaS has paying users, add a real external monitor
# (UptimeRobot / Better Stack free tiers) and keep this as the second opinion
# that also hits a health route backed by a real DB query, which dumb pingers don't.
#
# SECRETS REQUIRED:
#   ALERT_WEBHOOK_URL - Slack/Discord incoming webhook
# (URLs below are plain env vars, they are not secret.)

name: Uptime and error check

on:
  schedule:
    # every 10 min, offset to :07 to dodge the top-of-the-hour cron rush.
    # 5 min is GitHub's minimum interval; more frequent is silently ignored.
    - cron: "7,17,27,37,47,57 * * * *"
  workflow_dispatch: {}

env:
  PROD_URL: https://yourapp.com # <- your production URL
  API_URL: https://yourapp.com/api/health # <- a route that touches your DB

jobs:
  check:
    runs-on: ubuntu-latest
    permissions:
      contents: read
    # If a check hangs, don't burn 6 hours of Actions minutes (the default
    # job timeout). Kill it fast; the next scheduled run is minutes away.
    timeout-minutes: 3

    steps:
      # No checkout needed: this job never touches your code.

      # curl flags, decoded:
      #   -s silent  -o /dev/null throw away the body
      #   -w "%{http_code}" print only the status code
      #   --max-time 20  a "slow" site is a down site for users
      #   --retry 2 --retry-delay 5  one blip should not page you at 3am;
      #     retries happen inside this step, 5s apart
      - name: Ping homepage
        id: home
        run: |
          code=$(curl -s -o /dev/null -w "%{http_code}" \
            --max-time 20 --retry 2 --retry-delay 5 "$PROD_URL" || echo "000")
          echo "code=$code" >> "$GITHUB_OUTPUT"
          echo "Homepage: $code"
          [ "$code" = "200" ] || exit 1

      # A health route should hit the DB (e.g. SELECT 1) so this catches
      # "site renders but database is on fire", the classic silent outage.
      - name: Ping API health route
        id: api
        # Run even if the homepage check failed, so the alert names both.
        if: always()
        run: |
          code=$(curl -s -o /dev/null -w "%{http_code}" \
            --max-time 20 --retry 2 --retry-delay 5 "$API_URL" || echo "000")
          echo "code=$code" >> "$GITHUB_OUTPUT"
          echo "API: $code"
          [ "$code" = "200" ] || exit 1

      - name: Alert on failure
        if: failure()
        env:
          WEBHOOK: ${{ secrets.ALERT_WEBHOOK_URL }}
          HOME_CODE: ${{ steps.home.outputs.code }}
          API_CODE: ${{ steps.api.outputs.code }}
        run: |
          msg="DOWN ALERT: ${PROD_URL} returned ${HOME_CODE:-?}, API returned ${API_CODE:-?} (000 = timeout/DNS/conn refused). Run: ${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}/actions/runs/${GITHUB_RUN_ID}"
          curl -sS -X POST -H 'Content-Type: application/json' \
            -d "{\"text\": \"$msg\", \"content\": \"$msg\"}" \
            "$WEBHOOK"

# CAVEATS THAT BITE:
# - 60-day auto-disable: GitHub disables scheduled workflows after 60 days
#   with no commits to the repo. If your project is "done", your monitor
#   dies quietly two months later. Commit occasionally or re-enable manually
#   (Actions tab shows a banner), or run this from an active repo.
# - This alerts on EVERY failed run. At 10-min intervals a 2-hour outage is
#   ~12 pings. For an indie project that is a feature (you cannot miss it).
