Skip to content
Open
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
252 changes: 252 additions & 0 deletions .github/workflows/precompile-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,252 @@
name: Assets Precompile Check

on:
push:
branches:
- 'master'
pull_request:
paths-ignore:
- '**.md'
- 'docs/**'
- 'react_on_rails_pro/**'
workflow_dispatch:
inputs:
force_run:
description: 'Force run all jobs (bypass detect-changes)'
required: false
type: boolean
default: false

jobs:
detect-changes:
permissions:
contents: read
actions: read
runs-on: ubuntu-22.04
outputs:
docs_only: ${{ steps.detect.outputs.docs_only }}
run_dummy_tests: ${{ steps.detect.outputs.run_dummy_tests }}
has_full_ci_label: ${{ steps.check-label.outputs.result }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 50
persist-credentials: false
- name: Check for full-ci label
id: check-label
uses: ./.github/actions/check-full-ci-label
- name: Detect relevant changes
id: detect
run: |
if [ "${{ inputs.force_run }}" = "true" ] || [ "${{ steps.check-label.outputs.result }}" = "true" ]; then
echo "run_dummy_tests=true" >> "$GITHUB_OUTPUT"
echo "docs_only=false" >> "$GITHUB_OUTPUT"
exit 0
fi

BASE_REF="${{ github.event.pull_request.base.sha || github.event.before || 'origin/master' }}"
script/ci-changes-detector "$BASE_REF"
shell: bash
- name: Guard docs-only master pushes
if: github.event_name == 'push' && github.ref == 'refs/heads/master'
uses: ./.github/actions/ensure-master-docs-safety
with:
docs-only: ${{ steps.detect.outputs.docs_only }}
previous-sha: ${{ github.event.before }}

precompile-check:
needs: detect-changes
# Skip only if: master push AND docs-only changes
# Otherwise run if: on master OR workflow_dispatch OR dummy tests needed
if: |
!(
github.event_name == 'push' &&
github.ref == 'refs/heads/master' &&
needs.detect-changes.outputs.docs_only == 'true'
) && (
github.ref == 'refs/heads/master' ||
github.event_name == 'workflow_dispatch' ||
needs.detect-changes.outputs.run_dummy_tests == 'true'
)
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- name: Setup Ruby
uses: ruby/setup-ruby@v1
with:
ruby-version: '3.4'
bundler: 2.5.9
# libyaml-dev is needed for psych v5
- name: Fix dependency for libyaml-dev
run: sudo apt install libyaml-dev
- name: Setup Node
uses: ./.github/actions/setup-node-with-retry
with:
node-version: '22'
- name: Setup pnpm
uses: pnpm/action-setup@v4
- name: Get pnpm store directory
shell: bash
run: echo "STORE_PATH=$(pnpm store path --silent)" >> "$GITHUB_ENV"
- name: Setup pnpm cache
uses: actions/cache@v4
with:
path: ${{ env.STORE_PATH }}
key: ${{ runner.os }}-pnpm-store-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
${{ runner.os }}-pnpm-store-
- name: Print system information
run: |
echo "Linux release: "; cat /etc/issue
echo "Current user: "; whoami
echo "Current directory: "; pwd
echo "Ruby version: "; ruby -v
echo "Node version: "; node -v
echo "pnpm version: "; pnpm --version
echo "Bundler version: "; bundle --version
- name: Install Node modules with pnpm for renderer package
run: |
pnpm install --frozen-lockfile
pnpm add -g yalc
- name: yalc publish for react-on-rails
run: cd packages/react-on-rails && yalc publish
- name: yalc add react-on-rails
run: cd react_on_rails/spec/dummy && yalc add react-on-rails
- name: Install Node modules with pnpm for dummy app
run: cd react_on_rails/spec/dummy && pnpm install --ignore-workspace
- name: Save dummy app ruby gems to cache
uses: actions/cache@v4
with:
path: react_on_rails/spec/dummy/vendor/bundle
key: dummy-app-gem-cache-${{ hashFiles('react_on_rails/spec/dummy/Gemfile.lock') }}-precompile
- name: Install Ruby Gems for dummy app
run: |
cd react_on_rails/spec/dummy
bundle lock --add-platform 'x86_64-linux'
if ! bundle check --path=vendor/bundle; then
bundle _2.5.9_ install --path=vendor/bundle --jobs=4 --retry=3
fi
- name: Build ReScript files
run: cd react_on_rails/spec/dummy && pnpm run build:rescript
- name: Generate file system-based packs
run: cd react_on_rails/spec/dummy && RAILS_ENV=production bundle exec rake react_on_rails:generate_packs
- name: Run assets:precompile and check output
run: |
cd react_on_rails/spec/dummy

echo "Running RAILS_ENV=production bin/rake assets:precompile..."
echo "=========================================="

# Run precompile and capture both stdout and stderr
# Use pipefail to catch rake failures even when piped through tee
set -o pipefail
RAILS_ENV=production bin/rake assets:precompile 2>&1 | tee precompile_output.txt
PRECOMPILE_EXIT=${PIPESTATUS[0]}

echo "=========================================="
echo "Precompile finished. Checking output for known issues..."
echo ""

# Check for known failure patterns
FAILURES_FOUND=0

# Check if rake command itself failed
if [ "$PRECOMPILE_EXIT" -ne 0 ]; then
echo "::error::Precompile command failed with exit code $PRECOMPILE_EXIT"
FAILURES_FOUND=1
fi

# Pattern 1: Duplicate webpack compilation (indicates rake tasks running twice)
# Look for webpack's "Compiled successfully" message which appears once per compilation
if grep -q "Compiled successfully" precompile_output.txt; then
COMPILE_SUCCESS_COUNT=$(grep -c "Compiled successfully" precompile_output.txt || true)
if [ "$COMPILE_SUCCESS_COUNT" -gt 1 ]; then
echo "::error::FAILURE: Detected $COMPILE_SUCCESS_COUNT webpack compilations (expected 1). Tasks may be running twice."
echo " Matching lines:"
grep -n "Compiled successfully" precompile_output.txt | head -5
FAILURES_FOUND=1
fi
fi

# Pattern 2: Duplicate task execution messages
if grep -q "react_on_rails:generate_packs" precompile_output.txt; then
GENERATE_PACKS_COUNT=$(grep -c "react_on_rails:generate_packs" precompile_output.txt || true)
if [ "$GENERATE_PACKS_COUNT" -gt 1 ]; then
echo "::error::FAILURE: react_on_rails:generate_packs task ran $GENERATE_PACKS_COUNT times (should only run once)."
echo " Matching lines:"
grep -n "react_on_rails:generate_packs" precompile_output.txt
FAILURES_FOUND=1
fi
fi

# Pattern 3: Module not found errors
if grep -Ei "module not found|cannot find module|can't resolve" precompile_output.txt; then
echo "::error::FAILURE: Module resolution errors detected in precompile output."
echo " Sample matching lines:"
grep -Ei "module not found|cannot find module|can't resolve" precompile_output.txt | head -3
FAILURES_FOUND=1
fi

# Pattern 4: Webpack build errors (use specific webpack error markers)
if grep -Ei "webpack.*error|failed to compile|compilation failed|ERROR in" precompile_output.txt; then
echo "::error::FAILURE: Webpack compilation errors detected."
echo " Sample matching lines:"
grep -Ei "webpack.*error|failed to compile|compilation failed|ERROR in" precompile_output.txt | head -3
FAILURES_FOUND=1
fi

# Pattern 5: Ruby/Rails errors during precompile (match error class format)
if grep -E "(NameError|LoadError|NoMethodError|SyntaxError):" precompile_output.txt; then
echo "::error::FAILURE: Ruby errors detected during precompile."
echo " Sample matching lines:"
grep -E "(NameError|LoadError|NoMethodError|SyntaxError):" precompile_output.txt | head -3
FAILURES_FOUND=1
fi

# Pattern 6: Asset pipeline errors
if grep -Ei "Sprockets::FileNotFound|Asset.*was not declared" precompile_output.txt; then
echo "::error::FAILURE: Asset pipeline errors detected."
echo " Sample matching lines:"
grep -Ei "Sprockets::FileNotFound|Asset.*was not declared" precompile_output.txt | head -3
FAILURES_FOUND=1
fi

# Pattern 7: Memory issues
if grep -Ei "javascript heap out of memory|killed|out of memory" precompile_output.txt; then
echo "::error::FAILURE: Memory-related errors detected."
echo " Sample matching lines:"
grep -Ei "javascript heap out of memory|killed|out of memory" precompile_output.txt | head -3
FAILURES_FOUND=1
fi

# Pattern 8: Check for warnings that might indicate problems
WARNING_COUNT=$(grep -ci "warning" precompile_output.txt || true)
if [ "$WARNING_COUNT" -gt 10 ]; then
echo "::warning::High number of warnings detected: $WARNING_COUNT warnings found. Please review."
echo " Sample warnings:"
grep -i "warning" precompile_output.txt | head -5
fi

if [ "$FAILURES_FOUND" -eq 1 ]; then
echo ""
echo "=========================================="
echo "PRECOMPILE CHECK FAILED"
echo "=========================================="
echo "Review the output above for details."
exit 1
fi

echo ""
echo "=========================================="
echo "PRECOMPILE CHECK PASSED"
echo "=========================================="
echo "No known failure patterns detected in precompile output."
- name: Upload precompile output
if: always()
uses: actions/upload-artifact@v4
with:
name: precompile-output-${{ github.run_id }}
path: react_on_rails/spec/dummy/precompile_output.txt
retention-days: 7
Loading