Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
127 commits
Select commit Hold shift + click to select a range
c4f772e
Add additional question text fields to form parameters
rileyseaburg Sep 2, 2025
bece872
Refactor Gemfile: remove duplicate gems and clean up comments
rileyseaburg Sep 2, 2025
127d6dd
Refactor FormsController: replace individual question text parameters…
rileyseaburg Sep 2, 2025
d75246c
Add test script for dynamic question parameter generation
rileyseaburg Sep 2, 2025
ca46af3
Replace unprocessable_entity with unprocessable_content status codes
rileyseaburg Sep 2, 2025
22df7b4
Update Ruby version and dependencies in Gemfile and Gemfile.lock; adj…
rileyseaburg Sep 2, 2025
d8db7b1
Fix tzinfo-data gem platform specification for Windows compatibility
rileyseaburg Sep 2, 2025
1519ea8
Update action cable, mailbox, mailer, pack, text, view, job, model, r…
rileyseaburg Sep 3, 2025
f9e91dd
Update Ruby version in CircleCI configuration to 3.4.5
rileyseaburg Sep 3, 2025
f9f726b
Add .ruby-version file specifying Ruby version 3.4.5
rileyseaburg Sep 4, 2025
5d59088
Change response status from unprocessable_entity to unprocessable_con…
rileyseaburg Sep 4, 2025
d46f9be
Change response status from unprocessable_content to unprocessable_en…
rileyseaburg Sep 10, 2025
8ccedcf
Downgrade Ruby version from 3.4.5 to 3.2.8
rileyseaburg Sep 10, 2025
0869a38
Add Rust-based widget renderer for performance optimization
rileyseaburg Oct 29, 2025
e56a9ba
Downgrade Ruby version from 3.4.7 to 3.2.8 in Gemfile
rileyseaburg Oct 29, 2025
d70eba2
Update config.yml
rileyseaburg Oct 29, 2025
b0f1e10
Update Gemfile
rileyseaburg Oct 29, 2025
8914d6e
Update form.rb
rileyseaburg Oct 29, 2025
7294149
Update form_data.rs
rileyseaburg Oct 29, 2025
a9e2849
Upgrade Ruby version from 3.2.8 to 3.4.7 in .ruby-version and Gemfile
rileyseaburg Oct 30, 2025
344b7f5
feat: Add Rust widget renderer with 12.1x performance improvement
rileyseaburg Nov 4, 2025
b7e9d93
security: Fix CSRF vulnerability in benchmark controller
rileyseaburg Nov 4, 2025
c618186
Update process.yml
rileyseaburg Nov 4, 2025
1f894a8
feat: Add ERB direct render benchmark for accurate comparison
rileyseaburg Nov 4, 2025
ed9d065
Fix Rust syntax errors in template_renderer.rs
rileyseaburg Nov 4, 2025
ef922fd
Fix widget rendering test failures by providing request context
rileyseaburg Nov 5, 2025
51ba429
config: enable public file server in test environment
rileyseaburg Nov 5, 2025
28b23ed
Fix Rust widget renderer: Implement HTML body generation and JSON ser…
rileyseaburg Nov 20, 2025
689c266
Fix spec failure in forms_spec.rb and update error-fix.md
rileyseaburg Nov 20, 2025
06c3468
Fix Rust widget logo rendering and flaky admin form spec
rileyseaburg Nov 20, 2025
b70a34b
Merge pull request #1898 from GSA/feature/rust-widget-renderer
rileyseaburg Nov 20, 2025
f92d949
Add custom Rust buildpack, update manifests, and fix CSV export 500 e…
rileyseaburg Nov 20, 2025
e3a6ebe
Add gemspec and lib for widget_renderer gem
rileyseaburg Nov 20, 2025
bf136ac
Fix widget_renderer gem loading and dependencies
rileyseaburg Nov 20, 2025
2b6bf2c
Revert path change in widget_renderer.rb
rileyseaburg Nov 20, 2025
5a17716
Add robust path detection for widget_renderer library
rileyseaburg Nov 20, 2025
087321a
Add file existence check for widget_renderer library path
rileyseaburg Nov 20, 2025
87ab8a2
Fix Rutie path resolution for Cloud Foundry
rileyseaburg Nov 20, 2025
dc64737
Fix Rutie path resolution by appending dummy lib directory
rileyseaburg Nov 20, 2025
82c1c34
Add ldd debug to extconf.rb
rileyseaburg Nov 20, 2025
ea05dbe
Bump widget_renderer version to 0.1.1
rileyseaburg Nov 21, 2025
e233401
Update Gemfile.lock for widget_renderer 0.1.1
rileyseaburg Nov 21, 2025
077aaea
Add ldd debug to widget_renderer.rb
rileyseaburg Nov 21, 2025
711f520
Add file details debug to widget_renderer.rb
rileyseaburg Nov 21, 2025
0002ceb
Add target directories to .cfignore
rileyseaburg Nov 21, 2025
7e0f3ac
Explicitly build Rust extension in supply script
rileyseaburg Nov 21, 2025
1a7c15c
Add debug logging to supply script
rileyseaburg Nov 21, 2025
183aca1
Update Ruby version and buildpack config
rileyseaburg Nov 21, 2025
926d00f
Add more debug logging to widget_renderer.rb
rileyseaburg Nov 21, 2025
4e633b9
Add debug logging to extconf.rb
rileyseaburg Nov 21, 2025
c63db54
Update manifest and widget renderer initializer
rileyseaburg Nov 21, 2025
9195b1f
Fix manifest indentation
rileyseaburg Nov 21, 2025
ec30c15
Fix rust buildpack PATH export
rileyseaburg Nov 21, 2025
a23288b
Ensure PATH includes cargo for downstream buildpacks
rileyseaburg Nov 21, 2025
b4839c0
Use CARGO_HOME for Rust build and avoid PATH override
rileyseaburg Nov 21, 2025
b4e34e9
Seed PATH with cargo and node for subsequent buildpacks
rileyseaburg Nov 21, 2025
6f24ae5
Only prepend cargo bin without overriding PATH
rileyseaburg Nov 21, 2025
572f97e
Stop exporting PATH from rust buildpack supply
rileyseaburg Nov 21, 2025
d06de70
Install Node via nvm in rust buildpack supply
rileyseaburg Nov 21, 2025
af4c7f4
Use rust + ruby buildpacks only for staging
rileyseaburg Nov 21, 2025
555f654
Remove nvm install and keep PATH untouched in rust supply
rileyseaburg Nov 21, 2025
55b17d7
Run ruby buildpack before rust buildpack in staging
rileyseaburg Nov 21, 2025
d624fbb
Prepend cargo to PATH for ruby buildpack and run rust first
rileyseaburg Nov 21, 2025
8040a69
Remove cargo PATH export in rust supply
rileyseaburg Nov 21, 2025
5ecfac5
Install rust via extconf and use ruby buildpack only
rileyseaburg Nov 21, 2025
618fca9
Copy built Rust lib into extension root
rileyseaburg Nov 21, 2025
c482ff8
Attempt runtime build of widget renderer if missing
rileyseaburg Nov 21, 2025
80836cc
Build widget_renderer at runtime via profile.d hook
rileyseaburg Nov 21, 2025
1bef659
Copy widget_renderer .so into target/release and root
rileyseaburg Nov 21, 2025
209cd21
Move runtime build hook to .profile.d and keep lib copies
rileyseaburg Nov 21, 2025
e1ef470
Add GitHub Action to build Linux widget .so artifact
rileyseaburg Nov 21, 2025
cd7dc87
Run widget build action on develop, staging, production releases
rileyseaburg Nov 21, 2025
4009bf8
Enable manual dispatch for widget build workflow
rileyseaburg Nov 21, 2025
37b8b0e
Restore rust buildpack and prepend cargo for bundler
rileyseaburg Nov 21, 2025
d623261
Fix duplicate workflow_dispatch in widget build workflow
rileyseaburg Nov 21, 2025
83ba4e8
Use native rustup in widget workflow (no third-party action)
rileyseaburg Nov 21, 2025
cdadddb
Use actions-rs toolchain to install Rust in widget workflow
rileyseaburg Nov 21, 2025
b100b09
Fix artifact path format in widget workflow
rileyseaburg Nov 21, 2025
539f661
Tighten ignore for env/vars files
rileyseaburg Nov 21, 2025
bb3cd67
Look for widget artifact in workspace target dir
rileyseaburg Nov 21, 2025
8af0c02
Fix widget build script app root detection
rileyseaburg Nov 21, 2025
2db8e84
Make widget build script locate ext directory flexibly
rileyseaburg Nov 21, 2025
51bbc6a
Link rutie against shared ruby in runtime build
rileyseaburg Nov 21, 2025
36b2721
Avoid rutie static link; skip linking when building at runtime
rileyseaburg Nov 21, 2025
a80e494
Prefer cached Rust toolchain in runtime build
rileyseaburg Nov 21, 2025
2eaaf05
Ensure widget .so is included in CF bits
rileyseaburg Nov 21, 2025
6143f92
Copy shipped widget .so into target/release at runtime
rileyseaburg Nov 21, 2025
fa7dbbe
Let Rutie define WidgetRenderer (drop Ruby module wrapper)
rileyseaburg Nov 22, 2025
d598548
Load widget renderer from lib/widget_renderer
rileyseaburg Nov 22, 2025
8d0bbd1
Remove stale WidgetRenderer module before Rutie init
rileyseaburg Nov 22, 2025
936da01
Guard WidgetRenderer constant as class before Rutie init
rileyseaburg Nov 22, 2025
a23cc09
Allow app-staging host in staging manifest
rileyseaburg Nov 22, 2025
1fa69f2
Use app-staging as asset host to satisfy SRI
rileyseaburg Nov 22, 2025
c1ecb52
Scope session cookie domain via optional env
rileyseaburg Nov 22, 2025
d98161b
Point LOGIN_GOV_REDIRECT_URI to app-staging host
rileyseaburg Nov 22, 2025
9c96767
Pass question text field to Rust renderer
rileyseaburg Nov 22, 2025
faf7e69
Clean up cx collections export tests and fix service csv list
rileyseaburg Nov 22, 2025
b420feb
Merge branch 'feature/rust-widget-renderer' into develop
rileyseaburg Nov 22, 2025
4580b73
Bump Ruby to 3.4.7
rileyseaburg Nov 24, 2025
6cc6804
Build Rust widget renderer in CircleCI
rileyseaburg Nov 24, 2025
4b566d9
Use cargo build for widget renderer in CI
rileyseaburg Nov 24, 2025
8ff23e8
Coerce nil booleans before calling Rust renderer
rileyseaburg Nov 24, 2025
2dfa28e
Skip Rust widget renderer in test env to stabilize specs
rileyseaburg Nov 24, 2025
0c32cce
Default element_selector for widget renderer
rileyseaburg Nov 24, 2025
609891d
Stabilize form permissions spec expectations
rileyseaburg Nov 24, 2025
c6fe6d2
Revert Ruby target to 3.2.8 for CF buildpack
rileyseaburg Nov 24, 2025
1b0c575
Use prebuilt widget renderer .so before compiling at runtime
rileyseaburg Nov 24, 2025
b92b49b
Fix widget renderer build artifact detection
rileyseaburg Nov 24, 2025
0081849
Make widget renderer tolerate null booleans
rileyseaburg Nov 24, 2025
d48eeb4
Add logging and extra fallback for widget renderer .so in pre-start
rileyseaburg Nov 24, 2025
cf2a312
Allow widget renderer pre-start to build if no prebuilt lib
rileyseaburg Nov 24, 2025
0395cf6
Set HOME to /home/vcap before building widget renderer
rileyseaburg Nov 24, 2025
fc0ebbe
Harden widget renderer runtime build paths
rileyseaburg Nov 24, 2025
42d9cc4
Trigger CircleCI deploy
rileyseaburg Nov 24, 2025
21c7ccf
Guard CF deploy steps to a single parallel node
rileyseaburg Nov 24, 2025
16004a5
Precompile done.svg so the landing page renders
rileyseaburg Nov 24, 2025
1bea5e4
Link done.svg in manifest and clean precompile entry
rileyseaburg Nov 24, 2025
ee4a044
Allow asset fallback in staging
rileyseaburg Nov 24, 2025
4203ce3
Enable Rack::Attack middleware
rileyseaburg Nov 24, 2025
12b0b2f
Stabilize digital product create feature spec
rileyseaburg Nov 24, 2025
2e448c4
Loosen digital product path assertion
rileyseaburg Nov 24, 2025
82b503d
Avoid runtime Rust build in widget renderer
rileyseaburg Nov 24, 2025
2c78f55
Increase memory allocation to 2G for Rust widget renderer
rileyseaburg Nov 25, 2025
273f1d0
Fix SRI CORS issue by adding crossorigin attribute to asset tags
rileyseaburg Nov 25, 2025
54b8531
Add CORS headers for static assets to support SRI cross-origin requests
rileyseaburg Nov 25, 2025
2af401e
Add prebuilt Linux libwidget_renderer.so for Cloud Foundry deployment
rileyseaburg Nov 25, 2025
051deb6
Add debug logging for WidgetRenderer initialization
rileyseaburg Nov 25, 2025
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
8 changes: 8 additions & 0 deletions .cfignore
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,11 @@
/public/packs
/public/packs-test
/node_modules

