Pre-compiled Assets Solution
Problem
The GitHub Actions workflow was failing during the “Install JavaScript dependencies and precompile assets” step due to low RAM on the runner. Asset compilation is memory-intensive and was causing out-of-memory errors.
Solution
Implemented a pre-compiled assets approach that packages compiled assets and stores them in the repository, eliminating the need for asset compilation during CI/CD runs.
Implementation
1. Asset Packaging Script (bin/package_assets.sh)
- Collects compiled assets from
public/packs,public/assets, andtmp/cache/assets - Creates a compressed tar.gz archive in
vendor/precompiled_assets/ - Generates metadata about the build environment
- Size: ~9MB compressed package
2. Asset Extraction Script (bin/extract_assets.sh)
- Extracts pre-compiled assets from the vendor directory
- Automatically used by GitHub Actions workflow
- Provides fast asset availability without compilation
3. Asset Validation Script (bin/validate_assets.sh)
- Validates that assets are properly extracted and usable
- Shows statistics about available assets
- Helps debug asset-related issues
4. Modified GitHub Workflow
Updated .github/workflows/test-coverage.yml to:
- First check for cached assets
- If no cache, use pre-compiled assets from vendor directory
- Only fall back to compilation if neither option is available
- Reduced memory allocation from 4GB to 2GB for compilation fallback
5. Repository Changes
- Added
vendor/precompiled_assets/to store the asset package - Updated
.gitignoreto include pre-compiled assets directory - Created
.env.ci: CI-specific environment configuration with localhost settings - Modified workflow: Uses
.env.ciinstead of.env.examplefor proper service connectivity - Added comprehensive documentation
Benefits
- Eliminates RAM Issues: No more out-of-memory errors during asset compilation
- Faster CI/CD: Asset extraction (~30 seconds) vs compilation (~10+ minutes)
- More Reliable: Consistent assets across all environments
- Skips Unnecessary Steps: No Node.js/Yarn setup when using pre-compiled assets
- Fallback Safety: Still compiles if pre-compiled assets aren’t available
- Easy Maintenance: Simple scripts to update assets when needed
Usage Workflow
For Developers
When making asset changes:
# 1. Compile assets locally
bin/webpack
bundle exec rails assets:precompile RAILS_ENV=test
# 2. Package for CI/CD
bin/package_assets.sh
# 3. Commit the package
git add vendor/precompiled_assets/
git commit -m "Update pre-compiled assets"
For CI/CD
The workflow is now optimized to:
- Always install Node.js - Required for Rails database commands (ExecJS runtime)
- Check for pre-compiled assets first - If available, skips Yarn dependency installation
- Check for cached assets - Uses cached compiled assets if available
- Extract pre-compiled assets - Fast extraction with validation
- Fallback to compilation - Only if neither cache nor pre-compiled assets exist
Performance Benefits:
- Node.js setup: ~30 seconds (always needed for Rails)
- When using pre-compiled assets: Skips ~2-3 minutes of Yarn dependency installation
- Total time saved: ~10-12 minutes per CI/CD run
- Reduced complexity: Fewer moving parts = more reliable builds
- Validates asset availability
- Falls back to compilation only if needed
Files Created/Modified
New Files
bin/package_assets.sh- Asset packaging scriptbin/extract_assets.sh- Asset extraction scriptbin/validate_assets.sh- Asset validation scriptvendor/precompiled_assets/assets.tar.gz- Compressed asset package (9MB)vendor/precompiled_assets/metadata.json- Build metadatavendor/precompiled_assets/README.md- Documentation.env.ci- CI-specific environment configuration
Modified Files
.github/workflows/test-coverage.yml- Updated workflow logic and environment config.gitignore- Added exception for precompiled assets and .env.cibin/README.md- Added script documentation
Maintenance
When to Update Pre-compiled Assets
Update pre-compiled assets when:
- JavaScript dependencies change (
package.json,yarn.lock) - CSS/SCSS files are modified
- Asset-related configuration changes
- Rails asset pipeline configuration changes
The package includes metadata showing when it was created and what environment was used, making it easy to track asset freshness.
Important: Node.js Runtime Requirement
Always install Node.js: Even when using pre-compiled assets, Rails requires a JavaScript runtime (ExecJS) for database operations like bin/fix_schema and rails db:create. The workflow always installs Node.js (~30 seconds) but only conditionally installs Yarn dependencies (~2-3 minutes) when asset compilation is needed.
See docs/NODEJS_EXECJS_RUNTIME_FIX.md for detailed explanation.
Result
The GitHub Actions workflow should now complete successfully without memory issues, using pre-compiled assets instead of compiling them during the CI/CD run.