Skip to content

Developer Guide

mdeguzis edited this page Jul 8, 2026 · 2 revisions

Developer Guide

How to build, test, and deploy the proton-pulse-web site locally and via GitHub Actions.

Prerequisites

  • Node.js + pnpm (npm install -g pnpm)
  • gh CLI authenticated (gh auth login)
  • shellcheck for shell linting (pkg install shellcheck on Termux, apt install shellcheck on Debian/Ubuntu)
  • Python + uv for the data pipeline scripts

Local setup

git clone git@github.com:mdeguzis/proton-pulse-web.git
cd proton-pulse-web
make install      # install node deps (vite + jest) via pnpm
make setup        # bootstrap Python deps via uv

Pull runtime data files needed for local rendering:

make sync-runtime   # copies scoring-info.json and form-schema.json from the plugin repo (or GitHub)

Local dev server

make serve

Opens a Vite dev server at http://localhost:5173 with CSS hot-module reload. Every .html in the repo root is served as its own route.

Pre-push gate

Run this before every commit that touches JS or CSS:

make pre-push

This runs in order:

  1. make build -- updates ?v=HASH cache-bust query strings on all JS imports and HTML asset refs
  2. make test-js -- Jest unit tests + manifest completeness check
  3. make smoke -- headless Firefox render-path smoke test against a local staged copy

Individual targets are available if you only need one step:

make build      # cache-bust only
make test-js    # Jest only
make smoke      # smoke only
make smoke-live # same smoke harness pointed at https://www.proton-pulse.com

Adding a new JS or CSS file

Two extra steps are required or the file will 404 on the live site:

  1. Add the path to gh-pages-manifest.txt (the deploy job only copies listed files).
  2. Add it to every relevant deploy step in .github/workflows/update-data.yml.

The manifest test (tests/manifest.test.js) enforces rule 1 automatically -- make test-js will fail if a manifest JS file imports something not listed.


Deployment lifecycle

Overview

local changes
    |
make pre-push        (cache-bust + Jest + smoke)
    |
git commit + push
    |
make gh-staging      (staging-preview job -- no prod change)
    |
verify at https://mdeguzis.github.io/proton-pulse-web-staging/
    |
make gh-pages-only   (pages-only job -- promotes to prod)
    |
https://www.proton-pulse.com live

Staging deploy

Deploys the current main branch shell files (HTML/JS/CSS) to the staging site only. Reuses the existing gh-pages game data -- no pipeline run needed.

make gh-staging
  • Triggers the staging_only path in update-data.yml
  • Only the staging-preview job runs; all pipeline jobs are skipped
  • Preview at: https://mdeguzis.github.io/proton-pulse-web-staging/

Promote to production

Once staging is verified:

make gh-pages-only
  • Triggers the pages_only path in update-data.yml
  • Redeploys shell files to https://www.proton-pulse.com
  • Also syncs the updated files to staging as a side effect

Full pipeline + deploy

For changes that require fresh game data (new pipeline features, data format changes, coverage backfill):

make gh-run

Runs the full 3-stage pipeline (build -> probe-chunks -> finalize) then deploys to production.

Watch active runs

make gh-run-watch                              # watch all workflows
make gh-run-watch WATCH_ALL_WORKFLOWS=false    # watch update-data.yml only
make gh-run-watch WATCH_INTERVAL=5             # refresh every 5s (default: 10s)

Polls until all active runs finish, then exits.


Triggering workflows manually via GitHub UI

Go to: https://github.com/mdeguzis/proton-pulse-web/actions/workflows/update-data.yml

Click Run workflow and fill in the inputs:

Input Type Description
staging_only boolean Deploy shell files to staging only, skip production
pages_only boolean Redeploy shell files to production (pages-only, no data pipeline)
backfill_app_ids string Comma-separated Steam app IDs to backfill (e.g. 730,570)
coverage_backfill_issue_type choice Coverage issue type: no-titles, bad-app-id, no-protondb-data
coverage_backfill_limit string Max apps to process for coverage backfill (0 = no limit)

Leave all inputs blank to run the full daily pipeline.


Targeted and coverage backfills

Backfill specific app IDs without running the full pipeline:

make gh-backfill-apps BACKFILL_APP_IDS=1145350,2358720

Backfill apps with a known coverage gap:

make gh-coverage-backfill COVERAGE_BACKFILL_ISSUE_TYPE=no-titles COVERAGE_BACKFILL_LIMIT=50

Valid issue types: no-titles, bad-app-id, no-protondb-data.


Makefile target reference

Target Description
make build Update ?v=HASH cache-bust strings in HTML and JS imports
make test-js Run Jest unit tests and manifest completeness check
make pre-push Full pre-push gate: build + test-js + smoke
make smoke Render-path smoke test against a local staged copy
make smoke-live Same smoke harness pointed at the production URL
make serve Vite dev server with CSS HMR at http://localhost:5173
make install Install node deps via pnpm
make setup Bootstrap Python deps and install pg_dump
make sync-runtime Pull scoring-info.json and form-schema.json from the plugin repo
make test Run linting + Python test suite
make lint Run pyright + pylint + shellcheck
make test-py Run Python test suite via uv
make gh-staging Deploy to staging only (no prod change)
make gh-pages-only Promote current main to production
make gh-run Trigger full data pipeline + production deploy
make gh-backfill-apps Trigger targeted app backfill
make gh-coverage-backfill Trigger coverage-based backfill
make gh-run-watch Poll active workflow runs until they finish
make gh-check Verify gh CLI is installed and authenticated
make backup-supabase Dump Supabase DB via pg_dump
make fetch-steam-catalog Fetch and cache Steam app IDs

Staging site details

Item Value
Repo mdeguzis/proton-pulse-web-staging
URL https://mdeguzis.github.io/proton-pulse-web-staging/
Branch gh-pages
Updated by staging_only and pages_only workflow paths
Secret required STAGING_DEPLOY_TOKEN in proton-pulse-web repo secrets

The staging token is a fine-grained PAT scoped to proton-pulse-web-staging with Contents: Read and write permission.


Secrets and environment

Every secret this project reads -- Supabase edge-function secrets, GitHub Actions secrets, Discord webhooks -- is enumerated on the Secrets-and-Environment page. Consult it before adding a new secret so we can reuse existing names, and consult it during rotation so no location is missed.

Clone this wiki locally