# Ignore Rust build artifacts, but keep the prebuilt widget library
target/
ext/widget_renderer/target/
!ext/widget_renderer/target/
!ext/widget_renderer/target/release/
!ext/widget_renderer/target/release/libwidget_renderer.so
!ext/widget_renderer/libwidget_renderer.so
45 changes: 36 additions & 9 deletions .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,11 @@
# Check https://circleci.com/docs/2.0/language-ruby/ for more details
#
version: 2.1
orbs:
browser-tools: circleci/[email protected]

jobs:
build:
docker:
- image: cimg/ruby:3.3.4-browsers
- image: cimg/ruby:3.2.8-browsers # Matches deployed Ruby version in CF
environment:
RAILS_ENV: test
PGHOST: 127.0.0.1
Expand All @@ -27,19 +25,37 @@ jobs:
POSTGRES_USER: root
POSTGRES_DB: touchpoints_test

parallelism: 1
parallelism: 4
working_directory: ~/repo

steps:
- run:
name: Update packages
command: sudo apt-get update

- browser-tools/install-chrome: # required for selenium used by tachometer benchmark smoke tests
chrome-version: 116.0.5845.96
- run:
name: Ensure Chrome is available
command: |
# cimg/ruby:*-browsers images already include Chrome; skip orb command to avoid "Cannot find declaration" errors
echo "Using cimg/ruby:3.4.7-browsers which includes Chrome"

