Environments

Environments

Stages

We use the STAGE environment variable across services to define the distinct types of deployment environments:

  1. local - An individual machine used for local development, whether a laptop, local Docker container, or remote Docker container.

  2. dev - We don't have a fixed dev environment. We practice continuous deployment, so while we have automated testing and manual code review, there is no 'pre-production' environment where code is manually tested or used internally. This value exists in the STAGE enum by convention so that if we deploy an environment that should operate distinctly from local but is not prod or staging, such as a PR environment specific to an open PR, we can define specific logic.

  3. staging - We deploy to staging from the main branch. There is no time offset between staging and production (although technically for our backend apps on AWS ECS, Terraform Cloud deploys new image versions to staging first, so if the deployment itself fails in staging it won't deploy to production). Staging allows us to 1) configure distinct environment variables and distinct behavior based on STAGE and 2) allows us to provide a distinct set of Flipt configuration values for a service when it is in staging. In the future, we may add E2E testing that runs in staging before production deployment happens, but right now we automatically deploy to production following a successful staging deployment.

  4. prod - Our production environment is represented by our various pieces of cloud infrastructure that service *.pivot.app traffic and single-tenant enterprise deployments. prod deploys from the main branch.

In addition to this article, read about local development and code review.

Overall Deployment Process

Write code

Bugs and features should each have a branch created by the developer based on the main branch.

Pull request

When ready for feedback, PR against the main branch. Practice small PRs, and use PostHog feature flags (for frontend changes) or Flipt configuration flags (for backend changes) as appropriate to avoid unexpected behaviour.

CI suite runs automatically on each PR and services that are affected will rebuild. Desktop app binaries will be attached to the PR. Cloudflare Pages frontend apps will build and preview URLs will be posted on the PR.

Once testing and approved, squash your PR to main.

Automated release

There are quite a few deployment targets triggered by commits to the main branches of our two monorepos. All of these can be monitored via GitHub workflows or status checks to some degree.

  1. Backend (deployed on ECS) services in the pivot repo will be built and the new image pushed to AWS ECR. This will kickoff separate GitHub Actions workflows in pivot-internal (learn more here) to deploy the new image version to each environment with Terraform Cloud, starting with staging.
  2. Changes that affect the web app (Expo web export) in the pivot repo will deploy via Cloudflare Pages.
  3. Changes that affect the Docs site in the pivot repo at /apps/docs will trigger a redeploy via Cloudflare Pages. (Same for Storybook)
  4. Changes to Terraform files in the pivot-internal repo trigger Terraform Cloud to run a plan on the PR. Once merged, Terraform Cloud will run a a plan and then an apply to the backend staging AWS account and/or the appropriate other workspaces, depending on the specific path in the repo of the Terraform changes. For the backend staging AWS account specifically, apply is automatic, however otherwise the run must be approved in Terraform Cloud.
  5. Changes the apps deployed to Cloudflare Pages in pivot-internal like Engbook and the marketing website will deploy.
  6. Changes to PivotAdmin in pivot-internal will deploy via Cloudflare Pages.
  7. Changes that affect the Expo app in /apps/expo will deploy to the App Store and Google Play store via EAS Update and EAS Submit, however this will only happen if the version number is incremented. You can't accidentally deploy to the app stores or accidentally push an OTA update because you have to have manually incremented the version. Even if no version number is incremented, EAS will store a build of the new version for internal use via the Expo Custom Development Client.
  8. Similar to the mobile app, the desktop apps built with Tauri will deploy if the Expo app is affected and the Tauri app version number is incremented. Tauri binaries are built from the apps/expo codebase and pushed to Cloudflare R2 Storage.