mirror of
https://github.com/vercel/workflow.git
synced 2026-09-14 19:59:43 +08:00
677867bd19
Backport of #1882
631 lines
23 KiB
YAML
631 lines
23 KiB
YAML
name: Performance Benchmarks
|
|
|
|
on:
|
|
pull_request:
|
|
branches: [main]
|
|
types: [opened, synchronize, reopened, labeled]
|
|
push:
|
|
branches: [main]
|
|
workflow_dispatch: # Allow manual triggers
|
|
inputs:
|
|
full_suite:
|
|
description: 'Run full benchmark suite (includes long-running 100+ step benchmarks)'
|
|
required: false
|
|
type: boolean
|
|
default: false
|
|
|
|
concurrency:
|
|
group: ${{ github.workflow }}-${{ github.ref }}
|
|
cancel-in-progress: ${{ github.ref != 'refs/heads/main' }}
|
|
|
|
jobs:
|
|
# Phase 0: Update PR comment to show benchmarks are running
|
|
pr-comment-start:
|
|
name: Create PR Comment
|
|
runs-on: ubuntu-latest
|
|
if: github.event_name == 'pull_request' && !contains(github.event.pull_request.labels.*.name, 'workflow-server-test')
|
|
timeout-minutes: 2
|
|
|
|
steps:
|
|
- name: Find existing benchmark comment
|
|
uses: peter-evans/find-comment@v3
|
|
id: find-comment
|
|
with:
|
|
issue-number: ${{ github.event.pull_request.number }}
|
|
comment-author: 'github-actions[bot]'
|
|
body-includes: '<!-- benchmark-results -->'
|
|
|
|
- name: Get existing comment body
|
|
if: steps.find-comment.outputs.comment-id != ''
|
|
id: get-comment
|
|
uses: actions/github-script@v7
|
|
with:
|
|
script: |
|
|
const comment = await github.rest.issues.getComment({
|
|
owner: context.repo.owner,
|
|
repo: context.repo.repo,
|
|
comment_id: ${{ steps.find-comment.outputs.comment-id }}
|
|
});
|
|
// Extract the results section (everything after the header and running message)
|
|
const body = comment.data.body;
|
|
// Remove any existing stale warning and running message
|
|
let resultsSection = body
|
|
.replace(/<!-- benchmark-results -->\n## 📊 Benchmark Results\n\n> ⚠️ \*\*Results below are stale\*\*[^\n]*\n\n/g, '')
|
|
.replace(/<!-- benchmark-results -->\n## 📊 Benchmark Results\n\n/g, '')
|
|
.replace(/⏳ \*\*Benchmarks are running\.\.\.\*\*\n\n---\n_Started at:[^_]*_\n\n---\n\n/g, '')
|
|
.replace(/⏳ \*\*Benchmarks are running\.\.\.\*\*\n\n---\n_Started at:[^_]*_/g, '')
|
|
.trim();
|
|
|
|
// If there's actual content left (benchmark tables), save it
|
|
if (resultsSection && resultsSection.includes('|')) {
|
|
core.setOutput('has-results', 'true');
|
|
core.setOutput('previous-results', resultsSection);
|
|
} else {
|
|
core.setOutput('has-results', 'false');
|
|
}
|
|
|
|
- name: Create new benchmark comment
|
|
if: steps.find-comment.outputs.comment-id == ''
|
|
uses: marocchino/sticky-pull-request-comment@v2
|
|
with:
|
|
header: benchmark-results
|
|
message: |
|
|
<!-- benchmark-results -->
|
|
## 📊 Benchmark Results
|
|
|
|
⏳ **Benchmarks are running...**
|
|
|
|
This comment will be updated with the results when the benchmarks complete.
|
|
|
|
---
|
|
_Started at: ${{ github.event.pull_request.updated_at }}_
|
|
|
|
- name: Update existing benchmark comment with stale warning
|
|
if: steps.find-comment.outputs.comment-id != '' && steps.get-comment.outputs.has-results == 'true'
|
|
uses: marocchino/sticky-pull-request-comment@v2
|
|
with:
|
|
header: benchmark-results
|
|
message: |
|
|
<!-- benchmark-results -->
|
|
## 📊 Benchmark Results
|
|
|
|
> ⚠️ **Results below are stale** and not from the latest commit. This comment will be updated when CI completes on the latest run.
|
|
|
|
⏳ **Benchmarks are running...**
|
|
|
|
---
|
|
_Started at: ${{ github.event.pull_request.updated_at }}_
|
|
|
|
---
|
|
|
|
${{ steps.get-comment.outputs.previous-results }}
|
|
|
|
- name: Update existing benchmark comment without results
|
|
if: steps.find-comment.outputs.comment-id != '' && steps.get-comment.outputs.has-results != 'true'
|
|
uses: marocchino/sticky-pull-request-comment@v2
|
|
with:
|
|
header: benchmark-results
|
|
message: |
|
|
<!-- benchmark-results -->
|
|
## 📊 Benchmark Results
|
|
|
|
⏳ **Benchmarks are running...**
|
|
|
|
This comment will be updated with the results when the benchmarks complete.
|
|
|
|
---
|
|
_Started at: ${{ github.event.pull_request.updated_at }}_
|
|
|
|
# Phase 1: Build all packages (not workbenches)
|
|
build:
|
|
name: Build Packages
|
|
runs-on: ubuntu-latest
|
|
if: ${{ !contains(github.event.pull_request.labels.*.name, 'workflow-server-test') }}
|
|
timeout-minutes: 30
|
|
env:
|
|
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
|
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
|
|
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Setup environment
|
|
uses: ./.github/actions/setup-workflow-dev
|
|
with:
|
|
build-packages: 'true'
|
|
|
|
# Cache node_modules and package build outputs
|
|
- name: Upload build artifacts
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: build-artifacts
|
|
path: |
|
|
node_modules
|
|
packages/*/dist
|
|
packages/core/src/version.ts
|
|
retention-days: 1
|
|
|
|
# Phase 2a: Local benchmarks (no postgres)
|
|
benchmark-local:
|
|
name: Benchmark Local (${{ matrix.app }})
|
|
runs-on: ubuntu-latest
|
|
needs: build
|
|
if: ${{ !contains(github.event.pull_request.labels.*.name, 'workflow-server-test') }}
|
|
timeout-minutes: 60
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
# Note: Use actual directory names, not symlinks (nitro -> nitro-v3)
|
|
app: [nextjs-turbopack, nitro-v3, express]
|
|
|
|
env:
|
|
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
|
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
|
|
WORKFLOW_PUBLIC_MANIFEST: '1'
|
|
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Setup environment
|
|
uses: ./.github/actions/setup-workflow-dev
|
|
with:
|
|
install-dependencies: 'false'
|
|
build-packages: 'false'
|
|
|
|
- name: Download build artifacts
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
name: build-artifacts
|
|
path: .
|
|
|
|
- name: Install dependencies
|
|
run: pnpm install --frozen-lockfile
|
|
|
|
# For PRs, download baseline results from the PR's base branch
|
|
- name: Download baseline from PR base branch
|
|
if: github.event_name == 'pull_request'
|
|
continue-on-error: true
|
|
uses: dawidd6/action-download-artifact@v6
|
|
with:
|
|
workflow: benchmarks.yml
|
|
branch: ${{ github.event.pull_request.base.ref }}
|
|
name: baseline-benchmark-results
|
|
path: baseline-results
|
|
if_no_artifact_found: warn
|
|
|
|
- name: Build workbench
|
|
run: pnpm turbo run build --filter='./workbench/${{ matrix.app }}'
|
|
|
|
- name: Run benchmarks
|
|
env:
|
|
DEPLOYMENT_URL: "http://localhost:3000"
|
|
APP_NAME: ${{ matrix.app }}
|
|
# Run full suite on nextjs-turbopack only (stress tests are too slow to run on all apps)
|
|
BENCHMARK_FULL_SUITE: ${{ matrix.app == 'nextjs-turbopack' && ((github.event_name == 'workflow_dispatch' && inputs.full_suite) || contains(github.event.pull_request.labels.*.name, 'stress-test')) }}
|
|
run: |
|
|
cd workbench/${{ matrix.app }}
|
|
pnpm start &
|
|
echo "Waiting for server to start..."
|
|
sleep 15
|
|
cd ../..
|
|
pnpm vitest bench packages/core/e2e/bench.bench.ts --run --outputJson=bench-results-${{ matrix.app }}-local.json
|
|
|
|
- name: Render benchmark results
|
|
uses: ./.github/actions/render-benchmarks
|
|
with:
|
|
benchmark-file: bench-results-${{ matrix.app }}-local.json
|
|
app-name: ${{ matrix.app }}
|
|
backend: local
|
|
baseline-file: baseline-results/bench-results-${{ matrix.app }}-local.json
|
|
|
|
- name: Upload benchmark results
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: bench-results-${{ matrix.app }}-local
|
|
path: |
|
|
bench-results-${{ matrix.app }}-local.json
|
|
bench-timings-${{ matrix.app }}-local.json
|
|
|
|
# Phase 2b: Postgres benchmarks (with postgres service)
|
|
benchmark-postgres:
|
|
name: Benchmark Postgres (${{ matrix.app }})
|
|
runs-on: ubuntu-latest
|
|
needs: build
|
|
if: ${{ !contains(github.event.pull_request.labels.*.name, 'workflow-server-test') }}
|
|
timeout-minutes: 60
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
# Note: Use actual directory names, not symlinks (nitro -> nitro-v3)
|
|
app: [nextjs-turbopack, nitro-v3, express]
|
|
|
|
services:
|
|
postgres:
|
|
image: postgres:18-alpine
|
|
env:
|
|
POSTGRES_USER: world
|
|
POSTGRES_PASSWORD: world
|
|
POSTGRES_DB: world
|
|
ports:
|
|
- 5432:5432
|
|
options: >-
|
|
--health-cmd pg_isready
|
|
--health-interval 10s
|
|
--health-timeout 5s
|
|
--health-retries 5
|
|
|
|
env:
|
|
TURBO_TOKEN: ${{ secrets.TURBO_TOKEN }}
|
|
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
|
|
WORKFLOW_PUBLIC_MANIFEST: '1'
|
|
WORKFLOW_TARGET_WORLD: "@workflow/world-postgres"
|
|
WORKFLOW_POSTGRES_URL: "postgres://world:world@localhost:5432/world"
|
|
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Setup environment
|
|
uses: ./.github/actions/setup-workflow-dev
|
|
with:
|
|
install-dependencies: 'false'
|
|
build-packages: 'false'
|
|
|
|
- name: Download build artifacts
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
name: build-artifacts
|
|
path: .
|
|
|
|
- name: Install dependencies
|
|
run: pnpm install --frozen-lockfile
|
|
|
|
# For PRs, download baseline results from the PR's base branch
|
|
- name: Download baseline from PR base branch
|
|
if: github.event_name == 'pull_request'
|
|
continue-on-error: true
|
|
uses: dawidd6/action-download-artifact@v6
|
|
with:
|
|
workflow: benchmarks.yml
|
|
branch: ${{ github.event.pull_request.base.ref }}
|
|
name: baseline-benchmark-results
|
|
path: baseline-results
|
|
if_no_artifact_found: warn
|
|
|
|
- name: Setup PostgreSQL database
|
|
run: ./packages/world-postgres/bin/setup.js
|
|
|
|
# Build workbench with postgres world (build output differs based on target world)
|
|
- name: Build workbench for postgres
|
|
run: pnpm turbo run build --filter='./workbench/${{ matrix.app }}'
|
|
|
|
- name: Run benchmarks
|
|
env:
|
|
DEPLOYMENT_URL: "http://localhost:3000"
|
|
APP_NAME: ${{ matrix.app }}
|
|
# Run full suite on nextjs-turbopack only (stress tests are too slow to run on all apps)
|
|
BENCHMARK_FULL_SUITE: ${{ matrix.app == 'nextjs-turbopack' && ((github.event_name == 'workflow_dispatch' && inputs.full_suite) || contains(github.event.pull_request.labels.*.name, 'stress-test')) }}
|
|
run: |
|
|
cd workbench/${{ matrix.app }}
|
|
pnpm start &
|
|
echo "Waiting for server to start..."
|
|
sleep 15
|
|
cd ../..
|
|
pnpm vitest bench packages/core/e2e/bench.bench.ts --run --outputJson=bench-results-${{ matrix.app }}-postgres.json
|
|
|
|
- name: Render benchmark results
|
|
uses: ./.github/actions/render-benchmarks
|
|
with:
|
|
benchmark-file: bench-results-${{ matrix.app }}-postgres.json
|
|
app-name: ${{ matrix.app }}
|
|
backend: postgres
|
|
baseline-file: baseline-results/bench-results-${{ matrix.app }}-postgres.json
|
|
|
|
- name: Upload benchmark results
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: bench-results-${{ matrix.app }}-postgres
|
|
path: |
|
|
bench-results-${{ matrix.app }}-postgres.json
|
|
bench-timings-${{ matrix.app }}-postgres.json
|
|
|
|
# Phase 2c: Vercel benchmarks (needs build artifacts for packages)
|
|
benchmark-vercel:
|
|
name: Benchmark Vercel (${{ matrix.app.name }})
|
|
runs-on: ubuntu-latest
|
|
needs: build
|
|
if: ${{ !contains(github.event.pull_request.labels.*.name, 'workflow-server-test') }}
|
|
timeout-minutes: 90
|
|
permissions:
|
|
id-token: write
|
|
contents: read
|
|
deployments: read
|
|
strategy:
|
|
fail-fast: false
|
|
matrix:
|
|
app:
|
|
- name: "nextjs-turbopack"
|
|
project-id: "prj_yjkM7UdHliv8bfxZ1sMJQf1pMpdi"
|
|
project-slug: "example-nextjs-workflow-turbopack"
|
|
- name: "nitro-v3"
|
|
project-id: "prj_e7DZirYdLrQKXNrlxg7KmA6ABx8r"
|
|
project-slug: "workbench-nitro-workflow"
|
|
- name: "express"
|
|
project-id: "prj_cCZjpBy92VRbKHHbarDMhOHtkuIr"
|
|
project-slug: "workbench-express-workflow"
|
|
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Setup environment
|
|
uses: ./.github/actions/setup-workflow-dev
|
|
with:
|
|
install-dependencies: 'false'
|
|
build-packages: 'false'
|
|
|
|
- name: Download build artifacts
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
name: build-artifacts
|
|
path: .
|
|
|
|
- name: Install dependencies
|
|
run: pnpm install --frozen-lockfile
|
|
|
|
# For PRs, download baseline results from the PR's base branch
|
|
- name: Download baseline from PR base branch
|
|
if: github.event_name == 'pull_request'
|
|
continue-on-error: true
|
|
uses: dawidd6/action-download-artifact@v6
|
|
with:
|
|
workflow: benchmarks.yml
|
|
branch: ${{ github.event.pull_request.base.ref }}
|
|
name: baseline-benchmark-results
|
|
path: baseline-results
|
|
if_no_artifact_found: warn
|
|
|
|
- name: Wait for Vercel deployment
|
|
id: waitForDeployment
|
|
uses: ./.github/actions/wait-for-vercel-project
|
|
with:
|
|
team-id: "team_nO2mCG4W8IxPIeKoSsqwAxxB"
|
|
project-id: ${{ matrix.app.project-id }}
|
|
vercel-token: ${{ secrets.VERCEL_LABS_TOKEN }}
|
|
timeout: 1000
|
|
check-interval: 15
|
|
environment: ${{ github.ref == 'refs/heads/main' && 'production' || 'preview' }}
|
|
|
|
- name: Run benchmarks
|
|
env:
|
|
DEPLOYMENT_URL: ${{ steps.waitForDeployment.outputs.deployment-url }}
|
|
APP_NAME: ${{ matrix.app.name }}
|
|
VERCEL_DEPLOYMENT_ID: ${{ steps.waitForDeployment.outputs.deployment-id }}
|
|
WORKFLOW_VERCEL_ENV: ${{ github.ref == 'refs/heads/main' && 'production' || 'preview' }}
|
|
WORKFLOW_VERCEL_AUTH_TOKEN: ${{ secrets.VERCEL_LABS_TOKEN }}
|
|
WORKFLOW_VERCEL_TEAM: "team_nO2mCG4W8IxPIeKoSsqwAxxB"
|
|
WORKFLOW_VERCEL_PROJECT: ${{ matrix.app.project-id }}
|
|
WORKFLOW_VERCEL_PROJECT_SLUG: ${{ matrix.app.project-slug }}
|
|
# Trusted-sources OIDC token is minted on demand by
|
|
# scripts/trusted-sources-headers.mjs via the runner's
|
|
# ACTIONS_ID_TOKEN_REQUEST_URL/_TOKEN env vars (auto-set when
|
|
# `permissions: id-token: write` is on the job) and re-minted
|
|
# before its 5-minute expiry, so long benchmark runs keep a
|
|
# fresh token throughout.
|
|
# See: https://vercel.com/docs/deployment-protection/methods-to-bypass-deployment-protection/trusted-sources
|
|
# Run full suite on nextjs-turbopack only (stress tests are too slow to run on all apps)
|
|
BENCHMARK_FULL_SUITE: ${{ matrix.app.name == 'nextjs-turbopack' && ((github.event_name == 'workflow_dispatch' && inputs.full_suite) || contains(github.event.pull_request.labels.*.name, 'stress-test')) }}
|
|
run: |
|
|
pnpm vitest bench packages/core/e2e/bench.bench.ts --run --outputJson=bench-results-${{ matrix.app.name }}-vercel.json
|
|
|
|
- name: Render benchmark results
|
|
uses: ./.github/actions/render-benchmarks
|
|
with:
|
|
benchmark-file: bench-results-${{ matrix.app.name }}-vercel.json
|
|
app-name: ${{ matrix.app.name }}
|
|
backend: vercel
|
|
baseline-file: baseline-results/bench-results-${{ matrix.app.name }}-vercel.json
|
|
|
|
- name: Upload benchmark results
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: bench-results-${{ matrix.app.name }}-vercel
|
|
path: |
|
|
bench-results-${{ matrix.app.name }}-vercel.json
|
|
bench-timings-${{ matrix.app.name }}-vercel.json
|
|
|
|
# Phase 2d: Community World benchmarks (dynamically generated from worlds-manifest.json)
|
|
getCommunityWorldsMatrix:
|
|
name: Get Community Worlds Matrix
|
|
runs-on: ubuntu-latest
|
|
if: ${{ !contains(github.event.pull_request.labels.*.name, 'workflow-server-test') }}
|
|
outputs:
|
|
matrix: ${{ steps.set-matrix.outputs.matrix }}
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Setup environment
|
|
uses: ./.github/actions/setup-workflow-dev
|
|
with:
|
|
install-dependencies: 'false'
|
|
build-packages: 'false'
|
|
|
|
- id: set-matrix
|
|
run: echo "matrix=$(node ./scripts/create-community-worlds-matrix.mjs)" >> $GITHUB_OUTPUT
|
|
|
|
benchmark-community:
|
|
name: Benchmark Community World (${{ matrix.world.name }})
|
|
if: ${{ !contains(github.event.pull_request.labels.*.name, 'workflow-server-test') }}
|
|
needs: [build, getCommunityWorldsMatrix]
|
|
strategy:
|
|
fail-fast: false
|
|
matrix: ${{ fromJson(needs.getCommunityWorldsMatrix.outputs.matrix) }}
|
|
uses: ./.github/workflows/benchmark-community-world.yml
|
|
with:
|
|
world-id: ${{ matrix.world.id }}
|
|
world-name: ${{ matrix.world.name }}
|
|
world-package: ${{ matrix.world.package }}
|
|
service-type: ${{ matrix.world.service-type }}
|
|
env-vars: ${{ matrix.world.env-vars }}
|
|
setup-command: ${{ matrix.world.setup-command }}
|
|
# Run full suite only when manually triggered with full_suite=true
|
|
full-suite: ${{ (github.event_name == 'workflow_dispatch' && inputs.full_suite) || contains(github.event.pull_request.labels.*.name, 'stress-test') }}
|
|
secrets: inherit
|
|
|
|
# Phase 3: Aggregate all benchmark results and create comparison
|
|
summary:
|
|
name: Benchmark Summary
|
|
runs-on: ubuntu-latest
|
|
needs: [benchmark-local, benchmark-postgres, benchmark-vercel, benchmark-community]
|
|
if: always() && !cancelled()
|
|
timeout-minutes: 10
|
|
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Download all benchmark artifacts
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
pattern: bench-results-*
|
|
path: benchmark-results
|
|
merge-multiple: true
|
|
|
|
- name: List downloaded files
|
|
run: find benchmark-results -type f -name "*.json" | sort
|
|
|
|
# For PRs, download baseline results from the PR's base branch
|
|
- name: Download baseline from PR base branch
|
|
if: github.event_name == 'pull_request'
|
|
continue-on-error: true
|
|
uses: dawidd6/action-download-artifact@v6
|
|
with:
|
|
workflow: benchmarks.yml
|
|
branch: ${{ github.event.pull_request.base.ref }}
|
|
name: baseline-benchmark-results
|
|
path: baseline-results
|
|
if_no_artifact_found: warn
|
|
|
|
- name: Aggregate and compare benchmarks
|
|
id: aggregate
|
|
run: |
|
|
# Check if baseline results exist
|
|
BASELINE_ARG=""
|
|
if [ -d "baseline-results" ] && [ "$(ls -A baseline-results 2>/dev/null)" ]; then
|
|
echo "Found baseline results from main branch"
|
|
BASELINE_ARG="--baseline baseline-results"
|
|
else
|
|
echo "No baseline results found, showing results without comparison"
|
|
fi
|
|
# Capture output to both file and step summary
|
|
node .github/scripts/aggregate-benchmarks.js benchmark-results $BASELINE_ARG --run-url "${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}" | tee benchmark-summary.md >> $GITHUB_STEP_SUMMARY
|
|
|
|
- name: Check benchmark job statuses
|
|
id: check-status
|
|
run: |
|
|
# Check if any benchmark jobs failed
|
|
LOCAL_STATUS="${{ needs.benchmark-local.result }}"
|
|
POSTGRES_STATUS="${{ needs.benchmark-postgres.result }}"
|
|
VERCEL_STATUS="${{ needs.benchmark-vercel.result }}"
|
|
COMMUNITY_STATUS="${{ needs.benchmark-community.result }}"
|
|
|
|
echo "local=$LOCAL_STATUS" >> $GITHUB_OUTPUT
|
|
echo "postgres=$POSTGRES_STATUS" >> $GITHUB_OUTPUT
|
|
echo "vercel=$VERCEL_STATUS" >> $GITHUB_OUTPUT
|
|
echo "community=$COMMUNITY_STATUS" >> $GITHUB_OUTPUT
|
|
|
|
# Community world failures are warnings, not errors
|
|
if [[ "$LOCAL_STATUS" == "failure" || "$POSTGRES_STATUS" == "failure" || "$VERCEL_STATUS" == "failure" ]]; then
|
|
echo "has_failures=true" >> $GITHUB_OUTPUT
|
|
else
|
|
echo "has_failures=false" >> $GITHUB_OUTPUT
|
|
fi
|
|
|
|
if [[ "$COMMUNITY_STATUS" == "failure" ]]; then
|
|
echo "has_warnings=true" >> $GITHUB_OUTPUT
|
|
else
|
|
echo "has_warnings=false" >> $GITHUB_OUTPUT
|
|
fi
|
|
|
|
- name: Update PR comment with results
|
|
if: github.event_name == 'pull_request'
|
|
uses: marocchino/sticky-pull-request-comment@v2
|
|
with:
|
|
header: benchmark-results
|
|
path: benchmark-summary.md
|
|
|
|
- name: Append failure notice to PR comment
|
|
if: github.event_name == 'pull_request' && steps.check-status.outputs.has_failures == 'true'
|
|
uses: marocchino/sticky-pull-request-comment@v2
|
|
with:
|
|
header: benchmark-results
|
|
append: true
|
|
message: |
|
|
|
|
---
|
|
❌ **Some benchmark jobs failed:**
|
|
- Local: ${{ needs.benchmark-local.result }}
|
|
- Postgres: ${{ needs.benchmark-postgres.result }}
|
|
- Vercel: ${{ needs.benchmark-vercel.result }}
|
|
|
|
Check the [workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details.
|
|
|
|
- name: Append community warning to PR comment
|
|
if: github.event_name == 'pull_request' && steps.check-status.outputs.has_warnings == 'true'
|
|
uses: marocchino/sticky-pull-request-comment@v2
|
|
with:
|
|
header: benchmark-results
|
|
append: true
|
|
message: |
|
|
|
|
---
|
|
⚠️ **Community world benchmarks failed** (non-blocking):
|
|
- Community Worlds: ${{ needs.benchmark-community.result }}
|
|
|
|
Check the [workflow run](${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}) for details.
|
|
|
|
# On main branch, save results as baseline for future PR comparisons
|
|
- name: Upload baseline results
|
|
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: baseline-benchmark-results
|
|
path: benchmark-results/
|
|
retention-days: 90
|
|
|
|
# Publish benchmark results to GitHub Pages (main branch only)
|
|
publish-results:
|
|
name: Publish Benchmark Results
|
|
runs-on: ubuntu-latest
|
|
needs: [summary]
|
|
if: github.event_name == 'push' && github.ref == 'refs/heads/main'
|
|
timeout-minutes: 5
|
|
|
|
permissions:
|
|
contents: write
|
|
|
|
steps:
|
|
- uses: actions/checkout@v4
|
|
|
|
- name: Download all benchmark artifacts
|
|
uses: actions/download-artifact@v4
|
|
with:
|
|
pattern: bench-*
|
|
path: benchmark-results
|
|
merge-multiple: true
|
|
|
|
- name: Generate docs data
|
|
run: |
|
|
mkdir -p docs-data
|
|
node .github/scripts/generate-docs-data.js \
|
|
--type benchmarks \
|
|
--results-dir benchmark-results \
|
|
--output docs-data/benchmark-results.json \
|
|
--commit "${{ github.sha }}" \
|
|
--branch "${{ github.ref_name }}"
|
|
|
|
- name: Deploy to GitHub Pages
|
|
uses: peaceiris/actions-gh-pages@v4
|
|
with:
|
|
github_token: ${{ secrets.GITHUB_TOKEN }}
|
|
publish_dir: ./docs-data
|
|
destination_dir: ci
|
|
keep_files: true
|