Remove shouldRevalidateStale concept from CacheHandlers #39026
Workflow file for this run
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
name: build-and-test | |
on: | |
push: | |
branches: ['canary'] | |
pull_request: | |
types: [opened, synchronize] | |
env: | |
NAPI_CLI_VERSION: 2.14.7 | |
TURBO_VERSION: 2.1.2 | |
NODE_MAINTENANCE_VERSION: 18 | |
NODE_LTS_VERSION: 20 | |
TEST_CONCURRENCY: 8 | |
# disable backtrace for test snapshots | |
RUST_BACKTRACE: 0 | |
TURBO_TEAM: 'vercel' | |
TURBO_REMOTE_ONLY: 'true' | |
NEXT_TELEMETRY_DISABLED: 1 | |
# we build a dev binary for use in CI so skip downloading | |
# canary next-swc binaries in the monorepo | |
NEXT_SKIP_NATIVE_POSTINSTALL: 1 | |
DATADOG_API_KEY: ${{ secrets.DATA_DOG_API_KEY }} | |
NEXT_JUNIT_TEST_REPORT: 'true' | |
DD_ENV: 'ci' | |
TEST_TIMINGS_TOKEN: ${{ secrets.TEST_TIMINGS_TOKEN }} | |
NEXT_TEST_JOB: 1 | |
jobs: | |
optimize-ci: | |
uses: ./.github/workflows/graphite_ci_optimizer.yml | |
secrets: inherit | |
changes: | |
name: Determine changes | |
runs-on: ubuntu-latest | |
permissions: | |
contents: read | |
steps: | |
- uses: actions/checkout@v4 | |
with: | |
fetch-depth: 25 | |
- name: check for docs only change | |
id: docs-change | |
run: | | |
echo "DOCS_ONLY<<EOF" >> $GITHUB_OUTPUT; | |
echo "$(node scripts/run-for-change.js --not --type docs --exec echo 'false')" >> $GITHUB_OUTPUT; | |
echo 'EOF' >> $GITHUB_OUTPUT | |
- name: check for release | |
id: is-release | |
run: | | |
if [[ $(node ./scripts/check-is-release.js 2> /dev/null || :) = v* ]]; | |
then | |
echo "IS_RELEASE=true" >> $GITHUB_OUTPUT | |
else | |
echo "IS_RELEASE=false" >> $GITHUB_OUTPUT | |
fi | |
outputs: | |
docs-only: ${{ steps.docs-change.outputs.DOCS_ONLY != 'false' }} | |
is-release: ${{ steps.is-release.outputs.IS_RELEASE == 'true' }} | |
build-native: | |
name: build-native | |
uses: ./.github/workflows/build_reusable.yml | |
with: | |
skipInstallBuild: 'yes' | |
stepName: 'build-native' | |
secrets: inherit | |
build-next: | |
name: build-next | |
uses: ./.github/workflows/build_reusable.yml | |
with: | |
skipNativeBuild: 'yes' | |
stepName: 'build-next' | |
secrets: inherit | |
lint: | |
name: lint | |
needs: ['build-native', 'build-next'] | |
uses: ./.github/workflows/build_reusable.yml | |
with: | |
afterBuild: pnpm lint-no-typescript && pnpm check-examples | |
stepName: 'lint' | |
secrets: inherit | |
validate-docs-links: | |
runs-on: ubuntu-latest | |
steps: | |
- uses: actions/checkout@v4 | |
- uses: actions/setup-node@v4 | |
with: | |
node-version: 18 | |
- run: corepack enable | |
- name: 'Run link checker' | |
run: node ./.github/actions/validate-docs-links/dist/index.js | |
env: | |
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} | |
check-types-precompiled: | |
name: types and precompiled | |
needs: ['changes', 'build-native', 'build-next'] | |
uses: ./.github/workflows/build_reusable.yml | |
with: | |
afterBuild: pnpm types-and-precompiled | |
stepName: 'types-and-precompiled' | |
secrets: inherit | |
test-cargo-unit: | |
name: test cargo unit | |
needs: ['changes', 'build-next'] | |
if: ${{ needs.changes.outputs.docs-only == 'false' }} | |
uses: ./.github/workflows/build_reusable.yml | |
with: | |
needsRust: 'yes' | |
needsNextest: 'yes' | |
skipNativeBuild: 'yes' | |
afterBuild: turbo run test-cargo-unit | |
mold: 'yes' | |
stepName: 'test-cargo-unit' | |
secrets: inherit | |
test-bench: | |
name: test cargo benches | |
needs: ['optimize-ci', 'changes', 'build-next'] | |
if: ${{ needs.optimize-ci.outputs.skip == 'false' && needs.changes.outputs.docs-only == 'false' }} | |
uses: ./.github/workflows/test-turbopack-rust-bench-test.yml | |
secrets: inherit | |
rust-check: | |
name: rust check | |
needs: ['changes', 'build-next'] | |
if: ${{ needs.changes.outputs.docs-only == 'false' }} | |
uses: ./.github/workflows/build_reusable.yml | |
with: | |
needsRust: 'yes' | |
skipInstallBuild: 'yes' | |
skipNativeBuild: 'yes' | |
afterBuild: turbo run rust-check | |
stepName: 'rust-check' | |
secrets: inherit | |
rust-doc-check: | |
name: rustdoc check | |
needs: ['changes', 'build-next'] | |
if: ${{ needs.changes.outputs.docs-only == 'false' }} | |
uses: ./.github/workflows/build_reusable.yml | |
with: | |
needsRust: 'yes' | |
skipInstallBuild: 'yes' | |
skipNativeBuild: 'yes' | |
afterBuild: ./scripts/deploy-turbopack-docs.sh | |
stepName: 'rust-doc-check' | |
secrets: inherit | |
ast-grep: | |
needs: ['changes', 'build-next'] | |
runs-on: ubuntu-latest | |
name: ast-grep lint | |
steps: | |
- uses: actions/checkout@v4 | |
- name: ast-grep lint step | |
uses: ast-grep/action@v1.5.0 | |
with: | |
version: 0.26.1 | |
devlow-bench: | |
name: Run devlow benchmarks | |
needs: ['optimize-ci', 'changes', 'build-next', 'build-native'] | |
if: ${{ needs.optimize-ci.outputs.skip == 'false' && needs.changes.outputs.docs-only == 'false' && !github.event.pull_request.head.repo.fork }} | |
strategy: | |
fail-fast: false | |
matrix: | |
mode: | |
- '--turbopack=false' | |
- '--turbopack=true' | |
selector: | |
- '--scenario=heavy-npm-deps-dev --page=homepage' | |
- '--scenario=heavy-npm-deps-build --page=homepage' | |
uses: ./.github/workflows/build_reusable.yml | |
with: | |
afterBuild: pnpm install && ./node_modules/.bin/devlow-bench ./scripts/devlow-bench.mjs --datadog=ubuntu-latest-16-core ${{ matrix.mode }} ${{ matrix.selector }} | |
stepName: 'devlow-bench-${{ matrix.mode }}-${{ matrix.selector }}' | |
secrets: inherit | |
test-turbopack-dev: | |
name: test turbopack dev | |
needs: ['optimize-ci', 'changes', 'build-next', 'build-native'] | |
if: ${{ needs.optimize-ci.outputs.skip == 'false' && needs.changes.outputs.docs-only == 'false' }} | |
strategy: | |
fail-fast: false | |
matrix: | |
group: [1/5, 2/5, 3/5, 4/5, 5/5] | |
# Empty value uses default | |
react: ['', '18.3.1'] | |
uses: ./.github/workflows/build_reusable.yml | |
with: | |
afterBuild: RUST_BACKTRACE=0 NEXT_EXTERNAL_TESTS_FILTERS="$(pwd)/test/turbopack-dev-tests-manifest.json" TURBOPACK=1 TURBOPACK_DEV=1 NEXT_E2E_TEST_TIMEOUT=240000 NEXT_TEST_MODE=dev NEXT_TEST_REACT_VERSION="${{ matrix.react }}" node run-tests.js --test-pattern '^(test\/(development|e2e))/.*\.test\.(js|jsx|ts|tsx)$' --timings -g ${{ matrix.group }} -c ${TEST_CONCURRENCY} | |
stepName: 'test-turbopack-dev-react-${{ matrix.react }}-${{ matrix.group }}' | |
secrets: inherit | |
test-turbopack-integration: | |
name: test turbopack development integration | |
needs: ['optimize-ci', 'changes', 'build-next', 'build-native'] | |
if: ${{ needs.optimize-ci.outputs.skip == 'false' && needs.changes.outputs.docs-only == 'false' }} | |
strategy: | |
fail-fast: false | |
matrix: | |
group: [1/5, 2/5, 3/5, 4/5, 5/5] | |
# Empty value uses default | |
react: [''] | |
uses: ./.github/workflows/build_reusable.yml | |
with: | |
nodeVersion: 18.18.2 | |
afterBuild: RUST_BACKTRACE=0 NEXT_EXTERNAL_TESTS_FILTERS="$(pwd)/test/turbopack-dev-tests-manifest.json" TURBOPACK=1 TURBOPACK_DEV=1 NEXT_TEST_REACT_VERSION="${{ matrix.react }}" node run-tests.js --timings -g ${{ matrix.group }} -c ${TEST_CONCURRENCY} --type integration | |
stepName: 'test-turbopack-integration-react-${{ matrix.react }}-${{ matrix.group }}' | |
secrets: inherit | |
test-turbopack-production: | |
name: test turbopack production | |
needs: ['optimize-ci', 'changes', 'build-next', 'build-native'] | |
if: ${{ needs.optimize-ci.outputs.skip == 'false' && needs.changes.outputs.docs-only == 'false' }} | |
strategy: | |
fail-fast: false | |
matrix: | |
group: [1/5, 2/5, 3/5, 4/5, 5/5] | |
# Empty value uses default | |
# TODO: Run with React 18. | |
# Integration tests use the installed React version in next/package.json.include: | |
# We can't easily switch like we do for e2e tests. | |
# Skipping this dimensions until we can figure out a way to test multiple React versions. | |
react: ['', '18.3.1'] | |
uses: ./.github/workflows/build_reusable.yml | |
with: | |
nodeVersion: 18.18.2 | |
afterBuild: RUST_BACKTRACE=0 NEXT_EXTERNAL_TESTS_FILTERS="$(pwd)/test/turbopack-build-tests-manifest.json" TURBOPACK=1 TURBOPACK_BUILD=1 NEXT_TEST_MODE=start NEXT_TEST_REACT_VERSION="${{ matrix.react }}" node run-tests.js --timings -g ${{ matrix.group }} -c ${TEST_CONCURRENCY} --type production | |
stepName: 'test-turbopack-production-react-${{ matrix.react }}-${{ matrix.group }}' | |
secrets: inherit | |
test-turbopack-production-integration: | |
name: test turbopack production integration | |
needs: ['optimize-ci', 'changes', 'build-next', 'build-native'] | |
if: ${{ needs.optimize-ci.outputs.skip == 'false' && needs.changes.outputs.docs-only == 'false' }} | |
strategy: | |
fail-fast: false | |
matrix: | |
group: [1/5, 2/5, 3/5, 4/5, 5/5] | |
uses: ./.github/workflows/build_reusable.yml | |
with: | |
nodeVersion: 18.18.2 | |
afterBuild: RUST_BACKTRACE=0 NEXT_EXTERNAL_TESTS_FILTERS="$(pwd)/test/turbopack-build-tests-manifest.json" TURBOPACK=1 TURBOPACK_BUILD=1 node run-tests.js --timings -g ${{ matrix.group }} -c ${TEST_CONCURRENCY} --type integration | |
stepName: 'test-turbopack-production-integration-${{ matrix.group }}' | |
secrets: inherit | |
test-next-swc-wasm: | |
name: test next-swc wasm | |
needs: ['optimize-ci', 'changes', 'build-next'] | |
if: ${{ needs.optimize-ci.outputs.skip == 'false' && needs.changes.outputs.docs-only == 'false' }} | |
uses: ./.github/workflows/build_reusable.yml | |
with: | |
afterBuild: rustup target add wasm32-unknown-unknown && curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh && node ./scripts/normalize-version-bump.js && turbo run build-wasm -- --target nodejs && git checkout . && mv crates/wasm/pkg crates/wasm/pkg-nodejs && node ./scripts/setup-wasm.mjs && NEXT_TEST_MODE=start TEST_WASM=true node run-tests.js test/production/pages-dir/production/test/index.test.ts test/e2e/streaming-ssr/index.test.ts | |
stepName: 'test-next-swc-wasm' | |
secrets: inherit | |
#[NOTE] currently this only checks building wasi target | |
test-next-swc-napi-wasi: | |
name: test next-swc wasi | |
needs: ['optimize-ci', 'changes', 'build-next'] | |
# TODO: Re-enable this when https://github.com/napi-rs/napi-rs/issues/2009 is addressed. | |
# Specifically, the `platform` value is now `threads` in | |
# https://github.com/napi-rs/napi-rs/blob/e4ad4767efaf093fdff3dc768856f6100a6e3f72/cli/src/api/build.ts#L530 | |
if: false | |
# if: ${{ needs.changes.outputs.docs-only == 'false' }} | |
uses: ./.github/workflows/build_reusable.yml | |
with: | |
afterBuild: rustup target add wasm32-wasip1-threads && turbo run build-native-wasi | |
stepName: 'test-next-swc-napi-wasi' | |
secrets: inherit | |
test-unit: | |
name: test unit | |
needs: ['changes'] | |
if: ${{ needs.changes.outputs.docs-only == 'false' }} | |
strategy: | |
fail-fast: false | |
matrix: | |
node: [18, 20] # TODO: use env var like [env.NODE_MAINTENANCE_VERSION, env.NODE_LTS_VERSION] | |
uses: ./.github/workflows/build_reusable.yml | |
with: | |
nodeVersion: ${{ matrix.node }} | |
afterBuild: node run-tests.js -c ${TEST_CONCURRENCY} --type unit | |
stepName: 'test-unit-${{ matrix.node }}' | |
secrets: inherit | |
test-new-tests-dev: | |
name: Test new tests for flakes (dev) | |
needs: ['optimize-ci', 'changes', 'build-native', 'build-next'] | |
if: ${{ needs.optimize-ci.outputs.skip == 'false' && needs.changes.outputs.docs-only == 'false' }} | |
strategy: | |
fail-fast: false | |
matrix: | |
group: [1/4, 2/4, 3/4, 4/4] | |
uses: ./.github/workflows/build_reusable.yml | |
with: | |
afterBuild: node scripts/test-new-tests.mjs --flake-detection --mode dev --group ${{ matrix.group }} | |
stepName: 'test-new-tests-dev-${{matrix.group}}' | |
secrets: inherit | |
test-new-tests-start: | |
name: Test new tests for flakes (prod) | |
needs: ['optimize-ci', 'changes', 'build-native', 'build-next'] | |
if: ${{ needs.optimize-ci.outputs.skip == 'false' && needs.changes.outputs.docs-only == 'false' }} | |
strategy: | |
fail-fast: false | |
matrix: | |
group: [1/4, 2/4, 3/4, 4/4] | |
uses: ./.github/workflows/build_reusable.yml | |
with: | |
afterBuild: node scripts/test-new-tests.mjs --flake-detection --mode start --group ${{ matrix.group }} | |
stepName: 'test-new-tests-start-${{matrix.group}}' | |
secrets: inherit | |
test-new-tests-deploy: | |
name: Test new tests when deployed | |
needs: | |
['optimize-ci', 'test-prod', 'test-new-tests-dev', 'test-new-tests-start'] | |
if: ${{ needs.optimize-ci.outputs.skip == 'false' && needs.changes.outputs.docs-only == 'false' && !github.event.pull_request.head.repo.fork }} | |
strategy: | |
fail-fast: false | |
matrix: | |
group: [1/4, 2/4, 3/4, 4/4] | |
uses: ./.github/workflows/build_reusable.yml | |
with: | |
afterBuild: node scripts/test-new-tests.mjs --mode deploy --group ${{ matrix.group }} | |
stepName: 'test-new-tests-deploy-${{matrix.group}}' | |
secrets: inherit | |
test-dev: | |
name: test dev | |
needs: ['optimize-ci', 'changes', 'build-native', 'build-next'] | |
if: ${{ needs.optimize-ci.outputs.skip == 'false' && needs.changes.outputs.docs-only == 'false' }} | |
strategy: | |
fail-fast: false | |
matrix: | |
group: [1/4, 2/4, 3/4, 4/4] | |
# Empty value uses default | |
react: ['', '18.3.1'] | |
uses: ./.github/workflows/build_reusable.yml | |
with: | |
afterBuild: NEXT_TEST_MODE=dev NEXT_TEST_REACT_VERSION="${{ matrix.react }}" node run-tests.js --timings -g ${{ matrix.group }} -c ${TEST_CONCURRENCY} --type development | |
stepName: 'test-dev-react-${{ matrix.react }}-${{ matrix.group }}' | |
secrets: inherit | |
test-prod: | |
name: test prod | |
needs: ['optimize-ci', 'changes', 'build-native', 'build-next'] | |
if: ${{ needs.optimize-ci.outputs.skip == 'false' && needs.changes.outputs.docs-only == 'false' }} | |
strategy: | |
fail-fast: false | |
matrix: | |
group: [1/5, 2/5, 3/5, 4/5, 5/5] | |
# Empty value uses default | |
react: ['', '18.3.1'] | |
uses: ./.github/workflows/build_reusable.yml | |
with: | |
afterBuild: NEXT_TEST_MODE=start NEXT_TEST_REACT_VERSION="${{ matrix.react }}" node run-tests.js --timings -g ${{ matrix.group }} -c ${TEST_CONCURRENCY} --type production | |
stepName: 'test-prod-react-${{ matrix.react }}-${{ matrix.group }}' | |
secrets: inherit | |
test-integration: | |
name: test integration | |
needs: ['optimize-ci', 'changes', 'build-native', 'build-next'] | |
if: ${{ needs.optimize-ci.outputs.skip == 'false' && needs.changes.outputs.docs-only == 'false' }} | |
strategy: | |
fail-fast: false | |
matrix: | |
group: | |
- 1/12 | |
- 2/12 | |
- 3/12 | |
- 4/12 | |
- 5/12 | |
- 6/12 | |
- 7/12 | |
- 8/12 | |
- 9/12 | |
- 10/12 | |
- 11/12 | |
- 12/12 | |
# Empty value uses default | |
# TODO: Run with React 18. | |
# Integration tests use the installed React version in next/package.json.include: | |
# We can't easily switch like we do for e2e tests. | |
# Skipping this dimensions until we can figure out a way to test multiple React versions. | |
react: [''] | |
uses: ./.github/workflows/build_reusable.yml | |
with: | |
nodeVersion: 18.18.2 | |
afterBuild: NEXT_TEST_REACT_VERSION="${{ matrix.react }}" node run-tests.js --timings -g ${{ matrix.group }} -c ${TEST_CONCURRENCY} --type integration | |
stepName: 'test-integration-${{ matrix.group }}-react-${{ matrix.react }}' | |
secrets: inherit | |
test-firefox-safari: | |
name: test firefox and safari | |
needs: ['optimize-ci', 'changes', 'build-native', 'build-next'] | |
if: ${{ needs.optimize-ci.outputs.skip == 'false' && needs.changes.outputs.docs-only == 'false' }} | |
uses: ./.github/workflows/build_reusable.yml | |
with: | |
afterBuild: pnpm playwright install && | |
BROWSER_NAME=firefox node run-tests.js test/production/pages-dir/production/test/index.test.ts && | |
NEXT_TEST_MODE=start BROWSER_NAME=safari node run-tests.js -c 1 test/production/pages-dir/production/test/index.test.ts test/e2e/basepath.test.ts && | |
BROWSER_NAME=safari DEVICE_NAME='iPhone XR' node run-tests.js -c 1 test/production/prerender-prefetch/index.test.ts | |
stepName: 'test-firefox-safari' | |
secrets: inherit | |
# TODO: remove these jobs once PPR is the default | |
# Manifest generated via: https://gist.github.com/wyattjoh/2ceaebd82a5bcff4819600fd60126431 | |
test-ppr-integration: | |
name: test ppr integration | |
needs: ['optimize-ci', 'changes', 'build-native', 'build-next'] | |
if: ${{ needs.optimize-ci.outputs.skip == 'false' && needs.changes.outputs.docs-only == 'false' }} | |
uses: ./.github/workflows/build_reusable.yml | |
with: | |
nodeVersion: 18.18.2 | |
afterBuild: __NEXT_EXPERIMENTAL_PPR=true NEXT_EXTERNAL_TESTS_FILTERS="test/ppr-tests-manifest.json" node run-tests.js --timings -c ${TEST_CONCURRENCY} --type integration | |
stepName: 'test-ppr-integration' | |
secrets: inherit | |
test-ppr-dev: | |
name: test ppr dev | |
needs: ['optimize-ci', 'changes', 'build-native', 'build-next'] | |
if: ${{ needs.optimize-ci.outputs.skip == 'false' && needs.changes.outputs.docs-only == 'false' }} | |
strategy: | |
fail-fast: false | |
matrix: | |
group: [1/4, 2/4, 3/4, 4/4] | |
uses: ./.github/workflows/build_reusable.yml | |
with: | |
afterBuild: __NEXT_EXPERIMENTAL_PPR=true NEXT_EXTERNAL_TESTS_FILTERS="test/ppr-tests-manifest.json" NEXT_TEST_MODE=dev node run-tests.js --timings -g ${{ matrix.group }} -c ${TEST_CONCURRENCY} --type development | |
stepName: 'test-ppr-dev-${{ matrix.group }}' | |
secrets: inherit | |
test-ppr-prod: | |
name: test ppr prod | |
needs: ['optimize-ci', 'changes', 'build-native', 'build-next'] | |
if: ${{ needs.optimize-ci.outputs.skip == 'false' && needs.changes.outputs.docs-only == 'false' }} | |
strategy: | |
fail-fast: false | |
matrix: | |
group: [1/4, 2/4, 3/4, 4/4] | |
uses: ./.github/workflows/build_reusable.yml | |
with: | |
afterBuild: __NEXT_EXPERIMENTAL_PPR=true NEXT_EXTERNAL_TESTS_FILTERS="test/ppr-tests-manifest.json" NEXT_TEST_MODE=start node run-tests.js --timings -g ${{ matrix.group }} -c ${TEST_CONCURRENCY} --type production | |
stepName: 'test-ppr-prod-${{ matrix.group }}' | |
secrets: inherit | |
report-test-results-to-datadog: | |
needs: | |
[ | |
'changes', | |
'test-unit', | |
'test-dev', | |
'test-prod', | |
'test-integration', | |
'test-ppr-dev', | |
'test-ppr-prod', | |
'test-ppr-integration', | |
'test-turbopack-dev', | |
'test-turbopack-integration', | |
'test-turbopack-production', | |
'test-turbopack-production-integration', | |
] | |
if: ${{ always() && needs.changes.outputs.docs-only == 'false' && !github.event.pull_request.head.repo.fork }} | |
runs-on: ubuntu-latest | |
name: report test results to datadog | |
steps: | |
- name: Download test report artifacts | |
id: download-test-reports | |
uses: actions/download-artifact@v4 | |
with: | |
pattern: test-reports-* | |
path: test | |
merge-multiple: true | |
- name: Upload test report to datadog | |
run: | | |
if [ -d ./test/test-junit-report ]; then | |
# Add a `test.type` tag to distinguish between turbopack and next.js runs | |
DD_ENV=ci npx @datadog/datadog-ci@2.23.1 junit upload --tags test.type:nextjs --service nextjs ./test/test-junit-report | |
fi | |
if [ -d ./test/turbopack-test-junit-report ]; then | |
# Add a `test.type` tag to distinguish between turbopack and next.js runs | |
DD_ENV=ci npx @datadog/datadog-ci@2.23.1 junit upload --tags test.type:turbopack --service nextjs ./test/turbopack-test-junit-report | |
fi | |
tests-pass: | |
needs: | |
[ | |
'build-native', | |
'build-next', | |
'lint', | |
'validate-docs-links', | |
'check-types-precompiled', | |
'test-unit', | |
'test-dev', | |
'test-prod', | |
'test-integration', | |
'test-firefox-safari', | |
'test-ppr-dev', | |
'test-ppr-prod', | |
'test-ppr-integration', | |
'test-cargo-unit', | |
'rust-check', | |
'test-next-swc-wasm', | |
'test-turbopack-dev', | |
'test-turbopack-integration', | |
'test-new-tests-dev', | |
'test-new-tests-start', | |
'test-new-tests-deploy', | |
'test-turbopack-production', | |
'test-turbopack-production-integration', | |
] | |
if: always() | |
runs-on: ubuntu-latest | |
name: thank you, next | |
steps: | |
- run: exit 1 | |
if: ${{ always() && (contains(needs.*.result, 'failure') || contains(needs.*.result, 'cancelled')) }} |