Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
15 changes: 15 additions & 0 deletions .github/workflows/rspec_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ jobs:
DRIVER: selenium_chrome
CHROME_BIN: /usr/bin/google-chrome
USE_COVERALLS: true
RENDERER_PASSWORD: devPassword
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Security: hardcoded secret in plain text

devPassword is committed in the clear. Anyone who reads this repo can authenticate directly to the node renderer if it were ever accidentally exposed. Use a GitHub Actions secret instead:

Suggested change
RENDERER_PASSWORD: devPassword
RENDERER_PASSWORD: ${{ secrets.RENDERER_PASSWORD }}

Add a RENDERER_PASSWORD secret to the repository settings (Settings → Secrets → Actions) with any value for the test environment.


steps:
- name: Install Chrome
Expand Down Expand Up @@ -82,6 +83,20 @@ jobs:
- name: Build shakapacker chunks
run: NODE_ENV=development bundle exec bin/shakapacker

- name: Start Node renderer for SSR
run: |
node react-on-rails-pro-node-renderer.js &
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

CI: Node renderer output is discarded, making failures undiagnosable

The background process started with & sends both stdout and stderr to /dev/null (GitHub Actions default for backgrounded steps). If the renderer crashes between the TCP readiness check and the rspec run — or logs a startup warning that points to a misconfiguration — there's no way to see it.

Suggested change
node react-on-rails-pro-node-renderer.js &
nohup node react-on-rails-pro-node-renderer.js > node-renderer.log 2>&1 &

Then add a log dump on failure:

          echo "Node renderer failed to start within 30 seconds"
          echo "--- node-renderer.log ---"
          cat node-renderer.log || true
          exit 1

This preserves renderer output for the failure case without adding noise to successful runs.

echo "Waiting for Node renderer on port 3800..."
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

CI reliability: nc may not be installed

nc (netcat) is not present on all GitHub-hosted Ubuntu runners by default. If the runner image doesn't include it, the check silently fails (nc not found → 2>/dev/null swallows the error → loop runs to timeout).

Use Bash's built-in /dev/tcp instead, which is always available:

Suggested change
echo "Waiting for Node renderer on port 3800..."
if bash -c '</dev/tcp/localhost/3800' 2>/dev/null; then

for i in $(seq 1 30); do
if nc -z localhost 3800 2>/dev/null; then
echo "Node renderer is ready"
exit 0
fi
sleep 1
done
echo "Node renderer failed to start within 30 seconds"
exit 1

- name: Run rspec with xvfb
uses: coactions/setup-xvfb@v1
with:
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ client/app/bundles/comments/rescript/**/*.bs.js
# Using React on Rails default directory
/ssr-generated/

# Node renderer bundle cache
.node-renderer-bundles/

