chore(e2e-tests): Use tarball symlinks for E2E tests instead of verdaccio#20386
chore(e2e-tests): Use tarball symlinks for E2E tests instead of verdaccio#20386
Conversation
size-limit report 📦
|
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ 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.
aad44f0 to
4f79dac
Compare
logaretm
left a comment
There was a problem hiding this comment.
Nice one, I was wondering if it handled transitive deps and it does with the overrides 👍
4f79dac to
a2f4233
Compare
a2f4233 to
4cccd63
Compare
| overrides: { | ||
| ...overrides, | ||
| ...fixedOverrides, | ||
| }, |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
this is expected, we need to be able to override this.

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
"@sentry/browser": "file:../../packed/sentry-browser-packed.tgz",yarn test:preparewill 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)pnpm.overridessection for all our apps pointing them to the packed folder, to ensure we get these as transitive dependencies as wellLocally, you can continue to use
yarn test:run test-app-nameand 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.