Skip to content

fix(sanity): support runtime staging flag for auto-updating deploys#12563

Open
rexxars wants to merge 3 commits intomainfrom
rexxars/staging-globalthis
Open

fix(sanity): support runtime staging flag for auto-updating deploys#12563
rexxars wants to merge 3 commits intomainfrom
rexxars/staging-globalthis

Conversation

@rexxars
Copy link
Copy Markdown
Member

@rexxars rexxars commented Apr 1, 2026

Description

When auto-updating studios are deployed with SANITY_INTERNAL_ENV=staging, they load the sanity package from the production CDN (sanity-cdn.com). The production bundle has the bare __SANITY_STAGING__ identifier statically replaced with false by Vite and tree-shaken away, so the staging check never fires - causing the studio to hit api.sanity.io instead of api.sanity.work.

This PR:

  • Adds a globalThis.__SANITY_STAGING__ runtime check that survives tree-shaking (property access on globalThis can't be statically eliminated by Vite's define)
  • Centralizes all staging detection into a single isStaging constant in core/environment/isStaging.ts, evaluated once at module load (matching the isDev/isProd pattern)
  • Replaces scattered inline __SANITY_STAGING__ checks across createAuthStore, fetchCreateCompatibleAppId, and fetchLatestVersions

The companion CLI change will inject <script>globalThis.__SANITY_STAGING__ = true</script> into the HTML before module scripts when deploying in staging mode.

What to review

  • packages/sanity/src/core/environment/isStaging.ts - the new centralized constant with three detection strategies (build-time constant, runtime global, import map URL)
  • The consumer files now just reference isStaging instead of duplicating the check inline

Testing

Unit tests in isStaging.test.ts covering all three detection paths and their combinations. Tests use vi.resetModules() + dynamic imports to re-evaluate the constant for each scenario.

Notes for release

N/A - Internal staging infrastructure only.

When studios are deployed with `SANITY_INTERNAL_ENV=staging` but load
modules from the production CDN, the build-time `__SANITY_STAGING__`
constant gets tree-shaken away. Add a `globalThis.__SANITY_STAGING__`
runtime check that survives bundling, and centralize all staging
detection into a single `isStaging()` function.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel bot commented Apr 1, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
page-building-studio Ready Ready Preview, Comment Apr 3, 2026 4:53pm
test-studio Ready Ready Preview, Comment Apr 3, 2026 4:53pm

Request Review

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 1, 2026

📦 Bundle Stats — sanity

Compared against main (611e177e) · v5.19.0 (npm)

sanity

Metric Value vs main (611e177) vs v5.19.0
Internal (raw) 4.41 MB -34 B, -0.0% -64 B, -0.0%
Internal (gzip) 1.01 MB +33 B, +0.0% +25 B, +0.0%
Bundled (raw) 12.09 MB -34 B, -0.0% -33.9 KB, -0.3%
Bundled (gzip) 2.72 MB +26 B, +0.0% -7.0 KB, -0.3%
Import time 1.41s -5ms, -0.3% +42ms, +3.1%

bin:sanity

Metric Value vs main (611e177) vs v5.19.0
Internal (raw) 7.1 KB - -
Internal (gzip) 2.9 KB - -
Bundled (raw) 7.1 KB - -
Bundled (gzip) 2.8 KB - -
Import time 5ms +0ms, +0.6% +1ms, +10.8% ⚠️

🗺️ View treemap · Artifacts

Details
  • Import time regressions over 10% are flagged with ⚠️
  • Sizes shown as raw / gzip 🗜️. Internal bytes = own code only. Total bytes = with all dependencies. Import time = Node.js cold-start median.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 1, 2026

🧪 E2E Preview environment

🔑 Environment Variables for Local Testing

This is the preview URL for the E2E tests: https://e2e-studio-e4zugld17.sanity.dev

To run the E2E tests locally, you can use the following environment variables, then run pnpm test:e2e --ui to open the Playwright test runner.

💬 Remember to build the project first with pnpm build:e2e.

  SANITY_E2E_PROJECT_ID=ittbm412
  SANITY_E2E_BASE_URL=https://e2e-studio-e4zugld17.sanity.dev
  SANITY_E2E_DATASET="update depending the project you want to test (pr-12563-chromium-23954206871 || pr-12563-firefox-23954206871 )"
  SANITY_E2E_DATASET_CHROMIUM=pr-12563-chromium-23954206871
  SANITY_E2E_DATASET_FIREFOX=pr-12563-firefox-23954206871

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 1, 2026

📊 Playwright Test Report

Download Full E2E Report

This report contains test results, including videos of failing tests.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 1, 2026

📚 TypeDoc Generation Result

TypeDoc generated successfully!

  • File size: 8.2M
  • Total exports: 1062
  • Artifact: sanity-typedoc-6e161a90d7fcf3790ae25a65a0fba1fb95487335

The TypeDoc JSON file has been generated and validated. All documentation scripts completed successfully.

The staging environment does not change at runtime, so evaluate it once
at module load time instead of on every call.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 1, 2026

⚡️ Editor Performance Report

Updated Fri, 03 Apr 2026 17:00:26 GMT