- checkout

- run:
name: Install Rust toolchain
command: |
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --default-toolchain stable
echo 'source $HOME/.cargo/env' >> $BASH_ENV
source $HOME/.cargo/env
rustc --version
cargo --version

- run:
name: Build widget renderer (Rust)
command: |
source $HOME/.cargo/env
cargo build --release --manifest-path ext/widget_renderer/Cargo.toml

# Download and cache dependencies
- restore_cache:
keys:
Expand Down Expand Up @@ -90,11 +106,23 @@ jobs:

- run:
name: Deploy Sidekiq worker servers
command: ./.circleci/deploy-sidekiq.sh
command: |
# Only deploy from a single parallel node to avoid concurrent CF pushes.
if [ "${CIRCLE_NODE_INDEX:-0}" != "0" ]; then
echo "Skipping Sidekiq deploy on parallel node ${CIRCLE_NODE_INDEX}"
exit 0
fi
./.circleci/deploy-sidekiq.sh

- run:
name: Deploy web server(s)
command: ./.circleci/deploy.sh
command: |
# Only deploy from a single parallel node to avoid concurrent CF pushes.
if [ "${CIRCLE_NODE_INDEX:-0}" != "0" ]; then
echo "Skipping web deploy on parallel node ${CIRCLE_NODE_INDEX}"
exit 0
fi
./.circleci/deploy.sh

