Skip to content

chore(e2e-tests): Use tarball symlinks for E2E tests instead of verdaccio - #20386

Merged
mydea merged 11 commits into
developfrom
fn/e2e-test-linked
Apr 22, 2026
Merged

chore(e2e-tests): Use tarball symlinks for E2E tests instead of verdaccio#20386
mydea merged 11 commits into
developfrom
fn/e2e-test-linked

Conversation

@mydea

@mydeamydea commented Apr 17, 2026

Copy link
Copy Markdown
Member

This PR completely removes verdaccio in favor of referencing the built tarballs directly.
We rely on pnpm overrides which we inject into the test app to ensure that also transitive dependencies are correct.

This is basically instant and reduces about 20s of verdaccio/registry preparation time we used to have before each e2e test app.

How it works

  • We use a reference to a tarball for internal dependencies in our e2e tests. these are virtual files in /packed directory, e.g. "@sentry/browser": "file:../../packed/sentry-browser-packed.tgz",
  • yarn test:prepare will create/update those packed files with symlinks to the current tarballs (which have the version in their filename so we cannot just link to them directly consistently)
  • Additionally, we adjust the created test apps in the tmp dir by adding a pnpm.overrides section for all our apps pointing them to the packed folder, to ensure we get these as transitive dependencies as well

Locally, you can continue to use yarn test:run test-app-name and it will do all of that under the hood, nothing else needed (except to generate the tarballs, as before). On CI I adjusted the places to run the necessary pieces in addition to ensure everything works as expected.

Example generated test app

It effectively creates a package.json for the test app that looks like this:

{
"name": "node-hapi",
"version": "1.0.0",
"private": true,
"scripts": {
"build": "tsc",
"start": "node src/app.js",
"test": "playwright test",
"clean": "npx rimraf node_modules pnpm-lock.yaml",
"test:build": "pnpm install",
"test:assert": "pnpm test"
},
"dependencies": {
"@hapi/boom": "10.0.1",
"@hapi/hapi": "21.3.10",
"@sentry/node": "file:../../packed/sentry-node-packed.tgz"
},
"devDependencies": {
"@playwright/test": "~1.56.0",
"@sentry-internal/test-utils": "link:~/my-app/dev-packages/test-utils"
},
"volta": {
"extends": "~/my-app/dev-packages/e2e-tests/package.json"
},
"pnpm": {
"overrides": {
"@sentry-internal/browser-utils": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-internal-browser-utils-packed.tgz",
"@sentry-internal/eslint-config-sdk": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-internal-eslint-config-sdk-packed.tgz",
"@sentry-internal/eslint-plugin-sdk": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-internal-eslint-plugin-sdk-packed.tgz",
"@sentry-internal/feedback": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-internal-feedback-packed.tgz",
"@sentry-internal/replay": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-internal-replay-packed.tgz",
"@sentry-internal/replay-canvas": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-internal-replay-canvas-packed.tgz",
"@sentry-internal/typescript": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-internal-typescript-packed.tgz",
"@sentry/angular": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-angular-packed.tgz",
"@sentry/astro": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-astro-packed.tgz",
"@sentry/aws-serverless": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-aws-serverless-packed.tgz",
"@sentry/browser": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-browser-packed.tgz",
"@sentry/bun": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-bun-packed.tgz",
"@sentry/cloudflare": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-cloudflare-packed.tgz",
"@sentry/core": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-core-packed.tgz",
"@sentry/deno": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-deno-packed.tgz",
"@sentry/effect": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-effect-packed.tgz",
"@sentry/elysia": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-elysia-packed.tgz",
"@sentry/ember": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-ember-packed.tgz",
"@sentry/gatsby": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-gatsby-packed.tgz",
"@sentry/google-cloud-serverless": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-google-cloud-serverless-packed.tgz",
"@sentry/hono": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-hono-packed.tgz",
"@sentry/nestjs": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-nestjs-packed.tgz",
"@sentry/nextjs": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-nextjs-packed.tgz",
"@sentry/node": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-node-packed.tgz",
"@sentry/node-core": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-node-core-packed.tgz",
"@sentry/node-native": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-node-native-packed.tgz",
"@sentry/nuxt": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-nuxt-packed.tgz",
"@sentry/opentelemetry": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-opentelemetry-packed.tgz",
"@sentry/profiling-node": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-profiling-node-packed.tgz",
"@sentry/react": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-react-packed.tgz",
"@sentry/react-router": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-react-router-packed.tgz",
"@sentry/remix": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-remix-packed.tgz",
"@sentry/solid": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-solid-packed.tgz",
"@sentry/solidstart": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-solidstart-packed.tgz",
"@sentry/svelte": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-svelte-packed.tgz",
"@sentry/sveltekit": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-sveltekit-packed.tgz",
"@sentry/tanstackstart": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-tanstackstart-packed.tgz",
"@sentry/tanstackstart-react": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-tanstackstart-react-packed.tgz",
"@sentry/types": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-types-packed.tgz",
"@sentry/vercel-edge": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-vercel-edge-packed.tgz",
"@sentry/vue": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-vue-packed.tgz",
"@sentry/wasm": "file:~/my-app/dev-packages/e2e-tests/packed/sentry-wasm-packed.tgz"
}
}
}

then installs this normally with the regular registry.

@mydeamydea self-assigned this Apr 17, 2026
@github-actions

github-actionsBot commented Apr 17, 2026

Copy link
Copy Markdown
Contributor

size-limit report 📦

