Skip to content

Web Deploy Workflow

mdeguzis edited this page Jul 5, 2026 · 4 revisions

Web Deploy Workflow

This page covers the end-to-end release process for proton-pulse-web -- from local changes through staging review to production.

Contents


Branch and issue workflow

Every change needs a GitHub issue. This is the paper trail and the anchor for staging/prod comments.

All in-progress code goes to the staging branch. Production (main) only receives code through a reviewed and approved PR.

Features

  1. Create a GitHub issue: gh issue create --repo mdeguzis/proton-pulse-web --title "..." --label enhancement
  2. Create a feature branch off staging: git checkout staging && git checkout -b feature/<short-name>
  3. Do all work on the feature branch. Reference the issue in commits: feat: ... (closes #N)
  4. Merge the feature branch into staging when ready: git checkout staging && git merge feature/<short-name> && git push origin staging
  5. Go through the staging review flow. Open a PR staging -> main once satisfied.
  6. After the issue closes, delete the branch: git push origin --delete feature/<short-name>

Bugs

  1. Create a GitHub issue: gh issue create --repo mdeguzis/proton-pulse-web --title "..." --label bug
  2. Commit the fix to the staging branch (or a fix/<short-name> branch merged into staging).
  3. Reference the issue in the commit: fix: ... (closes #N)

Branch naming: feature/<short-name> for features, fix/<short-name> for standalone bug branches.


Overview

All changes follow this path:

local changes -> pre-push checks -> push to staging -> staging deploy -> staging review -> PR staging->main -> production

Production (main) is never touched until staging has been reviewed and the PR has been approved. Branch protection on main requires 1 approved review and a passing test CI check before any merge can proceed.


Before you start

The web app lives at:

~/src/decky-proton-pulse-project/proton-pulse-web/

All deploy targets require gh (GitHub CLI) and a valid session. Confirm before starting:

gh auth status

Make sure you are on the staging branch before making changes:

git checkout staging

Step 1: make changes and pre-push

After editing JS or CSS, run:

make pre-push

This runs three things in sequence:

  1. cache-bust (make build) - recomputes ?v= hashes on all JS/CSS imports based on file content. Every file that changed gets a new hash; unchanged files keep theirs.
  2. Jest tests (make coverage) - unit tests, manifest completeness check, and coverage gate.
  3. Smoke render (make smoke) - headless render check that catches missing imports before they hit CI.

If any step fails, fix it before committing. Do not commit with a failing make pre-push.

Adding a new JS or CSS file

Two extra steps are required when adding a new file:

  1. Add it to gh-pages-manifest.txt -- the pages-only deploy only copies files listed there. A missing entry means the import 404s silently on production.
  2. Add it to every relevant deploy step in .github/workflows/update-data.yml.

The manifest test in Jest catches rule 1 automatically -- npm test will fail if a manifest JS file imports something not listed in the manifest.


Step 2: commit and push to staging

git add <files>
git commit -m "feat: ..."
git push origin staging

Commit messages must follow Conventional Commits: feat:, fix:, chore:, ci:, docs:, etc.

On push, CI runs automatically:

  • CI (ci.yml) - Jest tests with coverage, Supabase schema/RLS integration tests
  • Sync staging repo (sync-staging-main.yml) - mirrors changes to proton-pulse-web-staging repo

Watch CI at: https://github.com/mdeguzis/proton-pulse-web/actions


Step 3: deploy to staging site

make gh-staging

This triggers update-data.yml with staging_only=true. The workflow checks out the staging branch and copies all shell files to the staging repo's gh-pages branch via orphan commit (no shared history with production's gh-pages).

The target prints the Actions run URL and the staging preview URL when it fires.

Staging site: https://mdeguzis.github.io/proton-pulse-web-staging/

After triggering, wait for the run to finish before reviewing. Watch the run:

make gh-run-watch

Step 4: review on staging

Open the staging site and verify:

  • The change you made works as expected
  • No regressions on pages you did not touch (home, app, admin if relevant)
  • No console errors in browser DevTools

Post the staging run URL and staging preview URL as a comment on the relevant GitHub issue.

Do not make further commits or trigger another staging deploy until the user confirms the staging looks correct. One staging deploy per iteration.


Step 5: open a PR and merge to main

This step must always be performed by a human. Never merge the PR yourself.

Once staging is confirmed good, open a PR from staging to main:

gh pr create --base main --head staging --repo mdeguzis/proton-pulse-web --title "..." --body "..."

Branch protection on main requires:

  • At least 1 approved review
  • Passing test CI status check

The user reviews the PR, approves it, and merges it. Only after the merge does production get updated.


Step 6: promote to production

After the PR is merged to main:

make gh-pages-only

This deploys the current main branch content to the live site without re-running the data pipeline. Before firing the workflow it verifies that the staging site is in sync with origin/staging -- if staging is behind, it will refuse and print the SHA mismatch.

Watch the run:

make gh-run-watch

Live site: https://www.proton-pulse.com/

Post the production run URL as a follow-up comment on the issue and close it.


Full pipeline deploy

Use this when game data also needs refreshing (new pipeline features, data format changes, or a scheduled full refresh):

make gh-run

This runs the full data pipeline (Steam catalog fetch, ProtonDB probe, finalize, search index) and then deploys to production. It also requires the staging site to be in sync with origin/staging.


Staging deploy paths (pick the smallest one that fits)

Staging has three deploy targets. Pick the smallest one that actually exercises the change so verification stays fast.

flowchart TD
    A[Change on staging] --> B{Touches JS / CSS / HTML only?}
    B -- yes --> C[make gh-staging<br/>~2 min<br/>shell only, staging reads prod data]
    B -- no --> D{Touches finalize.py or<br/>search-index / recent-reports /<br/>stats / most_played shape only?}
    D -- yes --> E[make gh-staging-finalize<br/>~5 min<br/>skip probe + build,<br/>restore prod chunk state,<br/>rerun finalize + stats,<br/>push to staging repo]
    D -- no --> F[make gh-staging-pipeline<br/>~30 min<br/>full pipeline against staging,<br/>push to staging repo]
    C --> G[Verify at staging URL]
    E --> G
    F --> G
    G --> H{Looks right?}
    H -- yes --> I[Open PR staging to main]
    H -- no --> A
Loading

Rules for picking:

  • If the change is UI-only, gh-staging is enough. Staging falls back to prod data through fetchDataWithProdFallback, so cards render exactly as they will on prod.
  • If the change adds or renames a field in a pipeline JSON output (search-index column, recent-reports field, stats bucket), gh-staging-finalize regenerates the affected files against prod chunk state. This is the right target for schema-only shape changes.
  • Reach for gh-staging-pipeline only when the change needs fresh probe data (new backfill logic, changed probe cadence, a new signal source).

The staging_with_finalize mode reuses the sharded chunk state saved to gh-pages/.pipeline-state/ (see Data-Pipeline). No probing happens on this path, which is why it lands in about the wall time of a normal finalize step.


CI workflows

Workflow Trigger What it does
CI (ci.yml) push to main/staging, daily Jest + coverage, Supabase schema/RLS tests
Update ProtonDB Data (update-data.yml) manual dispatch, staging/prod deploy targets Data pipeline and/or deploy to gh-pages
Content Moderation (content-moderation.yml) scheduled Scans submitted reports for banned phrases
Sync staging repo (sync-staging-main.yml) push to main/staging, daily Mirrors branch to staging repo
pages-build-deployment automatic on gh-pages push GitHub Pages build for the live site

Badges for all workflows are in the README.

Supabase schema tests

tests/supabaseSchema.test.js runs against the live Supabase Management API using SUPABASE_URL and SUPABASE_TOKEN secrets. Tests use describeIfCreds and skip automatically when credentials are absent (forked PRs). The tests include 2-attempt retry logic with 3s backoff for transient Supabase 5xx responses.


Skipping staging

Staging review may be skipped only for:

  • Typo-only README or docs changes
  • CI/workflow-only changes with no site impact
  • Hotfixes the user has already verified on the live site

For everything else, go through staging.


Emergency overrides

If you need to promote to production without going through the staging sync check (e.g. a hotfix that was already verified live):

FORCE_DEPLOY=1 make gh-pages-only

Use this sparingly. It bypasses the staging SHA check entirely.

Clone this wiki locally