cron_tasks:
docker:
Expand All @@ -112,7 +140,6 @@ jobs:
command: ./.circleci/cron.sh

workflows:
version: 2
daily_workflow:
triggers:
- schedule:
Expand Down
52 changes: 52 additions & 0 deletions .github/workflows/build-widget.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
name: Build Rust Widget

on:
push:
branches:
- main
- develop
- staging
tags:
- 'production-*'
release:
types: [published]
workflow_dispatch:

jobs:
build-widget:
runs-on: ubuntu-22.04
steps:
- name: Checkout
uses: actions/checkout@v4

- name: Set up Rust (stable)
uses: actions-rs/toolchain@v1
with:
toolchain: stable
override: true

- name: Build widget (Linux .so)
working-directory: ext/widget_renderer
run: cargo build --release

- name: Prepare artifact for CF
run: |
set -euo pipefail
mkdir -p ext/widget_renderer/target/release target/release
artifact=$(find target ext/widget_renderer/target -maxdepth 4 -name 'libwidget_renderer*.so' 2>/dev/null | head -n 1 || true)
if [ -z "${artifact}" ]; then
echo "No built libwidget_renderer.so found. Current target tree:"
find target ext/widget_renderer/target -maxdepth 4 -type f | sed 's/^/ /'
exit 1
fi
echo "Using artifact: ${artifact}"
cp "${artifact}" ext/widget_renderer/libwidget_renderer.so
cp "${artifact}" ext/widget_renderer/target/release/libwidget_renderer.so

