Skip to content

Commit

Permalink
Merge pull request #10298 from getsentry/prepare-release/7.95.0
Browse files Browse the repository at this point in the history
meta(changelog): Update changelog for v7.95.0
  • Loading branch information
mydea committed Jan 23, 2024
2 parents fc0e55f + d98bd74 commit 9fcfd51
Show file tree
Hide file tree
Showing 157 changed files with 1,801 additions and 1,126 deletions.
1 change: 1 addition & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ jobs:
- 'packages/replay/**'
- 'packages/replay-canvas/**'
- 'packages/feedback/**'
- 'packages/wasm/**'
browser_integration:
- *shared
- *browser
Expand Down
41 changes: 41 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,47 @@

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

## 7.95.0

### Important Changes

#### Deprecations

This release includes some deprecations in preparation for v8.

Most notably, it deprecates the `Replay` & `Feedback` classes in favor of a functional replacement:

```js
import * as Sentry from '@sentry/browser';

Sentry.init({
integrations: [
// Instead of
new Sentry.Replay(),
new Sentry.Feedback(),
// Use the functional replacement:
Sentry.replayIntegration(),
Sentry.feedbackIntegration(),
],
});
```

- feat(core): Deprecate `Span.origin` in favor of `sentry.origin` attribute (#10260)
- feat(core): Deprecate `Span.parentSpanId` (#10244)
- feat(core): Expose `isInitialized()` to replace checking via `getClient` (#10296)
- feat(replay): Deprecate `Replay`, `ReplayCanvas`, `Feedback` classes (#10270)
- feat(wasm): Deprecate `Wasm` integration class (#10230)

### Other Changes

- feat: Make `parameterize` function available through browser and node API (#10085)
- feat(feedback): Configure feedback border radius (#10289)
- feat(sveltekit): Update default integration handling & deprecate `addOrUpdateIntegration` (#10263)
- fix(replay-canvas): Add missing dependency on @sentry/utils (#10279)
- fix(tracing): Don't send negative ttfb (#10286)

Work in this release contributed by @AleshaOleg. Thank you for your contribution!

## 7.94.1

This release fixes a publishing issue.
Expand Down
25 changes: 18 additions & 7 deletions MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,12 @@ npx @sentry/migr8@latest
This will let you select which updates to run, and automatically update your code. Make sure to still review all code
changes!

## Deprecate using `getClient()` to check if the SDK was initialized

In v8, `getClient()` will stop returning `undefined` if `Sentry.init()` was not called. For cases where this may be used
to check if Sentry was actually initialized, using `getClient()` will thus not work anymore. Instead, you should use the
new `Sentry.isInitialized()` utility to check this.

## Deprecate `getCurrentHub()`

In v8, you will no longer have a Hub, only Scopes as a concept. This also means that `getCurrentHub()` will eventually
Expand All @@ -28,13 +34,17 @@ integrations from the `Integrations.XXX` hash, is deprecated in favor of using t

The following list shows how integrations should be migrated:

| Old | New |
| ------------------------ | ------------------------------- |
| `new InboundFilters()` | `inboundFiltersIntegrations()` |
| `new FunctionToString()` | `functionToStringIntegration()` |
| `new LinkedErrors()` | `linkedErrorsIntegration()` |
| `new ModuleMetadata()` | `moduleMetadataIntegration()` |
| `new RequestData()` | `requestDataIntegration()` |
| Old | New | Packages |
| ------------------------ | ------------------------------- | ------------------------------------------------------------------------------------------------------- |
| `new InboundFilters()` | `inboundFiltersIntegration()` | `@sentry/core`, `@sentry/browser`, `@sentry/node`, `@sentry/deno`, `@sentry/bun`, `@sentry/vercel-edge` |
| `new FunctionToString()` | `functionToStringIntegration()` | `@sentry/core`, `@sentry/browser`, `@sentry/node`, `@sentry/deno`, `@sentry/bun`, `@sentry/vercel-edge` |
| `new LinkedErrors()` | `linkedErrorsIntegration()` | `@sentry/core`, `@sentry/browser`, `@sentry/node`, `@sentry/deno`, `@sentry/bun`, `@sentry/vercel-edge` |
| `new ModuleMetadata()` | `moduleMetadataIntegration()` | `@sentry/core`, `@sentry/browser` |
| `new RequestData()` | `requestDataIntegration()` | `@sentry/core`, `@sentry/node`, `@sentry/deno`, `@sentry/bun`, `@sentry/vercel-edge` |
| `new Wasm() ` | `wasmIntegration()` | `@sentry/wasm` |
| `new Replay()` | `replayIntegration()` | `@sentry/browser` |
| `new ReplayCanvas()` | `replayCanvasIntegration()` | `@sentry/browser` |
| `new Feedback()` | `feedbackIntegration()` | `@sentry/browser` |

## Deprecate `hub.bindClient()` and `makeMain()`

Expand Down Expand Up @@ -193,6 +203,7 @@ In v8, the Span class is heavily reworked. The following properties & methods ar
- `span.getTraceContext()`: Use `spanToTraceContext(span)` utility function instead.
- `span.sampled`: Use `span.isRecording()` instead.
- `span.spanId`: Use `span.spanContext().spanId` instead.
- `span.parentSpanId`: Use `spanToJSON(span).parent_span_id` instead.
- `span.traceId`: Use `span.spanContext().traceId` instead.
- `span.name`: Use `spanToJSON(span).description` instead.
- `span.description`: Use `spanToJSON(span).description` instead.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
import { parameterize } from '@sentry/utils';

const x = 'first';
const y = 'second';

Sentry.captureMessage(parameterize`This is a log statement with ${x} and ${y} params`);
Sentry.captureMessage(Sentry.parameterize`This is a log statement with ${x} and ${y} params`);
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,6 @@ import { sentryTest } from '../../../../utils/fixtures';
import { getFirstSentryEnvelopeRequest } from '../../../../utils/helpers';

sentryTest('should capture a parameterized representation of the message', async ({ getLocalTestPath, page }) => {
const bundle = process.env.PW_BUNDLE;

if (bundle && bundle.startsWith('bundle_')) {
sentryTest.skip();
}

const url = await getLocalTestPath({ testDir: __dirname });

const eventData = await getFirstSentryEnvelopeRequest<Event>(page, url);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { expect } from '@playwright/test';
import type { Event } from '@sentry/types';
import type { SerializedEvent } from '@sentry/types';

import { sentryTest } from '../../../../utils/fixtures';
import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers';
Expand All @@ -10,7 +10,7 @@ sentryTest('should send a transaction in an envelope', async ({ getLocalTestPath
}

const url = await getLocalTestPath({ testDir: __dirname });
const transaction = await getFirstSentryEnvelopeRequest<Event>(page, url);
const transaction = await getFirstSentryEnvelopeRequest<SerializedEvent>(page, url);

expect(transaction.transaction).toBe('parent_span');
expect(transaction.spans).toBeDefined();
Expand All @@ -22,14 +22,13 @@ sentryTest('should report finished spans as children of the root transaction', a
}

const url = await getLocalTestPath({ testDir: __dirname });
const transaction = await getFirstSentryEnvelopeRequest<Event>(page, url);

const rootSpanId = transaction?.contexts?.trace?.spanId;
const transaction = await getFirstSentryEnvelopeRequest<SerializedEvent>(page, url);

expect(transaction.spans).toHaveLength(1);

const span_1 = transaction.spans?.[0];
// eslint-disable-next-line deprecation/deprecation
expect(span_1?.description).toBe('child_span');
expect(span_1?.parentSpanId).toEqual(rootSpanId);
expect(span_1?.parent_span_id).toEqual(transaction?.contexts?.trace?.span_id);
expect(span_1?.origin).toEqual('manual');
expect(span_1?.data?.['sentry.origin']).toEqual('manual');
});
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { expect } from '@playwright/test';
import type { Event } from '@sentry/types';
import type { SerializedEvent } from '@sentry/types';

import { sentryTest } from '../../../../utils/fixtures';
import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers';
Expand All @@ -10,7 +10,7 @@ sentryTest('should report a transaction in an envelope', async ({ getLocalTestPa
}

const url = await getLocalTestPath({ testDir: __dirname });
const transaction = await getFirstSentryEnvelopeRequest<Event>(page, url);
const transaction = await getFirstSentryEnvelopeRequest<SerializedEvent>(page, url);

expect(transaction.transaction).toBe('test_transaction_1');
expect(transaction.spans).toBeDefined();
Expand All @@ -22,28 +22,26 @@ sentryTest('should report finished spans as children of the root transaction', a
}

const url = await getLocalTestPath({ testDir: __dirname });
const transaction = await getFirstSentryEnvelopeRequest<Event>(page, url);
const transaction = await getFirstSentryEnvelopeRequest<SerializedEvent>(page, url);

const rootSpanId = transaction?.contexts?.trace?.spanId;
const rootSpanId = transaction?.contexts?.trace?.span_id;

expect(transaction.spans).toHaveLength(3);

const span_1 = transaction.spans?.[0];

// eslint-disable-next-line deprecation/deprecation
expect(span_1?.op).toBe('span_1');
expect(span_1?.parentSpanId).toEqual(rootSpanId);
// eslint-disable-next-line deprecation/deprecation
expect(span_1?.data).toMatchObject({ foo: 'bar', baz: [1, 2, 3] });
expect(span_1).toBeDefined();
expect(span_1!.op).toBe('span_1');
expect(span_1!.parent_span_id).toEqual(rootSpanId);
expect(span_1!.data).toMatchObject({ foo: 'bar', baz: [1, 2, 3] });

const span_3 = transaction.spans?.[1];
// eslint-disable-next-line deprecation/deprecation
expect(span_3?.op).toBe('span_3');
expect(span_3?.parentSpanId).toEqual(rootSpanId);
expect(span_3).toBeDefined();
expect(span_3!.op).toBe('span_3');
expect(span_3!.parent_span_id).toEqual(rootSpanId);

const span_5 = transaction.spans?.[2];
// eslint-disable-next-line deprecation/deprecation
expect(span_5?.op).toBe('span_5');
// eslint-disable-next-line deprecation/deprecation
expect(span_5?.parentSpanId).toEqual(span_3?.spanId);
expect(span_5).toBeDefined();
expect(span_5!.op).toBe('span_5');
expect(span_5!.parent_span_id).toEqual(span_3!.span_id);
});
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ sentryTest(
// Start buffering and assert that it is enabled
expect(
await page.evaluate(() => {
// eslint-disable-next-line deprecation/deprecation
const replayIntegration = (window as unknown as Window & { Replay: InstanceType<typeof Replay> }).Replay;
// @ts-expect-error private
const replay = replayIntegration._replay;
Expand All @@ -87,6 +88,7 @@ sentryTest(
const [req0] = await Promise.all([
reqPromise0,
page.evaluate(async () => {
// eslint-disable-next-line deprecation/deprecation
const replayIntegration = (window as unknown as Window & { Replay: Replay }).Replay;
await replayIntegration.flush();
}),
Expand Down Expand Up @@ -210,6 +212,7 @@ sentryTest(
// Start buffering and assert that it is enabled
expect(
await page.evaluate(() => {
// eslint-disable-next-line deprecation/deprecation
const replayIntegration = (window as unknown as Window & { Replay: InstanceType<typeof Replay> }).Replay;
// @ts-expect-error private
const replay = replayIntegration._replay;
Expand All @@ -230,6 +233,7 @@ sentryTest(
const [req0] = await Promise.all([
reqPromise0,
page.evaluate(async () => {
// eslint-disable-next-line deprecation/deprecation
const replayIntegration = (window as unknown as Window & { Replay: Replay }).Replay;
await replayIntegration.flush({ continueRecording: false });
}),
Expand Down Expand Up @@ -324,6 +328,7 @@ sentryTest(
// Start buffering and assert that it is enabled
expect(
await page.evaluate(() => {
// eslint-disable-next-line deprecation/deprecation
const replayIntegration = (window as unknown as Window & { Replay: InstanceType<typeof Replay> }).Replay;
const replay = replayIntegration['_replay'];
replayIntegration.startBuffering();
Expand All @@ -342,6 +347,7 @@ sentryTest(
expect(errorEvent0.tags?.replayId).toBeUndefined();

await page.evaluate(async () => {
// eslint-disable-next-line deprecation/deprecation
const replayIntegration = (window as unknown as Window & { Replay: Replay }).Replay;
replayIntegration['_replay'].getOptions().errorSampleRate = 1.0;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ import { sentryTest } from '../../../utils/fixtures';
import { envelopeRequestParser, shouldSkipTracingTest, waitForTransactionRequest } from '../../../utils/helpers';
import { getReplaySnapshot, shouldSkipReplayTest, waitForReplayRunning } from '../../../utils/replayHelpers';

type TestWindow = Window & { Sentry: typeof Sentry; Replay: Sentry.Replay };
type TestWindow = Window & {
Sentry: typeof Sentry;
// eslint-disable-next-line deprecation/deprecation
Replay: Sentry.Replay;
};

sentryTest(
'should add replay_id to dsc of transactions when in session mode',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { expect } from '@playwright/test';
import type { Event } from '@sentry/types';
import type { SerializedEvent } from '@sentry/types';

import { sentryTest } from '../../../../utils/fixtures';
import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers';
Expand All @@ -16,16 +16,14 @@ sentryTest('should capture a FID vital.', async ({ browserName, getLocalTestPath
// To trigger FID
await page.click('#fid-btn');

const eventData = await getFirstSentryEnvelopeRequest<Event>(page);
const eventData = await getFirstSentryEnvelopeRequest<SerializedEvent>(page);

expect(eventData.measurements).toBeDefined();
expect(eventData.measurements?.fid?.value).toBeDefined();

// eslint-disable-next-line deprecation/deprecation
const fidSpan = eventData.spans?.filter(({ description }) => description === 'first input delay')[0];

expect(fidSpan).toBeDefined();
// eslint-disable-next-line deprecation/deprecation
expect(fidSpan?.op).toBe('ui.action');
expect(fidSpan?.parentSpanId).toBe(eventData.contexts?.trace_span_id);
expect(fidSpan?.parent_span_id).toBe(eventData.contexts?.trace?.span_id);
});
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { expect } from '@playwright/test';
import type { Event } from '@sentry/types';
import type { SerializedEvent } from '@sentry/types';

import { sentryTest } from '../../../../utils/fixtures';
import { getFirstSentryEnvelopeRequest, shouldSkipTracingTest } from '../../../../utils/helpers';
Expand All @@ -11,18 +11,16 @@ sentryTest('should capture FP vital.', async ({ browserName, getLocalTestPath, p
}

const url = await getLocalTestPath({ testDir: __dirname });
const eventData = await getFirstSentryEnvelopeRequest<Event>(page, url);
const eventData = await getFirstSentryEnvelopeRequest<SerializedEvent>(page, url);

expect(eventData.measurements).toBeDefined();
expect(eventData.measurements?.fp?.value).toBeDefined();

// eslint-disable-next-line deprecation/deprecation
const fpSpan = eventData.spans?.filter(({ description }) => description === 'first-paint')[0];

expect(fpSpan).toBeDefined();
// eslint-disable-next-line deprecation/deprecation
expect(fpSpan?.op).toBe('paint');
expect(fpSpan?.parentSpanId).toBe(eventData.contexts?.trace_span_id);
expect(fpSpan?.parent_span_id).toBe(eventData.contexts?.trace?.span_id);
});

sentryTest('should capture FCP vital.', async ({ getLocalTestPath, page }) => {
Expand All @@ -31,16 +29,14 @@ sentryTest('should capture FCP vital.', async ({ getLocalTestPath, page }) => {
}

const url = await getLocalTestPath({ testDir: __dirname });
const eventData = await getFirstSentryEnvelopeRequest<Event>(page, url);
const eventData = await getFirstSentryEnvelopeRequest<SerializedEvent>(page, url);

expect(eventData.measurements).toBeDefined();
expect(eventData.measurements?.fcp?.value).toBeDefined();

// eslint-disable-next-line deprecation/deprecation
const fcpSpan = eventData.spans?.filter(({ description }) => description === 'first-contentful-paint')[0];

expect(fcpSpan).toBeDefined();
// eslint-disable-next-line deprecation/deprecation
expect(fcpSpan?.op).toBe('paint');
expect(fcpSpan?.parentSpanId).toBe(eventData.contexts?.trace_span_id);
expect(fcpSpan?.parent_span_id).toBe(eventData.contexts?.trace?.span_id);
});
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ test('Should trace outgoing fetch requests inside middleware and create breadcru
type: 'fetch',
url: 'http://localhost:3030/',
'sentry.op': 'http.client',
'sentry.origin': 'auto.http.wintercg_fetch',
},
description: 'GET http://localhost:3030/',
op: 'http.client',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => {
'otel.kind': 'SERVER',
'http.response.status_code': 200,
'sentry.op': 'http.server',
'sentry.origin': 'auto.http.otel.http',
},
op: 'http.server',
span_id: expect.any(String),
Expand All @@ -87,6 +88,7 @@ test('Propagates trace for outgoing http requests', async ({ baseURL }) => {
'otel.kind': 'SERVER',
'http.response.status_code': 200,
'sentry.op': 'http.server',
'sentry.origin': 'auto.http.otel.http',
},
op: 'http.server',
parent_span_id: outgoingHttpSpanId,
Expand Down Expand Up @@ -159,6 +161,7 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => {
'otel.kind': 'SERVER',
'http.response.status_code': 200,
'sentry.op': 'http.server',
'sentry.origin': 'auto.http.otel.http',
},
op: 'http.server',
span_id: expect.any(String),
Expand All @@ -182,6 +185,7 @@ test('Propagates trace for outgoing fetch requests', async ({ baseURL }) => {
'otel.kind': 'SERVER',
'http.response.status_code': 200,
'sentry.op': 'http.server',
'sentry.origin': 'auto.http.otel.http',
},
op: 'http.server',
parent_span_id: outgoingHttpSpanId,
Expand Down

0 comments on commit 9fcfd51

Please sign in to comment.