Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
42a211c
feat: add pre_seed_renderer_cache rake task for Docker builds
justin808 Apr 12, 2026
4cf80db
fix: address PR review feedback for pre_seed_renderer_cache
justin808 Apr 13, 2026
ce54137
fix: extract shared cache dir resolution and fix spurious deprecation…
justin808 Apr 13, 2026
c192130
fix: add regression test and fix test teardown for pre_seed_renderer_…
justin808 Apr 13, 2026
9bd5c9a
fix: add once-per-process guard for deprecation warning and spec comment
justin808 Apr 13, 2026
5261cb7
fix: address remaining review feedback for pre_seed_renderer_cache
justin808 Apr 13, 2026
8e71646
fix: raise on missing RSC manifests, clarify docs and comments
justin808 Apr 13, 2026
e5451da
fix: stub RSC manifests to real files so test reaches bundle-not-foun…
justin808 Apr 13, 2026
06644cc
Align renderer cache staging with bundle hashes
justin808 Apr 15, 2026
701c064
fix: address final review feedback for renderer cache staging
justin808 Apr 18, 2026
84e8201
refactor: extract shared renderer-cache helpers, thread-safe deprecat…
justin808 Apr 18, 2026
7448145
fix: validate bundle path before hash computation, and harden paths
justin808 Apr 18, 2026
c15d6a9
Harden preseed renderer cache assets
justin808 Apr 23, 2026
0332ac5
test: assert renderer cache manifest symlinks
justin808 Apr 29, 2026
195f535
refactor: unify renderer cache staging with mode: :copy / :symlink (#…
justin808 Apr 29, 2026
5423458
refactor(pro): tighten renderer cache helpers from review
justin808 Apr 29, 2026
4b4601b
refactor(pro): address renderer cache review feedback
justin808 Apr 29, 2026
cd307fc
refactor(pro): polish renderer cache from review round 4
justin808 Apr 30, 2026
9b7b510
refactor(pro): guard blank bundle hash and drop dead .dup
justin808 May 3, 2026
7607d7f
Add /stress-test Claude Code command for adversarial QA (#3207)
AbanoubGhadban Apr 30, 2026
94f4896
feat: add rolling_deploy_adapter for seeding previous bundle hashes
justin808 Apr 18, 2026
94ef776
fix: address PR C review feedback for rolling_deploy_adapter
justin808 Apr 18, 2026
0cef59d
fix: address remaining PR C review feedback (security, robustness, docs)
justin808 Apr 18, 2026
a1f2398
Avoid hangs and path escape in rolling deploy seeding
justin808 Apr 18, 2026
daadf59
fix: harden rolling deploy adapter follow-ups
justin808 Apr 19, 2026
84168f3
fix: address rolling-deploy adapter follow-up review feedback
justin808 Apr 19, 2026
3afe5a4
Harden rolling deploy follow-up fixes
justin808 Apr 23, 2026
463412f
Clarify rolling deploy shared assets
justin808 Apr 23, 2026
f3d6864
Harden rolling deploy review follow-ups
justin808 Apr 23, 2026
ca196b4
Harden rolling deploy cache staging cleanup
justin808 Apr 23, 2026
6cc7cf5
Tighten rolling deploy upload signature validation
justin808 Apr 23, 2026
861a54d
Reject extra required rolling deploy upload keywords
justin808 Apr 23, 2026
27df7e1
Tighten rolling deploy staging review fixes
justin808 Apr 23, 2026
98cfccc
Harden rolling deploy asset staging
justin808 Apr 23, 2026
af8f57c
Harden rolling deploy adapter edge cases
justin808 Apr 23, 2026
9c6db5f
Harden rolling deploy adapter validation
justin808 Apr 23, 2026
6a59810
Polish rolling deploy review follow-ups
justin808 Apr 29, 2026
b3a5f8d
Polish rolling deploy review follow-ups (round 2)
justin808 Apr 29, 2026
776eb28
Reject *args + explicit keywords in rolling_deploy upload signature
justin808 Apr 30, 2026
4601a4a
Polish rolling deploy review follow-ups (round 3)
justin808 Apr 30, 2026
f78d4b4
Exclude two more flaky GitHub URLs from markdown link check
justin808 Apr 30, 2026
112c4a7
Harden rolling deploy staging diagnostics
justin808 Apr 30, 2026
6496fdc
Polish rolling deploy review follow-ups (round 4)
justin808 Apr 30, 2026
3fb63c0
Polish rolling deploy review follow-ups (round 5)
justin808 May 3, 2026
21df338
Merge base branch and address review feedback
justin808 May 4, 2026
9122a52
Merge latest base and stabilize link checks
justin808 May 4, 2026
34cda42
Polish rolling deploy review follow-ups (round 6)
justin808 May 5, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .lychee.toml
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,13 @@ exclude = [
'^https://storybook\.js\.org', # Intermittent connection resets from CI
'^https://redux\.js\.org/?$', # Intermittent connection resets from CI
'^https://angularjs\.org/?$', # Connection failed from CI
'^https://eslint\.org/?$', # Intermittent connection resets from CI
'^https://frigade\.com/blog/bundle-size-reduction-with-rsc-and-frigade/?$', # Connection failed from CI
'^https://tanstack\.com/router', # Connection failed from CI
'^https://lodash\.com', # Connection reset from CI
'^https://vite-ruby\.netlify\.app/?$', # Intermittent connection resets from CI
'^https://vite\.dev/?$', # Intermittent connection failures from CI
'^https://vite\.dev/guide/?$', # Intermittent connection failures from CI

# ============================================================================
# PLANNED DEPLOYMENTS NOT YET LIVE
Expand Down Expand Up @@ -113,6 +116,8 @@ exclude = [
'^https://github\.com/shakacode/react_on_rails/compare/',
'^https://github\.com/shakacode/react_on_rails/pull/[0-9]+$', # Intermittent 5xx from GitHub PR pages in CI
'^https://github\.com/shakacode/shakapacker/blob/cdf32835d3e0949952b8b4b53063807f714f9b24/package/environments/base\.js(#.*)?$', # Intermittent 502 from GitHub blob view in CI
'^https://github\.com/K4sku$', # Intermittent 502 from GitHub user page in CI
'^https://github\.com/dzirtusss$', # Intermittent 502 from GitHub user page in CI

# ============================================================================
# DELETED GITHUB USER ACCOUNTS (return 502/404 from CI)
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,11 @@ After a release, run `/update-changelog` in Claude Code to analyze commits, writ

- **[Pro]** **Pre-seed renderer cache for Docker builds**: New `react_on_rails_pro:pre_seed_renderer_cache` rake task copies compiled server bundles into the Node Renderer's bundle-hash cache directory structure during Docker image builds, eliminating the 410→retry cold-start latency (200ms–1s+) on the first SSR request after deployment. Supports `RENDERER_SERVER_BUNDLE_CACHE_PATH`, RSC bundles, and rolling-deploy guidance centered on current and previous bundle hashes. The legacy `pre_stage_bundle_for_node_renderer` task now stages the same cache layout via symlinks for same-filesystem workflows. **Note:** `RENDERER_BUNDLE_PATH` is now deprecated in favor of `RENDERER_SERVER_BUNDLE_CACHE_PATH` across both tasks. Existing users with `RENDERER_BUNDLE_PATH` set will see a deprecation warning on stderr. [PR 3124](https://github.com/shakacode/react_on_rails/pull/3124) by [justin808](https://github.com/justin808).

- **[Pro]** **Rolling-deploy adapter protocol**: New `config.rolling_deploy_adapter` pluggable module (protocol: `previous_bundle_hashes`, `fetch`, `upload`) that seeds previously-deployed bundle hashes into the Node Renderer cache, preventing 410→retry for draining-version requests during rolling deploys. `assets:precompile` auto-calls `upload` in production-like environments so the next deploy can fetch the just-built bundle. `PREVIOUS_BUNDLE_HASHES` env var overrides discovery for CI. `react_on_rails:doctor` probes the adapter and reports protocol conformance, discovery latency, and resolved cache dir. Each seeded hash carries its own `loadable-stats.json` / RSC manifests so client-side hydration stays consistent with the deployed asset pipeline for that hash. See `docs/pro/rolling-deploy-adapters.md` for the full protocol spec and reference implementations (S3, Control Plane, Filesystem).

#### Changed

- **[Pro]** **`PreSeedRendererCache` and `PrepareNodeRenderBundles` now auto-stage `loadable-stats.json`**: `ReactOnRailsPro::RendererCacheHelpers.collect_assets` now appends `loadable-stats.json` whenever the file exists on disk, so every caller (rolling-deploy seeding, `pre_seed_renderer_cache`, `pre_stage_bundle_for_node_renderer`) stages it automatically. **Action required for upgraders:** if your `assets_to_copy` config explicitly listed `loadable-stats.json`, remove that entry — otherwise you'll see a "Duplicate asset basenames in assets_to_copy" warning on every stage. The duplicate is harmless (`stage_assets` keeps the last entry per basename), but the warning is noise.
- **[Pro]** **Unified renderer cache staging**: `ReactOnRailsPro::PreSeedRendererCache.call(mode: :copy | :symlink)` is now the single entry point for staging the Node Renderer cache. Both modes produce the same `<cache>/<bundleHash>/<bundleHash>.js` layout. The `react_on_rails_pro:pre_seed_renderer_cache` rake task accepts `MODE=copy` (default; Docker/image builds) or `MODE=symlink` (same-filesystem). `MODE=copy` now raises a clear error when neither `RENDERER_SERVER_BUNDLE_CACHE_PATH` nor `RENDERER_BUNDLE_PATH` is set in non-dev/test environments, because the Node renderer's default lookup can differ from the Ruby side and would silently drop pre-seeded bundles in the wrong directory. The legacy `react_on_rails_pro:pre_stage_bundle_for_node_renderer` task and `ReactOnRailsPro::PrepareNodeRenderBundles` class remain as deprecated shims that emit a once-per-process warning and delegate to `mode: :symlink`. `react_on_rails:doctor` flags deploy scripts that still reference the deprecated task. [PR 3167](https://github.com/shakacode/react_on_rails/pull/3167) by [justin808](https://github.com/justin808).
- **[Pro]** **Pro generator now creates the Node Renderer at `renderer/node-renderer.js`**: The canonical location for the Node Renderer entry point is now a dedicated top-level `renderer/` directory instead of `client/`, making it straightforward to exclude from production Docker builds that strip JS sources after bundling. Docs and Pro `spec/dummy` now use the new path consistently. Existing apps are unaffected — the generator skips files that already exist (including a legacy `client/node-renderer.js`). Fixes [Issue 3073](https://github.com/shakacode/react_on_rails/issues/3073). [PR 3165](https://github.com/shakacode/react_on_rails/pull/3165) by [justin808](https://github.com/justin808).

Expand Down
23 changes: 16 additions & 7 deletions docs/pro/node-renderer.md
Original file line number Diff line number Diff line change
Expand Up @@ -163,19 +163,28 @@ RUN bundle exec rake react_on_rails_pro:pre_seed_renderer_cache

### Rolling deploys: seed current and previous bundle hashes

During a rolling deploy, new renderer instances can receive requests for both the current deployed bundle hash and the previous hash while old Rails instances drain. Treat this as a two-hash cache-seeding problem, not a single-file problem.
During a rolling deploy, new renderer instances can receive requests for both the current deployed bundle hash and the previous hash while old Rails instances drain. Treat this as a two-hash cache-seeding problem, not a single-file problem — and each seeded hash must carry its own companion `loadable-stats.json` / RSC manifests built in lockstep with that bundle.

At startup, aim to have the cache contain:
`pre_seed_renderer_cache` handles the current bundle. For previous hashes, configure a **`rolling_deploy_adapter`** that:

- the current server bundle hash
- the previous server bundle hash
- the current and previous RSC bundle hashes as well, if RSC support is enabled
- any required copied assets and RSC manifests in each seeded hash directory
- Publishes each successful deploy's bundle + companion assets to an artifact store (S3, Control Plane image registry, etc.) via its `upload` method — called automatically after `assets:precompile` in production-like environments.
- Advertises recent deploys' bundle hashes via `previous_bundle_hashes`.
- Retrieves the bundle + assets for a given historical hash via `fetch`.

`pre_seed_renderer_cache` seeds the current locally built bundle outputs. For the previous deployed hash, the most practical approach is to publish bundle artifacts keyed by hash after each successful deploy, then fetch the previous hash artifact during the next build and place it into the same `<cache>/<bundleHash>/...` layout before boot.
```ruby
# config/initializers/react_on_rails_pro.rb
ReactOnRailsPro.configure do |config|
config.rolling_deploy_adapter = MyApp::S3RollingDeployAdapter
end
```

During the next build, `pre_seed_renderer_cache` calls `previous_bundle_hashes`, deduplicates against the current hash, then fetches and stages each into `<cache>/<bundleHash>/...` — preventing 410→retry for draining-version requests.

See [Rolling-Deploy Adapters](./rolling-deploy-adapters.md) for the full protocol spec, reference implementations (S3, Control Plane, Filesystem), and a discussion of the loadable-stats wrinkle.

## Further Reading

- [Rolling-Deploy Adapters](./rolling-deploy-adapters.md) — Protocol spec and reference implementations for `rolling_deploy_adapter`
- [Node Renderer basics](../oss/building-features/node-renderer/basics.md) — Architecture and core concepts
- [JavaScript configuration](../oss/building-features/node-renderer/js-configuration.md) — Node-side config options
- [Error reporting and tracing](../oss/building-features/node-renderer/error-reporting-and-tracing.md) — Monitoring in production
Expand Down
Loading
Loading