diff --git a/.github/workflows/benchmark-policy.yml b/.github/workflows/benchmark-policy.yml index 4074b7c..7417f55 100644 --- a/.github/workflows/benchmark-policy.yml +++ b/.github/workflows/benchmark-policy.yml @@ -13,16 +13,41 @@ permissions: jobs: policy: name: Benchmark Policy + concurrency: + group: benchmark-policy-${{ github.event.pull_request.number }} + cancel-in-progress: >- + ${{ + !contains(fromJSON('["labeled", "unlabeled", "edited"]'), github.event.action) || + contains(fromJSON('["labeled", "unlabeled"]'), github.event.action) && github.event.label.name == 'benchmarks: skip' || + github.event.action == 'edited' && github.event.changes.base != null + }} runs-on: ubuntu-latest timeout-minutes: 10 steps: + - id: event + name: Classify PR event + env: + RELEVANT: >- + ${{ + !contains(fromJSON('["labeled", "unlabeled", "edited"]'), github.event.action) || + contains(fromJSON('["labeled", "unlabeled"]'), github.event.action) && github.event.label.name == 'benchmarks: skip' || + github.event.action == 'edited' && github.event.changes.base != null + }} + run: echo "relevant=$RELEVANT" >> "$GITHUB_OUTPUT" - uses: actions/checkout@v7 + if: ${{ steps.event.outputs.relevant == 'true' }} with: persist-credentials: false - uses: actions/setup-node@v7 + if: ${{ steps.event.outputs.relevant == 'true' }} with: node-version: '24' - run: npm ci --ignore-scripts + if: ${{ steps.event.outputs.relevant == 'true' }} - run: node scripts/pr-policy.ts + if: ${{ steps.event.outputs.relevant == 'true' }} env: - GH_TOKEN: ${{ github.token }} \ No newline at end of file + GH_TOKEN: ${{ github.token }} + - name: Preserve the current policy result + if: ${{ steps.event.outputs.relevant == 'false' }} + run: echo "Policy inputs are unchanged" \ No newline at end of file diff --git a/.github/workflows/benchmark-trigger.yml b/.github/workflows/benchmark-trigger.yml index 2cbfe4c..7b1ee1f 100644 --- a/.github/workflows/benchmark-trigger.yml +++ b/.github/workflows/benchmark-trigger.yml @@ -13,7 +13,27 @@ permissions: issues: read jobs: + event: + name: Classify Benchmark Event + runs-on: ubuntu-latest + timeout-minutes: 5 + outputs: + relevant: ${{ steps.event.outputs.relevant }} + steps: + - id: event + env: + RELEVANT: >- + ${{ + github.event_name == 'push' || + !contains(fromJSON('["labeled", "unlabeled", "edited"]'), github.event.action) || + contains(fromJSON('["labeled", "unlabeled"]'), github.event.action) && github.event.label.name == 'benchmarks: skip' || + github.event.action == 'edited' && github.event.changes.base != null + }} + run: echo "relevant=$RELEVANT" >> "$GITHUB_OUTPUT" + workload: + needs: event + if: ${{ needs.event.outputs.relevant == 'true' }} concurrency: group: benchmark-${{ github.event.pull_request.number || github.ref }} cancel-in-progress: true @@ -22,17 +42,26 @@ jobs: benchmark-status: name: Benchmark Status if: ${{ always() && github.event_name == 'pull_request' }} - needs: workload + needs: [event, workload] + concurrency: + group: benchmark-${{ github.event.pull_request.number }} + cancel-in-progress: false runs-on: ubuntu-latest timeout-minutes: 5 steps: - uses: actions/checkout@v7 + if: ${{ needs.event.outputs.relevant == 'true' }} with: persist-credentials: false - uses: actions/setup-node@v7 + if: ${{ needs.event.outputs.relevant == 'true' }} with: node-version: '24' - name: Require the benchmark workload to succeed + if: ${{ needs.event.outputs.relevant == 'true' }} env: BENCHMARK_JOB_RESULTS: ${{ toJSON(needs) }} - run: node scripts/check-ci-status.ts \ No newline at end of file + run: node scripts/check-ci-status.ts + - name: Preserve the current benchmark result + if: ${{ needs.event.outputs.relevant == 'false' }} + run: echo "Benchmark inputs are unchanged" \ No newline at end of file diff --git a/docs/README.md b/docs/README.md index 664a417..59954af 100644 --- a/docs/README.md +++ b/docs/README.md @@ -106,7 +106,7 @@ The preview URL then returns 404. ## CI Rules * `benchmarks: skip` replaces publishable measurements with one-request smoke coverage on KVM and MSHV. Smoke results are not published. Dependabot applies the label automatically. -* Required checks evaluate the current PR policy on every subscribed event. Label and description edits restart the benchmark workflow. Measurements run unless `benchmarks: skip` is present. +* Required checks reevaluate when code, the base branch, or the `benchmarks: skip` label changes. Other labels and title or body edits refresh the required contexts after active checks finish. * Each of the 36 measurement jobs runs all three strategies sequentially with a fresh server process for each. Retrying a job repeats its three strategies. * Preview builds run independently of benchmarks. Draft PRs have no preview. * Production uses published history. Previews include matching pending results when available.