Skip to content

feat: add ws-plugin and cron-plugin to official Motia plugins #1145

feat: add ws-plugin and cron-plugin to official Motia plugins

feat: add ws-plugin and cron-plugin to official Motia plugins #1145

Workflow file for this run

name: E2E Tests (PR)
on:
pull_request:
types: [opened, synchronize, reopened, labeled]
branches: [main]
paths:
- 'packages/**'
- 'playground/**'
- '!packages/docs/**'
- '.github/workflows/e2e-tests-pr.yml'
workflow_dispatch:
inputs:
branch:
description: 'Branch to run E2E tests against'
required: true
default: 'main'
type: string
permissions:
contents: read
checks: write
pull-requests: write
jobs:
e2e-pr-tests:
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest]
template: [motia-tutorial-typescript, motia-tutorial-python]
runs-on: ${{ matrix.os }}
timeout-minutes: 30
env:
CI: true
NODE_ENV: test
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.event.inputs.branch || github.sha }}
fetch-depth: 0
- name: Verify checkout branch
run: |
echo "Current branch: $(git branch --show-current || echo 'detached HEAD')"
echo "Current commit: $(git rev-parse HEAD)"
echo "Event name: ${{ github.event_name }}"
if [ "${{ github.event_name }}" == "pull_request" ]; then
echo "PR head SHA: ${{ github.event.pull_request.head.sha }}"
echo "PR head ref: ${{ github.event.pull_request.head.ref }}"
echo "PR base ref: ${{ github.event.pull_request.base.ref }}"
echo "Expected commit SHA: ${{ github.event.pull_request.head.sha }}"
echo "Actual commit SHA: $(git rev-parse HEAD)"
if [ "$(git rev-parse HEAD)" != "${{ github.event.pull_request.head.sha }}" ]; then
echo "⚠️ WARNING: Checkout SHA mismatch!"
exit 1
fi
fi
- uses: pnpm/action-setup@v4
- name: Setup
uses: ./.github/actions/setup
- name: Install Redis
run: |
if [ "${{ runner.os }}" == "Linux" ]; then
sudo apt-get update
sudo apt-get install -y redis-server
redis-server --daemonize yes
elif [ "${{ runner.os }}" == "macOS" ]; then
brew install redis
brew services start redis
fi
sleep 2
redis-cli ping || echo "Redis not responding to ping"
- name: Get Playwright version
id: playwright-version
run: |
cd packages/e2e
PLAYWRIGHT_VERSION=$(node -p "require('./package.json').dependencies['@playwright/test'] || require('./package.json').devDependencies['@playwright/test']")
echo "version=$PLAYWRIGHT_VERSION" >> $GITHUB_OUTPUT
- name: Cache Playwright browsers
uses: actions/cache@v4
id: playwright-cache
with:
path: |
~/.cache/ms-playwright
~/AppData/Local/ms-playwright
~/Library/Caches/ms-playwright
key: playwright-${{ runner.os }}-${{ steps.playwright-version.outputs.version }}-${{ hashFiles('pnpm-lock.yaml') }}
restore-keys: |
playwright-${{ runner.os }}-${{ steps.playwright-version.outputs.version }}-
playwright-${{ runner.os }}-
- name: Install E2E dependencies and browsers
run: |
cd packages/e2e
pnpm install
pnpm exec playwright install
pnpm exec playwright install-deps
- name: Clean previous test artifacts
run: |
cd packages/e2e
pnpm clean
- name: Verify built CLI
run: |
# Verify the built CLI exists
if [ ! -f "packages/snap/dist/cli.mjs" ]; then
echo "❌ Built CLI not found at packages/snap/dist/cli.mjs"
echo "Available files in dist:"
ls -la packages/snap/dist/ || echo "dist directory not found"
exit 1
fi
# Make CLI executable through node
echo "✅ Built CLI found at packages/snap/dist/cli.mjs"
node packages/snap/dist/cli.mjs --version || echo "CLI version check failed"
- name: Record test start time
run: echo "START_TIME=$(date +%s)" >> $GITHUB_ENV
- name: Run PR E2E tests with built CLI
id: run_tests
uses: nick-fields/retry@v3
with:
timeout_minutes: 10
max_attempts: 2
retry_on: error
shell: bash
command: |
cd packages/e2e
echo "🧪 Starting PR E2E tests - Template: ${{ matrix.template }}, OS: ${{ matrix.os }}"
# Export the built CLI path for tests to use
export MOTIA_CLI_PATH="$GITHUB_WORKSPACE/packages/snap/dist/cli.mjs"
export MOTIA_ANALYTICS_DISABLED=true
export MOTIA_API_URL=http://localhost:3000
export MOTIA_TEST_TEMPLATE=${{ matrix.template }}
export REDISMS_SYSTEM_BINARY=$(which redis-server)
# Run tests based on template (no sharding)
if [ "${{ matrix.template }}" == "motia-tutorial-python" ]; then
pnpm test:pr:python --reporter=line,html,github
else
pnpm test:pr --reporter=line,html,github
fi
- name: Record test metrics
if: always()
run: |
TEST_DURATION=$(($(date +%s) - $START_TIME))
echo "TEST_DURATION=$TEST_DURATION" >> $GITHUB_ENV
echo "::notice title=Test Duration::${{ matrix.template }} on ${{ matrix.os }} completed in $TEST_DURATION seconds"
# Output performance metrics
echo "### Performance Metrics - ${{ matrix.os }} - ${{ matrix.template }}" >> $GITHUB_STEP_SUMMARY
echo "- Duration: ${TEST_DURATION}s" >> $GITHUB_STEP_SUMMARY
echo "- Status: ${{ steps.run_tests.outcome }}" >> $GITHUB_STEP_SUMMARY
- name: Process test results
id: test_result
if: always()
run: |
echo "📊 Test Results Summary:"
echo "- Template: ${{ matrix.template }}"
echo "- OS: ${{ matrix.os }}"
echo "- Test outcome: ${{ steps.run_tests.outcome }}"
echo "- Duration: ${{ env.TEST_DURATION }} seconds"
if [ "${{ steps.run_tests.outcome }}" == "success" ]; then
echo "result=success" >> $GITHUB_OUTPUT
echo "✅ PR E2E tests passed for ${{ matrix.template }} on ${{ matrix.os }}"
else
echo "result=failure" >> $GITHUB_OUTPUT
echo "::error title=Test Failed::E2E tests failed for ${{ matrix.template }} on ${{ matrix.os }}"
# Extract and display error summary if available
if [ -f "packages/e2e/test-results/results.json" ]; then
echo "### Failed Tests Summary" >> $GITHUB_STEP_SUMMARY
jq -r '.failures[]' packages/e2e/test-results/results.json >> $GITHUB_STEP_SUMMARY 2>/dev/null || true
fi
exit 1
fi
- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: e2e-pr-test-results-${{ github.event.number }}-${{ matrix.os }}-${{ matrix.template }}
path: |
packages/e2e/playwright-report/
packages/e2e/test-results/
packages/e2e/test-results.xml
retention-days: 7
- name: Clean up test artifacts
if: always()
run: |
echo "🧹 Cleaning up test artifacts..."
# Kill any processes on port 3000
if command -v lsof &> /dev/null; then
PORT_PIDS=$(lsof -ti:3000 2>/dev/null || true)
if [ ! -z "$PORT_PIDS" ]; then
echo "$PORT_PIDS" | xargs -r kill -9 2>/dev/null || true
fi
fi
# Clean up any test project directories created during tests
rm -rf packages/e2e/motia-e2e-test-project* 2>/dev/null || true
echo "✅ Cleanup complete"
# Windows-specific job that only runs when e2e-windows label is present
e2e-pr-tests-windows:
if: contains(github.event.pull_request.labels.*.name, 'e2e-windows')
strategy:
fail-fast: false
matrix:
template: [motia-tutorial-typescript, motia-tutorial-python]
runs-on: windows-latest
timeout-minutes: 30
env:
CI: true
NODE_ENV: test
steps:
- uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.head.sha || github.event.inputs.branch || github.sha }}
fetch-depth: 0
- name: Verify checkout branch
shell: bash
run: |
echo "Current branch: $(git branch --show-current || echo 'detached HEAD')"
echo "Current commit: $(git rev-parse HEAD)"
echo "Event name: ${{ github.event_name }}"
if [ "${{ github.event_name }}" == "pull_request" ]; then
echo "PR head SHA: ${{ github.event.pull_request.head.sha }}"
echo "PR head ref: ${{ github.event.pull_request.head.ref }}"
echo "PR base ref: ${{ github.event.pull_request.base.ref }}"
echo "Expected commit SHA: ${{ github.event.pull_request.head.sha }}"
echo "Actual commit SHA: $(git rev-parse HEAD)"
if [ "$(git rev-parse HEAD)" != "${{ github.event.pull_request.head.sha }}" ]; then
echo "WARNING: Checkout SHA mismatch!"
exit 1
fi
fi
- uses: pnpm/action-setup@v4
- name: Setup
uses: ./.github/actions/setup
- name: Get Playwright version
id: playwright-version
shell: bash
run: |
cd packages/e2e
PLAYWRIGHT_VERSION=$(node -p "require('./package.json').dependencies['@playwright/test'] || require('./package.json').devDependencies['@playwright/test']")
echo "version=$PLAYWRIGHT_VERSION" >> $GITHUB_OUTPUT
- name: Cache Playwright browsers
uses: actions/cache@v4
id: playwright-cache
with:
path: |
~/.cache/ms-playwright
~/AppData/Local/ms-playwright
~/Library/Caches/ms-playwright
key: playwright-${{ runner.os }}-${{ steps.playwright-version.outputs.version }}-${{ hashFiles('pnpm-lock.yaml') }}
restore-keys: |
playwright-${{ runner.os }}-${{ steps.playwright-version.outputs.version }}-
playwright-${{ runner.os }}-
- name: Install E2E dependencies and browsers
shell: bash
run: |
cd packages/e2e
pnpm install
pnpm exec playwright install
pnpm exec playwright install-deps
- name: Clean previous test artifacts
shell: bash
run: |
cd packages/e2e
pnpm clean
- name: Verify built CLI (Windows)
shell: cmd
run: |
if not exist "packages\snap\dist\cli.mjs" (
echo Built CLI not found at packages\snap\dist\cli.mjs
dir packages\snap\dist\ 2>nul || echo dist directory not found
exit /b 1
)
echo Built CLI found at packages\snap\dist\cli.mjs
node packages\snap\dist\cli.mjs --version || echo CLI version check failed
- name: Record test start time
shell: bash
run: echo "START_TIME=$(date +%s)" >> $GITHUB_ENV
- name: Set test environment variables (Windows)
shell: pwsh
run: |
echo "MOTIA_CLI_PATH=$env:GITHUB_WORKSPACE\packages\snap\dist\cli.mjs" >> $env:GITHUB_ENV
echo "MOTIA_ANALYTICS_DISABLED=true" >> $env:GITHUB_ENV
echo "MOTIA_API_URL=http://localhost:3000" >> $env:GITHUB_ENV
echo "MOTIA_TEST_TEMPLATE=${{ matrix.template }}" >> $env:GITHUB_ENV
echo "MOTIA_WINDOWS_FAST_MODE=true" >> $env:GITHUB_ENV
- name: Run PR E2E tests with built CLI (Windows)
id: run_tests
uses: nick-fields/retry@v3
with:
timeout_minutes: 10
max_attempts: 2
retry_on: error
shell: bash
command: |
cd packages/e2e
echo "Starting PR E2E tests - Template: ${{ matrix.template }}, OS: windows-latest"
# Run tests based on template (no sharding)
if [ "${{ matrix.template }}" == "motia-tutorial-python" ]; then
pnpm test:pr:python --reporter=line,html,github
else
pnpm test:pr --reporter=line,html,github
fi
- name: Record test metrics
if: always()
shell: bash
run: |
TEST_DURATION=$(($(date +%s) - $START_TIME))
echo "TEST_DURATION=$TEST_DURATION" >> $GITHUB_ENV
echo "::notice title=Test Duration::${{ matrix.template }} on windows-latest completed in $TEST_DURATION seconds"
# Output performance metrics
echo "### Performance Metrics - windows-latest - ${{ matrix.template }}" >> $GITHUB_STEP_SUMMARY
echo "- Duration: ${TEST_DURATION}s" >> $GITHUB_STEP_SUMMARY
echo "- Status: ${{ steps.run_tests.outcome }}" >> $GITHUB_STEP_SUMMARY
- name: Process test results
id: test_result
if: always()
shell: bash
run: |
echo "Test Results Summary:"
echo "- Template: ${{ matrix.template }}"
echo "- OS: windows-latest"
echo "- Test outcome: ${{ steps.run_tests.outcome }}"
echo "- Duration: ${{ env.TEST_DURATION }} seconds"
if [ "${{ steps.run_tests.outcome }}" == "success" ]; then
echo "result=success" >> $GITHUB_OUTPUT
echo "PR E2E tests passed for ${{ matrix.template }} on windows-latest"
else
echo "result=failure" >> $GITHUB_OUTPUT
echo "::error title=Test Failed::E2E tests failed for ${{ matrix.template }} on windows-latest"
# Extract and display error summary if available
if [ -f "packages/e2e/test-results/results.json" ]; then
echo "### Failed Tests Summary" >> $GITHUB_STEP_SUMMARY
jq -r '.failures[]' packages/e2e/test-results/results.json >> $GITHUB_STEP_SUMMARY 2>/dev/null || true
fi
exit 1
fi
- name: Upload test results
if: always()
uses: actions/upload-artifact@v4
with:
name: e2e-pr-test-results-${{ github.event.number }}-windows-latest-${{ matrix.template }}
path: |
packages/e2e/playwright-report/
packages/e2e/test-results/
packages/e2e/test-results.xml
retention-days: 7
- name: Clean up test artifacts (Windows)
if: always()
shell: pwsh
run: |
Write-Host "Cleaning up test artifacts..."
# Kill any processes on port 3000
$processes = Get-NetTCPConnection -LocalPort 3000 -ErrorAction SilentlyContinue | Select-Object -ExpandProperty OwningProcess -Unique
foreach ($proc in $processes) {
Stop-Process -Id $proc -Force -ErrorAction SilentlyContinue
}
# Clean up any test project directories created during tests
Remove-Item -Path "packages\e2e\motia-e2e-test-project*" -Recurse -Force -ErrorAction SilentlyContinue
Write-Host "Cleanup complete"
# Aggregate results from all matrix jobs
check-results:
needs: [e2e-pr-tests, e2e-pr-tests-windows]
runs-on: ubuntu-latest
if: always()
outputs:
result: ${{ steps.check_result.outputs.result }}
run_id: ${{ github.run_id }}
pr_number: ${{ github.event.pull_request.number }}
steps:
- name: Check all test results
id: check_result
run: |
echo "📊 Checking results from all test jobs..."
MAIN_RESULT='${{ needs.e2e-pr-tests.result }}'
WINDOWS_RESULT='${{ needs.e2e-pr-tests-windows.result }}'
echo "Main tests (Ubuntu/macOS) result: $MAIN_RESULT"
echo "Windows tests result: $WINDOWS_RESULT"
# Main tests must pass
if [ "$MAIN_RESULT" != "success" ]; then
echo "result=failure" >> $GITHUB_OUTPUT
echo "❌ Main PR E2E tests failed"
echo "### PR E2E Tests: FAILED ❌" >> $GITHUB_STEP_SUMMARY
exit 1
fi
# Windows tests must pass if they ran (not skipped)
if [ "$WINDOWS_RESULT" == "failure" ]; then
echo "result=failure" >> $GITHUB_OUTPUT
echo "❌ Windows PR E2E tests failed"
echo "### PR E2E Tests: FAILED ❌ (Windows)" >> $GITHUB_STEP_SUMMARY
exit 1
fi
echo "result=success" >> $GITHUB_OUTPUT
if [ "$WINDOWS_RESULT" == "skipped" ]; then
echo "✅ All PR E2E tests passed (Windows tests skipped - no e2e-windows label)"
echo "### PR E2E Tests: PASSED ✅ (Windows skipped)" >> $GITHUB_STEP_SUMMARY
else
echo "✅ All PR E2E tests passed (including Windows)"
echo "### PR E2E Tests: PASSED ✅ (including Windows)" >> $GITHUB_STEP_SUMMARY
fi