Skip to content

chore(ci,docs): retire staging — dev→beta→main ladder + beta-first self-host plan - #670

Merged
onerandomdevv merged 3 commits into
devfrom
chore/dev-beta-main-ladder
Jul 27, 2026
Merged

chore(ci,docs): retire staging — dev→beta→main ladder + beta-first self-host plan#670
onerandomdevv merged 3 commits into
devfrom
chore/dev-beta-main-ladder

Conversation

@onerandomdevv

@onerandomdevv onerandomdevv commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

What

Retires staging and moves the promotion ladder to dev → beta → main, and reframes the self-host runbook around the agreed rollout: beta = disposable rehearsal on a VPS, prod on its own dedicated box later, early-access via allowlist on prod (no beta→prod data migration).

Why

For a small, fast team, four always-on tiers (dev/staging/beta/main) is overhead. dev + per-PR ephemeral preview envs already cover pre-beta testing, so staging's job folds into dev. Beta becomes a throwaway proving ground for the self-hosted Openship stack; real early-access users live on prod behind an allowlist from day one, so nothing ever migrates between environments (they're separate Neon DBs and beta uses sandbox payments).

Changes

.github/workflows/promotion-guard.yml

  • ALLOWED map → [main]=beta, [beta]=dev (staging removed)
  • Trigger branches: [main, beta]
  • Comments + violation message updated to the dev → beta → main ladder

TWIZRR_SELF_HOST_DEPLOYMENT.md

  • New environment-model table (dev=team QA, beta=disposable rehearsal, prod=dedicated + allowlist)
  • "No beta→prod migration" principle documented
  • Spec table leads with Contabo VPS 8 (month-to-month, 1 IPv4); two-box end state
  • Phase 5 → Deploy on BETA first; env matrix now beta vs prod; Phase 6 → prod on its own box + allowlist early-access; give dev its own host at cutover
  • Promotion mapping drops staging; notes staging branch + Neon are retired/dormant

Follow-ups (not in this PR)

  • Mark the guard status check required in the beta and main rulesets
  • Retire the staging git branch + Neon ep-mute-glitter (leave dormant or delete)
  • Provision the Contabo beta box and begin Phase 1

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Documentation
    • Updated self-host deployment guidance to use a beta-first rollout.
    • Revised environment, infrastructure, and production go-live instructions for separate beta and production deployments.
    • Documented the simplified promotion path: dev → beta → main.
  • Chores
    • Updated promotion checks to enforce the new branch workflow and remove staging protections.

…lf-host plan

- promotion-guard: ALLOWED now [main]=beta [beta]=dev; trigger branches [main, beta];
  comments + error message updated for the dev→beta→main ladder
- TWIZRR_SELF_HOST_DEPLOYMENT: beta = disposable rehearsal (Contabo VPS 8), prod on
  a dedicated box later, early-access via allowlist on prod (no beta→prod data
  migration); spec table, env matrix, and Phase 5/6 reframed beta-vs-prod

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@codesandbox

codesandbox Bot commented Jul 27, 2026

Copy link
Copy Markdown

Review or Edit in CodeSandbox

Open the branch in Web EditorVS CodeInsiders

Open Preview

@vercel

vercel Bot commented Jul 27, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
twizrr-admin Ready Ready Preview, Comment Jul 27, 2026 5:50pm
twizrr-app Ready Ready Preview, Comment Jul 27, 2026 5:50pm
twizrr-web Ready Ready Preview, Comment Jul 27, 2026 5:50pm

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Warning

Review limit reached

@onerandomdevv, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 7 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 9568c8b1-197c-4594-8452-ace43a46e78d

📥 Commits

Reviewing files that changed from the base of the PR and between 696c6bd and d55b90e.

📒 Files selected for processing (1)
  • TWIZRR_SELF_HOST_DEPLOYMENT.md
📝 Walkthrough

Walkthrough

The promotion workflow now enforces dev → beta → main. The self-host deployment runbook updates infrastructure guidance, environment mappings, beta deployment steps, production promotion requirements, and the retirement of staging.

Changes

Beta-First Promotion and Deployment

Layer / File(s) Summary
Promotion guard ladder
.github/workflows/promotion-guard.yml
Pull requests targeting main and beta are checked against the direct dev → beta → main promotion mapping.
Deployment model and environment mapping
TWIZRR_SELF_HOST_DEPLOYMENT.md
Infrastructure, provider sizing, Neon prerequisites, and environment variables are revised for beta and production deployments.
Beta rollout and production promotion
TWIZRR_SELF_HOST_DEPLOYMENT.md
Beta deployment and smoke tests precede production go-live on a dedicated box, with staging marked dormant and the updated promotion mapping documented.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The description covers the main change but omits required template sections like type, area, testing, checklist, screenshots, and reviewer notes. Add the missing template sections: type of change, area affected, test steps with expected result, pre-commit checklist, screenshots/N/A, and notes for reviewer.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately summarizes the staging retirement and dev→beta→main promotion ladder update.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch chore/dev-beta-main-ladder

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (1)
.github/workflows/promotion-guard.yml (1)

