Skip to content

test(agent-eval): gate Pro onboarding claims on replayable evidence (… #8337

test(agent-eval): gate Pro onboarding claims on replayable evidence (…

test(agent-eval): gate Pro onboarding claims on replayable evidence (… #8337

name: Assets Precompile Check
permissions:
contents: read
on:
push:
branches:
- 'main'
- 'release/**'
# Always trigger on main/release branches; non-runtime detection handles skipping heavy jobs
pull_request:
types: [opened, synchronize, reopened, ready_for_review]
merge_group:
workflow_dispatch:
inputs:
force_full_hosted:
description: 'Force full hosted CI (bypass optimized detect-changes)'
required: false
type: boolean
default: false
pull_request_base_ref:
description: 'Pull request base branch for label/command dispatches'
required: false
type: string
pull_request_base_sha:
description: 'Pull request base SHA for label/command dispatches'
required: false
type: string
jobs:
detect-changes:
# Branch deletion push events have no checkoutable release ref.
if: github.event_name != 'push' || github.event.deleted != true
permissions:
contents: read
actions: read
issues: read
runs-on: ubuntu-22.04
outputs:
docs_only: ${{ steps.detect.outputs.docs_only }}
non_runtime_only: ${{ steps.detect.outputs.non_runtime_only }}
run_dummy_tests: ${{ steps.detect.outputs.run_dummy_tests }}
should_run_hosted_ci: ${{ steps.hosted-ci.outputs.should_run_hosted_ci }}
should_force_full_hosted_ci: ${{ steps.hosted-ci.outputs.should_force_full_hosted_ci }}
steps:
- uses: actions/checkout@v4
with:
# Full history is only needed for workflow_dispatch base-SHA reruns.
fetch-depth: ${{ github.event_name == 'workflow_dispatch' && '0' || '50' }}
persist-credentials: false
- name: Select hosted CI mode
id: hosted-ci
uses: ./.github/actions/hosted-ci-selectors
with:
force-full-hosted: ${{ inputs.force_full_hosted || false }}
base-ref: ${{ inputs.pull_request_base_ref || '' }}
- name: Detect relevant changes
id: detect
env:
DISPATCH_BASE_REF: ${{ inputs.pull_request_base_ref || '' }}
DISPATCH_BASE_SHA: ${{ inputs.pull_request_base_sha || '' }}
run: |
# Force-full hosted CI is the explicit escape hatch that bypasses
# optimized change selection. Hosted readiness alone stays path-based.
if [ "${{ steps.hosted-ci.outputs.should_force_full_hosted_ci }}" = "true" ]; then
{
echo "run_dummy_tests=true"
echo "docs_only=false"
echo "non_runtime_only=false"
} >> "$GITHUB_OUTPUT"
exit 0
fi
if [ -n "$DISPATCH_BASE_SHA" ]; then
export GITHUB_BASE_REF="$DISPATCH_BASE_REF"
BASE_REF="$DISPATCH_BASE_SHA"
else
BASE_REF="${{ github.event.pull_request.base.sha || github.event.merge_group.base_sha || github.event.before || 'origin/main' }}"
fi
script/ci-changes-detector "$BASE_REF"
shell: bash
- name: Guard docs-only main pushes
if: |
(github.event_name == 'push' && github.ref == 'refs/heads/main') ||
(github.event_name == 'merge_group' &&
github.event.merge_group.base_ref == 'refs/heads/main')
uses: ./.github/actions/ensure-main-docs-safety
with:
docs-only: ${{ steps.detect.outputs.docs_only }}
previous-sha: ${{ github.event.before || github.event.merge_group.base_sha }}
precompile-check:
needs: detect-changes
# Run hosted precompile validation only when hosted CI is allowed and dummy paths changed.
if: |
needs.detect-changes.outputs.should_run_hosted_ci == 'true' &&
needs.detect-changes.outputs.run_dummy_tests == 'true'
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- name: Read runtime versions
id: tool-versions
uses: ./.github/actions/read-tool-versions
- name: Setup Ruby
uses: ./.github/actions/setup-ruby
with:
ruby-version: ${{ steps.tool-versions.outputs.ruby-minor-version }}
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: ${{ steps.tool-versions.outputs.node-version }}
- 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
run: pnpm install --frozen-lockfile
- name: Build workspace packages
run: pnpm run build
- name: Install Ruby Gems for dummy app
uses: ./.github/actions/setup-bundle
with:
working-directory: react_on_rails/spec/dummy
ruby-version: ${{ steps.tool-versions.outputs.ruby-minor-version }}
install-libyaml: 'false'
- name: Build ReScript files
run: pnpm --filter "react_on_rails" 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: Clean compiled assets
# Clobber removes both Sprockets assets (public/assets) and webpack output (public/webpack)
# This ensures we test a fresh build, not cached "Everything's up-to-date" output
run: cd react_on_rails/spec/dummy && RAILS_ENV=production bundle exec rake assets:clobber
- name: Run assets:precompile and capture output
# Timeout prevents hung webpack processes from running for 6 hours.
# Typical precompile takes 2-5 minutes; 15 minutes is generous.
timeout-minutes: 15
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 "=========================================="
# Check if rake command itself failed
if [ "$PRECOMPILE_EXIT" -ne 0 ]; then
echo "::error::Precompile command failed with exit code $PRECOMPILE_EXIT"
exit "$PRECOMPILE_EXIT"
fi
- name: Validate precompile output
run: script/validate-precompile-output react_on_rails/spec/dummy/precompile_output.txt
- 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