- name: Upload artifact
uses: actions/upload-artifact@v4
with:
name: libwidget_renderer.so
path: |
ext/widget_renderer/libwidget_renderer.so
ext/widget_renderer/target/release/libwidget_renderer.so
16 changes: 16 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,15 +25,31 @@
/config/master.key

# Don't check in these things
.env
.env.development
.env.*
.manifest.yml
.csv
vars.yml
vars*.yml

# For Macs
.DS_Store

/coverage/

# Ignore RSpec example status persistence file
/spec/examples.txt

/public/packs
/public/packs-test
/node_modules

target/
**/target/

# Rust extension build artifacts
ext/widget_renderer/Makefile
ext/widget_renderer/*.dylib
# Keep the prebuilt Linux .so for Cloud Foundry deployment
!ext/widget_renderer/libwidget_renderer.so
72 changes: 72 additions & 0 deletions .profile.d/build_widget_renderer.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
#!/usr/bin/env bash
# We want failures in optional copy steps to fall through to the build step,
# not kill the process before Rails boots.
set -uo pipefail

if [ -d "${HOME}/ext/widget_renderer" ]; then
EXT_DIR="${HOME}/ext/widget_renderer"
elif [ -d "${HOME}/app/ext/widget_renderer" ]; then
EXT_DIR="${HOME}/app/ext/widget_renderer"
else
echo "===> widget_renderer: extension directory not found under HOME: ${HOME}"
exit 1
fi
LIB_SO="${EXT_DIR}/libwidget_renderer.so"
LIB_DYLIB="${EXT_DIR}/libwidget_renderer.dylib"

echo "===> widget_renderer: checking for native library in ${EXT_DIR}"

# Helper: hydrate from a built library if it already exists.
copy_lib() {
local src="$1"
if [ -f "$src" ]; then
echo "===> widget_renderer: using prebuilt library at $src"
mkdir -p "${EXT_DIR}/target/release"
cp "$src" "${EXT_DIR}/target/release/libwidget_renderer.so"
cp "$src" "${EXT_DIR}/libwidget_renderer.so"
return 0
else
echo "===> widget_renderer: no library at $src"
fi
return 1
}

# Try common build locations before attempting to compile. Do not exit early if they are absent.
set +e
copy_lib "${EXT_DIR}/target/release/libwidget_renderer.so" || \
copy_lib "${HOME}/target/release/libwidget_renderer.so" || \
copy_lib "${HOME}/app/target/release/libwidget_renderer.so" || \
copy_lib "${HOME}/app/ext/widget_renderer/libwidget_renderer.so"
copy_status=$?
set -e

# Build the Rust extension at runtime if the shared library is missing.
if [ ! -f "$LIB_SO" ] && [ ! -f "$LIB_DYLIB" ]; then
echo "===> widget_renderer: building native extension"

# Ensure Cargo toolchain from the Rust buildpack is used (avoid reinstall).
if [ -d "/home/vcap/deps/0/rust/cargo/bin" ]; then
export CARGO_HOME="/home/vcap/deps/0/rust/cargo"
fi
if [ -d "/home/vcap/deps/0/rust/rustup" ]; then
export RUSTUP_HOME="/home/vcap/deps/0/rust/rustup"
fi
# Cargo requires HOME to match the runtime user’s home dir (/home/vcap), not /home/vcap/app.
export HOME="/home/vcap"
echo "===> widget_renderer: CARGO_HOME=${CARGO_HOME:-unset}"
echo "===> widget_renderer: RUSTUP_HOME=${RUSTUP_HOME:-unset}"

# Tell rutie to link against the shared Ruby library provided by the Ruby buildpack.
RUBY_LIB_PATH=$(ruby -e 'require "rbconfig"; print RbConfig::CONFIG["libdir"]')
RUBY_SO_NAME=$(ruby -e 'require "rbconfig"; print RbConfig::CONFIG["RUBY_SO_NAME"]')
export RUTIE_RUBY_LIB_PATH="$RUBY_LIB_PATH"
export RUTIE_RUBY_LIB_NAME="$RUBY_SO_NAME"
unset RUBY_STATIC
export NO_LINK_RUTIE=1

cd "$EXT_DIR"
ruby extconf.rb
make
else
echo "===> widget_renderer: native extension already present"
fi
1 change: 1 addition & 0 deletions .rspec
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
--format documentation
--profile 10
1 change: 1 addition & 0 deletions .ruby-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.2.8
Loading
Loading