Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

meta: Update CHANGELOG for 8.23.0 #13170

Merged
merged 15 commits into from
Aug 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
87 changes: 31 additions & 56 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -434,6 +434,11 @@ jobs:
timeout-minutes: 10
runs-on: ubuntu-20.04
steps:
- name: Check out base commit (${{ github.event.pull_request.base.sha }})
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.base.sha }}

- name: Check out current commit (${{ needs.job_get_metadata.outputs.commit_label }})
uses: actions/checkout@v4
with:
Expand All @@ -446,8 +451,15 @@ jobs:
uses: ./.github/actions/restore-cache
env:
DEPENDENCY_CACHE_KEY: ${{ needs.job_build.outputs.dependency_cache_key }}
- name: Run tests
run: yarn test-ci-browser

- name: Run affected tests
run: yarn test:pr:browser --base=${{ github.event.pull_request.base.sha }}
if: github.event_name == 'pull_request'

- name: Run all tests
run: yarn test:ci:browser
if: github.event_name != 'pull_request'

- name: Compute test coverage
uses: codecov/codecov-action@v4
with:
Expand Down Expand Up @@ -478,7 +490,7 @@ jobs:
DEPENDENCY_CACHE_KEY: ${{ needs.job_build.outputs.dependency_cache_key }}
- name: Run tests
run: |
yarn test-ci-bun
yarn test:ci:bun

job_deno_unit_tests:
name: Deno Unit Tests
Expand Down Expand Up @@ -521,6 +533,10 @@ jobs:
matrix:
node: [14, 16, 18, 20, 22]
steps:
- name: Check out base commit (${{ github.event.pull_request.base.sha }})
uses: actions/checkout@v4
with:
ref: ${{ github.event.pull_request.base.sha }}
- name: Check out current commit (${{ needs.job_get_metadata.outputs.commit_label }})
uses: actions/checkout@v4
with:
Expand All @@ -533,10 +549,19 @@ jobs:
uses: ./.github/actions/restore-cache
env:
DEPENDENCY_CACHE_KEY: ${{ needs.job_build.outputs.dependency_cache_key }}
- name: Run tests

- name: Run affected tests
run: yarn test:pr:node --base=${{ github.event.pull_request.base.sha }}
if: github.event_name == 'pull_request'
env:
NODE_VERSION: ${{ matrix.node }}
run: yarn test-ci-node

- name: Run all tests
run: yarn test:ci:node
if: github.event_name != 'pull_request'
env:
NODE_VERSION: ${{ matrix.node }}

- name: Compute test coverage
uses: codecov/codecov-action@v4
with:
Expand Down Expand Up @@ -570,56 +595,6 @@ jobs:
- name: Unit Test
run: yarn lerna run test --scope @sentry/profiling-node

job_nextjs_integration_test:
name: Nextjs (Node ${{ matrix.node }}) Tests
needs: [job_get_metadata, job_build]
if: needs.job_get_metadata.outputs.changed_nextjs == 'true' || github.event_name != 'pull_request'
timeout-minutes: 25
runs-on: ubuntu-20.04
strategy:
fail-fast: false
matrix:
node: [14, 16, 18, 20, 22]
steps:
- name: Check out current commit (${{ needs.job_get_metadata.outputs.commit_label }})
uses: actions/checkout@v4
with:
ref: ${{ env.HEAD_COMMIT }}
- name: Set up Node
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- name: Restore caches
uses: ./.github/actions/restore-cache
env:
DEPENDENCY_CACHE_KEY: ${{ needs.job_build.outputs.dependency_cache_key }}
- name: Get npm cache directory
id: npm-cache-dir
run: echo "dir=$(npm config get cache)" >> $GITHUB_OUTPUT
- name: Get Playwright version
id: playwright-version
run: echo "version=$(node -p "require('@playwright/test/package.json').version")" >> $GITHUB_OUTPUT
- uses: actions/cache@v4
name: Check if Playwright browser is cached
id: playwright-cache
with:
path: ${{ steps.npm-cache-dir.outputs.dir }}
key: ${{ runner.os }}-Playwright-${{steps.playwright-version.outputs.version}}
- name: Install Playwright browser if not cached
if: steps.playwright-cache.outputs.cache-hit != 'true'
run: npx playwright install --with-deps
env:
PLAYWRIGHT_BROWSERS_PATH: ${{steps.npm-cache-dir.outputs.dir}}
- name: Install OS dependencies of Playwright if cache hit
if: steps.playwright-cache.outputs.cache-hit == 'true'
run: npx playwright install-deps
- name: Run tests
env:
NODE_VERSION: ${{ matrix.node }}
run: |
cd packages/nextjs
yarn test:integration

