Skip to content

Commit d21ae31

Browse files
committed
Use locally built serverless package instead of pulling from npm in e2e tests
1 parent c4e92d4 commit d21ae31

File tree

4 files changed

+83
-4
lines changed

4 files changed

+83
-4
lines changed

.github/workflows/build.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -992,6 +992,8 @@ jobs:
992992
working-directory: ${{ runner.temp }}/test-application
993993
timeout-minutes: 7
994994
run: ${{ matrix.build-command || 'pnpm test:build' }}
995+
env:
996+
SENTRY_E2E_WORKSPACE_ROOT: ${{ github.workspace }}
995997

996998
- name: Install Playwright
997999
uses: ./.github/actions/install-playwright
@@ -1003,6 +1005,8 @@ jobs:
10031005
working-directory: ${{ runner.temp }}/test-application
10041006
timeout-minutes: 10
10051007
run: ${{ matrix.assert-command || 'pnpm test:assert' }}
1008+
env:
1009+
SENTRY_E2E_WORKSPACE_ROOT: ${{ github.workspace }}
10061010

10071011
- name: Upload Playwright Traces
10081012
uses: actions/upload-artifact@v5

dev-packages/e2e-tests/run.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,8 @@ async function run(): Promise<void> {
7676
REACT_APP_E2E_TEST_DSN: dsn,
7777
E2E_TEST_SENTRY_ORG_SLUG: process.env.E2E_TEST_SENTRY_ORG_SLUG || DEFAULT_SENTRY_ORG_SLUG,
7878
E2E_TEST_SENTRY_PROJECT: process.env.E2E_TEST_SENTRY_PROJECT || DEFAULT_SENTRY_PROJECT,
79+
// Pass workspace root so tests copied to temp dirs can find local packages
80+
SENTRY_E2E_WORKSPACE_ROOT: resolve(__dirname, '../..'),
7981
};
8082

8183
const env = {

dev-packages/e2e-tests/test-applications/aws-serverless/src/stack.ts

Lines changed: 50 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,17 @@ const LAYER_DIR = './node_modules/@sentry/aws-serverless/';
1515
const DEFAULT_NODE_VERSION = '22';
1616
export const SAM_PORT = 3001;
1717

18+
function resolvePackagesDir(): string {
19+
// When running via the e2e test runner, tests are copied to a temp directory
20+
// so we need the workspace root passed via env var
21+
const workspaceRoot = process.env.SENTRY_E2E_WORKSPACE_ROOT;
22+
if (workspaceRoot) {
23+
return path.join(workspaceRoot, 'packages');
24+
}
25+
// Fallback for local development when running from the original location
26+
return path.resolve(__dirname, '../../../../../packages');
27+
}
28+
1829
export class LocalLambdaStack extends Stack {
1930
sentryLayer: CfnResource;
2031

@@ -67,10 +78,46 @@ export class LocalLambdaStack extends Stack {
6778
const functionName = `${addLayer ? 'Layer' : 'Npm'}${lambdaDir}`;
6879

6980
if (!addLayer) {
81+
const lambdaPath = path.resolve(functionsDir, lambdaDir);
82+
const packageLockPath = path.join(lambdaPath, 'package-lock.json');
83+
const nodeModulesPath = path.join(lambdaPath, 'node_modules');
84+
85+
// Point the dependency at the locally built packages so tests use the current workspace bits
86+
// We need to link all @sentry/* packages that are dependencies of aws-serverless
87+
// because otherwise npm will try to install them from the registry, where the current version is not yet published
88+
const packagesToLink = ['aws-serverless', 'node', 'core', 'node-core', 'opentelemetry'];
89+
const dependencies: Record<string, string> = {};
90+
91+
const packagesDir = resolvePackagesDir();
92+
for (const pkgName of packagesToLink) {
93+
const pkgDir = path.join(packagesDir, pkgName);
94+
if (!fs.existsSync(pkgDir)) {
95+
throw new Error(
96+
`[LocalLambdaStack] Workspace package ${pkgName} not found at ${pkgDir}. Did you run the build?`,
97+
);
98+
}
99+
const relativePath = path.relative(lambdaPath, pkgDir);
100+
dependencies[`@sentry/${pkgName}`] = `file:${relativePath.replace(/\\/g, '/')}`;
101+
}
102+
70103
console.log(`[LocalLambdaStack] Install dependencies for ${functionName}`);
71-
const packageJson = { dependencies: { '@sentry/aws-serverless': '* || latest' } };
72-
fs.writeFileSync(path.join(functionsDir, lambdaDir, 'package.json'), JSON.stringify(packageJson, null, 2));
73-
execFileSync('npm', ['install', '--prefix', path.join(functionsDir, lambdaDir)], { stdio: 'inherit' });
104+
105+
if (fs.existsSync(packageLockPath)) {
106+
// Prevent stale lock files from pinning the published package version
107+
fs.rmSync(packageLockPath);
108+
}
109+
110+
if (fs.existsSync(nodeModulesPath)) {
111+
// Ensure we reinstall from the workspace instead of reusing cached dependencies
112+
fs.rmSync(nodeModulesPath, { recursive: true, force: true });
113+
}
114+
115+
const packageJson = {
116+
dependencies,
117+
};
118+
119+
fs.writeFileSync(path.join(lambdaPath, 'package.json'), JSON.stringify(packageJson, null, 2));
120+
execFileSync('npm', ['install', '--prefix', lambdaPath], { stdio: 'inherit' });
74121
}
75122

76123
new CfnResource(this, functionName, {

dev-packages/e2e-tests/test-applications/aws-serverless/tests/lambda-fixtures.ts

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export const test = base.extend<{ testEnvironment: LocalLambdaStack; lambdaClien
1717
console.log('[testEnvironment fixture] Setting up AWS Lambda test infrastructure');
1818

1919
execSync('docker network prune -f');
20-
execSync(`docker network create --driver bridge ${DOCKER_NETWORK_NAME}`);
20+
createDockerNetwork();
2121

2222
const hostIp = await getHostIp();
2323
const app = new App();
@@ -71,6 +71,8 @@ export const test = base.extend<{ testEnvironment: LocalLambdaStack; lambdaClien
7171
resolve(void 0);
7272
}, 5000);
7373
});
74+
75+
removeDockerNetwork();
7476
}
7577
},
7678
{ scope: 'worker', auto: true },
@@ -88,3 +90,27 @@ export const test = base.extend<{ testEnvironment: LocalLambdaStack; lambdaClien
8890
await use(lambdaClient);
8991
},
9092
});
93+
94+
function createDockerNetwork() {
95+
try {
96+
execSync(`docker network create --driver bridge ${DOCKER_NETWORK_NAME}`);
97+
} catch (error) {
98+
const stderr = (error as { stderr?: Buffer }).stderr?.toString() ?? '';
99+
if (stderr.includes('already exists')) {
100+
console.log(`[testEnvironment fixture] Reusing existing docker network ${DOCKER_NETWORK_NAME}`);
101+
return;
102+
}
103+
throw error;
104+
}
105+
}
106+
107+
function removeDockerNetwork() {
108+
try {
109+
execSync(`docker network rm ${DOCKER_NETWORK_NAME}`);
110+
} catch (error) {
111+
const stderr = (error as { stderr?: Buffer }).stderr?.toString() ?? '';
112+
if (!stderr.includes('No such network')) {
113+
console.warn(`[testEnvironment fixture] Failed to remove docker network ${DOCKER_NETWORK_NAME}: ${stderr}`);
114+
}
115+
}
116+
}

0 commit comments

Comments
 (0)