Benchmark reference
latency of sanity@latest
experiment
latency of this branch
Δ (%)
latency difference
arrayI18n (simple-en) 66.7 efps (15ms) 66.7 efps (15ms) +0ms (-/-%)
article (title) 48.8 efps (21ms) 48.8 efps (21ms) +0ms (-/-%)
article (body) 53.2 efps (19ms) 52.9 efps (19ms) +0ms (+0.5%)
article (string inside object) 47.6 efps (21ms) 50.0 efps (20ms) -1ms (-4.8%)
article (string inside array) 55.6 efps (18ms) 55.6 efps (18ms) +0ms (-/-%)
recipe (name) 99.9+ efps (10ms) 99.9+ efps (10ms) +0ms (-/-%)
recipe (description) 54.1 efps (19ms) 54.1 efps (19ms) +0ms (-/-%)
recipe (instructions) 99.9+ efps (6ms) 99.9+ efps (6ms) +0ms (-/-%)
singleString (stringField) 99.9+ efps (5ms) 99.9+ efps (6ms) +1ms (-/-%)
synthetic (title) 58.8 efps (17ms) 66.7 efps (15ms) -2ms (-11.8%)
synthetic (string inside object) 62.5 efps (16ms) 71.4 efps (14ms) -2ms (-12.5%)

efps — editor "frames per second". The number of updates assumed to be possible within a second.

Derived from input latency. efps = 1000 / input_latency

Detailed information

🏠 Reference result

The performance result of sanity@latest

Benchmark latency p75 p90 p99 blocking time test duration
arrayI18n (simple-en) 15ms 18ms 21ms 43ms 12ms 5.7s
article (title) 21ms 28ms 38ms 61ms 25ms 7.4s
article (body) 19ms 21ms 32ms 71ms 198ms 4.9s
article (string inside object) 21ms 25ms 31ms 45ms 0ms 6.1s
article (string inside array) 18ms 19ms 22ms 48ms 0ms 6.2s
recipe (name) 10ms 14ms 29ms 68ms 0ms 5.5s
recipe (description) 19ms 21ms 26ms 34ms 0ms 4.3s
recipe (instructions) 6ms 9ms 10ms 12ms 0ms 3.0s
singleString (stringField) 5ms 8ms 11ms 21ms 0ms 4.3s
synthetic (title) 17ms 19ms 22ms 98ms 1271ms 9.1s
synthetic (string inside object) 16ms 17ms 21ms 81ms 990ms 8.4s

🧪 Experiment result

The performance result of this branch

Benchmark latency p75 p90 p99 blocking time test duration
arrayI18n (simple-en) 15ms 18ms 27ms 41ms 0ms 5.7s
article (title) 21ms 27ms 35ms 70ms 46ms 7.2s
article (body) 19ms 20ms 26ms 82ms 187ms 4.9s
article (string inside object) 20ms 24ms 41ms 54ms 0ms 6.1s
article (string inside array) 18ms 20ms 25ms 44ms 8ms 6.2s
recipe (name) 10ms 14ms 21ms 63ms 1ms 5.2s
recipe (description) 19ms 21ms 22ms 30ms 0ms 4.3s
recipe (instructions) 6ms 10ms 11ms 33ms 0ms 3.0s
singleString (stringField) 6ms 9ms 11ms 19ms 0ms 4.4s
synthetic (title) 15ms 17ms 45ms 84ms 1332ms 9.1s
synthetic (string inside object) 14ms 16ms 20ms 78ms 969ms 8.3s

📚 Glossary

column definitions

  • benchmark — the name of the test, e.g. "article", followed by the label of the field being measured, e.g. "(title)".
  • latency — the time between when a key was pressed and when it was rendered. derived from a set of samples. the median (p50) is shown to show the most common latency.
  • p75 — the 75th percentile of the input latency in the test run. 75% of the sampled inputs in this benchmark were processed faster than this value. this provides insight into the upper range of typical performance.
  • p90 — the 90th percentile of the input latency in the test run. 90% of the sampled inputs were faster than this. this metric helps identify slower interactions that occurred less frequently during the benchmark.
  • p99 — the 99th percentile of the input latency in the test run. only 1% of sampled inputs were slower than this. this represents the worst-case scenarios encountered during the benchmark, useful for identifying potential performance outliers.
  • blocking time — the total time during which the main thread was blocked, preventing user input and UI updates. this metric helps identify performance bottlenecks that may cause the interface to feel unresponsive.
  • test duration — how long the test run took to complete.

@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 3, 2026

Coverage Report

Status Category Percentage Covered / Total
🔵 Lines 39.63% 26104 / 65862
🔵 Statements 32.06% 33882 / 105666
🔵 Functions 28.46% 5263 / 18492
🔵 Branches 24.55% 20692 / 84279
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
packages/sanity/src/core/environment/isStaging.ts 88.88% 91.66% 100% 88.88% 14
packages/sanity/src/core/store/_legacy/authStore/createAuthStore.ts 43.85% 31.25% 56.52% 43.63% 32, 38, 49-51, 62, 66, 77-81, 91-92, 99-102, 107-113, 133-163, 198, 200, 232-341, 346
packages/sanity/src/core/store/studio-app/fetchCreateCompatibleAppId.ts 100% 88.23% 100% 100%
packages/sanity/src/core/studio/packageVersionStatus/fetchLatestVersions.ts 20.83% 25% 0% 22.72% 11-37, 45-61, 70-86
Generated in workflow #54316 for commit 79e8387 by the Vitest Coverage Report Action

Copy link
Copy Markdown
Member

@bjoerge bjoerge left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants