Skip to content

feat(dsn): infer project from directory name when DSN detection fails#178

Merged
BYK merged 8 commits intomainfrom
feat/infer-project-from-directory
Feb 5, 2026
Merged

feat(dsn): infer project from directory name when DSN detection fails#178
BYK merged 8 commits intomainfrom
feat/infer-project-from-directory

Conversation

@BYK
Copy link
Member

@BYK BYK commented Feb 5, 2026

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.

  • Uses bidirectional word-boundary matching (\b regex)
  • Directory cli matches project sentry-cli or cli-website
  • Directory sentry-docs matches project docs
  • Results are cached using the existing DSN cache with source: "inferred"
  • Gracefully handles unauthenticated state

Changes

  • src/lib/api-client.ts: Add findProjectsByPattern() function with escapeRegex() and matchesWordBoundary() helpers
  • src/lib/dsn/types.ts: Add "inferred" to DsnSource type
  • src/lib/resolve-target.ts: Add inferFromDirectoryName() with caching, integrate into resolveAllTargets() and resolveOrgAndProject()
  • test/lib/resolve-target.test.ts: Add unit tests for word boundary matching
  • test/lib/word-boundary.property.test.ts: Add property-based tests using fast-check

Notes

The implementation plan is available as a git note on the commit.

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
@github-actions
Copy link
Contributor

github-actions bot commented Feb 5, 2026

Semver Impact of This PR

🟡 Minor (new features)

📋 Changelog Preview

This is how your changes will appear in the changelog.
Entries from this PR are highlighted with a left border (blockquote style).


New Features ✨

Dsn

  • Infer project from directory name when DSN detection fails by BYK in #178
  • Add project root detection for automatic DSN discovery by BYK in #159

Other

  • (issue) Replace --org/--project flags with /ID syntax by BYK in #161
  • (lib) Add anyTrue helper for parallel-with-early-exit pattern by BYK in #174
  • (telemetry) Add withTracing helper to reduce Sentry span boilerplate by BYK in #172

Bug Fixes 🐛

  • (types) Align schema types with Sentry API by betegon in #169
  • ParseIssueArg now checks slashes before dashes by BYK in #177
  • Address bugbot review comments on dsn-cache model-based tests by BYK in #176
  • Added nullable in substatus's zod validation by MathurAditya724 in #157

Internal Changes 🔧

  • (upgrade) Use centralized user-agent for GitHub API requests by BYK in #173

Other

  • test: add property tests for API command and human formatters by BYK in #181
  • test: remove redundant DB tests covered by model-based tests by BYK in #180
  • test: add property tests for async utilities (Phase 4) by BYK in #179
  • test: add model-based tests for DSN and project cache by BYK in #171
  • test: add model-based and property-based testing with fast-check by BYK in #166

🤖 This preview updates automatically when you update the PR.

@github-actions
Copy link
Contributor

github-actions bot commented Feb 5, 2026

Codecov Results 📊

❌ Patch coverage is 37.58%. Project has 2264 uncovered lines.
❌ Project coverage is 70.19%. Comparing base (base) to head (head).

Files with missing lines (33)
File Patch % Lines
human.ts 31.80% ⚠️ 684 Missing
resolve-target.ts 15.28% ⚠️ 366 Missing
oauth.ts 25.10% ⚠️ 194 Missing
upgrade.ts 40.23% ⚠️ 153 Missing
api-client.ts 73.67% ⚠️ 148 Missing
resolver.ts 3.23% ⚠️ 120 Missing
errors.ts 5.94% ⚠️ 95 Missing
migration.ts 47.44% ⚠️ 82 Missing
version-check.ts 34.04% ⚠️ 62 Missing
telemetry.ts 77.43% ⚠️ 51 Missing
api.ts 89.80% ⚠️ 47 Missing
seer.ts 75.54% ⚠️ 45 Missing
preload.ts 38.71% ⚠️ 38 Missing
seer.ts 79.87% ⚠️ 30 Missing
schema.ts 52.73% ⚠️ 26 Missing
utils.ts 87.43% ⚠️ 24 Missing
detector.ts 90.10% ⚠️ 20 Missing
code-scanner.ts 95.00% ⚠️ 16 Missing
dsn-cache.ts 94.62% ⚠️ 12 Missing
fs-utils.ts 57.14% ⚠️ 9 Missing
project-root.ts 97.73% ⚠️ 7 Missing
feedback.ts 84.21% ⚠️ 6 Missing
auth.ts 95.52% ⚠️ 6 Missing
upgrade.ts 93.83% ⚠️ 5 Missing
colors.ts 91.84% ⚠️ 4 Missing
env-file.ts 97.58% ⚠️ 3 Missing
sentry-urls.ts 88.00% ⚠️ 3 Missing
project-aliases.ts 97.40% ⚠️ 2 Missing
project-root-cache.ts 96.92% ⚠️ 2 Missing
alias.ts 99.28% ⚠️ 1 Missing
parser.ts 98.63% ⚠️ 1 Missing
helpers.ts 94.74% ⚠️ 1 Missing
helpers.ts 94.74% ⚠️ 1 Missing
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 added 4 commits February 5, 2026 00:54
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)
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.
@BYK BYK marked this pull request as ready for review February 5, 2026 01:42
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.
Copy link

@cursor cursor bot left a 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.

- 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
@BYK BYK merged commit 3335bfa into main Feb 5, 2026
24 checks passed
@BYK BYK deleted the feat/infer-project-from-directory branch February 5, 2026 09:43
Sign up for free to 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.

1 participant