Skip to content

Commit e95324d

Browse files
authored
Merge branch 'develop' into onur/dataloader-integration
2 parents a247f50 + e944daa commit e95324d

File tree

101 files changed

+1079
-378
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

101 files changed

+1079
-378
lines changed

.github/workflows/build.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1168,7 +1168,7 @@ jobs:
11681168
- name: Set up Node
11691169
uses: actions/setup-node@v4
11701170
with:
1171-
node-version-file: 'dev-packages/e2e-tests/package.json'
1171+
node-version: 22
11721172
- name: Restore caches
11731173
uses: ./.github/actions/restore-cache
11741174
with:
+98
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
name: "Automation: Update GH Project"
2+
on:
3+
pull_request:
4+
types:
5+
- closed
6+
- opened
7+
- reopened
8+
- ready_for_review
9+
- converted_to_draft
10+
11+
jobs:
12+
# Check if PR is in project
13+
check_project:
14+
name: Check if PR is in project
15+
runs-on: ubuntu-latest
16+
steps:
17+
- name: Check if PR is in project
18+
continue-on-error: true
19+
id: check_project
20+
uses: github/update-project-action@f980378bc179626af5b4e20ec05ec39c7f7a6f6d
21+
with:
22+
github_token: ${{ secrets.GH_PROJECT_AUTOMATION }}
23+
organization: getsentry
24+
project_number: 31
25+
content_id: ${{ github.event.pull_request.node_id }}
26+
field: Status
27+
operation: read
28+
29+
- name: If project field is read, set is_in_project to 1
30+
if: steps.check_project.outputs.field_read_value
31+
id: is_in_project
32+
run: echo "is_in_project=1" >> "$GITHUB_OUTPUT"
33+
34+
outputs:
35+
is_in_project: ${{ steps.is_in_project.outputs.is_in_project || '0' }}
36+
37+
# When a PR is a draft, it should go into "In Progress"
38+
mark_as_in_progress:
39+
name: "Mark as In Progress"
40+
needs: check_project
41+
if: |
42+
needs.check_project.outputs.is_in_project == '1'
43+
&& (github.event.action == 'opened' || github.event.action == 'reopened' || github.event.action == 'converted_to_draft')
44+
&& github.event.pull_request.draft == true
45+
runs-on: ubuntu-latest
46+
steps:
47+
- name: Update status to in_progress
48+
uses: github/update-project-action@f980378bc179626af5b4e20ec05ec39c7f7a6f6d
49+
with:
50+
github_token: ${{ secrets.GH_PROJECT_AUTOMATION }}
51+
organization: getsentry
52+
project_number: 31
53+
content_id: ${{ github.event.pull_request.node_id }}
54+
field: Status
55+
value: "🏗 In Progress"
56+
57+
# When a PR is not a draft, it should go into "In Review"
58+
mark_as_in_review:
59+
name: "Mark as In Review"
60+
needs: check_project
61+
if: |
62+
needs.check_project.outputs.is_in_project == '1'
63+
&& (github.event.action == 'opened' || github.event.action == 'reopened' || github.event.action == 'ready_for_review')
64+
&& github.event.pull_request.draft == false
65+
runs-on: ubuntu-latest
66+
steps:
67+
- name: Update status to in_review
68+
id: update_status
69+
uses: github/update-project-action@f980378bc179626af5b4e20ec05ec39c7f7a6f6d
70+
with:
71+
github_token: ${{ secrets.GH_PROJECT_AUTOMATION }}
72+
organization: getsentry
73+
project_number: 31
74+
content_id: ${{ github.event.pull_request.node_id }}
75+
field: Status
76+
value: "👀 In Review"
77+
78+
# By default, closed PRs go into "Ready for Release"
79+
# But if they are closed without merging, they should go into "Done"
80+
mark_as_done:
81+
name: "Mark as Done"
82+
needs: check_project
83+
if: |
84+
needs.check_project.outputs.is_in_project == '1'
85+
&& github.event.action == 'closed' && github.event.pull_request.merged == false
86+
runs-on: ubuntu-latest
87+
steps:
88+
- name: Update status to done
89+
id: update_status
90+
uses: github/update-project-action@f980378bc179626af5b4e20ec05ec39c7f7a6f6d
91+
with:
92+
github_token: ${{ secrets.GH_PROJECT_AUTOMATION }}
93+
organization: getsentry
94+
project_number: 31
95+
content_id: ${{ github.event.pull_request.node_id }}
96+
field: Status
97+
value: "✅ Done"
98+

