2929 default : ' 60s'
3030 type : string
3131 connections :
32- description : ' Concurrent connections/virtual users'
32+ description : ' Concurrent connections/virtual users (also used as max) '
3333 required : false
3434 default : 10
3535 type : number
36- max_connections :
37- description : ' Maximum connections/virtual users'
38- required : false
39- type : number
4036 web_concurrency :
4137 description : ' Number of Puma worker processes'
4238 required : false
4339 default : 4
4440 type : number
45- rails_max_threads :
46- description : ' Maximum number of Puma threads'
41+ rails_threads :
42+ description : ' Number of Puma threads (min and max will be same) '
4743 required : false
4844 default : 3
4945 type : number
50- rails_min_threads :
51- description : ' Minimum number of Puma threads (same as maximum if not set)'
52- required : false
53- type : number
5446 tools :
5547 description : ' Comma-separated list of tools to run'
5648 required : false
5749 default : ' fortio,vegeta,k6'
5850 type : string
51+ app_version :
52+ description : ' Which app version to benchmark'
53+ required : false
54+ default : ' both'
55+ type : choice
56+ options :
57+ - ' both'
58+ - ' core_only'
59+ - ' pro_only'
5960 push :
6061 branches :
6162 - master
7172 DURATION : ${{ github.event.inputs.duration || '30s' }}
7273 REQUEST_TIMEOUT : ${{ github.event.inputs.request_timeout || '60s' }}
7374 CONNECTIONS : ${{ github.event.inputs.connections || 10 }}
74- MAX_CONNECTIONS : ${{ github.event.inputs.max_connections || github.event.inputs. connections || 10 }}
75+ MAX_CONNECTIONS : ${{ github.event.inputs.connections || 10 }}
7576 WEB_CONCURRENCY : ${{ github.event.inputs.web_concurrency || 4 }}
76- RAILS_MAX_THREADS : ${{ github.event.inputs.rails_max_threads || 3 }}
77- RAILS_MIN_THREADS : ${{ github.event.inputs.rails_min_threads || github.event.inputs.rails_max_threads || 3 }}
77+ RAILS_MAX_THREADS : ${{ github.event.inputs.rails_threads || 3 }}
78+ RAILS_MIN_THREADS : ${{ github.event.inputs.rails_threads || 3 }}
7879 TOOLS : ${{ github.event.inputs.tools || 'fortio,vegeta,k6' }}
7980
8081jobs :
8182 benchmark :
8283 runs-on : ubuntu-latest
84+ env :
85+ REACT_ON_RAILS_PRO_LICENSE : ${{ secrets.REACT_ON_RAILS_PRO_LICENSE }}
8386
8487 steps :
8588 # ============================================
@@ -176,8 +179,8 @@ jobs:
176179 - name : Setup Ruby
177180 uses : ruby/setup-ruby@v1
178181 with :
179- ruby-version : ' 3.4 '
180- bundler : 2.5.9
182+ ruby-version : ' 3.3.7 '
183+ bundler : 2.5.4
181184
182185 - name : Fix dependency for libyaml-dev
183186 run : sudo apt install libyaml-dev -y
@@ -208,29 +211,34 @@ jobs:
208211 run : cd packages/react-on-rails && yarn install --no-progress --no-emoji --frozen-lockfile && yalc publish
209212
210213 - name : yalc add react-on-rails
214+ if : github.event.inputs.app_version != 'pro_only'
211215 run : cd spec/dummy && yalc add react-on-rails
212216
213217 - name : Install Node modules with Yarn for dummy app
218+ if : github.event.inputs.app_version != 'pro_only'
214219 run : cd spec/dummy && yarn install --no-progress --no-emoji
215220
216221 - name : Save dummy app ruby gems to cache
222+ if : github.event.inputs.app_version != 'pro_only'
217223 uses : actions/cache@v4
218224 with :
219225 path : spec/dummy/vendor/bundle
220226 key : dummy-app-gem-cache-${{ hashFiles('spec/dummy/Gemfile.lock') }}
221227
222228 - name : Install Ruby Gems for dummy app
229+ if : github.event.inputs.app_version != 'pro_only'
223230 run : |
224231 cd spec/dummy
225232 bundle lock --add-platform 'x86_64-linux'
226233 if ! bundle check --path=vendor/bundle; then
227- bundle _2.5.9_ install --path=vendor/bundle --jobs=4 --retry=3
234+ bundle _2.5.4_ install --path=vendor/bundle --jobs=4 --retry=3
228235 fi
229236
230237 - name : generate file system-based packs
231238 run : cd spec/dummy && RAILS_ENV="production" bundle exec rake react_on_rails:generate_packs
232239
233240 - name : Prepare production assets
241+ if : github.event.inputs.app_version != 'pro_only'
234242 run : |
235243 set -e # Exit on any error
236244 echo "🔨 Building production assets..."
@@ -244,6 +252,7 @@ jobs:
244252 echo "✅ Production assets built successfully"
245253
246254 - name : Start production server
255+ if : github.event.inputs.app_version != 'pro_only'
247256 run : |
248257 set -e # Exit on any error
249258 echo "🚀 Starting production server..."
@@ -268,14 +277,15 @@ jobs:
268277 exit 1
269278
270279 # ============================================
271- # STEP 5: RUN BENCHMARKS
280+ # STEP 5: RUN CORE BENCHMARKS
272281 # ============================================
273282
274- - name : Execute benchmark suite
275- timeout-minutes : 20
283+ - name : Execute Core benchmark suite
284+ if : github.event.inputs.app_version != 'pro_only'
285+ timeout-minutes : 120
276286 run : |
277287 set -e # Exit on any error
278- echo "🏃 Running benchmark suite..."
288+ echo "🏃 Running Core benchmark suite..."
279289
280290 if ! ruby spec/performance/bench.rb; then
281291 echo "❌ ERROR: Benchmark execution failed"
@@ -284,7 +294,8 @@ jobs:
284294
285295 echo "✅ Benchmark suite completed successfully"
286296
287- - name : Validate benchmark results
297+ - name : Validate Core benchmark results
298+ if : github.event.inputs.app_version != 'pro_only'
288299 run : |
289300 set -e # Exit on any error
290301 echo "🔍 Validating benchmark output files..."
@@ -322,39 +333,176 @@ jobs:
322333 echo "Continuing with available results..."
323334 fi
324335
325- # ============================================
326- # STEP 6: COLLECT BENCHMARK RESULTS
327- # ============================================
328-
329- - name : Upload benchmark results
336+ - name : Upload Core benchmark results
330337 uses : actions/upload-artifact@v4
331- if : always() # Upload even if benchmark fails
338+ if : github.event.inputs.app_version != 'pro_only' && always()
332339 with :
333- name : benchmark-results-${{ github.run_number }}
340+ name : benchmark-core- results-${{ github.run_number }}
334341 path : bench_results/
335342 retention-days : 30
336343 if-no-files-found : warn
337344
338- - name : Verify artifact upload
339- if : success()
345+ # ============================================
346+ # STEP 6: SETUP PRO APPLICATION SERVER
347+ # ============================================
348+ - name : Cache Pro package node modules
349+ if : github.event.inputs.app_version != 'core_only'
350+ uses : actions/cache@v4
351+ with :
352+ path : react_on_rails_pro/node_modules
353+ key : v4-pro-package-node-modules-cache-${{ hashFiles('react_on_rails_pro/yarn.lock') }}
354+
355+ - name : Cache Pro dummy app node modules
356+ if : github.event.inputs.app_version != 'core_only'
357+ uses : actions/cache@v4
358+ with :
359+ path : react_on_rails_pro/spec/dummy/node_modules
360+ key : v4-pro-dummy-app-node-modules-cache-${{ hashFiles('react_on_rails_pro/spec/dummy/yarn.lock') }}
361+
362+ - name : Cache Pro dummy app Ruby gems
363+ if : github.event.inputs.app_version != 'core_only'
364+ uses : actions/cache@v4
365+ with :
366+ path : react_on_rails_pro/spec/dummy/vendor/bundle
367+ key : v4-pro-dummy-app-gem-cache-${{ hashFiles('react_on_rails_pro/spec/dummy/Gemfile.lock') }}
368+
369+ - name : Install Node modules with Yarn for Pro package
370+ if : github.event.inputs.app_version != 'core_only'
371+ run : |
372+ cd react_on_rails_pro
373+ sudo yarn global add yalc
374+ yarn install --frozen-lockfile --no-progress --no-emoji
375+
376+ - name : Install Node modules with Yarn for Pro dummy app
377+ if : github.event.inputs.app_version != 'core_only'
378+ run : cd react_on_rails_pro/spec/dummy && yarn install --frozen-lockfile --no-progress --no-emoji
379+
380+ - name : Install Ruby Gems for Pro dummy app
381+ if : github.event.inputs.app_version != 'core_only'
382+ run : |
383+ cd react_on_rails_pro/spec/dummy
384+ bundle lock --add-platform 'x86_64-linux'
385+ bundle config set path vendor/bundle
386+ bundle _2.5.4_ check || bundle _2.5.4_ install --jobs=4 --retry=3
387+
388+ - name : Generate file-system based entrypoints for Pro
389+ if : github.event.inputs.app_version != 'core_only'
390+ run : cd react_on_rails_pro/spec/dummy && bundle exec rake react_on_rails:generate_packs
391+
392+ - name : Prepare Pro production assets
393+ if : github.event.inputs.app_version != 'core_only'
340394 run : |
341- echo "✅ Benchmark results uploaded as workflow artifacts"
342- echo "📦 Artifact name: benchmark-results-${{ github.run_number }}"
343- echo "🔗 Access artifacts from the Actions tab in GitHub"
395+ set -e
396+ echo "🔨 Building Pro production assets..."
397+ cd react_on_rails_pro/spec/dummy
398+
399+ if ! bin/prod-assets; then
400+ echo "❌ ERROR: Failed to build production assets"
401+ exit 1
402+ fi
403+
404+ echo "✅ Production assets built successfully"
405+
406+ - name : Start Pro production server
407+ if : github.event.inputs.app_version != 'core_only'
408+ run : |
409+ set -e
410+ echo "🚀 Starting Pro production server..."
411+ cd react_on_rails_pro/spec/dummy
412+
413+ # Start server in background
414+ bin/prod &
415+ echo "Server started in background"
416+
417+ # Wait for server to be ready (max 30 seconds)
418+ echo "⏳ Waiting for server to be ready..."
419+ for i in {1..30}; do
420+ if curl -fsS http://localhost:3001 > /dev/null; then
421+ echo "✅ Server is ready and responding"
422+ exit 0
423+ fi
424+ echo " Attempt $i/30: Server not ready yet..."
425+ sleep 1
426+ done
427+
428+ echo "❌ ERROR: Server failed to start within 30 seconds"
429+ exit 1
344430
345431 # ============================================
346- # WORKFLOW COMPLETION
432+ # STEP 7: RUN PRO BENCHMARKS
347433 # ============================================
348434
435+ - name : Execute Pro benchmark suite
436+ if : github.event.inputs.app_version != 'core_only'
437+ timeout-minutes : 120
438+ run : |
439+ set -e
440+ echo "🏃 Running Pro benchmark suite..."
441+
442+ if ! PRO=true ruby spec/performance/bench.rb; then
443+ echo "❌ ERROR: Benchmark execution failed"
444+ exit 1
445+ fi
446+
447+ echo "✅ Benchmark suite completed successfully"
448+
449+ - name : Validate Pro benchmark results
450+ if : github.event.inputs.app_version != 'core_only'
451+ run : |
452+ set -e
453+ echo "🔍 Validating Pro benchmark output files..."
454+
455+ RESULTS_DIR="bench_results"
456+ REQUIRED_FILES=("summary.txt")
457+ MISSING_FILES=()
458+
459+ if [ ! -d "${RESULTS_DIR}" ]; then
460+ echo "❌ ERROR: Benchmark results directory '${RESULTS_DIR}' not found"
461+ exit 1
462+ fi
463+
464+ echo "Generated files:"
465+ ls -lh ${RESULTS_DIR}/ || true
466+ echo ""
467+
468+ for file in "${REQUIRED_FILES[@]}"; do
469+ if [ ! -f "${RESULTS_DIR}/${file}" ]; then
470+ MISSING_FILES+=("${file}")
471+ fi
472+ done
473+
474+ if [ ${#MISSING_FILES[@]} -eq 0 ]; then
475+ echo "✅ All required benchmark output files present"
476+ echo "📊 Summary preview:"
477+ head -20 ${RESULTS_DIR}/summary.txt || true
478+ else
479+ echo "⚠️ WARNING: Some required files are missing:"
480+ printf ' - %s\n' "${MISSING_FILES[@]}"
481+ echo "Continuing with available results..."
482+ fi
483+
484+ - name : Upload Pro benchmark results
485+ uses : actions/upload-artifact@v4
486+ if : github.event.inputs.app_version != 'core_only' && always()
487+ with :
488+ name : benchmark-pro-results-${{ github.run_number }}
489+ path : bench_results/
490+ retention-days : 30
491+ if-no-files-found : warn
492+
493+ # ============================================
494+ # STEP 8: WORKFLOW COMPLETION
495+ # ============================================
349496 - name : Workflow summary
350497 if : always()
351498 run : |
352499 echo "📋 Benchmark Workflow Summary"
353- echo "=============================="
500+ echo "==================================== "
354501 echo "Status: ${{ job.status }}"
355502 echo "Run number: ${{ github.run_number }}"
356503 echo "Triggered by: ${{ github.actor }}"
357504 echo "Branch: ${{ github.ref_name }}"
505+ echo "App version: ${{ github.event.inputs.app_version || 'both' }}"
358506 echo ""
359507 if [ "${{ job.status }}" == "success" ]; then
360508 echo "✅ All steps completed successfully"
0 commit comments