ReviewOS

stacks/ts-cloud

Ship pull-request and branch preview environments with TTL cleanup

#149
Closed chris opened this 2 months ago ·
2 months ago

Roadmap relationship

Outcome

Create isolated, traceable preview environments from branches or pull requests, update them on new commits, publish stable preview URLs/status, and remove them automatically according to TTL and pull-request lifecycle.

Current gap

PreviewEnvironmentManager and env:preview exist but deployment, persistence, cleanup, cost lookup, domain handling, and provider integration are placeholders. Preview state is currently in memory and uses a fake URL.

User experience

  • Configure previews per application: enable, base environment, branch rules, domain pattern, TTL, resource overrides, secrets policy, and cleanup behavior.
  • Show preview list/status, PR/branch/commit, creator, age/expiry, URL, latest deployment, cost estimate, and teardown errors.
  • Post deployment status and URL back to supported Git providers; update in place on new commits.
  • Warn before manual deletion, support extend/rebuild, and surface leaked-resource reconciliation.

Scope

  • Persist preview definitions and instances; derive deterministic collision-safe names, stack/resource tags, and stable URLs.
  • Clone a safe subset of base environment config with explicit resource/secret inheritance rules and size/cost caps.
  • Implement create/update/destroy through existing deployment/provider primitives and durable jobs.
  • React to PR open/synchronize/reopen/close and branch deletion events idempotently.
  • Add scheduled TTL cleanup, keep-count limits, dry run, provider reconciliation, and cost tagging.
  • Support serverless/static first and document capability requirements for server/container previews.

Technical direction

  • Use immutable source SHA plus preview identity; never deploy an ambiguous moving branch without resolving a commit.
  • Tag every provider resource with preview/project/expiry identifiers and discover orphaned resources by tag.
  • Separate desired preview record from last observed provider state.
  • Design database strategy explicitly: isolated, snapshot/clone, shared read-only, or disabled.

Safety and operability

  • Default to no production secrets and no production write endpoints; require explicit per-secret opt-in.
  • Apply budget/resource ceilings and block public previews when domain/TLS/auth policy is unsatisfied.
  • Teardown is idempotent, audited, and does not delete untagged or shared resources.
  • Untrusted fork PRs never receive privileged credentials by default.

Acceptance criteria

  • A valid PR event creates one preview, later commits update it, and close/TTL removes it.
  • Preview URLs and provider statuses point to the exact deployed commit.
  • Fork and secret policies prevent credential exposure.
  • Failed cleanup remains visible and retryable with an exact resource reconciliation report.

Verification

  • Webhook lifecycle/deduplication, naming collision, TTL, orphan discovery, secret inheritance, and fork-policy tests.
  • Provider-tagged create/update/destroy integration fixtures.
  • End-to-end PR open → deploy → update → close flow.

Non-goals

  • Full production-sized clones by default.
  • Sharing mutable production databases with untrusted previews.
  • Supporting every provider/resource combination in the first release.
8 days ago

Implemented end to end on main in small conventional commits.

Delivered:

  • persistent preview definitions, instances, desired/observed state, collision-safe names, stable URLs, exact-SHA identity, explicit secret inheritance, fork policy, database strategy, cost/CPU/memory caps
  • durable and retryable create/update/destroy handlers with isolated stack names, exact source checkout verification, tagged provider resources, teardown error visibility, and idempotent lifecycle
  • pull-request open/update/close plus matching branch push/delete reconciliation across supported hosted webhook formats
  • TTL, max-age, keep-count, dry-run cleanup, provider tag reconciliation, leak reporting, cost estimates, scheduled cleanup, and manual extend/rebuild/destroy
  • hosted provider pending/success/failure commit statuses linked to the preview URL
  • CLI, resource-scoped API/client/OpenAPI, responsive dashboard page, configuration UX, exact-name deletion confirmation, and operator documentation
  • deterministic FIFO handling for durable jobs sharing a timestamp, found during the release gate

Verification at closure:

  • bun test: 2,634 pass, 0 fail, 2 skip, 2 todo; 7,237 assertions across 355 files
  • bunx tsc --noEmit -p packages/ts-cloud/tsconfig.json: clean
  • dashboard SSG: 44/44 routes
  • documentation: 36 pages

Primary commits: d5faf12, e184f05, 3231afb, f96a5b6, a1280c8, a7e7443, d1cd1f2, af4a637, 79ca5bb, e2a7215, 93cc4de, c8418be.

Sign in to comment on this issue.