diff --git a/.github/workflows/health-check.yml b/.github/workflows/health-check.yml new file mode 100644 index 0000000..dc0c5c4 --- /dev/null +++ b/.github/workflows/health-check.yml @@ -0,0 +1,55 @@ +name: Health Check + +on: + schedule: + - cron: '0 */6 * * *' + workflow_dispatch: + +jobs: + ping-health: + runs-on: ubuntu-latest + permissions: + issues: write + steps: + - name: Ping Health Endpoint + id: ping + run: | + status=$(curl -s -o /dev/null -w "%{http_code}" https://stepfi-api.onrender.com/api/v1/health || echo "000") + echo "status=$status" >> "$GITHUB_OUTPUT" + + - name: Handle Failure + if: steps.ping.outputs.status != '200' + uses: actions/github-script@v7 + with: + script: | + const status = '${{ steps.ping.outputs.status }}'; + const timestamp = new Date().toISOString(); + const issueTitle = `Health check failed at ${timestamp}`; + const issueBody = `The health check endpoint returned HTTP status ${status}.`; + const label = 'incident'; + + const { data: issues } = await github.rest.issues.listForRepo({ + owner: context.repo.owner, + repo: context.repo.repo, + state: 'open', + labels: label + }); + + if (issues.length > 0) { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issues[0].number, + body: `Health check failed again at ${timestamp} with HTTP status ${status}.` + }); + console.log(`Commented on existing incident issue #${issues[0].number}`); + } else { + await github.rest.issues.create({ + owner: context.repo.owner, + repo: context.repo.repo, + title: issueTitle, + body: issueBody, + labels: [label] + }); + console.log('Created new incident issue'); + } diff --git a/README.md b/README.md index 0d582e0..7c46c5d 100644 --- a/README.md +++ b/README.md @@ -165,6 +165,8 @@ The bootstrap command will guide you through the process of setting up a Supabas | **Swagger Docs** | https://stepfi-api.onrender.com/api/v1/docs | | **Health Check** | https://stepfi-api.onrender.com/api/v1/health | +> **Note**: A GitHub Action workflow pings the Health Check URL every 6 hours to keep the Render free tier instance warm and acts as a heartbeat monitor. If the ping fails (non-200 response), it automatically creates or updates a GitHub issue with the `incident` label to alert maintainers. + ## 🛠️ Error tracking Error tracking is powered by Sentry. To enable error tracking in development or production: diff --git a/context/progress-tracker.md b/context/progress-tracker.md index 3a5dd01..648f6d5 100644 --- a/context/progress-tracker.md +++ b/context/progress-tracker.md @@ -6,6 +6,11 @@ pure chore/docs commits). Direct pushes to main must also be logged here. --- +## 2026-07-23 + +- Added GitHub Actions health check workflow (`health-check.yml`) to ping the Render API every 6 hours to prevent the free tier instance from sleeping. Auto-creates or comments on issues with the `incident` label if the ping fails, preventing silent outages. +- Documented the ping URL and incident label in README. + ## 2026-07-19 - Wired `LiquidityContractClient` (restored under `src/blockchain/contracts/liquidity-contract.client.ts`) into `LiquidityService` constructor.