Skip to content

πŸ“ Set metric value font size to 0.2rem for ultra-minimal text #30

πŸ“ Set metric value font size to 0.2rem for ultra-minimal text

πŸ“ Set metric value font size to 0.2rem for ultra-minimal text #30

name: Performance Benchmarking
on:
# Run on pull requests to main branches
pull_request:
branches: [ main, testing, develop ]
paths-ignore:
- 'docs/**'
- '*.md'
- 'archive/**'
- 'examples/**'
# Run on pushes to main branches
push:
branches: [ main, testing, develop ]
paths-ignore:
- 'docs/**'
- '*.md'
- 'archive/**'
- 'examples/**'
# Allow manual triggering
workflow_dispatch:
inputs:
environment:
description: 'Environment to benchmark'
required: true
default: 'testing'
type: choice
options:
- development
- testing
- staging
update_baseline:
description: 'Update performance baseline'
required: false
default: false
type: boolean
env:
PYTHON_VERSION: '3.11'
jobs:
performance-benchmarks:
runs-on: ubuntu-latest
strategy:
matrix:
environment:
- ${{ github.event.inputs.environment || 'testing' }}
services:
postgres:
image: pgvector/pgvector:pg16
env:
POSTGRES_DB: second_brain_test
POSTGRES_USER: postgres
POSTGRES_PASSWORD: postgres
options: >-
--health-cmd pg_isready
--health-interval 10s
--health-timeout 5s
--health-retries 5
ports:
- 5432:5432
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v4
with:
python-version: ${{ env.PYTHON_VERSION }}
cache: 'pip'
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
pip install psutil pyyaml pytest httpx
- name: Setup database
run: |
python -c "
import asyncio
import asyncpg
async def setup():
conn = await asyncpg.connect(
'postgresql://postgres:postgres@localhost:5432/second_brain_test'
)
await conn.execute('CREATE EXTENSION IF NOT EXISTS vector;')
await conn.close()
asyncio.run(setup())
"
env:
DATABASE_URL: postgresql://postgres:postgres@localhost:5432/second_brain_test
- name: Start Second Brain server
run: |
export DATABASE_URL="postgresql://postgres:postgres@localhost:5432/second_brain_test"
export OPENAI_API_KEY="test-key"
export API_TOKENS="test-token"
# Determine port based on environment
case "${{ matrix.environment }}" in
"development") PORT=8000 ;;
"testing") PORT=8001 ;;
"staging") PORT=8002 ;;
*) PORT=8000 ;;
esac
# Start server in background
python -m uvicorn app.main:app --host 0.0.0.0 --port $PORT &
SERVER_PID=$!
echo "SERVER_PID=$SERVER_PID" >> $GITHUB_ENV
echo "SERVER_PORT=$PORT" >> $GITHUB_ENV
# Wait for server to start
echo "Waiting for server to start on port $PORT..."
for i in {1..30}; do
if curl -f http://localhost:$PORT/health >/dev/null 2>&1; then
echo "Server started successfully"
break
fi
if [ $i -eq 30 ]; then
echo "Server failed to start"
exit 1
fi
sleep 2
done
- name: Run performance benchmarks
run: |
# Update configuration for CI environment
python -c "
import yaml
with open('performance_config.yml', 'r') as f:
config = yaml.safe_load(f)
# Override URL for testing
config['environments']['${{ matrix.environment }}']['url'] = 'http://localhost:${{ env.SERVER_PORT }}'
config['environments']['${{ matrix.environment }}']['verify_ssl'] = False
# Enable appropriate tests for CI
if '${{ matrix.environment }}' != 'production':
config['benchmarks']['concurrent_load']['concurrent_requests'] = 20 # Reduced for CI
config['benchmarks']['system_resources']['monitoring_duration'] = 10 # Reduced for CI
with open('performance_config.yml', 'w') as f:
yaml.dump(config, f)
"
# Run the automated performance benchmark
python scripts/performance_automation.py ${{ matrix.environment }} \
${{ github.event.inputs.update_baseline == 'true' && '--update-baseline' || '' }}
- name: Upload performance results
uses: actions/upload-artifact@v3
if: always()
with:
name: performance-results-${{ matrix.environment }}
path: |
results/performance/${{ matrix.environment }}/*.json
results/performance/${{ matrix.environment }}/*.md
retention-days: 30
- name: Comment performance results on PR
if: github.event_name == 'pull_request'
uses: actions/github-script@v6
with:
script: |
const fs = require('fs');
const path = require('path');
// Find the latest markdown report
const resultsDir = `results/performance/${{ matrix.environment }}`;
const files = fs.readdirSync(resultsDir)
.filter(f => f.endsWith('.md') && f.includes('automation_report'))
.sort()
.reverse();
if (files.length === 0) {
console.log('No markdown report found');
return;
}
const reportPath = path.join(resultsDir, files[0]);
const reportContent = fs.readFileSync(reportPath, 'utf8');
// Create or update comment
const { data: comments } = await github.rest.issues.listComments({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
});
const botComment = comments.find(comment =>
comment.user.type === 'Bot' &&
comment.body.includes('Performance Benchmark Report')
);
const commentBody = `## πŸš€ Performance Benchmark Report - ${{ matrix.environment }}
${reportContent}
<details>
<summary>πŸ“Š View Detailed Results</summary>
Download the detailed performance artifacts for complete analysis.
</details>
---
*This comment was automatically generated by the Performance Benchmarking workflow.*`;
if (botComment) {
await github.rest.issues.updateComment({
owner: context.repo.owner,
repo: context.repo.repo,
comment_id: botComment.id,
body: commentBody
});
} else {
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: context.issue.number,
body: commentBody
});
}
- name: Check performance gate
run: |
# Check the exit code from performance automation
# It should have already failed if performance was below threshold
echo "βœ… Performance benchmarks completed"
# Parse the latest JSON report for additional checks
LATEST_REPORT=$(ls -t results/performance/${{ matrix.environment }}/automation_report_*.json | head -n1)
if [ -f "$LATEST_REPORT" ]; then
echo "πŸ“Š Analyzing performance report: $LATEST_REPORT"
# Extract key metrics using Python
python -c "
import json
import sys
with open('$LATEST_REPORT', 'r') as f:
report = json.load(f)
ci_status = report['ci_cd']['ci_status']
success_rate = report['ci_cd']['success_rate']
critical_issues = len(report['ci_cd']['critical_issues'])
regressions = report['ci_cd']['regressions_count']
print(f'CI Status: {ci_status}')
print(f'Success Rate: {success_rate:.1f}%')
print(f'Critical Issues: {critical_issues}')
print(f'Regressions: {regressions}')
if ci_status == 'FAIL':
print('❌ Performance benchmarks failed')
sys.exit(1)
elif critical_issues > 0:
print('⚠️ Critical performance issues detected')
sys.exit(1)
else:
print('βœ… Performance benchmarks passed')
"
else
echo "⚠️ No performance report found"
exit 1
fi
- name: Stop server
if: always()
run: |
if [ ! -z "$SERVER_PID" ]; then
kill $SERVER_PID || true
fi
# Job to run comprehensive performance analysis
performance-analysis:
runs-on: ubuntu-latest
needs: performance-benchmarks
if: always()
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Download all performance artifacts
uses: actions/download-artifact@v3
with:
path: artifacts/
- name: Analyze performance trends
run: |
echo "πŸ“ˆ Analyzing performance trends..."
# This could be enhanced to:
# 1. Compare performance across different environments
# 2. Generate trend reports over time
# 3. Create performance dashboards
# 4. Send notifications for significant changes
find artifacts/ -name "*.json" -type f | while read file; do
echo "Found performance report: $file"
# Basic analysis could be added here
done
- name: Generate performance summary
run: |
echo "## πŸ“Š Performance Summary" > performance-summary.md
echo "" >> performance-summary.md
echo "Performance benchmarks completed for all environments:" >> performance-summary.md
echo "" >> performance-summary.md
find artifacts/ -name "automation_report_*.md" -type f | while read file; do
env_name=$(echo "$file" | sed -n 's/.*performance-results-\([^/]*\).*/\1/p')
echo "- **$env_name**: [View Report]($file)" >> performance-summary.md
done
cat performance-summary.md
- name: Upload combined results
uses: actions/upload-artifact@v3
with:
name: performance-analysis
path: |
performance-summary.md
artifacts/
retention-days: 30