CHANGELOG.md

+33-1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,38 @@
1010

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

13+
## 8.30.0
14+
15+
### Important Changes
16+
17+
- _feat(node): Add `kafkajs` integration (#13528)_
18+
19+
This release adds a new integration that instruments `kafkajs` library with spans and traces. This integration is
20+
automatically enabled by default, but can be included with the `Sentry.kafkaIntegration()` import.
21+
22+
```js
23+
Sentry.init({
24+
integrations: [Sentry.kafkaIntegration()],
25+
});
26+
```
27+
28+
### Other Changes
29+
30+
- feat(core): Allow adding measurements without global client (#13612)
31+
- feat(deps): Bump @opentelemetry/instrumentation-undici from 0.5.0 to 0.6.0 (#13622)
32+
- feat(deps): Bump @sentry/cli from 2.33.0 to 2.35.0 (#13624)
33+
- feat(node): Use `@opentelemetry/instrumentation-undici` for fetch tracing (#13485)
34+
- feat(nuxt): Add server config to root folder (#13583)
35+
- feat(otel): Upgrade @opentelemetry/semantic-conventions to 1.26.0 (#13631)
36+
- fix(browser): check supportedEntryTypes before caling the function (#13541)
37+
- fix(browser): Ensure Standalone CLS span timestamps are correct (#13649)
38+
- fix(nextjs): Widen removal of 404 transactions (#13628)
39+
- fix(node): Remove ambiguity and race conditions when matching local variables to exceptions (#13501)
40+
- fix(node): Update OpenTelemetry instrumentation package for solidstart and opentelemetry (#13640)
41+
- fix(node): Update OpenTelemetry instrumentation package for solidstart and opentelemetry (#13642)
42+
- fix(vue): Ensure Vue `trackComponents` list matches components with or without `<>` (#13543)
43+
- ref(profiling): Conditionally shim cjs globals (#13267)
44+
1345
Work in this release was contributed by @Zen-cronic and @odanado. Thank you for your contributions!
1446

1547
## 8.29.0
@@ -34,7 +66,7 @@ import * as Sentry from '@sentry/node';
3466

3567
Sentry.init({
3668
dsn: '__PUBLIC_DSN__',
37-
registerEsmLoaderHooks: { onlyHookedModules: true },
69+
registerEsmLoaderHooks: { onlyIncludeInstrumentedModules: true },
3870
});
3971
```
4072

dev-packages/browser-integration-tests/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@sentry-internal/browser-integration-tests",
3-
"version": "8.29.0",
3+
"version": "8.30.0",
44
"main": "index.js",
55
"license": "MIT",
66
"engines": {
@@ -43,7 +43,7 @@
4343
"@babel/preset-typescript": "^7.16.7",
4444
"@playwright/test": "^1.44.1",
4545
"@sentry-internal/rrweb": "2.11.0",
46-
"@sentry/browser": "8.29.0",
46+
"@sentry/browser": "8.30.0",
4747
"axios": "1.6.7",
4848
"babel-loader": "^8.2.2",
4949
"html-webpack-plugin": "^5.5.0",

dev-packages/browser-integration-tests/suites/tracing/metrics/web-vitals-cls-standalone-spans/test.ts

+41
Original file line numberDiff line numberDiff line change
@@ -453,3 +453,44 @@ sentryTest("doesn't send further CLS after the first page hide", async ({ getLoc
453453
// a timeout or something similar.
454454
await navigationTxnPromise;
455455
});
456+
457+
sentryTest('CLS span timestamps are set correctly', async ({ getLocalTestPath, page }) => {
458+
const url = await getLocalTestPath({ testDir: __dirname });
459+
460+
const eventData = await getFirstSentryEnvelopeRequest<SentryEvent>(page, url);
461+
462+
expect(eventData.type).toBe('transaction');
463+
expect(eventData.contexts?.trace?.op).toBe('pageload');
464+
expect(eventData.timestamp).toBeDefined();
465+
466+
const pageloadEndTimestamp = eventData.timestamp!;
467+
468+
const spanEnvelopePromise = getMultipleSentryEnvelopeRequests<SpanEnvelope>(
469+
page,
470+
1,
471+
{ envelopeType: 'span' },
472+
properFullEnvelopeRequestParser,
473+
);
474+
475+
await triggerAndWaitForLayoutShift(page);
476+
477+
await hidePage(page);
478+
479+
const spanEnvelope = (await spanEnvelopePromise)[0];
480+
const spanEnvelopeItem = spanEnvelope[1][0][1];
481+
482+
expect(spanEnvelopeItem.start_timestamp).toBeDefined();
483+
expect(spanEnvelopeItem.timestamp).toBeDefined();
484+
485+
const clsSpanStartTimestamp = spanEnvelopeItem.start_timestamp!;
486+
const clsSpanEndTimestamp = spanEnvelopeItem.timestamp!;
487+
488+
// CLS performance entries have no duration ==> start and end timestamp should be the same
489+
expect(clsSpanStartTimestamp).toEqual(clsSpanEndTimestamp);
490+
491+
// We don't really care that they are very close together but rather about the order of magnitude
492+
// Previously, we had a bug where the timestamps would be significantly off (by multiple hours)
493+
// so we only ensure that this bug is fixed. 60 seconds should be more than enough.
494+
expect(clsSpanStartTimestamp - pageloadEndTimestamp).toBeLessThan(60);
495+
expect(clsSpanStartTimestamp).toBeGreaterThan(pageloadEndTimestamp);
496+
});

dev-packages/bundle-analyzer-scenarios/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@sentry-internal/bundle-analyzer-scenarios",
3-
"version": "8.29.0",
3+
"version": "8.30.0",
44
"description": "Scenarios to test bundle analysis with",
55
"repository": "git://github.com/getsentry/sentry-javascript.git",
66
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/dev-packages/bundle-analyzer-scenarios",

dev-packages/clear-cache-gh-action/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@sentry-internal/clear-cache-gh-action",
33
"description": "An internal Github Action to clear GitHub caches.",
4-
"version": "8.29.0",
4+
"version": "8.30.0",
55
"license": "MIT",
66
"engines": {
77
"node": ">=18"

dev-packages/e2e-tests/package.json

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@sentry-internal/e2e-tests",
3-
"version": "8.29.0",
3+
"version": "8.30.0",
44
"license": "MIT",
55
"private": true,
66
"scripts": {
@@ -14,7 +14,7 @@
1414
"test:prepare": "ts-node prepare.ts",
1515
"test:validate": "run-s test:validate-configuration test:validate-test-app-setups",
1616
"clean": "rimraf tmp node_modules pnpm-lock.yaml && yarn clean:test-applications",
17-
"clean:test-applications": "rimraf test-applications/**/{node_modules,dist,build,.next,.sveltekit,pnpm-lock.yaml} .last-run.json && pnpm store prune"
17+
"clean:test-applications": "rimraf --glob test-applications/**/{node_modules,dist,build,.next,.sveltekit,pnpm-lock.yaml} .last-run.json && pnpm store prune"
1818
},
1919
"devDependencies": {
2020
"@types/glob": "8.0.0",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import { test } from '@playwright/test';
2+
import { waitForTransaction } from '@sentry-internal/test-utils';
3+
4+
test('should create a transaction for a CJS pages router API endpoint', async ({ page }) => {
5+
let received404Transaction = false;
6+
waitForTransaction('nextjs-13', async transactionEvent => {
7+
return transactionEvent.transaction === 'GET /404' || transactionEvent.transaction === 'GET /_not-found';
8+
}).then(() => {
9+
received404Transaction = true;
10+
});
11+
12+
await page.goto('/page-that-doesnt-exist');
13+
14+
await new Promise<void>((resolve, reject) => {
15+
setTimeout(() => {
16+
if (received404Transaction) {
17+
reject(new Error('received 404 transaction'));
18+
} else {
19+
resolve();
20+
}
21+
}, 5_000);
22+
});
23+
});

dev-packages/e2e-tests/test-applications/nextjs-14/tests/generation-functions.test.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ test('Should emit a span for a generateMetadata() function invokation', async ({
1717
expect(transaction.spans).toContainEqual(
1818
expect.objectContaining({
1919
description: 'generateMetadata /generation-functions/page',
20-
origin: 'manual',
20+
origin: 'auto',
2121
parent_span_id: expect.any(String),
2222
span_id: expect.any(String),
2323
status: 'ok',
@@ -74,7 +74,7 @@ test('Should send a transaction event for a generateViewport() function invokati
7474
expect((await transactionPromise).spans).toContainEqual(
7575
expect.objectContaining({
7676
description: 'generateViewport /generation-functions/page',
77-
origin: 'manual',
77+
origin: 'auto',
7878
parent_span_id: expect.any(String),
7979
span_id: expect.any(String),
8080
status: 'ok',
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
// Because bundlers can now predetermine a static set of binaries we need to ensure those binaries
2+
// actually exists, else we risk a compile time error when bundling the package. This could happen
3+
// if we added a new binary in cpu_profiler.ts, but forgot to prebuild binaries for it. Because CI
4+
// only runs integration and unit tests, this change would be missed and could end up in a release.
5+
// Therefor, once all binaries are precompiled in CI and tests pass, run esbuild with bundle:true
6+
// which will copy all binaries to the outfile folder and throw if any of them are missing.
7+
import esbuild from 'esbuild';
8+
9+
console.log('Running build using esbuild version', esbuild.version);
10+
11+
esbuild.buildSync({
12+
platform: 'node',
13+
entryPoints: ['./index.ts'],
14+
outfile: './dist/index.shimmed.mjs',
15+
target: 'esnext',
16+
format: 'esm',
17+
bundle: true,
18+
loader: { '.node': 'copy' },
19+
banner: {
20+
js: `
21+
import { dirname } from 'node:path';
22+
import { fileURLToPath } from 'node:url';
23+
import { createRequire } from 'node:module';
24+
const require = createRequire(import.meta.url);
25+
const __filename = fileURLToPath(import.meta.url);
26+
const __dirname = dirname(__filename);
27+
`,
28+
},
29+
});

dev-packages/e2e-tests/test-applications/node-profiling/package.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@
44
"private": true,
55
"scripts": {
66
"typecheck": "tsc --noEmit",
7-
"build": "node build.mjs",
8-
"test": "npm run build && node dist/index.js",
9-
"clean": "npx rimraf node_modules",
7+
"build": "node build.mjs && node build.shimmed.mjs",
8+
"test": "node dist/index.js && node --experimental-require-module dist/index.js && node dist/index.shimmed.mjs",
9+
"clean": "npx rimraf node_modules dist",
1010
"test:build": "npm run typecheck && npm run build",
1111
"test:assert": "npm run test"
1212
},

dev-packages/external-contributor-gh-action/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"name": "@sentry-internal/external-contributor-gh-action",
33
"description": "An internal Github Action to add external contributors to the CHANGELOG.md file.",
4-
"version": "8.29.0",
4+
"version": "8.30.0",
55
"license": "MIT",
66
"engines": {
77
"node": ">=18"

dev-packages/node-integration-tests/package.json

+6-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@sentry-internal/node-integration-tests",
3-
"version": "8.29.0",
3+
"version": "8.30.0",
44
"license": "MIT",
55
"engines": {
66
"node": ">=14.18"
@@ -31,10 +31,10 @@
3131
"@nestjs/core": "^10.3.3",
3232
"@nestjs/platform-express": "^10.3.3",
3333
"@prisma/client": "5.9.1",
34-
"@sentry/aws-serverless": "8.29.0",
35-
"@sentry/node": "8.29.0",
36-
"@sentry/types": "8.29.0",
37-
"@sentry/utils": "8.29.0",
34+
"@sentry/aws-serverless": "8.30.0",
35+
"@sentry/node": "8.30.0",
36+
"@sentry/types": "8.30.0",
37+
"@sentry/utils": "8.30.0",
3838
"@types/mongodb": "^3.6.20",
3939
"@types/mysql": "^2.15.21",
4040
"@types/pg": "^8.6.5",
@@ -49,6 +49,7 @@
4949
"graphql": "^16.3.0",
5050
"http-terminator": "^3.2.0",
5151
"ioredis": "^5.4.1",
52+
"kafkajs": "2.2.4",
5253
"mongodb": "^3.7.3",
5354
"mongodb-memory-server-global": "^7.6.3",
5455
"mongoose": "^5.13.22",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
services:
2+
db:
3+
image: apache/kafka:latest
4+
restart: always
5+
container_name: integration-tests-kafka
6+
ports:
7+
- '9092:9092'

0 commit comments

Comments
 (0)