feat(dsn): infer project from directory name when DSN detection fails#178
Merged
feat(dsn): infer project from directory name when DSN detection fails#178
Conversation
Adds a fallback mechanism that uses the project root directory name to find matching Sentry projects when no DSN is found. Uses bidirectional word-boundary matching (`\b` regex) to handle cases like: - Directory `cli` matches project `sentry-cli` or `cli-website` - Directory `sentry-docs` matches project `docs` Changes: - Add `findProjectsByPattern()` API client function for server-side filtering - Add `inferFromDirectoryName()` in resolve-target with caching support - Add `"inferred"` source type to DSN types - Add unit tests and property-based tests using fast-check
Contributor
Semver Impact of This PR🟡 Minor (new features) 📋 Changelog PreviewThis is how your changes will appear in the changelog. New Features ✨Dsn
Other
Bug Fixes 🐛
Internal Changes 🔧
Other
🤖 This preview updates automatically when you update the PR. |
Contributor
Codecov Results 📊❌ Patch coverage is 37.58%. Project has 2264 uncovered lines. Files with missing lines (33)
Coverage diff@@ Coverage Diff @@
## main #PR +/-##
==========================================
- Coverage 70.81% 70.19% -0.62%
==========================================
Files 55 55 —
Lines 7451 7595 +144
Branches 0 0 —
==========================================
+ Hits 5276 5331 +55
- Misses 2175 2264 +89
- Partials 0 0 —Generated by Codecov Action |
BYK
commented
Feb 5, 2026
Add comprehensive tests for: - escapeRegex: special character escaping for safe regex - matchesWordBoundary: bidirectional word boundary matching - isValidDirNameForInference: directory name validation Export helper functions from api-client.ts and resolve-target.ts to enable direct unit testing of the matching logic. The property-based tests in word-boundary.property.test.ts provide additional coverage for edge cases.
Replace our custom escapeRegex helper with the native RegExp.escape function, which is available in Bun. This addresses PR review feedback and reduces custom code while relying on well-tested native functionality. - Remove escapeRegex function from api-client.ts - Remove escapeRegex tests (now covered by runtime behavior) - Keep matchesWordBoundary in api-client.ts (only used there for findProjectsByPattern)
- Import matchesWordBoundary from source instead of duplicating it - Remove duplicated 'real-world scenarios' tests (covered in api-client.test.ts) - Property tests now test the actual implementation with RegExp.escape
- Remove matchesWordBoundary example tests from api-client.test.ts (fully covered by property tests in word-boundary.property.test.ts) - Remove duplicate parseOrgProjectArg tests from resolve-target.test.ts (already tested in arg-parsing.test.ts) - Remove duplicate word boundary matching tests from resolve-target.test.ts (already tested in word-boundary.property.test.ts) - Convert isValidDirNameForInference to property-based tests using fast-check Net reduction: 274 lines removed, 82 added (192 lines less code)
BYK
commented
Feb 5, 2026
Hidden directories (starting with '.') like .env, .git, .config should not be used to infer project names. This also simplifies the logic since it covers the dot-only cases (., ..) automatically.
RegExp.escape is only available in Node.js 23.6+ (May 2025). Since the project supports Node.js >= 22, we need a fallback. This adds a polyfill that's used when the native function isn't available. Without this fix, the code would crash with 'TypeError: RegExp.escape is not a function' when inferring projects from directory names on Node.js 22.
There was a problem hiding this comment.
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.
- Catch all errors in inferFromDirectoryName (not just AuthError) to handle API/network failures gracefully - Use organization name for orgDisplay in fresh results to match cached behavior - Extend cache to store all inferred targets using allResolved field, ensuring consistent behavior between fresh and cached results
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds a fallback mechanism that uses the project root directory name to find matching Sentry projects when no DSN is found in the codebase.
\bregex)climatches projectsentry-cliorcli-websitesentry-docsmatches projectdocssource: "inferred"Changes
findProjectsByPattern()function withescapeRegex()andmatchesWordBoundary()helpers"inferred"toDsnSourcetypeinferFromDirectoryName()with caching, integrate intoresolveAllTargets()andresolveOrgAndProject()Notes
The implementation plan is available as a git note on the commit.