Files
supabase/apps/studio/turbo.jsonc
Alaister YoungandAlaister Young 690d67e372 fix(studio): hash TanStack deployment pins in build cache (#51054)
Studio builds now hash `VERCEL_DEPLOYMENT_ID` because TanStack embeds it
in server-function request pins. Cached output cannot retain an earlier
deployment ID when redeploying the same commit.

**Changed:**

- Move the ID from `passThroughEnv` into `build.env`, keeping runtime
pinning and Skew Protection settings intact.
- Turbo-managed Next builds with a new ID also invalidate the Studio
cache; upstream package caches remain reusable.

## To test

- Run strict Turbo dry runs with two deployment IDs for each framework:
Studio hashes should differ, an unchanged ID should remain stable, and
upstream hashes should remain unchanged.
- Build Next and TanStack. With skew protection enabled, confirm the
TanStack client/server output includes the current deployment pin.
- Reload an existing project and function editor and navigate through
settings without edits.

Validation: actual Turbo dry runs reproduced identical hashes before the
fix and verified distinct/stable hashes afterward for both frameworks.
Studio typecheck, full source lint ratchet, knip, formatting, and both
production builds passed. Emitted TanStack client/server artifacts
contain the synthetic validation ID and deployment header. Local
TanStack checks passed for overview/reload, untouched settings plus
Back, functions list, existing function source/reload, and final clean
return; no console errors or backend changes. Cache-key and genuine
server-function routing claims are separate from this UI coverage. No
new environment variable, dependency, or package patch is required.

Current Vercel app builds invoke the framework directly through the
Studio dispatcher; this change applies when Studio builds run through
Turbo.

---------

Co-authored-by: Alaister Young <10985857+alaister@users.noreply.github.com>
2026-10-07 18:47:17 +02:00

150 lines
5.1 KiB
JSON

{
"$schema": "./../../node_modules/turbo/schema.json",
"extends": ["//"],
"tasks": {
"build": {
"dependsOn": ["^build"],
"env": [
"ANALYZE",
"CI",
"NEXT_PUBLIC_SUPPORT_API_URL",
"NEXT_PUBLIC_CONTENT_API_URL",
"NEXT_PUBLIC_BASE_PATH",
"NEXT_PUBLIC_STRIPE_PUBLIC_KEY",
"NEXT_PUBLIC_SUPPORT_ANON_KEY",
"NEXT_PUBLIC_ENVIRONMENT",
"NEXT_PUBLIC_IS_PLATFORM",
"NEXT_PUBLIC_SITE_URL",
"NEXT_PUBLIC_API_URL",
"NEXT_PUBLIC_DOCS_URL",
"NEXT_PUBLIC_CONFIGCAT_SDK_KEY",
"NEXT_PUBLIC_CONFIGCAT_PROXY_URL",
"NEXT_PUBLIC_HCAPTCHA_SITE_KEY",
"NEXT_PUBLIC_SUPABASE_URL",
"NEXT_PUBLIC_SUPABASE_ANON_KEY",
"NEXT_PUBLIC_NODE_ENV",
"NEXT_PUBLIC_GOTRUE_URL",
"NEXT_PUBLIC_VERCEL_BRANCH_URL",
"NEXT_PUBLIC_GOOGLE_MAPS_KEY",
"NEXT_RUNTIME",
"NIMBUS_PROD_PROJECTS_URL",
"NIMBUS_PROD_PROJECTS_URL_WS",
"NODE_ENV",
"SUPABASE_URL",
"VERCEL",
"VERCEL_ENV",
// Vite embeds this ID in server-function request pins.
// A different deployment ID requires fresh build output.
"VERCEL_DEPLOYMENT_ID",
// Project-level Vercel settings Nitro's vercel preset reads at build
// time; they change the emitted routes and asset paths.
"VERCEL_SKEW_PROTECTION_ENABLED",
"VERCEL_IMMUTABLE_STATIC_FILES_ENABLED",
"VERCEL_HASH_SALT",
"MAINTENANCE_MODE",
// These envs are used in the packages
"NEXT_PUBLIC_STORAGE_KEY",
"NEXT_PUBLIC_AUTH_DEBUG_KEY",
"NEXT_PUBLIC_AUTH_PERSISTED_KEY",
"NEXT_PUBLIC_AUTH_NAVIGATOR_LOCK_KEY",
"NEXT_PUBLIC_AUTH_DETECT_SESSION_IN_URL",
"NEXT_PUBLIC_GOOGLE_TAG_MANAGER_ID",
"NEXT_PUBLIC_VERCEL_ENV",
"NEXT_PUBLIC_USERCENTRICS_RULESET_ID",
"NEXT_PUBLIC_MCP_URL",
"NEXT_PUBLIC_IS_NIMBUS",
"NEXT_PUBLIC_ONGOING_INCIDENT",
// These envs are technically passthrough env vars because they're only used on the server side of Nextjs
"PLATFORM_PG_META_URL",
"STUDIO_PG_META_URL",
"PG_META_CRYPTO_KEY",
"PGRST_DB_SCHEMAS",
"PGRST_DB_MAX_ROWS",
"PGRST_DB_EXTRA_SEARCH_PATH",
"POSTGRES_PASSWORD",
"POSTGRES_HOST",
"POSTGRES_USER_READ_WRITE",
"POSTGRES_USER_READ_ONLY",
"POSTGRES_DB",
"POSTGRES_PORT",
"READ_ONLY_URL",
"READ_ONLY_API_KEY",
"SUPABASE_SERVICE_KEY",
"SUPABASE_ANON_KEY",
"SUPABASE_PUBLISHABLE_KEY",
"SUPABASE_SECRET_KEY",
"SUPABASE_PUBLIC_URL",
"DEFAULT_PROJECT_NAME",
"DEFAULT_ORGANIZATION_NAME",
"OPENAI_API_KEY",
"BRAINTRUST_API_KEY",
"BRAINTRUST_PROJECT_ID",
"AUTH_JWT_SECRET",
"LOGFLARE_API_KEY",
"LOGFLARE_PUBLIC_ACCESS_TOKEN",
"LOGFLARE_PRIVATE_ACCESS_TOKEN",
"LOGFLARE_URL",
"SENTRY_ORG",
"SENTRY_PROJECT",
"SENTRY_AUTH_TOKEN",
"SKIP_ASSET_UPLOAD",
"NEXT_PUBLIC_SENTRY_DSN",
"AWS_BEDROCK_PROFILE",
"AWS_BEDROCK_ROLE_ARN",
"AWS_ACCESS_KEY_ID",
"AWS_SECRET_ACCESS_KEY",
"FORCE_ASSET_CDN",
"ASSET_CDN_S3_ENDPOINT",
"SITE_NAME",
"VERCEL_URL",
"IS_BRAINTRUST_PUSH",
"GITHUB_HEAD_REF",
"GITHUB_REF_NAME",
"GITHUB_PR_NUMBER",
"IS_THROTTLED",
"AI_PRO_MODEL",
"AI_NORMAL_MODEL",
"SUPPORT_SUPABASE_SECRET_KEY",
"STATUSPAGE_API_KEY",
"STATUSPAGE_PAGE_ID",
"INCIDENT_IO_API_KEY",
"INCIDENT_IO_WIDGET_URL",
"INCIDENT_IO_STATUS_PAGE_ID",
"LIVE_SUPABASE_SECRET_KEY",
// Selects the build mode for the studio's `build`/`start` scripts
// (e.g. e2e sets `MODE=test`). Listed so turbo invalidates the
// cache when it changes — without this, switching between test and
// production builds reuses a stale cached output.
"MODE",
// Read by the Nitro server behind `pnpm start`. Declared so the turbo
// env lint rule passes even though turbo doesn't drive `start`.
"PORT",
// Gates the TanStack vs Next path in vercel.ts and
// scripts/dispatch.js (the dev/build/start dispatcher).
"STUDIO_FRAMEWORK",
// Vite's built-in `import.meta.env.SSR` flag (used in ConnectStepsSection
// to gate Vite-only `import.meta.glob`). Not a real process env var
// but turbo's `no-undeclared-env-vars` lint flags any `env.SSR` access.
"SSR",
],
"passThroughEnv": [
"CURRENT_CLI_VERSION",
"VERCEL_GIT_COMMIT_REF",
"VERCEL_GIT_COMMIT_SHA",
"SNIPPETS_MANAGEMENT_FOLDER",
"EDGE_FUNCTIONS_MANAGEMENT_FOLDER",
"S3_PROTOCOL_ACCESS_KEY_ID",
"S3_PROTOCOL_ACCESS_KEY_SECRET",
],
"outputs": [
".next/**",
"!.next/cache/**",
"!.next/dev/**/*",
// TanStack Start via Nitro: node server and Vercel Build Output.
".output/**",
".vercel/output/**",
],
},
},
}