Skip to content

Commit 781f31c

Browse files
authored
Merge pull request #20707 from getsentry/prepare-release/10.52.0
meta(changelog): Update changelog for 10.52.0
2 parents ccbeda3 + 11a64f6 commit 781f31c

474 files changed

Lines changed: 18531 additions & 3782 deletions

File tree

Some content is hidden

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

.agents/skills/fix-security-vulnerability/SKILL.md

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ git pull origin develop
9292
git checkout -b fix/dependabot-alert-<alert-number>
9393
```
9494

95-
Then apply the fix commands from Step 5 of the single-alert workflow (edit `package.json`, `yarn install`, `yarn dedupe-deps:fix`, verify) — but **skip the "Do NOT commit" instruction**, since user approval was already obtained in Step 2b. After applying:
95+
Then apply the fix commands from Step 5 of the single-alert workflow (`npx yarn-update-dependency@latest <package>`, `yarn dedupe-deps:fix`, verify) — but **skip the "Do NOT commit" instruction**, since user approval was already obtained in Step 2b. After applying:
9696

9797
```bash
9898
# 3. Stage and commit the changes
@@ -263,8 +263,8 @@ Present findings and **wait for user approval** before making changes:
263263
<One of: Safe to bump / Version-specific test - do not bump / Bump parent package>
264264
265265
### Proposed Fix
266-
1. Update <file>: "<package>": "<new-version>"
267-
2. yarn install && yarn dedupe-deps:fix
266+
1. npx yarn-update-dependency@latest <package>
267+
2. yarn dedupe-deps:fix
268268
3. Verify with: yarn why <package>
269269
270270
Proceed?
@@ -273,15 +273,14 @@ Proceed?
273273
### Step 5: Apply Fix (After Approval)
274274
275275
```bash
276-
# 1. Edit package.json
277-
# 2. Update lockfile
278-
yarn install
279-
# 3. Deduplicate
276+
# 1. Upgrade the package (updates package.json + lockfile)
277+
npx yarn-update-dependency@latest <package>
278+
# 2. Deduplicate
280279
yarn dedupe-deps:fix
281-
# 4. Verify
280+
# 3. Verify
282281
yarn dedupe-deps:check
283282
yarn why <package>
284-
# 5. Show changes
283+
# 4. Show changes
285284
git diff
286285
```
287286
@@ -325,6 +324,7 @@ gh api --method PATCH repos/getsentry/sentry-javascript/dependabot/alerts/<numbe
325324
326325
| Command | Purpose |
327326
| ------------------------------------------------------------------------------------------------------------ | ---------------------------- |
327+
| `npx yarn-update-dependency@latest <pkg>` | Upgrade package across repo |
328328
| `yarn why <pkg>` | Show dependency tree |
329329
| `yarn dedupe-deps:fix` | Fix duplicates in yarn.lock |
330330
| `yarn dedupe-deps:check` | Verify no duplicate issues |

.agents/skills/write-tests/SKILL.md

Lines changed: 95 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,17 @@ Follow these steps in order before writing any test code.
2222
1. **Decide the framework.** Testing a function's return value, side effects, or module interactions
2323
→ Vitest (lives under `packages/<name>/test/`). Testing that a real HTTP request to a running app
2424
produces the correct Sentry envelope → Playwright (lives under
25-
`dev-packages/e2e-tests/test-applications/<app>/tests/`).
25+
`dev-packages/e2e-tests/test-applications/<app>/tests/`). Testing Node SDK instrumentation
26+
against real envelope output → node-integration-tests (lives under
27+
`dev-packages/node-integration-tests/suites/`).
28+
29+
**Parameterization differs by framework — pick the right one:**
30+
31+
| Framework | How to parameterize |
32+
| ---------------------- | ------------------------------------------------------------- |
33+
| Vitest | `it.each` / `it.for` (runner-integrated, one test each) |
34+
| Playwright E2E | `.forEach()` outside `test()` (registers separate tests) |
35+
| Node integration tests | Loops **inside** a single `test()` body (one Node.js process) |
2636

