mirror of
https://github.com/hanzoai/next.js.git
synced 2026-09-24 17:00:51 +00:00
[ci] Avoid running full CI mid-stack for GH-native stacks, same as we do for Graphite (#95218)
Running CI only on the top and bottom of the stack avoids expensive `O(n^2)` behavior when merging one PR at a time and recursively rebasing all the others starting at the bottom of the stack. GitHub added this to the webhook/GH actions object for us to be able to do this: https://vercel.slack.com/archives/C01SKER9S1G/p1777926655162839 Prior to this PR being part of a stack, fails open (runs full CI): <img width="1938" height="993" alt="Screenshot 2026-06-26 at 3 03 37 PM" src="https://github.com/user-attachments/assets/54d6055a-2860-45b3-a03a-a9356b3db2a4" /> Example mid-stack run (skips the full e2e jobs): <img width="1917" height="664" alt="Screenshot 2026-06-26 at 3 24 33 PM" src="https://github.com/user-attachments/assets/9ee466da-f3ea-4298-b5b8-2527d197c121" /> https://github.com/vercel/next.js/actions/runs/28268549361/job/83760907003?pr=95219
This commit is contained in:
@@ -22,7 +22,7 @@ env:
|
||||
|
||||
jobs:
|
||||
optimize-ci:
|
||||
uses: ./.github/workflows/graphite_ci_optimizer.yml
|
||||
uses: ./.github/workflows/pr_stack_optimizer.yml
|
||||
secrets: inherit
|
||||
|
||||
changes:
|
||||
|
||||
+32
-8
@@ -1,16 +1,19 @@
|
||||
# Avoid running the full CI on mid-stack PRs: https://graphite.dev/docs/stacking-and-ci
|
||||
#
|
||||
# We still run some high-signal low-cost jobs (e.g. lint, unit tests) on these mid-stack PRs, just
|
||||
# not anything slow (e.g. integration tests).
|
||||
# This supports both Graphite stacks and GitHub's native stacked PRs. For either kind of stack, we
|
||||
# only run the full CI on the very top and very bottom of the stack.
|
||||
#
|
||||
# We still run some high-signal low-cost jobs (e.g. lint, unit tests) on mid-stack PRs, just not
|
||||
# anything slow (e.g. integration tests).
|
||||
#
|
||||
# Because we don't use Graphite's CI batching, full CI will still run on every PR individually
|
||||
# before it merges. The goal is just to avoid wasting CI capacity when frequently rebasing large
|
||||
# stacks.
|
||||
#
|
||||
# This can by bypassed by labeling a PR with 'CI Bypass Graphite Optimization', and manually
|
||||
# re-running CI.
|
||||
# This can by bypassed by labeling a PR with 'CI Bypass PR Stack Optimization' (or the legacy
|
||||
# 'CI Bypass Graphite Optimization' label), and manually re-running CI.
|
||||
|
||||
name: Graphite CI Optimizer
|
||||
name: PR Stack Optimizer
|
||||
on:
|
||||
workflow_call:
|
||||
outputs:
|
||||
@@ -29,16 +32,34 @@ env:
|
||||
HAS_BYPASS_LABEL: |-
|
||||
${{
|
||||
github.event_name == 'pull_request' &&
|
||||
contains(github.event.pull_request.labels.*.name, 'CI Bypass Graphite Optimization')
|
||||
(
|
||||
contains(github.event.pull_request.labels.*.name, 'CI Bypass PR Stack Optimization') ||
|
||||
contains(github.event.pull_request.labels.*.name, 'CI Bypass Graphite Optimization')
|
||||
)
|
||||
}}
|
||||
# GitHub's native stacked PRs expose the PR's position within the stack. We skip expensive CI on
|
||||
# mid-stack PRs. Fail open if we don't have `stack.size`.
|
||||
IS_MID_STACK_NATIVE: |-
|
||||
${{
|
||||
github.event_name == 'pull_request' &&
|
||||
github.event.pull_request.stack.size != '' &&
|
||||
github.event.pull_request.stack.position != 1 &&
|
||||
github.event.pull_request.stack.position != github.event.pull_request.stack.size
|
||||
}}
|
||||
jobs:
|
||||
optimize-ci:
|
||||
name: Graphite CI Optimizer
|
||||
name: PR Stack Optimizer
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
# `== 'true'` comparison: If `step.check-skip` fails (`continue-on-error`), that output will
|
||||
# be an empty string, which sets our `skip` output to `'false'`.
|
||||
skip: ${{ env.HAS_BYPASS_LABEL == 'false' && steps.check-skip.outputs.skip == 'true' }}
|
||||
#
|
||||
# We skip if either Graphite's optimizer says to skip, or the PR is a mid-stack PR in a
|
||||
# GitHub native stack. The bypass label overrides both.
|
||||
skip: |-
|
||||
${{ env.HAS_BYPASS_LABEL == 'false' && (
|
||||
steps.check-skip.outputs.skip == 'true' || env.IS_MID_STACK_NATIVE == 'true'
|
||||
) }}
|
||||
steps:
|
||||
- name: Optimize CI
|
||||
id: check-skip
|
||||
@@ -52,6 +73,9 @@ jobs:
|
||||
echo 'github.event_name: ${{ github.event_name }}'
|
||||
echo "secrets.GRAPHITE_CI_OPTIMIZER_TOKEN != '': ${GRAPHITE_CI_OPTIMIZER_TOKEN_NON_EMPTY}"
|
||||
echo 'env.HAS_BYPASS_LABEL: ${{ env.HAS_BYPASS_LABEL }}'
|
||||
echo 'env.IS_MID_STACK_NATIVE: ${{ env.IS_MID_STACK_NATIVE }}'
|
||||
echo 'github.event.pull_request.stack.position: ${{ github.event.pull_request.stack.position }}'
|
||||
echo 'github.event.pull_request.stack.size: ${{ github.event.pull_request.stack.size }}'
|
||||
echo 'steps.check-skip.outputs.skip: ${{ steps.check-skip.outputs.skip }}'
|
||||
|
||||
env:
|
||||
Reference in New Issue
Block a user