mirror of
https://github.com/vercel/next.js.git
synced 2026-09-20 02:25:18 +08:00
3bf71ee3fd
### What? Adds a CI job that runs selected Rust unit tests under [Miri](https://github.com/rust-lang/miri) to detect undefined behavior in unsafe code. The job currently covers the low-level crates that are compatible with Miri: - `turbo-persistence` - `turbo-rcstr` - `turbo-tasks-malloc` It also makes those crates Miri-compatible by: - using provenance-free tagged-pointer operations in `turbo-rcstr`; - disabling mimalloc and native compression under Miri; - making mmap support a default-enabled Cargo feature that is disabled for Miri and wasm; - running persistence through file I/O when mmap is disabled; - skipping only tests measured to exceed the Miri time budget; - removing leaked test arenas from the analyzer predicate tests. ### Why? Miri can detect invalid memory access and other undefined behavior that normal Rust tests may not expose. Running it in CI gives low-level unsafe code an additional correctness check. The job uses an explicit package allowlist because Turbo Tasks builds its generated registry from linker sections, and Miri does not support the linker-defined section symbols required by that registry. ### How? - Installs the `miri` Rust component in CI and the development container. - Adds a dedicated `test-cargo-unit-miri` task and reusable workflow configuration. - Makes `memmap2` optional behind the default `mmap` feature and disables that feature in Miri CI and the wasm dependency graph. - Uses structural `cfg(miri)` branches for allocator and compression paths Miri cannot execute. - Re-enables three persistence compaction tests after measuring them successfully under Miri. - Keeps normal native behavior unchanged and documents measured Miri exclusions at the affected tests. Verification included focused normal and Miri tests for persistence, rcstr, allocation accounting, compression, and the refactored leak-free predicate cases. <!-- NEXT_JS_LLM --> <!-- fleet fb42942f-173a-484c-b4de-4e18354834c6 --> --------- Co-authored-by: vercel-fleet-prod[bot] <318278635+vercel-fleet-prod[bot]@users.noreply.github.com> Co-authored-by: Tobias Koppers <1365881+sokra@users.noreply.github.com>
529 lines
22 KiB
YAML
529 lines
22 KiB
YAML
name: Build Reusable
|
|
|
|
on:
|
|
workflow_call:
|
|
inputs:
|
|
afterBuild:
|
|
required: false
|
|
description: 'additional steps to run'
|
|
type: string
|
|
skipInstallBuild:
|
|
required: false
|
|
description: 'whether to skip pnpm install && pnpm build'
|
|
type: string
|
|
skipNativeBuild:
|
|
required: false
|
|
description: 'whether to skip building native modules'
|
|
type: string
|
|
skipNativeInstall:
|
|
required: false
|
|
description: 'whether to skip native postinstall script'
|
|
type: string
|
|
default: 'yes'
|
|
uploadAnalyzerArtifacts:
|
|
required: false
|
|
description: 'whether to upload analyzer artifacts'
|
|
type: string
|
|
nodeVersion:
|
|
required: false
|
|
description: 'version of Node.js to use'
|
|
type: string
|
|
needsRust:
|
|
required: false
|
|
description: 'if rust is needed'
|
|
type: string
|
|
needsNextest:
|
|
required: false
|
|
description: 'if nextest rust dep is needed'
|
|
type: string
|
|
needsRustJsInstall:
|
|
required: false
|
|
description: 'if Rust JS dependencies should be installed'
|
|
type: string
|
|
rustBuildProfile:
|
|
required: false
|
|
description: 'The profile to use for the build, default is `release-with-assertions`, also supports `` for debug and `release` for normal release'
|
|
type: string
|
|
default: 'release-with-assertions'
|
|
uploadSwcArtifact:
|
|
required: false
|
|
description: 'if swc artifact needs uploading'
|
|
type: string
|
|
rustCacheKey:
|
|
required: false
|
|
description: 'rustCacheKey to cache shared target assets'
|
|
type: string
|
|
stepName:
|
|
required: true
|
|
description: 'name of the step, to be used for the upload artifact unique key '
|
|
type: string
|
|
timeout_minutes:
|
|
description: 'Timeout in minutes'
|
|
required: false
|
|
type: number
|
|
default: 30
|
|
runs_on_labels:
|
|
description: 'List of runner labels'
|
|
required: false
|
|
type: string
|
|
default: '["ubuntu-latest-16-core-arm-oss"]'
|
|
overrideProxyAddress:
|
|
description: Override the proxy address to use for the test
|
|
required: false
|
|
type: string
|
|
default: ''
|
|
testTimingsArtifact:
|
|
description: >
|
|
Name of an uploaded artifact containing test-timings.json. When set,
|
|
download it instead of fetching via turbo. This can be useful in
|
|
ensuring that when failed jobs are retried, they end up with exactly
|
|
the same set of timings, and therefore run the same set of tests.
|
|
required: false
|
|
type: string
|
|
default: ''
|
|
testReportsArtifactPrefix:
|
|
description: 'Artifact name prefix for uploading test `*.results.json` files. Empty string disables upload.'
|
|
required: false
|
|
type: string
|
|
default: ''
|
|
uploadNativeArtifact:
|
|
description: >
|
|
When true, build and upload the native `next-swc.*.node` files as an
|
|
artifact named `next-swc-<target>`. When false, we may attempt to
|
|
download this artifact, falling back to rebuilding if the artifact is
|
|
not found.
|
|
required: false
|
|
type: boolean
|
|
default: false
|
|
browser:
|
|
description: 'Browser to use for tests'
|
|
required: false
|
|
type: string
|
|
default: 'chromium'
|
|
needsPlaywright:
|
|
description: 'whether Playwright browser installation is needed'
|
|
required: false
|
|
type: string
|
|
default: 'yes'
|
|
env:
|
|
# Newest @napi-rs/cli that runs on Node.js 20.9.0 (NODE_LTS_VERSION below):
|
|
# 3.5.0+ depends on @inquirer/prompts 8, whose @inquirer/core 11 requires
|
|
# `util.styleText` (Node >= 20.12) and crashes at CLI startup. The CLI here
|
|
# only orchestrates cargo and names artifacts (types are committed), so
|
|
# drifting from the workspace devDependency (3.7.2) is acceptable.
|
|
NAPI_CLI_VERSION: 3.4.1
|
|
TURBO_VERSION: 2.9.4
|
|
TURBO_ARGS: '-v --env-mode loose --remote-cache-timeout 300 --log-order stream'
|
|
NODE_LTS_VERSION: 20.9.0
|
|
# run-tests.js reads `TEST_CONCURRENCY` if no explicit `--concurrency` or `-c`
|
|
# argument is provided
|
|
TEST_CONCURRENCY: 8
|
|
# overrides `turbo_tasks::parallel::available_parallelism`. Smaller values are more CPU and memory
|
|
# efficient, but won't fully utilize all available CPU cores. A small value here makes sense since
|
|
# we're running many tests in parallel.
|
|
TURBO_TASKS_AVAILABLE_PARALLELISM: 4
|
|
# disable backtrace for test snapshots
|
|
RUST_BACKTRACE: 0
|
|
|
|
TURBO_TEAM: ${{ vars.TURBO_TEAM }}
|
|
# Prefer shared remote cache across runs, but keep local cache enabled so jobs
|
|
# degrade gracefully if the remote cache or token is unavailable.
|
|
TURBO_CACHE: 'local:rw,remote:rw'
|
|
|
|
NEXT_TELEMETRY_DISABLED: 1
|
|
# `skipNativeInstall: 'no'` must force the download even though CI otherwise
|
|
# skips it by default (see scripts/install-native.mjs), so emit an explicit
|
|
# '0' rather than an empty value.
|
|
NEXT_SKIP_NATIVE_POSTINSTALL: ${{ inputs.skipNativeInstall == 'yes' && '1' || '0' }}
|
|
DATADOG_API_KEY: ${{ secrets.DATA_DOG_API_KEY }}
|
|
NEXT_JUNIT_TEST_REPORT: 'true'
|
|
DD_ENV: 'ci'
|
|
# Vercel KV Store for test timings
|
|
KV_REST_API_URL: ${{ secrets.KV_REST_API_URL }}
|
|
KV_REST_API_TOKEN: ${{ secrets.KV_REST_API_TOKEN }}
|
|
NEXT_TEST_JOB: 1
|
|
# Per-job memoization of passed test files.
|
|
NEXT_TEST_PASSED_FILE: .next-test-passed.txt
|
|
VERCEL_TEST_TOKEN: ${{ secrets.VERCEL_TEST_TOKEN }}
|
|
VERCEL_TEST_TEAM: vtest314-next-e2e-tests
|
|
VERCEL_ADAPTER_TEST_TOKEN: ${{ secrets.VERCEL_ADAPTER_TEST_TOKEN }}
|
|
VERCEL_ADAPTER_TEST_TEAM: vtest314-next-adapter-e2e-tests
|
|
VERCEL_TURBOPACK_TEST_TOKEN: ${{ secrets.VERCEL_TURBOPACK_TEST_TOKEN }}
|
|
VERCEL_TURBOPACK_TEST_TEAM: vtest314-next-turbo-e2e-tests
|
|
PREVIEW_BUILDS_ACCESS: ${{ vars.PREVIEW_BUILDS_ACCESS }}
|
|
NEXT_TEST_PREFER_OFFLINE: 1
|
|
NEXT_CI_RUNNER: ${{ inputs.runs_on_labels }}
|
|
NEXT_TEST_PROXY_ADDRESS: ${{ inputs.overrideProxyAddress || '' }}
|
|
|
|
# defaults to 256, but we run a lot of tests in parallel, so the limit should be lower
|
|
NEXT_TURBOPACK_IO_CONCURRENCY: 64
|
|
|
|
# Disable warnings from baseline-browser-mapping
|
|
# https://github.com/web-platform-dx/baseline-browser-mapping/blob/ec8136ae9e034b332fab991d63a340d2e13b8afc/README.md?plain=1#L34
|
|
BASELINE_BROWSER_MAPPING_IGNORE_OLD_DATA: 1
|
|
|
|
jobs:
|
|
build:
|
|
timeout-minutes: ${{ inputs.timeout_minutes }}
|
|
runs-on: ${{ fromJson(inputs.runs_on_labels) }}
|
|
|
|
defaults:
|
|
run:
|
|
shell: bash -leuo pipefail {0}
|
|
|
|
outputs:
|
|
input_step_key: ${{ steps.var.outputs.input_step_key }}
|
|
|
|
steps:
|
|
# enforce consistent line endings for git on windows
|
|
- name: Configure git to use LF endings
|
|
if: ${{ runner.os == 'Windows' }}
|
|
run: |
|
|
git config --global core.autocrlf false
|
|
git config --global core.eol lf
|
|
shell: bash
|
|
|
|
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
|
with:
|
|
# Changing the checked out ref has wide implications:
|
|
# Be aware that all git-diff operations in the repo rely on the
|
|
# default behavior of GitHub actions (ref on push, merge-commit on PR).
|
|
fetch-depth: 25
|
|
persist-credentials: false
|
|
|
|
- name: Set up Turborepo remote cache
|
|
if: ${{ vars.TURBO_TEAM != '' }}
|
|
continue-on-error: true
|
|
uses: vercel/setup-turborepo-remote-cache-action@135046f5efcadb17337d9b29b8d5b4035ae64b10 # v1.0.0
|
|
with:
|
|
team: ${{ vars.TURBO_TEAM }}
|
|
|
|
# Depends on rust-toolchain.toml in the checkout
|
|
- name: Install Rust
|
|
id: install-rust
|
|
uses: ./.github/actions/setup-rust
|
|
background: true
|
|
if: ${{ inputs.uploadNativeArtifact || inputs.needsNextest == 'yes' || inputs.needsRust == 'yes' }}
|
|
|
|
- name: Install fnm
|
|
run: |
|
|
FNM_VERSION=v1.39.0
|
|
FNM_BIN_DIR="$HOME/.local/share/fnm/bin"
|
|
|
|
case "$RUNNER_OS" in
|
|
Linux)
|
|
# The asset names and sha256 are available on the GH releases page
|
|
# https://github.com/Schniz/fnm/releases
|
|
ARCH="$(uname -m)"
|
|
case "$ARCH" in
|
|
aarch64)
|
|
FNM_ASSET=fnm-arm64.zip
|
|
FNM_SHA256=4eaff58b2c5bf30d0934027572dd0b5bbb60d2a1af309230b53662d4b1d45599
|
|
;;
|
|
x86_64)
|
|
FNM_ASSET=fnm-linux.zip
|
|
FNM_SHA256=7807664f39d39fc518da1c35ba0181e4b3267603c4b1dedeb4b5fc6ae440a224
|
|
;;
|
|
*)
|
|
echo "::error::Unsupported architecture: $ARCH"
|
|
exit 1
|
|
;;
|
|
esac
|
|
FNM_EXE=fnm
|
|
;;
|
|
Windows)
|
|
FNM_ASSET=fnm-windows.zip
|
|
FNM_SHA256=8183bed4348cb78fdfd8abb3d1247fbeab7b2082f941363929c61e747c001e10
|
|
FNM_EXE=fnm.exe
|
|
;;
|
|
*)
|
|
echo "::error::Unsupported RUNNER_OS: $RUNNER_OS"
|
|
exit 1
|
|
;;
|
|
esac
|
|
FNM_BIN="$FNM_BIN_DIR/$FNM_EXE"
|
|
|
|
mkdir -p "$FNM_BIN_DIR"
|
|
curl -L --fail --retry 3 -o /tmp/fnm.zip \
|
|
"https://github.com/Schniz/fnm/releases/download/$FNM_VERSION/$FNM_ASSET"
|
|
echo "$FNM_SHA256 /tmp/fnm.zip" | sha256sum --check --status
|
|
unzip /tmp/fnm.zip "$FNM_EXE" -d "$FNM_BIN_DIR"
|
|
rm /tmp/fnm.zip
|
|
chmod +x "$FNM_BIN"
|
|
|
|
echo "$FNM_BIN_DIR" >> $GITHUB_PATH
|
|
"$FNM_BIN" env --corepack-enabled --json | \
|
|
jq -r 'to_entries|map("\(.key)=\(.value|tostring|@sh)")|.[]' | \
|
|
xargs -I {} echo "{}" >> $GITHUB_ENV
|
|
|
|
- name: Use Node.js ${{ inputs.nodeVersion || env.NODE_LTS_VERSION }}
|
|
run: |
|
|
fnm use --install-if-missing "$NODE_VERSION"
|
|
fnm default "$NODE_VERSION"
|
|
eval "$(fnm env)"
|
|
echo "$(dirname "$(which node)")" >> "$GITHUB_PATH"
|
|
env:
|
|
NODE_VERSION: ${{ inputs.nodeVersion || env.NODE_LTS_VERSION }}
|
|
|
|
# Debug used Node.js version in a separate step to ensure the Node.js
|
|
# version is set for the entire job
|
|
- name: Verify Node.js version
|
|
run: |
|
|
which node
|
|
node --version
|
|
pnpm --version
|
|
|
|
- run: corepack prepare --activate yarn@1.22.19 && npm i -g "@napi-rs/cli@${NAPI_CLI_VERSION}"
|
|
|
|
# clean up any previous artifacts to avoid hitting disk space limits
|
|
- run: git clean -xdf && rm -rf /tmp/next-repo-*; rm -rf /tmp/next-install-* /tmp/yarn-* /tmp/ncc-cache target
|
|
|
|
# Configure a git user so that Create Next App can initialize git repos during integration tests.
|
|
- name: Set CI git user
|
|
run: |
|
|
git config --global user.name "vercel-ci-bot"
|
|
git config --global user.email "infra+ci@vercel.com"
|
|
|
|
# normalize versions before build-native for better cache hits
|
|
- run: node scripts/normalize-version-bump.js
|
|
name: normalize versions
|
|
|
|
- name: Wait for Rust toolchain
|
|
wait: install-rust
|
|
|
|
- name: Install nextest
|
|
if: ${{ inputs.needsNextest == 'yes' }}
|
|
run: cargo binstall --no-confirm --locked cargo-nextest@0.9.133
|
|
|
|
- run: rustc --version
|
|
if: ${{ inputs.uploadNativeArtifact || inputs.needsNextest == 'yes' || inputs.needsRust == 'yes' }}
|
|
|
|
- name: Start sccache
|
|
uses: ./.github/actions/sccache
|
|
if: ${{ runner.os != 'Windows' && (inputs.uploadNativeArtifact || inputs.needsNextest == 'yes' || inputs.needsRust == 'yes') }}
|
|
|
|
# Infer the Rust target triple from the runner's OS/arch. napi would build
|
|
# for the host target if `--target` were omitted, but Turborepo does not
|
|
# segment its cache by OS/arch, so we pass an explicit `--target` to keep
|
|
# the cache key distinct per architecture. The native artifact is also
|
|
# named after this target so its name can't diverge from what we built.
|
|
- name: Determine native build target
|
|
id: native-target
|
|
run: |
|
|
case "$RUNNER_OS-$RUNNER_ARCH" in
|
|
Linux-X64) target=x86_64-unknown-linux-gnu ;;
|
|
Linux-ARM64) target=aarch64-unknown-linux-gnu ;;
|
|
Windows-X64) target=x86_64-pc-windows-msvc ;;
|
|
macOS-ARM64) target=aarch64-apple-darwin ;;
|
|
macOS-X64) target=x86_64-apple-darwin ;;
|
|
*) echo "Unsupported runner: $RUNNER_OS-$RUNNER_ARCH" >&2; exit 1 ;;
|
|
esac
|
|
echo "target=$target" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Download pre-built native binary
|
|
if: ${{ inputs.skipNativeBuild != 'yes' && !inputs.uploadNativeArtifact }}
|
|
id: native-download
|
|
continue-on-error: true
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: next-swc-${{ steps.native-target.outputs.target }}
|
|
path: packages/next-swc/native/
|
|
|
|
- name: Build native binary
|
|
if: ${{ inputs.skipNativeBuild != 'yes' && (inputs.uploadNativeArtifact || steps.native-download.outcome != 'success') }}
|
|
env:
|
|
RUST_BUILD_PROFILE: ${{ inputs.rustBuildProfile }}
|
|
NATIVE_TARGET: ${{ steps.native-target.outputs.target }}
|
|
run: pnpm dlx turbo@${TURBO_VERSION} run "build-native-${RUST_BUILD_PROFILE}" ${TURBO_ARGS} --summarize -- --target "${NATIVE_TARGET}"
|
|
|
|
- name: Upload native artifact
|
|
if: ${{ inputs.uploadNativeArtifact && inputs.skipNativeBuild != 'yes' }}
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: next-swc-${{ steps.native-target.outputs.target }}
|
|
path: packages/next-swc/native/next-swc.*.node
|
|
retention-days: 1
|
|
|
|
- name: Upload next-swc artifact
|
|
if: ${{ inputs.uploadSwcArtifact == 'yes' }}
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: next-swc-binary-${{ runner.os }}-${{ runner.arch }}
|
|
path: packages/next-swc/native/next-swc.*.node
|
|
|
|
# undo normalize version changes for install/build
|
|
- run: git checkout .
|
|
if: ${{ inputs.skipInstallBuild != 'yes' }}
|
|
|
|
- name: Get pnpm store directory
|
|
id: get-store-path
|
|
run: echo STORE_PATH=$(pnpm store path) >> $GITHUB_OUTPUT
|
|
|
|
- name: Cache pnpm store
|
|
# conditions must be subset of runs executing pnpm install, otherwise we
|
|
# risk caching an incomplete store
|
|
# If keep conditions in sync breaks, we can split into restore and save
|
|
# steps where saving runs based on the outcome of the install step
|
|
if: ${{ inputs.skipInstallBuild != 'yes' || inputs.needsRustJsInstall == 'yes' }}
|
|
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
|
timeout-minutes: 5
|
|
id: cache-pnpm-store
|
|
with:
|
|
path: ${{ steps.get-store-path.outputs.STORE_PATH }}
|
|
key: pnpm-store-root-v1-${{ hashFiles('pnpm-lock.yaml') }}
|
|
# Do not use restore-keys since it leads to indefinite growth of the cache.
|
|
|
|
- run: pnpm install
|
|
# condititions must be superset of cache step, otherwise we risk running install without a cache and then caching the incomplete store.
|
|
if: ${{ inputs.skipInstallBuild != 'yes' || inputs.needsRustJsInstall == 'yes' }}
|
|
|
|
- name: Install node-file-trace test dependencies
|
|
if: ${{ inputs.needsRustJsInstall == 'yes' }}
|
|
working-directory: turbopack/crates/turbopack-tracing/tests/node-file-trace
|
|
run: pnpm install --recursive
|
|
|
|
- name: Install Playwright browsers
|
|
background: true
|
|
if: ${{ inputs.skipInstallBuild != 'yes' && inputs.needsPlaywright != 'no' }}
|
|
env:
|
|
PLAYWRIGHT_BROWSERS: ${{ inputs.browser }}
|
|
WITH_DEPS: ${{ inputs.browser != 'chromium' && '--with-deps' || '' }}
|
|
run: |
|
|
# PLAYWRIGHT_BROWSERS can be a space-separated list, should expand
|
|
# into multiple arguments
|
|
pnpm playwright install --only-shell $WITH_DEPS $PLAYWRIGHT_BROWSERS
|
|
|
|
- name: Download pre-built test timings
|
|
if: ${{ inputs.testTimingsArtifact != '' }}
|
|
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
|
|
with:
|
|
name: ${{ inputs.testTimingsArtifact }}
|
|
|
|
- name: Verify test timings
|
|
if: ${{ inputs.testTimingsArtifact != '' }}
|
|
run: |
|
|
if [ ! -f test-timings.json ]; then
|
|
echo "::error::test-timings.json not found"
|
|
exit 1
|
|
fi
|
|
echo "Test timings loaded ($(wc -c < test-timings.json) bytes)"
|
|
|
|
- name: Fetch test timings via turbo
|
|
background: true
|
|
if: ${{ inputs.testTimingsArtifact == '' }}
|
|
run: pnpm dlx turbo@${TURBO_VERSION} run get-test-timings -- --build ${{ github.sha }}
|
|
|
|
- run: ANALYZE=1 pnpm build
|
|
if: ${{ inputs.skipInstallBuild != 'yes' }}
|
|
|
|
- name: Normalize input step names into path key
|
|
uses: actions/github-script@d746ffe35508b1917358783b479e04febd2b8f71 # v9.0.0
|
|
id: var
|
|
with:
|
|
script: |
|
|
core.setOutput('input_step_key', '${{ inputs.stepName }}'.toLowerCase().replaceAll(/[/.]/g, '-').trim('-'));
|
|
|
|
# Restore the list of tests that already passed in an earlier
|
|
# attempt of this same workflow run.
|
|
- name: Restore passed-tests cache
|
|
if: ${{ inputs.afterBuild }}
|
|
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
|
with:
|
|
path: ${{ env.NEXT_TEST_PASSED_FILE }}
|
|
key: next-test-passed-${{ steps.var.outputs.input_step_key }}-${{ github.run_id }}-attempt${{ github.run_attempt }}
|
|
restore-keys: |
|
|
next-test-passed-${{ steps.var.outputs.input_step_key }}-${{ github.run_id }}-
|
|
|
|
- name: Wait for background setup steps
|
|
wait-all:
|
|
|
|
- run: ${{ inputs.afterBuild }}
|
|
id: after-build
|
|
# defaults.run.shell sets a stronger options (`-leo pipefail`)
|
|
# Set this back to github action's weaker defaults:
|
|
# https://docs.github.com/en/actions/writing-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsshell
|
|
#
|
|
# We must use a login shell: fnm installation may modify the `.profile`
|
|
shell: bash -le {0}
|
|
timeout-minutes: ${{ inputs.timeout_minutes }}
|
|
|
|
# Save the passed-tests file so the next attempt (if any) can skip
|
|
# them. `always()` makes this run on success, failure, or cancellation.
|
|
# run-tests.js emits the `passed_tests_file` step output when it creates
|
|
# the file (before running any test), so this step is skipped for jobs
|
|
# that never run run-tests.js or that disable the result cache (e.g.
|
|
# flake detection) instead of warning about a missing path.
|
|
- name: Save passed-tests cache
|
|
if: ${{ always() && steps.after-build.outputs.passed_tests_file != '' }}
|
|
uses: actions/cache/save@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
|
with:
|
|
path: ${{ steps.after-build.outputs.passed_tests_file }}
|
|
key: next-test-passed-${{ steps.var.outputs.input_step_key }}-${{ github.run_id }}-attempt${{ github.run_attempt }}
|
|
|
|
- name: Upload test result artifacts
|
|
if: ${{ inputs.testReportsArtifactPrefix != '' && inputs.afterBuild && always() }}
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: ${{ inputs.testReportsArtifactPrefix }}-${{ steps.var.outputs.input_step_key }}
|
|
path: test/**/*.results.json
|
|
if-no-files-found: ignore
|
|
retention-days: 1
|
|
|
|
# This file messes up the tests because it influences the build root autodetection.
|
|
# Jest has a global cache, so PRs that poison the cache can bring down CI
|
|
- name: Clean up stray files
|
|
if: ${{ always() }}
|
|
run: rm -f /tmp/package-lock.json
|
|
|
|
- name: Upload Turborepo summary
|
|
if: ${{ always() }}
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
with:
|
|
name: turbo-run-summary-${{ steps.var.outputs.input_step_key }}
|
|
path: .turbo/runs
|
|
if-no-files-found: ignore
|
|
|
|
- name: Upload bundle analyzer artifacts
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
if: ${{ inputs.uploadAnalyzerArtifacts == 'yes' }}
|
|
with:
|
|
name: webpack bundle analysis stats-${{ steps.var.outputs.input_step_key }}
|
|
path: packages/next/dist/compiled/next-server/report.*.html
|
|
|
|
- name: Install datadog-ci
|
|
if: ${{ inputs.afterBuild && always() && !github.event.pull_request.head.repo.fork && env.DATADOG_API_KEY != '' }}
|
|
uses: ./.github/actions/setup-datadog-ci
|
|
|
|
- name: Upload test report to datadog
|
|
if: ${{ inputs.afterBuild && always() && !github.event.pull_request.head.repo.fork && env.DATADOG_API_KEY != '' }}
|
|
run: |
|
|
# Add a `test.type` tag to distinguish between turbopack and next.js runs
|
|
# Add a `nextjs.test_session.name` tag to help identify the job
|
|
if [ -d ./test/test-junit-report ]; then
|
|
"$DATADOG_CI_PATH" junit upload \
|
|
--skip-git-metadata-upload \
|
|
--service nextjs \
|
|
--tags test.type:nextjs \
|
|
--tags test_session.name:"${{ inputs.stepName }}" \
|
|
--tags runner.name:"${{ runner.name }}" \
|
|
./test/test-junit-report
|
|
fi
|
|
if [ -d ./test/turbopack-test-junit-report ]; then
|
|
"$DATADOG_CI_PATH" junit upload \
|
|
--skip-git-metadata-upload \
|
|
--service nextjs \
|
|
--tags test.type:turbopack \
|
|
--tags test_session.name:"${{ inputs.stepName }}" \
|
|
--tags runner.name:"${{ runner.name }}" \
|
|
./test/turbopack-test-junit-report
|
|
fi
|
|
|
|
- name: Upload Playwright Snapshots
|
|
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
|
if: ${{ inputs.afterBuild && always() }}
|
|
with:
|
|
name: test-playwright-snapshots-${{ steps.var.outputs.input_step_key }}
|
|
path: |
|
|
test/traces
|
|
if-no-files-found: ignore
|