job_browser_playwright_tests:
name: Playwright (${{ matrix.bundle }}${{ matrix.shard && format(' {0}/{1}', matrix.shard, matrix.shards) || ''}}) Tests
needs: [job_get_metadata, job_build]
Expand Down Expand Up @@ -994,6 +969,7 @@ jobs:
'ember-classic',
'ember-embroider',
'nextjs-app-dir',
'nextjs-13',
'nextjs-14',
'nextjs-15',
'react-17',
Expand Down Expand Up @@ -1302,7 +1278,6 @@ jobs:
job_deno_unit_tests,
job_node_unit_tests,
job_profiling_node_unit_tests,
job_nextjs_integration_test,
job_node_integration_tests,
job_browser_playwright_tests,
job_browser_loader_tests,
Expand Down
6 changes: 6 additions & 0 deletions .github/workflows/canary.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,12 @@ jobs:
- test-application: 'nextjs-app-dir'
build-command: 'test:build-latest'
label: 'nextjs-app-dir (latest)'
- test-application: 'nextjs-13'
build-command: 'test:build-canary'
label: 'nextjs-13 (canary)'
- test-application: 'nextjs-13'
build-command: 'test:build-latest'
label: 'nextjs-13 (latest)'
- test-application: 'nextjs-14'
build-command: 'test:build-canary'
label: 'nextjs-14 (canary)'
Expand Down
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,16 @@

- "You miss 100 percent of the chances you don't take. — Wayne Gretzky" — Michael Scott

## 8.23.0