12-16: 🔒 Security & Privacy | 🔵 Trivial

Make the ruleset dependency a release prerequisite.

This workflow only validates pull requests; it cannot prevent direct pushes or merges when guard is not required. Require the guard check in both the beta and main rulesets before relying on this ladder.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/promotion-guard.yml around lines 12 - 16, Update the
repository’s beta and main branch rulesets to require the guard status check
before treating this promotion workflow as a release prerequisite. Ensure the
guard check is configured as a required status check in both rulesets, covering
direct pushes and merges that bypass optional validation.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/promotion-guard.yml:
- Line 49: Update the nearby rationale for the ALLOWED mapping in the workflow
to reference “beta <- dev” instead of “staging <- dev,” preserving the existing
mapping and workflow behavior.

In `@TWIZRR_SELF_HOST_DEPLOYMENT.md`:
- Around line 85-95: Clarify the Contabo IPv4 guidance in the two-box deployment
section: state that each dedicated beta or production box has its own origin
IPv4, and limit any shared-one-IP wording to the single-box beta setup. Keep the
separate-box production requirement unchanged.
- Line 293: Update the WEB_URL / APP_URL / FRONTEND_URL deployment matrix
entries to use complete per-app origins instead of wildcard or placeholder
values: beta should list https://twizrr.com, https://app.beta.twizrr.com, and
https://admin.beta.twizrr.com, while production should list https://twizrr.com,
https://app.twizrr.com, and https://admin.twizrr.com.
- Line 21: Update both Hetzner plan references in
TWIZRR_SELF_HOST_DEPLOYMENT.md, including the deployment comparison and the
detailed recommendation, replacing deprecated CX42 with orderable CX43 and
updating the listed specifications and price to match CX43.
- Around line 295-296: Update the deployment environment-variable documentation
so PAYSTACK_WEBHOOK_SECRET is explicitly configured separately for beta and
production, rather than relying on PAYSTACK_SECRET_KEY fallback. Document
setting each webhook secret only in the matching twizrr-backend environment and
list distinct Paystack dashboard webhook URLs for beta and production.

---

Nitpick comments:
In @.github/workflows/promotion-guard.yml:
- Around line 12-16: Update the repository’s beta and main branch rulesets to
require the guard status check before treating this promotion workflow as a
release prerequisite. Ensure the guard check is configured as a required status
check in both rulesets, covering direct pushes and merges that bypass optional
validation.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: df9ac081-0d4e-4523-bbd8-1a6c6641caab

📥 Commits

Reviewing files that changed from the base of the PR and between 38b330c and 696c6bd.

📒 Files selected for processing (2)
  • .github/workflows/promotion-guard.yml
  • TWIZRR_SELF_HOST_DEPLOYMENT.md


# Allowed source for each protected target branch.
declare -A ALLOWED=( [main]="beta" [beta]="staging" [staging]="dev" )
declare -A ALLOWED=( [main]="beta" [beta]="dev" )

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Update the stale staging reference.

The mapping is correct, but the nearby rationale still mentions staging <- dev. Change it to beta <- dev so the workflow documentation matches the enforced ladder.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/promotion-guard.yml at line 49, Update the nearby
rationale for the ALLOWED mapping in the workflow to reference “beta <- dev”
instead of “staging <- dev,” preserving the existing mapping and workflow
behavior.

Comment thread TWIZRR_SELF_HOST_DEPLOYMENT.md Outdated
Comment thread TWIZRR_SELF_HOST_DEPLOYMENT.md Outdated
Comment thread TWIZRR_SELF_HOST_DEPLOYMENT.md Outdated
Comment on lines 295 to +296
| `PAYSTACK_*` / `NEXT_PUBLIC_PAYSTACK_PUBLIC_KEY` | **test** keys | **live** keys |
| `NEXT_PUBLIC_API_URL` | `https://api.staging.twizrr.com` | `https://api.twizrr.com` |
| `NEXT_PUBLIC_API_URL` | `https://api.beta.twizrr.com` | `https://api.twizrr.com` |

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Files matching deployment docs:"
git ls-files | rg -n 'TWIZRR_SELF_HOST_DEPLOYMENT\.md|deploy|deployment|paystack|PAYSTACK' || true

echo
echo "Relevant lines in TWIZRR_SELF_HOST_DEPLOYMENT.md around 260-320:"
if [ -f TWIZRR_SELF_HOST_DEPLOYMENT.md ]; then
  sed -n '260,320p' TWIZRR_SELF_HOST_DEPLOYMENT.md | cat -n -v
