Skip to content

fix: capture bench output to file and guard against missing bench_out… #51

fix: capture bench output to file and guard against missing bench_out…

fix: capture bench output to file and guard against missing bench_out… #51

Workflow file for this run

name: Benchmarks
on:
push:
branches: [main, develop]
pull_request:
branches: [main, develop]
schedule:
# Run daily at 2AM UTC for nightly benchmarks
- cron: '0 2 * * *'
env:
CARGO_TERM_COLOR: always
RUST_BACKTRACE: 1
jobs:
benchmarks:
name: Run Benchmarks
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
token: ${{ secrets.GITHUB_TOKEN }}
- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
components: clippy, rustfmt
- name: Cache cargo registry
uses: actions/cache@v4
with:
path: |
~/.cargo/registry
~/.cargo/git
key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-
- name: Build benchmarks
run: cargo build --benches --release
- name: Run benchmarks (CI mode)
run: |
cargo bench --bench write_bench --bench read_bench --bench scan_bench --bench mixed_bench --bench stress_bench -- --noplot 2>&1 | tee bench_output.txt
exit ${PIPESTATUS[0]}
continue-on-error: true
env:
CI: true
- name: Upload benchmark results
uses: actions/upload-artifact@v4
with:
name: benchmark-results
path: |
bench_output.txt
target/criterion
retention-days: 30
- name: Generate benchmark summary
if: github.event_name != 'pull_request'
run: |
DATE=$(date -u '+%Y-%m-%d %H:%M UTC')
RUN_URL="https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
# Guard: abort gracefully if bench_output.txt is missing or empty
if [ ! -s bench_output.txt ]; then
echo "⚠️ bench_output.txt ausente ou vazio — o benchmark pode ter travado ou falhado."
{
echo "<!-- BENCHMARK_RESULTS_START -->"
echo "> ⚠️ CI em **${DATE}** — benchmark não produziu resultados. [Ver run](${RUN_URL})"
echo ""
echo "<!-- BENCHMARK_RESULTS_END -->"
} > bench_block.txt
perl -i -0pe '
my $block = do { open my $f, "bench_block.txt" or die; local $/; <$f> };
s|<!-- BENCHMARK_RESULTS_START -->.*?<!-- BENCHMARK_RESULTS_END -->|$block|gs;
' README.md
exit 0
fi
# Parse Criterion output: lines like "time: [X.XX µs X.XX µs X.XX µs]"
ROWS=""
CURRENT_BENCH=""
while IFS= read -r line; do
# Detect benchmark name (lines that don't start with whitespace and aren't empty)
if echo "$line" | grep -qE '^[a-zA-Z].*/{0,1}[a-zA-Z]'; then
CURRENT_BENCH=$(echo "$line" | sed 's|/| / |g' | xargs)
fi
# Detect timing line
if echo "$line" | grep -qE 'time:.*\['; then
# Extract the middle (median) value
MEDIAN=$(echo "$line" | grep -oE '\[[^]]+\]' | head -1 | sed 's/\[//' | sed 's/\]//' | awk '{print $3, $4}')
if [ -n "$CURRENT_BENCH" ] && [ -n "$MEDIAN" ]; then
ROWS="$ROWS\n| \`$CURRENT_BENCH\` | $MEDIAN |"
fi
fi
done < bench_output.txt
# Build the full block
{
echo "<!-- BENCHMARK_RESULTS_START -->"
echo "> 🤖 Auto-updated by CI on **${DATE}** — [View run](${RUN_URL})"
echo ""
if [ -n "$ROWS" ]; then
echo "| Benchmark | Tempo (mediana) |"
echo "|-----------|----------------|"
printf "%b" "$ROWS"
echo ""
else
echo "*Nenhum resultado parseado — verifique os [artefatos do run](${RUN_URL}).*"
fi
echo ""
echo "<!-- BENCHMARK_RESULTS_END -->"
} > bench_block.txt
# Inject block into README between markers
perl -i -0pe '
my $block = do { open my $f, "bench_block.txt" or die; local $/; <$f> };
s|<!-- BENCHMARK_RESULTS_START -->.*?<!-- BENCHMARK_RESULTS_END -->|$block|gs;
' README.md
- name: Commit updated README
if: github.event_name != 'pull_request'
run: |
git config user.name "ElioNeto"
git config user.email "netoo.elio@hotmail.com"
git add README.md
git diff --staged --quiet || git commit -m "docs: update benchmark results [skip ci]"
git push
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Run clippy on benchmarks
run: cargo clippy --all-targets -- -D warnings
- name: Format check
run: cargo fmt --all -- --check