- feat(cloudflare): Add Cloudflare D1 instrumentation (#13142)
- feat(nestjs): Automatic instrumentation of nestjs interceptors before route execution (#13153)
- feat(nestjs): Automatic instrumentation of nestjs pipes (#13137)
- feat(nuxt): Filter out Nuxt build assets (#13148)
- feat(profiling): attach sdk info to chunks (#13145)
- fix(browser): Avoid showing browser extension error message in non-`window` global scopes (#13156)
- fix(nestjs): Inline Observable type to resolve missing 'rxjs' dependency (#13166)

## 8.22.0

### Important Changes
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Controller, Get, Param, UseGuards } from '@nestjs/common';
import { Controller, Get, Param, ParseIntPipe, UseGuards, UseInterceptors } from '@nestjs/common';
import { AppService } from './app.service';
import { ExampleGuard } from './example.guard';
import { ExampleInterceptor } from './example.interceptor';

@Controller()
export class AppController {
Expand All @@ -13,7 +14,7 @@ export class AppController {

@Get('test-middleware-instrumentation')
testMiddlewareInstrumentation() {
return this.appService.testMiddleware();
return this.appService.testSpan();
}

@Get('test-guard-instrumentation')
Expand All @@ -22,6 +23,17 @@ export class AppController {
return {};
}

@Get('test-interceptor-instrumentation')
@UseInterceptors(ExampleInterceptor)
testInterceptorInstrumentation() {
return this.appService.testSpan();
}

@Get('test-pipe-instrumentation/:id')
testPipeInstrumentation(@Param('id', ParseIntPipe) id: number) {
return { value: id };
}

@Get('test-exception/:id')
async testException(@Param('id') id: string) {
return this.appService.testException(id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export class AppService {
});
}

testMiddleware() {
testSpan() {
// span that should not be a child span of the middleware span
Sentry.startSpan({ name: 'test-controller-span' }, () => {});
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import { CallHandler, ExecutionContext, Injectable, NestInterceptor } from '@nestjs/common';
import * as Sentry from '@sentry/nestjs';

@Injectable()
export class ExampleInterceptor implements NestInterceptor {
intercept(context: ExecutionContext, next: CallHandler) {
Sentry.startSpan({ name: 'test-interceptor-span' }, () => {});
return next.handle().pipe();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -266,3 +266,155 @@ test('API route transaction includes nest guard span and span started in guard i
// 'ExampleGuard' is the parent of 'test-guard-span'
expect(testGuardSpan.parent_span_id).toBe(exampleGuardSpanId);
});

test('API route transaction includes nest pipe span for valid request', async ({ baseURL }) => {
const transactionEventPromise = waitForTransaction('nestjs', transactionEvent => {
return (
transactionEvent?.contexts?.trace?.op === 'http.server' &&
transactionEvent?.transaction === 'GET /test-pipe-instrumentation/:id'
);
});

const response = await fetch(`${baseURL}/test-pipe-instrumentation/123`);
expect(response.status).toBe(200);

const transactionEvent = await transactionEventPromise;

expect(transactionEvent).toEqual(
expect.objectContaining({
spans: expect.arrayContaining([
{
span_id: expect.any(String),
trace_id: expect.any(String),
data: {
'sentry.op': 'middleware.nestjs',
'sentry.origin': 'auto.middleware.nestjs',
},
description: 'ParseIntPipe',
parent_span_id: expect.any(String),
start_timestamp: expect.any(Number),
timestamp: expect.any(Number),
status: 'ok',
op: 'middleware.nestjs',
origin: 'auto.middleware.nestjs',
},
]),
}),
);
});

test('API route transaction includes nest pipe span for invalid request', async ({ baseURL }) => {
const transactionEventPromise = waitForTransaction('nestjs', transactionEvent => {
return (
transactionEvent?.contexts?.trace?.op === 'http.server' &&
transactionEvent?.transaction === 'GET /test-pipe-instrumentation/:id'
);
});

const response = await fetch(`${baseURL}/test-pipe-instrumentation/abc`);
expect(response.status).toBe(400);

const transactionEvent = await transactionEventPromise;

expect(transactionEvent).toEqual(
expect.objectContaining({
spans: expect.arrayContaining([
{
span_id: expect.any(String),
trace_id: expect.any(String),
data: {
'sentry.op': 'middleware.nestjs',
'sentry.origin': 'auto.middleware.nestjs',
},
description: 'ParseIntPipe',
parent_span_id: expect.any(String),
start_timestamp: expect.any(Number),
timestamp: expect.any(Number),
status: 'unknown_error',
op: 'middleware.nestjs',
origin: 'auto.middleware.nestjs',
},
]),
}),
);
});

test('API route transaction includes nest interceptor span. Spans created in and after interceptor are nested correctly', async ({
baseURL,
}) => {
const pageloadTransactionEventPromise = waitForTransaction('nestjs', transactionEvent => {
return (
transactionEvent?.contexts?.trace?.op === 'http.server' &&
transactionEvent?.transaction === 'GET /test-interceptor-instrumentation'
);
});

const response = await fetch(`${baseURL}/test-interceptor-instrumentation`);
expect(response.status).toBe(200);

const transactionEvent = await pageloadTransactionEventPromise;

expect(transactionEvent).toEqual(
expect.objectContaining({
spans: expect.arrayContaining([
{
span_id: expect.any(String),
trace_id: expect.any(String),
data: {
'sentry.op': 'middleware.nestjs',
'sentry.origin': 'auto.middleware.nestjs',
},
description: 'ExampleInterceptor',
parent_span_id: expect.any(String),
start_timestamp: expect.any(Number),
timestamp: expect.any(Number),
status: 'ok',
op: 'middleware.nestjs',
origin: 'auto.middleware.nestjs',
},
]),
}),
);

const exampleInterceptorSpan = transactionEvent.spans.find(span => span.description === 'ExampleInterceptor');
const exampleInterceptorSpanId = exampleInterceptorSpan?.span_id;

expect(transactionEvent).toEqual(
expect.objectContaining({
spans: expect.arrayContaining([
{
span_id: expect.any(String),
trace_id: expect.any(String),
data: expect.any(Object),
description: 'test-controller-span',
parent_span_id: expect.any(String),
start_timestamp: expect.any(Number),
timestamp: expect.any(Number),
status: 'ok',
origin: 'manual',
},
{
span_id: expect.any(String),
trace_id: expect.any(String),
data: expect.any(Object),
description: 'test-interceptor-span',
parent_span_id: expect.any(String),
start_timestamp: expect.any(Number),
timestamp: expect.any(Number),
status: 'ok',
origin: 'manual',
},
]),
}),
);

// verify correct span parent-child relationships
const testInterceptorSpan = transactionEvent.spans.find(span => span.description === 'test-interceptor-span');
const testControllerSpan = transactionEvent.spans.find(span => span.description === 'test-controller-span');

// 'ExampleInterceptor' is the parent of 'test-interceptor-span'
expect(testInterceptorSpan.parent_span_id).toBe(exampleInterceptorSpanId);

// 'ExampleInterceptor' is NOT the parent of 'test-controller-span'
expect(testControllerSpan.parent_span_id).not.toBe(exampleInterceptorSpanId);
});
Loading
Loading