-
-
Notifications
You must be signed in to change notification settings - Fork 1
feat(dsn): add project root detection for automatic DSN discovery #159
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Walk up from CWD to find project root before scanning for DSNs: - Check .env files for SENTRY_DSN during walk-up (immediate return if found) - Stop at VCS/CI markers (.git, .github, etc.) as definitive repo root - Use language markers (package.json, pyproject.toml, etc.) as fallback - Limit scan depth to 2 levels from project root for performance This ensures DSN detection works regardless of which subdirectory the user runs the CLI from within a project.
Semver Impact of This PR🟡 Minor (new features) 📋 Changelog PreviewThis is how your changes will appear in the changelog. New Features ✨
Bug Fixes 🐛
🤖 This preview updates automatically when you update the PR. |
…anner - Add language-agnostic code-scanner.ts that greps for DSN URL patterns - Filter commented lines using common prefixes (// # -- <!-- etc.) - Respect .gitignore via 'ignore' package - Scan concurrently with p-limit for performance - Remove 8 language-specific detector files and 6 test files - Add 28 new tests for the code scanner
Previously, finding a DSN in .env during walk-up would return immediately, bypassing code scanning. Now we always do a full scan with correct priority: code > env_file > env_var. The .env DSN still stops the walk-up (determines project root) but doesn't short-circuit detection.
- Optimize extractDsnsFromContent: extract matches first, then check line context - Add limit parameter for early exit in first-DSN extraction - Fix host validation: SENTRY_URL set -> only that host; not set -> only *.sentry.io - Use path.extname() instead of manual lastIndexOf - Use recursive readdir + incorporate ALWAYS_SKIP_DIRS into gitignore instance - Document file size check placement (avoids extra stat() calls) - Simplify createDetectedDsn usage with .filter(Boolean) - Simplify deduplication with Map<string, DetectedDsn> - Add Sentry.metrics for filesScanned/filesCollected/dsnsFound
- Use regex pattern for path separators to support Windows - Fix walkUpDirectories to check starting dir at stop boundary - Remove unnecessary export from checkEnvForDsn - Clean up unused exports in dsn/index.ts
Addressed all review commentsI have addressed all the review comments in the latest commits. Here is a summary: Code changes made:
Previously addressed (already in the code):
Design decisions (no change needed):
|
- Fix priority order in detectAllDsns: code DSNs now have priority - Fix walkUpDirectories stop boundary: check before moving to parent - Deduplicate ENV_FILES: import from env-file.ts instead of redefining - Normalize Windows paths: convert backslashes for ignore package - Update test to match correct priority order (code > env_file > env_var)
When SENTRY_URL is set to an invalid URL, the code scanner was silently failing to detect any DSNs because getExpectedHost() returned null. Now it: 1. Logs a warning (once per process) about the invalid URL 2. Falls back to SaaS behavior (accepting *.sentry.io DSNs) This is consistent with how other parts of the codebase handle invalid SENTRY_URL values (they fall back to the default SaaS URL).
The relativePath was being normalized for ig.ignores() but the original backslash path was pushed to files array. This caused inferPackagePath() to fail on Windows since it splits by "/" only. Now we normalize the path immediately after creation, ensuring: 1. The ignore package gets forward-slash paths 2. inferPackagePath() receives forward-slash paths 3. DetectedDsn.sourcePath is consistent across platforms
The function was exported but never used in production code - only in tests. It wasn't part of the public API (not re-exported from index.ts). The main detection algorithm uses findProjectRoot which handles project root detection differently, making this function redundant.
The verifyCachedDsn() function was returning null for source='env', causing a full directory scan on every invocation when the DSN came from the SENTRY_DSN environment variable. Now it properly verifies by checking if the env var still contains the same DSN value, providing the expected O(1) cache hit performance instead of O(n) directory scanning. This is especially important for CI/CD, Docker, and Kubernetes environments where SENTRY_DSN env var is the primary configuration method.
There was a problem hiding this comment.
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 2 potential issues.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
1. Cache verification now checks for higher-priority sources: - When cached DSN is from env var, checks for code DSNs first - When cached DSN is from env file, checks for code DSNs first - This ensures adding a code DSN after caching correctly updates priority 2. Fixed module-level state test pollution: - Exported _resetInvalidSentryUrlWarning() for testing - Tests now reset warning state in afterEach to prevent order dependencies Added tests for both fixes.
Summary
This PR implements project root detection and a language-agnostic DSN scanner for automatic Sentry DSN discovery. The CLI now walks up from CWD to find the project root, then scans from there with proper depth limiting and priority ordering.
Problem
sentry issue listfrom a subdirectory (e.g.,~/project/src/lib/) would miss.envfiles at~/project/.envSentry.init({ dsn: "..." })but missed DSNs assigned to variablesSolution
Project Root Detection:
.envfiles forSENTRY_DSN(stops walk-up but doesn't short-circuit detection).git,.github, etc.) - definitive repo rootpackage.json,pyproject.toml, etc.) - closest to CWD winsLanguage-Agnostic Code Scanner:
https://KEY@HOST/PROJECT_ID//,#,--,<!--, etc.).gitignorevia theignorepackageSENTRY_URLset → only that host; not set → only*.sentry.iop-limitfor performanceDSN Priority Order:
Changes
New Files:
src/lib/dsn/project-root.ts- Project root detection with Sentry instrumentationsrc/lib/dsn/code-scanner.ts- Language-agnostic DSN scannertest/lib/dsn/project-root.test.ts- 34 tests for project root detectiontest/lib/dsn/code-scanner.test.ts- 29 tests for code scannerModified:
src/lib/dsn/detector.ts- Uses project root and new scanner with correct prioritypackage.json- Addedignoreandp-limitdependenciesDeleted (replaced by code-scanner.ts):
src/lib/dsn/languages/*.ts(8 files: go, java, javascript, php, python, ruby, index, types)test/lib/dsn/languages/*.test.ts(6 test files)Key Features
SENTRY_URLignorepackage with built-in skip dirsp-limitTesting