2737
2. **Read 2–3 existing test files** in the target `test/` directory. Specifically note:
2838
- Which `vi.mock` style they use (string path or import form)
@@ -299,6 +309,64 @@ describe('patchRoute', () => {
299309

300310
---
301311

312+
## Writing node-integration-tests
313+
314+
Node integration tests (`dev-packages/node-integration-tests/`) use `createEsmAndCjsTests` to
315+
run a real Node scenario file and assert on captured Sentry envelopes.
316+
317+
### Minimize `test()` calls — each one spawns a separate Node process
318+
319+
**This is the opposite of the Playwright rule.** In Playwright, each `test()` is cheap — use
320+
`.forEach()` to register many tests. In node-integration-tests, each `test()` forks a fresh Node
321+
process with full startup cost. A `describe.each` matrix that looks reasonable in a unit test
322+
context balloons into dozens of cold starts and slows CI by a large factor.
323+
324+
**Rule: loop inside the test body, not around `test()` calls.**
325+
326+
```typescript
327+
// Bad: 2 routes × 5 methods = 10 separate Node processes
328+
createEsmAndCjsTests(__dirname, 'scenario.mjs', 'instrument.mjs', (createRunner, test) => {
329+
describe.each(['/sync', '/async'])('when using %s route', route => {
330+
describe.each(['get', 'post', 'put', 'delete', 'patch'])('when using %s method', method => {
331+
test('handles transaction', async () => {
332+
// ...
333+
});
334+
});
335+
});
336+
});
337+
```
338+
339+
```typescript
340+
// Good: one Node process, all combinations asserted in a single test run
341+
createEsmAndCjsTests(__dirname, 'scenario.mjs', 'instrument.mjs', (createRunner, test) => {
342+
test('handles transactions for all route/method/path combinations', async () => {
343+
const runner = createRunner();
344+
const requests: Array<{ method: string; url: string }> = [];
345+
346+
for (const route of ['/sync', '/async']) {
347+
for (const method of ['get', 'post', 'put', 'delete', 'patch']) {
348+
const fullPath = `${route}${path}`;
349+
runner.expect({
350+
transaction: { transaction: `${method.toUpperCase()} ${fullPath}` },
351+
});
352+
requests.push({ method, url: fullPath });
353+
}
354+
}
355+
356+
const started = runner.start();
357+
for (const req of requests) {
358+
await started.makeRequest(req.method, req.url);
359+
}
360+
await started.completed();
361+
}, 60_000);
362+
});
363+
```
364+
365+
If a subset of cases has meaningfully different expectations (e.g., error vs. success), split
366+
into two tests — not thirty.
367+
368+
---
369+
302370
## Writing Playwright E2E tests
303371

304372
### When to write E2E tests
@@ -366,17 +434,35 @@ expect(mechanism?.type).toBe('auto.http.hono.context_error');
366434

367435
### Parameterized E2E tests
368436

369-
For Playwright tests (unlike Vitest), `for...of` loops are the established codebase convention.
370-
Use `for...of` (not `.forEach()`) so Playwright's test registration works correctly:
437+
For Playwright tests (unlike Vitest), use standard JS `.forEach()` as this is recommended by Playwright,
438+
**not** `it.each` or `it.for`, which are Vitest-only APIs. The `.forEach()` runs at discovery time, registering
439+
each case as its own independent test. All cases then run separately at execution time.
371440

372441
```typescript
373-
for (const { name, prefix } of SCENARIOS) {
374-
test.describe(name, () => {
375-
test('captures named middleware span', async ({ baseURL }) => {
376-
// ...
377-
});
442+
[
443+
{ a: 1, b: 1, expected: 2 },
444+
{ a: 1, b: 2, expected: 3 },
445+
{ a: 2, b: 1, expected: 3 },
446+
].forEach(({ a, b, expected }) => {
447+
test(`given ${a} and ${b} as arguments, returns ${expected}`, ({ page }) => {
448+
expect(a + b).toEqual(expected);
378449
});
379-
}
450+
});
451+
```
452+
453+
**Don't put the loop inside a single test.** That collapses all cases into one test body — a
454+
failure in one iteration aborts the rest, and the runner reports a single failure with no
455+
per-case visibility:
456+
457+
```typescript
458+
// Bad: all routes tested in one test — a failure on /users skips /posts entirely
459+
test('captures transactions for all routes', async ({ baseURL }) => {
460+
for (const route of ['/users', '/posts', '/comments']) {
461+
const txn = await waitForTransaction(APP_NAME, e => e.transaction === `GET ${route}`);
462+
await fetch(`${baseURL}${route}`);
463+
expect(txn.contexts?.trace?.op).toBe('http.server');
464+
}
465+
});
380466
```
381467

382468
### Common pitfalls

.github/FLAKY_CI_FAILURE_TEMPLATE.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
---
22
title: '[Flaky CI]: {{ env.JOB_NAME }} - {{ env.TEST_NAME }}'
3-
labels: Tests
3+
labels: Tests, Bug
44
---
55

66
### Flakiness Type

.github/workflows/auto-release.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ jobs:
1919
steps:
2020
- name: Get auth token
2121
id: token
22-
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
22+
uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
2323
with:
2424
app-id: ${{ vars.SENTRY_RELEASE_BOT_CLIENT_ID }}
2525
private-key: ${{ secrets.SENTRY_RELEASE_BOT_PRIVATE_KEY }}
@@ -51,7 +51,7 @@ jobs:
5151
node-version-file: 'package.json'
5252

5353
- name: Prepare release
54-
uses: getsentry/craft@013a7b2113c2cac0ff32d5180cfeaefc7c9ce5b6 # v2.24.1
54+
uses: getsentry/craft@3dc647fee3586e57c7c31eb900fdec7cbb44f23f # v2.26.2
5555
if:
5656
github.event.pull_request.merged == true && steps.version-regex.outputs.match != '' &&
5757
steps.get_version.outputs.version != ''

.github/workflows/build.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,7 @@ jobs:
274274
pull-requests: write
275275
steps:
276276
- name: PR is opened against master
277-
uses: mshick/add-pr-comment@e7516d74559b5514092f5b096ed29a629a1237c6
277+
uses: mshick/add-pr-comment@8e4927817251f1ff60c001f04568532b38e0b4a0
278278
if: ${{ github.base_ref == 'master' && !startsWith(github.head_ref, 'prepare-release/') }}
279279
with:
280280
message: |
@@ -533,7 +533,7 @@ jobs:
533533
with:
534534
node-version-file: 'package.json'
535535
- name: Set up Deno
536-
uses: denoland/setup-deno@v2.0.3
536+
uses: denoland/setup-deno@v2.0.4
537537
with:
538538
deno-version: v2.1.5
539539
- name: Restore caches
@@ -1057,7 +1057,7 @@ jobs:
10571057
token: ${{ secrets.GITHUB_TOKEN }}
10581058
- name: Set up Deno
10591059
if: matrix.test-application == 'deno' || matrix.test-application == 'deno-streamed'
1060-
uses: denoland/setup-deno@v2.0.3
1060+
uses: denoland/setup-deno@v2.0.4
10611061
with:
10621062
deno-version: v2.1.5
10631063
- name: Restore caches

.github/workflows/bump-size-limits.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ jobs:
2929
steps:
3030
- name: Generate GitHub App token
3131
id: app-token
32-
uses: actions/create-github-app-token@v2
32+
uses: actions/create-github-app-token@v3
3333
with:
3434
app-id: ${{ vars.GITFLOW_APP_ID }}
3535
private-key: ${{ secrets.GITFLOW_APP_PRIVATE_KEY }}

.github/workflows/external-contributors.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ jobs:
3737

3838
- name: Generate GitHub App token
3939
id: app-token
40-
uses: actions/create-github-app-token@v2
40+
uses: actions/create-github-app-token@v3
4141
with:
4242
app-id: ${{ vars.GITFLOW_APP_ID }}
4343
private-key: ${{ secrets.GITFLOW_APP_PRIVATE_KEY }}

.github/workflows/gitflow-sync-develop.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ jobs:
2727

2828
- name: Generate GitHub App token
2929
id: app-token
30-
uses: actions/create-github-app-token@v2
30+
uses: actions/create-github-app-token@v3
3131
with:
3232
app-id: ${{ vars.GITFLOW_APP_ID }}
3333
private-key: ${{ secrets.GITFLOW_APP_PRIVATE_KEY }}

.github/workflows/pr-review-reminder.yml

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,12 @@ on:
77
# Saturday/Sunday are never counted as business days.
88
- cron: '0 10 * * 1-5'
99

10-
# pulls.* list + listRequestedReviewers → pull-requests: read
11-
# issues timeline + comments + createComment → issues: write
10+
# pulls.* list + listRequestedReviewers + createComment on PRs → pull-requests: write
1211
# repos.listCollaborators (outside) → Metadata read on the token (see GitHub App permission map)
1312
# checkout → contents: read
1413
permissions:
1514
contents: read
16-
issues: write
17-
pull-requests: read
15+
pull-requests: write
1816

1917
concurrency:
2018
group: ${{ github.workflow }}
@@ -27,7 +25,7 @@ jobs:
2725
runs-on: ubuntu-latest
2826
steps:
2927
- name: Checkout repository
30-
uses: actions/checkout@v4
28+
uses: actions/checkout@v6
3129

3230
- name: Remind pending reviewers
3331
uses: actions/github-script@v7

.github/workflows/release.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ jobs:
2323
steps:
2424
- name: Get auth token
2525
id: token
26-
uses: actions/create-github-app-token@29824e69f54612133e76f7eaac726eef6c875baf # v2.2.1
26+
uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
2727
with:
2828
app-id: ${{ vars.SENTRY_RELEASE_BOT_CLIENT_ID }}
2929
private-key: ${{ secrets.SENTRY_RELEASE_BOT_PRIVATE_KEY }}
@@ -36,7 +36,7 @@ jobs:
3636
with:
3737
node-version-file: 'package.json'
3838
- name: Prepare release
39-
uses: getsentry/craft@013a7b2113c2cac0ff32d5180cfeaefc7c9ce5b6 # v2.24.1
39+
uses: getsentry/craft@3dc647fee3586e57c7c31eb900fdec7cbb44f23f # v2.26.2
4040
env:
4141
GITHUB_TOKEN: ${{ steps.token.outputs.token }}
4242
with:

0 commit comments

Comments
 (0)