# Generated React on Rails packs
**/generated/**

Expand Down
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" }

ruby "3.4.6"

gem "react_on_rails", "16.6.0.rc.0"
gem "react_on_rails_pro", "16.6.0.rc.0"
gem "shakapacker", "10.0.0.rc.0"

# Bundle edge Rails instead: gem "rails", github: "rails/rails"
Expand Down
164 changes: 98 additions & 66 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,68 +1,68 @@
GEM
remote: https://rubygems.org/
specs:
action_text-trix (2.1.17)
action_text-trix (2.1.18)
railties
actioncable (8.1.2)
actionpack (= 8.1.2)
activesupport (= 8.1.2)
actioncable (8.1.3)
actionpack (= 8.1.3)
activesupport (= 8.1.3)
nio4r (~> 2.0)
websocket-driver (>= 0.6.1)
zeitwerk (~> 2.6)
actionmailbox (8.1.2)
actionpack (= 8.1.2)
activejob (= 8.1.2)
activerecord (= 8.1.2)
activestorage (= 8.1.2)
activesupport (= 8.1.2)
actionmailbox (8.1.3)
actionpack (= 8.1.3)
activejob (= 8.1.3)
activerecord (= 8.1.3)
activestorage (= 8.1.3)
activesupport (= 8.1.3)
mail (>= 2.8.0)
actionmailer (8.1.2)
actionpack (= 8.1.2)
actionview (= 8.1.2)
activejob (= 8.1.2)
activesupport (= 8.1.2)
actionmailer (8.1.3)
actionpack (= 8.1.3)
actionview (= 8.1.3)
activejob (= 8.1.3)
activesupport (= 8.1.3)
mail (>= 2.8.0)
rails-dom-testing (~> 2.2)
actionpack (8.1.2)
actionview (= 8.1.2)
activesupport (= 8.1.2)
actionpack (8.1.3)
actionview (= 8.1.3)
activesupport (= 8.1.3)
nokogiri (>= 1.8.5)
rack (>= 2.2.4)
rack-session (>= 1.0.1)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
useragent (~> 0.16)
actiontext (8.1.2)
actiontext (8.1.3)
action_text-trix (~> 2.1.15)
actionpack (= 8.1.2)
activerecord (= 8.1.2)
activestorage (= 8.1.2)
activesupport (= 8.1.2)
actionpack (= 8.1.3)
activerecord (= 8.1.3)
activestorage (= 8.1.3)
activesupport (= 8.1.3)
globalid (>= 0.6.0)
nokogiri (>= 1.8.5)
actionview (8.1.2)
activesupport (= 8.1.2)
actionview (8.1.3)
activesupport (= 8.1.3)
builder (~> 3.1)
erubi (~> 1.11)
rails-dom-testing (~> 2.2)
rails-html-sanitizer (~> 1.6)
activejob (8.1.2)
activesupport (= 8.1.2)
activejob (8.1.3)
activesupport (= 8.1.3)
globalid (>= 0.3.6)
activemodel (8.1.2)
activesupport (= 8.1.2)
activerecord (8.1.2)
activemodel (= 8.1.2)
activesupport (= 8.1.2)
activemodel (8.1.3)
activesupport (= 8.1.3)
activerecord (8.1.3)
activemodel (= 8.1.3)
activesupport (= 8.1.3)
timeout (>= 0.4.0)
activestorage (8.1.2)
actionpack (= 8.1.2)
activejob (= 8.1.2)
activerecord (= 8.1.2)
activesupport (= 8.1.2)
activestorage (8.1.3)
actionpack (= 8.1.3)
activejob (= 8.1.3)
activerecord (= 8.1.3)
activesupport (= 8.1.3)
marcel (~> 1.0)
activesupport (8.1.2)
activesupport (8.1.3)
base64
bigdecimal
concurrent-ruby (~> 1.0, >= 1.3.1)
Expand All @@ -75,14 +75,20 @@ GEM
securerandom (>= 0.3)
tzinfo (~> 2.0, >= 2.0.5)
uri (>= 0.13.1)
addressable (2.8.7)
public_suffix (>= 2.0.2, < 7.0)
addressable (2.9.0)
public_suffix (>= 2.0.2, < 8.0)
ast (2.4.3)
async (2.39.0)
console (~> 1.29)
fiber-annotation
io-event (~> 1.11)
metrics (~> 0.12)
traces (~> 0.18)
autoprefixer-rails (10.4.16.0)
execjs (~> 2)
awesome_print (1.9.2)
base64 (0.3.0)
bigdecimal (4.0.1)
bigdecimal (4.1.1)
bindex (0.8.1)
binding_of_caller (1.0.1)
debug_inspector (>= 1.2.0)
Expand Down Expand Up @@ -115,6 +121,10 @@ GEM
coffee-script-source (1.12.2)
concurrent-ruby (1.3.6)
connection_pool (3.0.2)
console (1.34.3)
fiber-annotation
fiber-local (~> 1.1)
json
coveralls_reborn (0.25.0)
simplecov (>= 0.18.1, < 0.22.0)
term-ansicolor (~> 1.6)
Expand All @@ -138,24 +148,32 @@ GEM
erb (6.0.2)
erubi (1.13.1)
erubis (2.7.0)
execjs (2.10.0)
execjs (2.10.1)
factory_bot (6.4.6)
activesupport (>= 5.0.0)
factory_bot_rails (6.4.3)
factory_bot (~> 6.4)
railties (>= 5.0.0)
ffi (1.17.2-arm64-darwin)
ffi (1.17.2-x86_64-linux-gnu)
fiber-annotation (0.2.0)
fiber-local (1.1.0)
fiber-storage
fiber-storage (1.0.1)
foreman (0.88.1)
generator_spec (0.10.0)
activesupport (>= 3.0.0)
railties (>= 3.0.0)
globalid (1.3.0)
activesupport (>= 6.1)
http-2 (1.1.3)
httpx (1.7.5)
http-2 (>= 1.1.3)
i18n (1.14.8)
concurrent-ruby (~> 1.0)
interception (0.5)
io-console (0.8.2)
io-event (1.15.1)
irb (1.17.0)
pp (>= 0.6.0)
prism (>= 1.3.0)
Expand All @@ -164,7 +182,9 @@ GEM
jbuilder (2.12.0)
actionview (>= 5.0.0)
activesupport (>= 5.0.0)
json (2.19.1)
json (2.19.3)
jwt (2.10.2)
base64
language_server-protocol (3.17.0.5)
launchy (3.0.1)
addressable (~> 2.8)
Expand All @@ -182,8 +202,9 @@ GEM
marcel (1.1.0)
matrix (0.4.2)
method_source (1.1.0)
metrics (0.15.0)
mini_mime (1.1.5)
minitest (6.0.2)
minitest (6.0.3)
drb (~> 2.0)
prism (~> 1.5)
mize (0.4.1)
Expand All @@ -199,9 +220,9 @@ GEM
net-smtp (0.5.1)
net-protocol
nio4r (2.7.5)
nokogiri (1.19.1-arm64-darwin)
nokogiri (1.19.2-arm64-darwin)
racc (~> 1.4)
nokogiri (1.19.1-x86_64-linux-gnu)
nokogiri (1.19.2-x86_64-linux-gnu)
racc (~> 1.4)
package_json (0.2.0)
parallel (1.27.0)
Expand All @@ -212,7 +233,7 @@ GEM
pp (0.6.3)
prettyprint
prettyprint (0.2.0)
prism (1.5.1)
prism (1.9.0)
protocol (2.0.0)
ruby_parser (~> 3.0)
pry (0.14.2)
Expand All @@ -235,11 +256,11 @@ GEM
psych (5.3.1)
date
stringio
public_suffix (6.0.2)
public_suffix (7.0.5)
puma (6.4.2)
nio4r (~> 2.0)
racc (1.8.1)
rack (3.2.5)
rack (3.2.6)
rack-proxy (0.7.7)
rack
rack-session (2.1.1)
Expand All @@ -249,20 +270,20 @@ GEM
rack (>= 1.3)
rackup (2.3.1)
rack (>= 3)
rails (8.1.2)
actioncable (= 8.1.2)
actionmailbox (= 8.1.2)
actionmailer (= 8.1.2)
actionpack (= 8.1.2)
actiontext (= 8.1.2)
actionview (= 8.1.2)
activejob (= 8.1.2)
activemodel (= 8.1.2)
activerecord (= 8.1.2)
activestorage (= 8.1.2)
activesupport (= 8.1.2)
rails (8.1.3)
actioncable (= 8.1.3)
actionmailbox (= 8.1.3)
actionmailer (= 8.1.3)
actionpack (= 8.1.3)
actiontext (= 8.1.3)
actionview (= 8.1.3)
activejob (= 8.1.3)
activemodel (= 8.1.3)
activerecord (= 8.1.3)
activestorage (= 8.1.3)
activesupport (= 8.1.3)
bundler (>= 1.15.0)
railties (= 8.1.2)
railties (= 8.1.3)
rails-dom-testing (2.3.0)
activesupport (>= 5.0.0)
minitest
Expand All @@ -278,9 +299,9 @@ GEM
json
require_all (~> 3.0)
ruby-progressbar
railties (8.1.2)
actionpack (= 8.1.2)
activesupport (= 8.1.2)
railties (8.1.3)
actionpack (= 8.1.3)
activesupport (= 8.1.3)
irb (~> 1.13)
rackup (>= 1.0.0)
rake (>= 12.2)
Expand All @@ -303,6 +324,16 @@ GEM
rails (>= 5.2)
rainbow (~> 3.0)
shakapacker (>= 6.0)
react_on_rails_pro (16.6.0.rc.0)
addressable
async (>= 2.29)
connection_pool
execjs (~> 2.9)
http-2 (>= 1.1.1)
httpx (~> 1.5)
jwt (~> 2.7)
rainbow
react_on_rails (= 16.6.0.rc.0)
redcarpet (3.6.0)
redis (5.3.0)
redis-client (>= 0.22.0)
Expand Down Expand Up @@ -425,6 +456,7 @@ GEM
tins (1.33.0)
bigdecimal
sync
traces (0.18.2)
tsort (0.2.0)
turbo-rails (2.0.11)
actionpack (>= 6.0.0)
Expand Down Expand Up @@ -486,7 +518,7 @@ DEPENDENCIES
rails-html-sanitizer
rails_best_practices
rainbow
react_on_rails (= 16.6.0.rc.0)
react_on_rails_pro (= 16.6.0.rc.0)
redcarpet
redis (~> 5.0)
rspec-rails (~> 6.0.0)
Expand Down
4 changes: 4 additions & 0 deletions Procfile.dev
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,7 @@ rails: bundle exec thrust bin/rails server -p 3000
wp-client: RAILS_ENV=development NODE_ENV=development bin/shakapacker-dev-server
# Server Rspack watcher for SSR bundle
wp-server: SERVER_BUNDLE_ONLY=yes bin/shakapacker --watch
# RSC Rspack watcher for React Server Components bundle
wp-rsc: RSC_BUNDLE_ONLY=true bin/shakapacker --watch
# React on Rails Pro Node renderer for SSR and RSC payload generation
node-renderer: node react-on-rails-pro-node-renderer.js
2 changes: 2 additions & 0 deletions app/controllers/pages_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ def simple; end

def rescript; end

def server_components; end

private

def set_comments
Expand Down
6 changes: 6 additions & 0 deletions app/views/pages/server_components.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<%= append_javascript_pack_tag('rsc-client-components') %>
<%= react_component("ServerComponentsPage",
prerender: false,
auto_load_bundle: false,
trace: Rails.env.development?,
id: "ServerComponentsPage-react-component-0") %>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hardcoded DOM id can cause collisions and is fragile

"ServerComponentsPage-react-component-0" mirrors React on Rails' auto-generated ID pattern. If the framework's ID generation logic changes, or if this component is ever rendered more than once on a page, this will silently conflict with the framework-assigned ID — potentially causing hydration failures or duplicate-ID accessibility violations.

Suggested change
id: "ServerComponentsPage-react-component-0") %>
trace: Rails.env.development?) %>

Unless there is a specific reason the RSC payload route needs to target this exact id (in which case that dependency should be documented), let the framework generate it.

Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
'use client';

import React from 'react';
import PropTypes from 'prop-types';
import BaseComponent from 'libs/components/BaseComponent';
Expand Down
Loading
Loading