What happens after a PR merges — image builds, dev auto-deploy, and the gated path to production.
Once a PR merges to trunk, deployment is no longer a PR check — these workflows aren't polled by merge-gatekeeper. They're the actual pipeline that gets live-dispatch (and every other deployable app) running in dev, and eventually production.
pull_request to trunk, merge_group, tag pushes (@**), and manual workflow_dispatch for a single app.turbo run build --affected --dry=json for turbo-managed apps like Dispatch), then builds and pushes each affected image to AWS ECR via a shared composite action.name: field is literally Docker Build; playwright-tests.yaml listens for this workflow's completion via workflow_run rather than rebuilding the image itself.trunk.deploy.yaml's setup job diffs the trunk commit range to determine which apps changed (again via turbo run build --affected for turbo apps, path heuristics for everything else). For each changed app, deploy-dev verifies the image exists in ECR (triggering a build if it doesn't) and syncs it via ArgoCD.Production deploys reach deploy.yaml one of two ways:
scheduled-deploy.yaml runs hourly (:30 past the hour, Mon–Fri). It checks the LaunchDarkly halt flag first, then reads .github/deployment-schedule.yaml to see which apps are scheduled for the current ET hour (computed from the workflow run's created_at, not wall-clock, so queue delays don't shift the hour check), and fires a repository_dispatch event per scheduled app. Scheduled deploys are currently halted — do not assume merging to trunk will reach production on its own schedule.workflow_dispatch on deploy.yaml directly, choosing an app, environment, and optional ref/force flags.For current release windows, blocked days, and the up-to-date release process (including how to request a manual deploy while scheduled deploys are halted), see:
Either path lands in the same gated sequence:
halt-releases flag as check-halted, skippable only with an explicit force flag on manual dispatch.deploy-prod runs inside a named GitHub Environment (e.g. production), which is what actually enforces required-reviewer approval before the deploy proceeds. If the approval is rejected, cleanup-release-on-skip removes the tag/release that was just created.deploy-application@trunk syncs the app in ArgoCD against the production cluster, and a Slack message announces the release.Why this shape: dev deploys are cheap and reversible, so they're automatic. Production deploys affect live responders and dispatchers, so every path into it — scheduled or manual — passes through the same halt check, the same dev-health precondition, and the same human approval gate. There's no way to reach production that skips all three.
Both dev and prod deploy jobs don't talk to Kubernetes directly. They call a reusable update-deployment.yaml workflow, which fires a repository_dispatch (update-image event) to a separate GitOps repo (prepared911/live-clusters). ArgoCD watches that repo and applies the manifest change. This indirection is why deploy jobs in this repo look like they "finish" quickly — the actual cluster rollout happens downstream, watched by ArgoCD rather than by GitHub Actions.
Not production, but part of the same pipeline — how to actually see a PR's changes running, before merge.
Vercel is wired up as a monorepo integration with one project per app that needs a static/SPA preview — prepared-docs, storybook, prepared-diagrams, dispatch_vite (Dispatch), beacon, and a few prototype/demo apps. Every PR triggers a build attempt for every project; Vercel's "Ignored Build Step" skips any project whose root directory didn't change in that PR, which is why merge-gatekeeper's ignore list has to name each project individually (see PR Checks).
For Dispatch, the dispatch_vite project builds the Vite frontend (using turbo/apps/dispatch/vercel.json) against CONFIG_ENV=development, so the preview talks to the real shared dev API. No label, no ArgoCD sync to wait for — this is the fastest way to see a frontend change live.
How to access it: the vercel[bot] app posts one comment per PR, updated on every push, with a table of every project's status. Projects that actually built show Ready with a direct Preview link (the live URL) and a Comment link (Vercel's live feedback widget); projects that were skipped show Ignored with only an Inspector link to the build log on the Vercel dashboard. You can also find each project's status directly in the PR's Checks tab, listed as Vercel – <project>.
Adding the preview label to a Dispatch PR spins up a full, isolated environment — its own ArgoCD namespace (pr-env-<PR#>), its own backend stack, not just the frontend. preview-argo-link.yaml posts and updates a PR comment with the Argo application link and the Portal URL (portal-<PR#>.prepared911.dev) as the environment comes up and becomes healthy. kill-old-pr-envs.yaml runs nightly and strips the label — tearing the environment down — after 7 days without activity, so idle PRs don't accumulate long-lived environments.
Reach for this when the shared dev API that Vercel points at doesn't have what you need yet (e.g. a paired backend change that hasn't merged) — otherwise the Vercel preview is faster and requires no setup.