name: Performance Regression Detection on: pull_request: branches: [main] paths: - 'ml/**' - 'common/**' - 'data/**' - 'trading_engine/**' workflow_dispatch: env: RUST_BACKTRACE: 1 CARGO_TERM_COLOR: always jobs: performance-check: name: Check Performance Regression runs-on: ubuntu-latest timeout-minutes: 30 steps: - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 0 # Full history for baseline comparison - name: Install Rust toolchain uses: dtolnay/rust-toolchain@stable with: components: rustfmt, clippy - name: Cache cargo registry uses: actions/cache@v3 with: path: ~/.cargo/registry key: ${{ runner.os }}-cargo-registry-${{ hashFiles('**/Cargo.lock') }} - name: Cache cargo index uses: actions/cache@v3 with: path: ~/.cargo/git key: ${{ runner.os }}-cargo-git-${{ hashFiles('**/Cargo.lock') }} - name: Cache target directory uses: actions/cache@v3 with: path: target key: ${{ runner.os }}-target-${{ hashFiles('**/Cargo.lock') }} - name: Download baseline (if exists) id: download-baseline continue-on-error: true run: | # Download baseline from artifacts or S3 (configure as needed) # For now, use git to get baseline from main branch git fetch origin main git checkout origin/main -- ml/benchmark_results/performance_baseline.json || echo "No baseline found" if [ -f ml/benchmark_results/performance_baseline.json ]; then echo "baseline_exists=true" >> $GITHUB_OUTPUT else echo "baseline_exists=false" >> $GITHUB_OUTPUT fi - name: Build ML workspace run: cargo build --release -p ml - name: Run performance benchmark id: benchmark run: | # Run benchmark and capture metrics cargo run --release -p ml --example quick_performance_benchmark -- \ --output ml/benchmark_results/current_performance.json \ --git-commit ${{ github.event.pull_request.head.sha || github.sha }} - name: Check for regression id: regression-check if: steps.download-baseline.outputs.baseline_exists == 'true' run: | # Run regression detection cargo run --release -p ml --example check_performance_regression -- \ --baseline ml/benchmark_results/performance_baseline.json \ --current ml/benchmark_results/current_performance.json \ --output ml/benchmark_results/regression_report.md # Capture exit code EXIT_CODE=$? echo "exit_code=$EXIT_CODE" >> $GITHUB_OUTPUT # Exit with regression status exit $EXIT_CODE - name: Upload regression report if: always() && steps.regression-check.outputs.exit_code != '' uses: actions/upload-artifact@v3 with: name: regression-report path: ml/benchmark_results/regression_report.md retention-days: 30 - name: Comment PR with results if: always() && github.event_name == 'pull_request' && steps.regression-check.outputs.exit_code != '' uses: actions/github-script@v6 with: script: | const fs = require('fs'); const reportPath = 'ml/benchmark_results/regression_report.md'; if (fs.existsSync(reportPath)) { const report = fs.readFileSync(reportPath, 'utf8'); const exitCode = '${{ steps.regression-check.outputs.exit_code }}'; const header = exitCode === '0' ? '✅ **Performance Check Passed**' : '❌ **Performance Regression Detected**'; await github.rest.issues.createComment({ issue_number: context.issue.number, owner: context.repo.owner, repo: context.repo.repo, body: `${header}\n\n${report}` }); } - name: Save baseline on main branch merge if: github.event_name == 'push' && github.ref == 'refs/heads/main' run: | # Copy current metrics as new baseline mkdir -p ml/benchmark_results cp ml/benchmark_results/current_performance.json ml/benchmark_results/performance_baseline.json # Commit baseline (if configured) # git config user.name "GitHub Actions" # git config user.email "actions@github.com" # git add ml/benchmark_results/performance_baseline.json # git commit -m "Update performance baseline [skip ci]" # git push - name: Fail job on regression if: steps.regression-check.outputs.exit_code == '1' run: | echo "Performance regression detected. Please review the report." exit 1 - name: First run - save initial baseline if: steps.download-baseline.outputs.baseline_exists == 'false' run: | echo "No baseline found. Saving current metrics as baseline." mkdir -p ml/benchmark_results cp ml/benchmark_results/current_performance.json ml/benchmark_results/performance_baseline.json echo "✅ Initial baseline saved. Future PRs will be compared against this."