PathSize% ChangeChange
@sentry/browser25.88 kB--
@sentry/browser - with treeshaking flags24.35 kB--
@sentry/browser (incl. Tracing)43.81 kB--
@sentry/browser (incl. Tracing + Span Streaming)45.5 kB--
@sentry/browser (incl. Tracing, Profiling)48.73 kB--
@sentry/browser (incl. Tracing, Replay)82.98 kB--
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags72.5 kB--
@sentry/browser (incl. Tracing, Replay with Canvas)87.67 kB--
@sentry/browser (incl. Tracing, Replay, Feedback)99.93 kB--
@sentry/browser (incl. Feedback)42.7 kB--
@sentry/browser (incl. sendFeedback)30.55 kB--
@sentry/browser (incl. FeedbackAsync)35.55 kB--
@sentry/browser (incl. Metrics)27.16 kB--
@sentry/browser (incl. Logs)27.29 kB--
@sentry/browser (incl. Metrics & Logs)27.98 kB--
@sentry/react27.62 kB--
@sentry/react (incl. Tracing)46.05 kB--
@sentry/vue30.71 kB--
@sentry/vue (incl. Tracing)45.62 kB--
@sentry/svelte25.89 kB--
CDN Bundle28.57 kB--
CDN Bundle (incl. Tracing)46.08 kB--
CDN Bundle (incl. Logs, Metrics)29.95 kB--
CDN Bundle (incl. Tracing, Logs, Metrics)47.12 kB--
CDN Bundle (incl. Replay, Logs, Metrics)68.92 kB--
CDN Bundle (incl. Tracing, Replay)83.14 kB--
CDN Bundle (incl. Tracing, Replay, Logs, Metrics)84.17 kB--
CDN Bundle (incl. Tracing, Replay, Feedback)88.61 kB--
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics)89.69 kB--
CDN Bundle - uncompressed83.59 kB--
CDN Bundle (incl. Tracing) - uncompressed137.62 kB--
CDN Bundle (incl. Logs, Metrics) - uncompressed87.73 kB--
CDN Bundle (incl. Tracing, Logs, Metrics) - uncompressed141.03 kB--
CDN Bundle (incl. Replay, Logs, Metrics) - uncompressed211.31 kB--
CDN Bundle (incl. Tracing, Replay) - uncompressed255.06 kB--
CDN Bundle (incl. Tracing, Replay, Logs, Metrics) - uncompressed258.46 kB--
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed267.97 kB--
CDN Bundle (incl. Tracing, Replay, Feedback, Logs, Metrics) - uncompressed271.36 kB--
@sentry/nextjs (client)48.58 kB--
@sentry/sveltekit (client)44.22 kB--
@sentry/node-core58.02 kB+0.01%+5 B 🔺
@sentry/node174.89 kB+0.01%+6 B 🔺
@sentry/node - without tracing97.98 kB+0.02%+10 B 🔺
@sentry/aws-serverless115.21 kB+0.02%+18 B 🔺

View base workflow run

@mydea
mydea marked this pull request as ready for review April 20, 2026 08:23
Comment threaddev-packages/e2e-tests/ciPnpmOverrides.ts Outdated
Comment threaddev-packages/e2e-tests/lib/pnpmOverrides.ts
Comment threaddev-packages/e2e-tests/lib/syncPackedTarballSymlinks.ts

@cursorcursorBot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit aad44f0. Configure here.

Comment threaddev-packages/e2e-tests/lib/copyToTemp.ts Outdated
@mydea
mydeaforce-pushed the fn/e2e-test-linked branch from aad44f0 to 4f79dacCompareApril 20, 2026 09:01

@JPeer264JPeer264 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That is amazing. It works like a charm. This is now perfect to resurrect #20056

@logaretmlogaretm left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice one, I was wondering if it handled transitive deps and it does with the overrides 👍

@mydea
mydeaforce-pushed the fn/e2e-test-linked branch from 4f79dac to a2f4233CompareApril 21, 2026 10:56
@mydea
mydeaforce-pushed the fn/e2e-test-linked branch from a2f4233 to 4cccd63CompareApril 21, 2026 13:59
Comment on lines +33 to +36
overrides: {
...overrides,
...fixedOverrides,
},

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: The merge order for pnpm.overrides is incorrect. Existing overrides from package.json are applied after the new tarball overrides, causing the new ones to be ignored on key conflicts.
Severity: MEDIUM

Suggested Fix

Reverse the spread operator order in the overrides object to be { ...fixedOverrides, ...overrides }. This ensures that the newly generated tarball overrides will correctly take precedence over any pre-existing overrides in the test application's package.json.

Prompt for AI Agent
Review the code at the location below. A potential bug has been identified by an AI
agent. Verify if this is a real issue. If it is, propose a fix; if not, explain why it's
not valid.
Location: dev-packages/e2e-tests/lib/pnpmOverrides.ts#L33-L36
Potential issue: In `dev-packages/e2e-tests/lib/pnpmOverrides.ts`, the function
responsible for injecting pnpm overrides merges objects in an incorrect order. The newly
generated tarball overrides (`overrides`) are spread into the final object before the
existing overrides from the test application's `package.json` (`fixedOverrides`). Due to
how JavaScript's spread syntax works, properties from the last object overwrite earlier
ones. This causes existing overrides in test applications to incorrectly take precedence
over the intended tarball overrides, which undermines the goal of testing with packed
tarballs.

Did we get this right? 👍 / 👎 to inform future reviews.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is expected, we need to be able to override this.

@mydea
mydea merged commit 215c16e into developApr 22, 2026
249 checks passed
@mydea
mydea deleted the fn/e2e-test-linked branch April 22, 2026 07:23
s1gr1d added a commit that referenced this pull request Apr 30, 2026
pnpm overrides handle local package installs via local `file:` paths.
The `npmrc` is not needed anymore but 3 files were still there as the
E2E tests were added after merging the PR linked below.
Builds on top of
#20386
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants

@mydea@logaretm@JPeer264