Skip to content

Add CI workflow to check assets:precompile output for failures #4

Add CI workflow to check assets:precompile output for failures

Add CI workflow to check assets:precompile output for failures #4

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