Runbook: Deploy Portfolio App
Purpose
Provide a deterministic deployment procedure for the Portfolio App that ensures:
- PR review and preview validation
- Staging validation in production-like environment
- CI gates are green before merge
- Production promotion is gated by imported checks
- Post-deploy validation is explicit
Governance Context
This runbook assumes Vercel and GitHub governance are already configured per rbk-vercel-setup-and-promotion-validation.md. Key governance already in place:
- Vercel Deployment Checks:
ci / qualityandci / buildare required for production promotion - GitHub Ruleset:
main-protectionandstaging-protectionrequire checks to pass and PR approval before merge - Environment Variables: Configured per scope (preview, staging, and production)
- Staging Domain:
staging-bns-portfolio.vercel.appmapped tostagingbranch
If governance has not been set up, see the setup runbook first (~120 minutes including staging setup).
Scope
Use when
- Publishing any Portfolio App change to production
- Releasing routing/navigation updates
- Shipping new project pages or evidence link updates
- Validating changes in staging before production deployment
Do not use when
- Experimenting locally without intent to deploy (use local validation only)
- Making documentation-only changes (portfolio-docs has separate workflow)
Prereqs / Inputs
- Access:
- ability to open PRs and merge to
main
- ability to open PRs and merge to
- Tools:
- Node (20+), pnpm, git
- Preconditions:
- change is on a feature branch
- PR template includes “No secrets added”
- local build and CI checks pass
Do not deploy content that includes secrets, internal endpoints, or sensitive logs/screenshots. If suspected, stop and treat as an incident.
Procedure / Content
Pre-merge checklist (quick)
- Local validation passed (choose one approach):
- Comprehensive:
pnpm verify(auto-formats, runs all checks with detailed reporting) - Individual:
pnpm lint && pnpm format:check && pnpm typecheck && pnpm audit --audit-level=high && pnpm build
- Comprehensive:
- PR readiness:
- PR template completed with security note (“No secrets added”)
- Vercel preview exists and routes render (
/,/cv,/projects, one project detail) - Evidence link UI is present and href values look correct
- Optional: external monitor reviewed (
external-link-monitorworkflow)
- CI governance:
- Required checks green:
ci / quality,ci / build - Branch ruleset active (e.g.,
main-protection) and required checks selected
- Required checks green:
1) Local preflight validation (required)
Recommended approach (comprehensive validation):
pnpm install
pnpm verify # Runs the full local verification suite with detailed error reporting
This runs: environment check, auto-format, format validation, lint, typecheck, audit, secret scanning, registry validation, build, performance checks, unit tests, and Playwright E2E checks.
Alternative: Quick validation (skip tests):
pnpm verify:quick # Skips tests/performance for faster local iteration
Alternative: Manual step-by-step:
From repository root:
pnpm install
pnpm format:write # Auto-fix formatting
pnpm lint # ESLint (zero warnings)
pnpm typecheck # TypeScript validation
pnpm audit --audit-level=high # Dependency vulnerability gate
pnpm registry:validate # Projects YAML schema check
pnpm build # Production build
pnpm test:e2e # Playwright E2E suite
pnpm links:check # Registry+E2E gate equivalent used by CI link-validation job
# Secrets scanning runs in CI on PRs (TruffleHog). Local verify uses a lightweight pattern scan.
Secrets scanning scope:
- TruffleHog-based
secrets:scanruns in CI on PRs and must pass. - Local verification does not run TruffleHog; a lightweight pattern-based scan is included.
- Optional local opt-in: enable pre-commit (
pip install pre-commit && pre-commit install) or install TruffleHog if you want to runpnpm secrets:scanmanually.
Optional local preview:
pnpm dev
Expected outcome:
- all commands succeed with no errors.
- Playwright E2E checks pass.
2) Open a PR (required)
- PR must include:
- what changed
- why
- evidence: local validation passed (verify script or manual commands)
- security note: "No secrets added"
- security note: “No secrets added”
3) Validate preview deployment
In the PR:
- confirm Vercel preview deployment exists
- validate critical routes:
/loads and primary CTA works/cvrenders correctly/projectsrenders list- at least one
/projects/[slug]renders and includes evidence links
- validate /docs links target the expected host/path (path strategy or subdomain strategy)
4) Merge to main
- Merge only when all required GitHub checks are green:
ci / qualityci / testci / link-validationci / build
- Use "Squash and merge" for clean history (recommended)
Note: Production deployment happens automatically from main after CI checks pass, but staging validation is required before considering production deployment complete.
5) Deploy to Staging
After merging to main, promote changes to staging for validation:
# Switch to staging branch
git checkout staging
git pull origin staging
# Merge main into staging
git merge main
# Push to trigger Vercel deployment to staging domain
git push origin staging
Expected outcome:
- Vercel deploys to
https://staging-bns-portfolio.vercel.app - CI checks run on staging branch
- Staging domain updates within 1-2 minutes
6) Validate Staging Deployment
Manual validation (required):
- Open
https://staging-bns-portfolio.vercel.appin browser - Verify critical paths:
- Home page loads (
/) - Navigation works (header, footer)
- CV page renders (
/cv) - Projects index renders (
/projects) - At least one project detail page renders (e.g.,
/projects/portfolio-app) - Contact page renders (
/contact)
- Home page loads (
- Verify evidence links:
- Evidence link elements render with non-empty href values
- Click sample links to sanity-check expected destinations
- Optional: use external monitor for live connectivity confirmation
- Check browser console:
- No JavaScript errors
- No failed network requests
- No React warnings in console
Automated validation (recommended):
# Run Playwright E2E tests against staging
PLAYWRIGHT_TEST_BASE_URL=https://staging-bns-portfolio.vercel.app pnpm test:e2e
# Or run specific test file
PLAYWRIGHT_TEST_BASE_URL=https://staging-bns-portfolio.vercel.app pnpm test:e2e:single
# Optional: run live external link monitor (non-blocking)
pnpm links:check:external
Expected outcome:
- All manual checks pass
- Automated tests pass (if running)
- No console errors; external-link monitor results reviewed when connectivity confidence is required
If staging validation fails:
- Do NOT proceed to production validation
- See Failure modes / Troubleshooting section below
- Either fix forward with hotfix PR or rollback (see rbk-portfolio-rollback.md)
7) Confirm Production Promotion
Production is already deployed because:
- Changes were merged to
mainin Step 4 - Vercel automatically deploys
mainbranch after CI checks pass - GitHub Deployment Checks ensure quality gates are met
Validation steps:
- Navigate to Vercel dashboard → portfolio-app → Deployments
- Find deployment from
mainbranch - Verify:
- Status: "Ready" (green checkmark)
- Branch:
main - Commit SHA matches your merged PR
- Production domain assigned:
https://bryce.seefieldt.ca(canonical domain)
8) Validate Production Deployment
Manual validation (required after staging passes):
- Open
https://bryce.seefieldt.cain browser - Verify same critical paths as staging:
- Home, CV, Projects, Contact pages render
- Evidence links render correctly and navigate to expected destinations
- No console errors
- Compare with staging:
- Production behavior matches staging validation
- No unexpected differences
If production validation fails but staging passed:
- Indicates environment-specific issue (check env vars)
- See Failure modes / Troubleshooting section
9) Env var verification (required)
Validate that the deployment environment is configured with the expected public-safe environment variables. This prevents broken evidence links and inconsistent metadata between Preview, Staging, and Production.
A) Verify Vercel environment variables (Preview + Staging + Production)
In Vercel Project Settings → Environment Variables, confirm these are present:
Required (recommended minimum):
NEXT_PUBLIC_DOCS_BASE_URL
Recommended for production polish:
NEXT_PUBLIC_SITE_URLNEXT_PUBLIC_GITHUB_URLNEXT_PUBLIC_LINKEDIN_URL
Optional:
NEXT_PUBLIC_CONTACT_EMAIL
Expected outcome:
- Values are set for Preview, Staging (as Preview), and Production (unless intentionally different)
- No sensitive values are stored in any
NEXT_PUBLIC_*variable
Note: Staging uses Preview environment scope in Vercel because it's deployed from a non-main branch (staging).
NEXT_PUBLIC_SITE_URLNEXT_PUBLIC_GITHUB_URLNEXT_PUBLIC_LINKEDIN_URL
Optional:
NEXT_PUBLIC_CONTACT_EMAIL
Expected outcome:
- Values are set for Preview and Production (unless intentionally different).
- No sensitive values are stored in any
NEXT_PUBLIC_*variable.
B) Verify runtime behavior in the deployed site
From the deployed environment (Preview or Production), validate behavior that depends on env:
- Documentation link(s) resolve correctly:
- clicking “Docs” or “Evidence” navigates to the Documentation App host/path derived from
NEXT_PUBLIC_DOCS_BASE_URL
- clicking “Docs” or “Evidence” navigates to the Documentation App host/path derived from
- Profile links navigate correctly:
- GitHub/LinkedIn links (if present) go to the configured destinations
- Optional mail link:
- contact email (if configured) generates a correct
mailto:link
- contact email (if configured) generates a correct
If validation fails:
- treat this as a release-blocking configuration defect
- correct env vars in Vercel and trigger a new deployment (or redeploy from the same commit)
- re-run post-deploy validation steps
7) Post-deploy validation
Validate production:
- core routes load (same set as preview)
- evidence links to docs remain correct in UI and destination expectations
- no broken images/assets
10) Record release evidence (recommended)
If change is material:
- Add/update a release note entry in Portfolio Docs App (portfolio program release notes)
- Update dossier pages if behavior changed
- Document any new evidence links or navigation changes
Validation / Expected outcomes
Deployment is successful when:
- Staging validation passes (all critical paths work, no console errors)
- Production site renders correctly
- Production behavior matches staging
- Required checks are green
- Evidence links are correct
- No sensitive information is exposed
Rollback / Recovery
Rollback if:
- Staging validation fails (fix or rollback before production impact)
- Production rendering is broken
- Critical routes 404
/docslinking is broken materially- Sensitive publication suspected
- Production behavior differs unexpectedly from staging
Primary rollback method:
-
Revert the offending PR on
main:git checkout maingit revert <commit-sha>git push origin main -
Update staging to match:
git checkout staginggit pull origin staginggit merge maingit push origin staging -
Validate rollback on both staging and production
For detailed rollback procedures, see rbk-portfolio-rollback.md.
Failure modes / Troubleshooting
Staging validation fails
Symptoms:
- Console errors on staging
- Evidence links broken on staging
- Navigation doesn't work on staging
Resolution:
- Do NOT proceed to production validation
- Investigate the failure locally:
git checkout staginggit pullpnpm installpnpm verify
- Choose fix strategy:
- Minor issue: Create hotfix PR, merge to main, redeploy to staging
- Major issue: Rollback main, update staging
Staging passes but production fails
Symptoms:
- Staging works correctly
- Production has different behavior, errors, or broken links
Likely causes:
- Environment variable mismatch between Preview (staging) and Production
- Build artifact differs between deployments
- Caching issues
Resolution:
- Compare environment variables in Vercel:
- Settings → Environment Variables
- Verify Preview and Production values match expectations
- Check Vercel deployment details:
- Verify both staging and production used same commit SHA
- Check build logs for differences
- Force redeploy production:
- Vercel → Deployments → Find production deployment → "Redeploy"
- If issue persists, rollback and investigate locally
- Preview succeeds but prod fails:
- compare env settings; confirm check gating; rollback if needed
- Promotion stuck “waiting for checks”:
- ensure CI runs on push to main; confirm check names match imported checks
- Broken evidence links:
- distinguish between app-side regression (broken href/render) and external outage (monitor alert)
- app-side regression: treat as release blocker; fix forward or rollback
- external outage only: track operationally; do not weaken deterministic PR gates
References
- Portfolio App dossier deployment:
docs/60-projects/portfolio-app/deployment.md - Hosting ADR:
docs/10-architecture/adr/adr-0007-portfolio-app-hosting-vercel-with-promotion-checks.md - Rollback runbook:
docs/50-operations/runbooks/rbk-portfolio-rollback.md - CI triage runbook:
docs/50-operations/runbooks/rbk-portfolio-ci-triage.md