-
Notifications
You must be signed in to change notification settings - Fork 0
Web Deploy Workflow
This page covers the end-to-end release process for proton-pulse-web -- from local changes through staging review to production.
- Branch and issue workflow
- Overview
- Before you start
- Step 1: make changes and pre-push
- Step 2: commit and push to staging
- Step 3: deploy to staging site
- Step 4: review on staging
- Step 5: open a PR and merge to main
- Step 6: promote to production
- Full pipeline deploy
- Staging deploy paths (pick the smallest one that fits)
- CI workflows
- Skipping staging
- Emergency overrides
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.
- Create a GitHub issue:
gh issue create --repo mdeguzis/proton-pulse-web --title "..." --label enhancement - Create a feature branch off
staging:git checkout staging && git checkout -b feature/<short-name> - Do all work on the feature branch. Reference the issue in commits:
feat: ... (closes #N) - Merge the feature branch into
stagingwhen ready:git checkout staging && git merge feature/<short-name> && git push origin staging - Go through the staging review flow. Open a PR
staging->mainonce satisfied. - After the issue closes, delete the branch:
git push origin --delete feature/<short-name>
- Create a GitHub issue:
gh issue create --repo mdeguzis/proton-pulse-web --title "..." --label bug - Commit the fix to the
stagingbranch (or afix/<short-name>branch merged intostaging). - Reference the issue in the commit:
fix: ... (closes #N)
Branch naming: feature/<short-name> for features, fix/<short-name> for standalone bug branches.
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.
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 statusMake sure you are on the staging branch before making changes:
git checkout stagingAfter editing JS or CSS, run:
make pre-pushThis runs three things in sequence:
-
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. -
Jest tests (
make coverage) - unit tests, manifest completeness check, and coverage gate. -
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.
Two extra steps are required when adding a new file:
- 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. - 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.
git add <files>
git commit -m "feat: ..."
git push origin stagingCommit 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 toproton-pulse-web-stagingrepo
Watch CI at: https://github.com/mdeguzis/proton-pulse-web/actions
make gh-stagingThis 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-watchOpen 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.
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
testCI status check
The user reviews the PR, approves it, and merges it. Only after the merge does production get updated.
After the PR is merged to main:
make gh-pages-onlyThis 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-watchLive site: https://www.proton-pulse.com/
Post the production run URL as a follow-up comment on the issue and close it.
Use this when game data also needs refreshing (new pipeline features, data format changes, or a scheduled full refresh):
make gh-runThis 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 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
Rules for picking:
- If the change is UI-only,
gh-stagingis enough. Staging falls back to prod data throughfetchDataWithProdFallback, 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-finalizeregenerates the affected files against prod chunk state. This is the right target for schema-only shape changes. - Reach for
gh-staging-pipelineonly 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.
| 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.
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.
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.
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-onlyUse this sparingly. It bypasses the staging SHA check entirely.