Deployment
See ENVIRONMENTS.md for a complete overview of all environments and their configurations.
CI/CD with GitHub Actions
This project uses GitHub Actions for automated deployment with separate workflows for frontend and backend:
Development Deploys (main branch)
Frontend Deploy
- File:
.github/workflows/deploy-frontend-dev.yml - Trigger: Pushes to
mainbranch (paths:web/,shared/,firestore.rules,firebase.json) - Deploys to Firebase Hosting
devtarget + Firestore rules - Uses secrets prefixed with
DEV_ - Generates
version.jsonfor deploy verification
- File:
Functions Deploy
- File:
.github/workflows/deploy-functions-dev.yml - Trigger: Pushes to
mainbranch (paths:functions/,shared/,firebase.json) - Deploys Cloud Functions to Firebase (Cloud Run)
- Sets environment variables on Cloud Run services
- Uses secrets prefixed with
DEV_ - Includes health checks for API endpoints
- File:
Production Deploy (Tag-based)
- File:
.github/workflows/deploy-prod.yml - Trigger: Pushes of version tags matching
v*.*.*(e.g.,v1.2.3) - Deploys: Frontend to Firebase Hosting
prodtarget + Firestore rules - Uses: Secrets prefixed with
PROD_ - Note: Functions source is in
functions/in this monorepo. Dev deploys automatically. Prod functions deploy viadeploy-functions-prod.ymlon version tags.
Why Tag-based Production Releases?
- Every production release has an immutable identifier (the tag) that points to the exact commit deployed
- Rollbacks are simple: redeploy an older tag
- No separate
prodbranch is required - Clear version history and release tracking
Required GitHub Secrets
Development (main branch)
Frontend secrets:
DEV_VITE_PUBLIC_APIKEYDEV_VITE_PUBLIC_AUTHDOMAINDEV_VITE_PUBLIC_PROJECTIDDEV_VITE_PUBLIC_STORAGEBUCKETDEV_VITE_PUBLIC_MESSAGINGSENDERIDDEV_VITE_PUBLIC_APPIDDEV_VITE_PUBLIC_MEASUREMENT_IDDEV_VITE_PUBLIC_VAPID_KEYDEV_FIREBASE_SERVICE_ACCOUNT(service account JSON content)
Functions integration secrets:
GOOGLE_CALENDAR_CLIENT_IDGOOGLE_CALENDAR_CLIENT_SECRETGOOGLE_CALENDAR_REDIRECT_URIDISCORD_CLIENT_IDDISCORD_CLIENT_SECRETDISCORD_REDIRECT_URIENCRYPTION_KEY
Build notification secrets:
DISCORD_WEBHOOK_BUILDS(Discord webhook URL for build notifications)DISCORD_WEBHOOK_AI_DEV(Discord webhook URL for dev channel)
Production (tag-based releases)
PROD_VITE_PUBLIC_APIKEYPROD_VITE_PUBLIC_AUTHDOMAINPROD_VITE_PUBLIC_PROJECTIDPROD_VITE_PUBLIC_STORAGEBUCKETPROD_VITE_PUBLIC_MESSAGINGSENDERIDPROD_VITE_PUBLIC_APPIDPROD_VITE_PUBLIC_MEASUREMENT_IDPROD_VITE_PUBLIC_VAPID_KEYPROD_VITE_PUBLIC_SERVICE_ACCOUNT(service account JSON content)PROD_VITE_API_URL(prod Cloud Run API URL — required, no fallback)
How it Works
Frontend Workflow
- Build job:
- Installs dependencies with
pnpm install - Builds the web app with
pnpm build:web - Generates
version.jsonwith commit SHA for deploy verification - Archives the build output (
web/dist/)
- Installs dependencies with
- Deploy job:
- Downloads the build artifact
- Deploys to Firebase Hosting:
firebase deploy --only hosting:dev(orhosting:prod) - Deploys Firestore rules:
firebase deploy --only firestore:rules - Deploys Firestore indexes:
firebase deploy --only firestore:indexes
- Health Check:
- Verifies frontend is accessible (HTTP 200)
- Verifies
version.jsonexists and SHA matches deployed commit
- Notify:
- Sends build status to Discord channels
Functions Workflow
- Build job:
- Installs dependencies with
pnpm install - Builds shared types:
pnpm build:shared - Builds functions:
pnpm build:functions
- Installs dependencies with
- Deploy job:
- Deploys Cloud Functions:
firebase deploy --only functions --project seed-start-7255a - Removes old environment variables from Cloud Run services
- Sets new environment variables (Calendar, Discord integrations)
- Deploys Cloud Functions:
- Health Check:
- Verifies API health endpoint returns 200 OK
- Validates JSON response
- Checks frontend homepage
- Notify:
- Sends build status to Discord channels
Adding/Updating Secrets
- Go to your GitHub repo > Settings > Secrets and variables > Actions.
- Add or update the required secrets for each environment.
How to Release to Production
A) Fast Path (Recommended): Tag the Commit and Push the Tag
From your local machine:
git checkout main
git pull
git tag -a v1.2.3 -m "Production release v1.2.3"
git push origin v1.2.3This triggers the production workflow and deploys exactly that tag.
B) Create Release via GitHub Website
- Go to your repo in GitHub
- Click Releases (right side) → Draft a new release
- In Choose a tag, type a new tag like
v1.2.3 - In Target, choose the branch/commit to tag:
- Usually
main(GitHub will tag the latest commit onmain) - Or select a specific commit if needed
- Usually
- Click Publish release
Result:
- GitHub creates the tag
v1.2.3 - Your
deploy-prod.yml(tag trigger) runs - Prod deploy happens
C) Rollback
To rollback production, redeploy a previous version tag (e.g., v1.2.2) by re-running the workflow for that tag in GitHub Actions (or pushing the tag if it didn't exist yet).
Small-team Guardrails
- Only cut tags from commits that already passed CI on
main - Protect tags if you want: disallow deleting tags (optional)
- Keep tag format consistent:
vX.Y.Z
This document describes how to build, test, and deploy the project, including CI/CD and environment setup.
Local Build Process
Build the entire project:
pnpm install
pnpm buildOr build specific packages:
# Build web only
pnpm build:web
# Build functions only
pnpm build:functions
# Build shared types
pnpm build:sharedOutput locations:
- Frontend:
web/dist/ - Functions:
functions/lib/ - Shared:
shared/dist/
Testing Before Deploy
Run tests and lint checks:
pnpm lint
pnpm testManual Deployment Steps
Note: Automated deployment via GitHub Actions is preferred. Manual deployment is for debugging only.
Ensure you have Firebase CLI:
bashnpm install -g firebase-tools firebase loginBuild the project:
bashpnpm buildDeploy to Firebase:
bash# Deploy everything firebase deploy --project seed-start-7255a # Or deploy specific targets firebase deploy --only hosting:dev --project seed-start-7255a firebase deploy --only functions --project seed-start-7255aVerify deployment by visiting the deployed URL.
CI/CD
- The project uses GitHub Actions for automated builds and deploys.
- All PRs should pass tests and lint before merging.
- Main branch deploys automatically to development.
- Production deploys are triggered by version tags (
v*.*.*).
Best Practices
- Never commit secrets or API keys to the repo.
- Use environment variables for sensitive config.
- Test thoroughly before deploying.
- Monitor error logs after deployment.
For more, see ARCHITECTURE.md or ask a maintainer.