fi

echo
echo "Search for PAYSTACK_WEBHOOK_SECRET in repository:"
rg -n "PAYSTACK_WEBHOOK_SECRET|paystack|PAYSTACK|webhook" TWIZRR_SELF_HOST_DEPLOYMENT.md . --glob '!node_modules' --glob '!dist' --glob '!build' | head -200

Repository: coded-devs/twizrr

Length of output: 28248


🌐 Web query:

Paystack webhook signature verification secret key different for sandbox live webhook secret key dashboard

💡 Result:

Yes, Paystack uses different secret keys for its sandbox (test) and live environments [1][2]. Because the webhook signature is generated using your secret key [3][4], the key used to verify the signature must match the environment from which the webhook was sent [1][2]. When configuring your webhook handler, ensure that your application uses the corresponding secret key based on the environment: 1. Test Mode: Use your Test Secret Key (prefixed with sk_test_) to verify signatures for webhooks received in the test environment [1][2]. 2. Live Mode: Use your Live Secret Key (prefixed with sk_live_) to verify signatures for webhooks received in the production environment [1][2]. You can find both sets of keys in your Paystack Dashboard under Settings > API Keys & Webhooks [1][2][4]. It is recommended to use environment variables to manage these keys securely and prevent the accidental use of test keys in production [5][6]. Failure to use the correct key for the respective environment will result in signature verification errors [5].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "Search Paystack secret/env var usage:"
rg -n "PAYSTACK_SECRET_KEY|PAYSTACK_WEBHOOK_SECRET|secretKey|webhook" apps backend packages apps/backend/src --glob '!node_modules' --glob '!dist' --glob '!build' 2>/dev/null | head -250 || true

echo
echo "Relevant deployment webhook instructions around line 343:"
sed -n '330,350p' TWIZRR_SELF_HOST_DEPLOYMENT.md | cat -n -v

Repository: coded-devs/twizrr

Length of output: 34443


Make PAYSTACK_WEBHOOK_SECRET beta/production-specific.

The backend falls back to PAYSTACK_SECRET_KEY when no webhook secret is set, and Paystack signs webhooks with each environment’s secret key. Keep PAYSTACK_WEBHOOK_SECRET separate from the beta and production secret keys, set them in twizrr-backend only for the matching environment, and configure the beta and prod dashboard webhook URLs separately.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@TWIZRR_SELF_HOST_DEPLOYMENT.md` around lines 295 - 296, Update the deployment
environment-variable documentation so PAYSTACK_WEBHOOK_SECRET is explicitly
configured separately for beta and production, rather than relying on
PAYSTACK_SECRET_KEY fallback. Document setting each webhook secret only in the
matching twizrr-backend environment and list distinct Paystack dashboard webhook
URLs for beta and production.

Source: MCP tools

…ity, concrete matrix origins

- Hetzner CX42/CX32 are deprecated (Jan 2026) → CX43 / CX33; growth path CX43→CX53
- clarify 1-IPv4 scope: beta box = one origin IP for all its surfaces; prod box gets its own
- env matrix: replace *.beta / "prod hosts" placeholders with concrete per-app origins

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@onerandomdevv
onerandomdevv merged commit d09777a into dev Jul 27, 2026
14 checks passed
@onerandomdevv
onerandomdevv deleted the chore/dev-beta-main-ladder branch July 27, 2026 17:58
onerandomdevv added a commit that referenced this pull request Jul 28, 2026
## What
Removes the last stale `staging` references now that the ladder is `dev
→ beta → main` and staging is being deleted everywhere.

## Changes
- **ci.yml** / **prisma-migrate.yml** — drop `staging` from branch
triggers → `[dev, beta, main]`
- **prisma-migrate.yml** — remove the `staging → 'staging'` GitHub
Environment mapping
- **promotion-guard.yml** — fix the illustrative fork-guard example
(`'staging <- dev'` → `'beta <- dev'`); the *logic* was already
de-staged in #670
- **apps/backend/.env.example**, **apps/web/.env.example** — payment-key
guidance: TEST keys now cover **local/dev/beta** (beta is a disposable
rehearsal on sandbox payments); **LIVE keys are production-only**
(previously mislabelled beta as LIVE)

## Note
The only remaining `staging` mention is the intentional "Staging was
dropped —" historical note in the guard header, which documents the
decision.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->

## Summary by CodeRabbit

- **Chores**
- Updated deployment workflows to use the `dev → beta → main` promotion
path.
- Removed `staging` from automated pull request and migration triggers.
- Updated environment selection for development, beta, and production
deployments.

- **Documentation**
  - Clarified CORS configuration guidance.
- Updated Paystack key instructions for local, development, beta, and
production environments.

<!-- end of auto-generated comment: release notes by coderabbit.ai -->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant