Skip to content

Commit

Permalink
chore(test): run related E2E deploy tests on PRs (vercel#63763)
Browse files Browse the repository at this point in the history
  • Loading branch information
balazsorban44 authored Apr 17, 2024
1 parent 754fada commit 3192172
Show file tree
Hide file tree
Showing 10 changed files with 217 additions and 86 deletions.
72 changes: 0 additions & 72 deletions .github/workflows/test_e2e_deploy.yml

This file was deleted.

81 changes: 81 additions & 0 deletions .github/workflows/test_e2e_deploy_related.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
name: Test E2E (Vercel Deploy), related

on:
pull_request:
types: [opened, synchronize]

jobs:
test:
if: github.repository_owner == 'vercel'
runs-on: ubuntu-latest

env:
CARGO_PROFILE_RELEASE_LTO: 'true'
DATADOG_API_KEY: ${{ secrets.DATA_DOG_API_KEY }}
DD_ENV: 'ci'
NAPI_CLI_VERSION: 2.16.2
NEXT_JUNIT_TEST_REPORT: 'true'
NEXT_TELEMETRY_DISABLED: 1
NEXT_TEST_JOB: 1
NEXT_TEST_MODE: 'deploy'
NODE_LTS_VERSION: 20
TEST_TIMINGS_TOKEN: ${{ secrets.TEST_TIMINGS_TOKEN }}
TURBO_REMOTE_ONLY: 'true'
TURBO_TEAM: 'vercel'
TURBO_VERSION: 1.12.5
VERCEL_TEST_TEAM: vtest314-next-e2e-tests
VERCEL_TEST_TOKEN: ${{ secrets.VERCEL_TEST_TOKEN }}

strategy:
fail-fast: false

steps:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_LTS_VERSION }}
check-latest: true

- name: Setup pnpm
run: corepack enable

- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 25

- name: Setup tests
run: |
pnpm install
pnpm run build
npm i -g vercel@latest
node scripts/run-e2e-test-project-reset.mjs
- name: Run tests
run: |
docker run --rm -v $(pwd):/work mcr.microsoft.com/playwright:v1.41.2-jammy /bin/bash -c "cd /work && \
NODE_VERSION=${{ env.NODE_LTS_VERSION }} ./scripts/setup-node.sh && \
corepack enable > /dev/null && \
NEXT_JUNIT_TEST_REPORT=${{ env.NEXT_JUNIT_TEST_REPORT }} \
DATADOG_API_KEY=${{ env.DATADOG_API_KEY }} \
DD_ENV=${{ env.DD_ENV }} \
VERCEL_TEST_TOKEN=${{ env.VERCEL_TEST_TOKEN }} \
VERCEL_TEST_TEAM=${{ env.VERCEL_TEST_TEAM }} \
NEXT_TEST_JOB=${{ env.NEXT_TEST_JOB }} \
NEXT_TEST_MODE=${{ env.NEXT_TEST_MODE }} \
TEST_TIMINGS_TOKEN=${{ env.TEST_TIMINGS_TOKEN }} \
xvfb-run node run-tests.js --related --timings -c 1 >> /proc/1/fd/1"
- name: Save test report as artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: test-reports
if-no-files-found: ignore
retention-days: 2
path: test/test-junit-report

- name: Upload test report to Datadog
continue-on-error: true
run: |
pnpx @datadog/[email protected] junit upload --tags test.type:nextjs_deploy_e2e --service nextjs ./test/test-junit-report
87 changes: 87 additions & 0 deletions .github/workflows/test_e2e_deploy_scheduled.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
name: Test E2E (Vercel Deploy), scheduled

on:
schedule:
# run every day at midnight
- cron: '0 0 * * *'
# allow triggering manually as well
workflow_dispatch:

jobs:
test:
if: github.repository_owner == 'vercel'
runs-on: ubuntu-latest

env:
CARGO_PROFILE_RELEASE_LTO: 'true'
DATADOG_API_KEY: ${{ secrets.DATA_DOG_API_KEY }}
DD_ENV: 'ci'
NAPI_CLI_VERSION: 2.16.2
NEXT_JUNIT_TEST_REPORT: 'true'
NEXT_TELEMETRY_DISABLED: 1
NEXT_TEST_CONTINUE_ON_ERROR: 1
NEXT_TEST_JOB: 1
NEXT_TEST_MODE: 'deploy'
NODE_LTS_VERSION: 20
TEST_TIMINGS_TOKEN: ${{ secrets.TEST_TIMINGS_TOKEN }}
TURBO_REMOTE_ONLY: 'true'
TURBO_TEAM: 'vercel'
TURBO_VERSION: 1.12.5
VERCEL_TEST_TEAM: vtest314-next-e2e-tests
VERCEL_TEST_TOKEN: ${{ secrets.VERCEL_TEST_TOKEN }}

strategy:
fail-fast: false
matrix:
group: [1, 2]

steps:
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: ${{ env.NODE_LTS_VERSION }}
check-latest: true

- name: Setup pnpm
run: corepack enable

- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 25

- name: Setup tests
run: |
pnpm install
pnpm run build
npm i -g vercel@latest
node scripts/run-e2e-test-project-reset.mjs
- name: Run tests
run: |
docker run --rm -v $(pwd):/work mcr.microsoft.com/playwright:v1.41.2-jammy /bin/bash -c "cd /work && \
NODE_VERSION=${{ env.NODE_LTS_VERSION }} ./scripts/setup-node.sh && \
corepack enable > /dev/null && \
NEXT_JUNIT_TEST_REPORT=${{ env.NEXT_JUNIT_TEST_REPORT }} \
DATADOG_API_KEY=${{ env.DATADOG_API_KEY }} \
DD_ENV=${{ env.DD_ENV }} \
VERCEL_TEST_TOKEN=${{ env.VERCEL_TEST_TOKEN }} \
VERCEL_TEST_TEAM=${{ env.VERCEL_TEST_TEAM }} \
NEXT_TEST_JOB=${{ env.NEXT_TEST_JOB }} \
NEXT_TEST_MODE=${{ env.NEXT_TEST_MODE }} \
TEST_TIMINGS_TOKEN=${{ env.TEST_TIMINGS_TOKEN }} \
xvfb-run node run-tests.js --type e2e --timings -g ${{ matrix.group }}/2 -c 1 >> /proc/1/fd/1"
- name: Save test report as artifacts
if: always()
uses: actions/upload-artifact@v4
with:
name: test-reports
if-no-files-found: ignore
retention-days: 2
path: test/test-junit-report

- name: Upload test report to Datadog
continue-on-error: true
run: |
pnpx @datadog/[email protected] junit upload --tags test.type:nextjs_deploy_e2e --service nextjs ./test/test-junit-report
8 changes: 6 additions & 2 deletions packages/next/src/server/base-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ import { AppRouteRouteMatcherProvider } from './future/route-matcher-providers/a
import { PagesAPIRouteMatcherProvider } from './future/route-matcher-providers/pages-api-route-matcher-provider'
import { PagesRouteMatcherProvider } from './future/route-matcher-providers/pages-route-matcher-provider'
import { ServerManifestLoader } from './future/route-matcher-providers/helpers/manifest-loaders/server-manifest-loader'
import { getTracer, SpanKind } from './lib/trace/tracer'
import { getTracer, isBubbledError, SpanKind } from './lib/trace/tracer'
import { BaseServerSpan } from './lib/trace/constants'
import { I18NProvider } from './future/helpers/i18n-provider'
import { sendResponse } from './send-response'
Expand Down Expand Up @@ -1390,7 +1390,11 @@ export default abstract class Server<
return this.renderError(null, req, res, '/_error', {})
}

if (this.minimalMode || this.renderOpts.dev || (err as any).bubble) {
if (
this.minimalMode ||
this.renderOpts.dev ||
(isBubbledError(err) && err.bubble)
) {
throw err
}
this.logError(getProperError(err))
Expand Down
19 changes: 16 additions & 3 deletions packages/next/src/server/lib/trace/tracer.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import type { FetchEventResult } from '../../web/types'
import type { SpanTypes } from './constants'
import { LogSpanAllowList, NextVanillaSpanAllowlist } from './constants'

Expand Down Expand Up @@ -36,10 +37,22 @@ const isPromise = <T>(p: any): p is Promise<T> => {
return p !== null && typeof p === 'object' && typeof p.then === 'function'
}

type BubbledError = Error & { bubble?: boolean }
export class BubbledError extends Error {
constructor(
public readonly bubble?: boolean,
public readonly result?: FetchEventResult
) {
super()
}
}

export function isBubbledError(error: unknown): error is BubbledError {
if (typeof error !== 'object' || error === null) return false
return error instanceof BubbledError
}

const closeSpanWithError = (span: Span, error?: Error) => {
if ((error as BubbledError | undefined)?.bubble === true) {
if (isBubbledError(error) && error.bubble) {
span.setAttribute('next.bubble', true)
} else {
if (error) {
Expand Down Expand Up @@ -307,7 +320,7 @@ class NextTracerImpl implements NextTracer {
}
try {
if (fn.length > 1) {
return fn(span, (err?: Error) => closeSpanWithError(span, err))
return fn(span, (err) => closeSpanWithError(span, err))
}

const result = fn(span)
Expand Down
7 changes: 2 additions & 5 deletions packages/next/src/server/next-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ import {
INSTRUMENTATION_HOOK_FILENAME,
RSC_PREFETCH_SUFFIX,
} from '../lib/constants'
import { getTracer } from './lib/trace/tracer'
import { BubbledError, getTracer } from './lib/trace/tracer'
import { NextNodeServerSpan } from './lib/trace/constants'
import { nodeFs } from './lib/node-fs-methods'
import { getRouteRegex } from '../shared/lib/router/utils/route-regex'
Expand Down Expand Up @@ -1675,10 +1675,7 @@ export default class NextNodeServer extends BaseServer<
if ('response' in result) {
if (isMiddlewareInvoke) {
bubblingResult = true
const err = new Error()
;(err as any).result = result
;(err as any).bubble = true
throw err
throw new BubbledError(true, result)
}

for (const [key, value] of Object.entries(
Expand Down
13 changes: 13 additions & 0 deletions run-tests.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ let argv = require('yargs/yargs')(process.argv.slice(2))
.string('g')
.alias('g', 'group')
.number('c')
.boolean('related')
.alias('r', 'related')
.alias('c', 'concurrency').argv

function escapeRegexp(str) {
Expand Down Expand Up @@ -197,6 +199,7 @@ async function main() {
group: argv.group ?? false,
testPattern: argv.testPattern ?? false,
type: argv.type ?? false,
related: argv.related ?? false,
retries: argv.retries ?? DEFAULT_NUM_RETRIES,
}
let numRetries = options.retries
Expand Down Expand Up @@ -232,12 +235,22 @@ async function main() {
let prevTimings

if (tests.length === 0) {
/** @type {RegExp | undefined} */
let testPatternRegex

if (options.testPattern) {
testPatternRegex = new RegExp(options.testPattern)
}

if (options.related) {
const { getRelatedTests } = await import('./scripts/run-related-test.mjs')
const tests = await getRelatedTests()
if (tests.length)
testPatternRegex = new RegExp(tests.map(escapeRegexp).join('|'))

console.log('Running related tests:', testPatternRegex.toString())
}

tests = (
await glob('**/*.test.{js,ts,tsx}', {
nodir: true,
Expand Down
4 changes: 3 additions & 1 deletion scripts/run-related-test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,9 @@ async function getChangedFilesFromPackages(baseBranch = 'canary') {
await exec('git config --global --add safe.directory /work')
await exec(`git remote set-branches --add origin ${baseBranch}`)
await exec(`git fetch origin ${baseBranch} --depth=20`)
const { stdout } = await exec(`git diff --name-only ${baseBranch}`)
const { stdout } = await exec(
`git diff 'origin/${baseBranch}...' --name-only`
)
return stdout
.trim()
.split('\n')
Expand Down
Loading

0 comments on commit 3192172

Please sign in to comment.