Skip to content

feat: add project delete command#397

Open
MathurAditya724 wants to merge 11 commits intomainfrom
feat/adi/project-delete
Open

feat: add project delete command#397
MathurAditya724 wants to merge 11 commits intomainfrom
feat/adi/project-delete

Conversation

@MathurAditya724
Copy link
Member

@MathurAditya724 MathurAditya724 commented Mar 11, 2026

Summary

Add sentry project delete subcommand for permanently deleting Sentry projects via the API.

Changes

  • src/commands/project/delete.ts — New command with safety measures:
    • Requires explicit <org>/<project> or <project> target (no auto-detect)
    • Interactive confirmation prompt (strict confirmed !== true check for Symbol(clack:cancel) gotcha)
    • --yes/-y flag to skip confirmation for CI/agent usage
    • --dry-run/-n flag to validate inputs and show what would be deleted without deleting
    • Refuses to run in non-interactive mode without --yes
    • Verifies project exists via getProject() before prompting
    • 403 errors throw ApiError with actionable message (preserves HTTP status for upstream handlers)
  • src/commands/project/index.ts — Registered delete in project route map
  • src/lib/api-client.ts — Added deleteProject() using @sentry/api SDK's deleteAProject
  • src/lib/oauth.ts — Added project:admin to OAuth scopes (required for project deletion; existing users must re-run sentry auth login)
  • test/commands/project/delete.test.ts — 10 unit tests covering happy path, error cases, dry-run, JSON output, and safety checks

Usage

sentry project delete acme-corp/my-app
sentry project delete my-app
sentry project delete acme-corp/my-app --yes
sentry project delete acme-corp/my-app --json --yes
sentry project delete acme-corp/my-app --dry-run

Notes

  • Existing tokens do not include project:admin — users need to re-authenticate via sentry auth login after upgrading
  • Local caches (DSN cache, project cache, defaults) are not cleared after deletion — stale entries may persist until TTL expiry (follow-up)

Add `sentry project delete` subcommand for permanently deleting Sentry
projects via the API.

Safety measures:
- Requires explicit target (no auto-detect to prevent accidental deletion)
- Confirmation prompt with --yes/-y flag to skip
- Refuses to run in non-interactive mode without --yes
- Verifies project exists before prompting

Changes:
- src/commands/project/delete.ts: New command implementation
- src/commands/project/index.ts: Register delete in route map
- src/lib/api-client.ts: Add deleteProject() using @sentry/api SDK
- test/commands/project/delete.test.ts: Unit tests (8 tests)
@github-actions
Copy link
Contributor

github-actions bot commented Mar 11, 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 ✨

Init

  • Add --team flag to relay team selection to project creation by MathurAditya724 in #403
  • Enforce canonical feature display order by betegon in #388
  • Accept multiple delimiter formats for --features flag by betegon in #386
  • Add git safety checks before wizard modifies files by betegon in #379
  • Add experimental warning before wizard runs by betegon in #378
  • Add init command for guided Sentry project setup by betegon in #283

Issue List

  • Auto-compact when table exceeds terminal height by BYK in #395
  • Redesign table to match Sentry web UI by BYK in #372

Other

  • (auth) Allow re-authentication without manual logout by BYK in #417
  • (trial) Auto-prompt for Seer trial + sentry trial list/start commands by BYK in #399
  • Add project delete command by MathurAditya724 in #397
  • Support SENTRY_HOST as alias for SENTRY_URL by betegon in #409
  • Add --dry-run flag to mutating commands by BYK in #387
  • Return-based output with OutputConfig on buildCommand by BYK in #380
  • Add --fields flag for context-window-friendly JSON output by BYK in #373
  • Magic @ selectors (@latest, @most_frequent) for issue commands by BYK in #371
  • Input hardening against agent hallucinations by BYK in #370
  • Add response caching for read-only API calls by BYK in #330

Bug Fixes 🐛

Init

  • Remove implementation detail from help text by betegon in #385
  • Truncate uncommitted file list to first 5 entries by MathurAditya724 in #381

Other

Documentation 📚

  • Update credential storage docs and remove stale config.json references by betegon in #408

Internal Changes 🔧

Init

  • Remove --force flag by betegon in #377
  • Remove dead determine-pm step label by betegon in #374

Other

  • (log/list) Convert non-follow paths to return CommandOutput by BYK in #410
  • (tests) Remove redundant and low-value tests by BYK in #418
  • Convert list command handlers to return data instead of writing stdout by BYK in #404
  • Split api-client.ts into focused domain modules by BYK in #405
  • Migrate non-streaming commands to CommandOutput with markdown rendering by BYK in #398
  • Convert Tier 2-3 commands to return-based output and consola by BYK in #394
  • Convert remaining Tier 1 commands to return-based output by BYK in #382
  • Converge Tier 1 commands to writeOutput helper by BYK in #376

Other

  • Minify JSON on read and pretty-print on write in init local ops by MathurAditya724 in #396

🤖 This preview updates automatically when you update the PR.

@github-actions
Copy link
Contributor

github-actions bot commented Mar 11, 2026

Codecov Results 📊

111 passed | Total: 111 | Pass Rate: 100% | Execution Time: 0ms

📊 Comparison with Base Branch

Metric Change
Total Tests
Passed Tests
Failed Tests
Skipped Tests

✨ No test changes detected

All tests are passing successfully.

✅ Patch coverage is 92.73%. Project has 1077 uncovered lines.
❌ Project coverage is 95.01%. Comparing base (base) to head (head).

Files with missing lines (3)
File Patch % Lines
oauth.ts 31.58% ⚠️ 182 Missing
human.ts 96.43% ⚠️ 44 Missing
projects.ts 92.31% ⚠️ 15 Missing
Coverage diff
@@            Coverage Diff             @@
##          main       #PR       +/-##
==========================================
- Coverage    95.02%    95.01%    -0.01%
==========================================
  Files          159       160        +1
  Lines        21404     21569      +165
  Branches         0         0         —
==========================================
+ Hits         20339     20492      +153
- Misses        1065      1077       +12
- Partials         0         0         —

Generated by Codecov Action

- Add 'project:admin' to OAuth SCOPES so new tokens include the
  permission required for project deletion
- Catch 403 in project delete command and show actionable message
  pointing users to re-authenticate or check their org role
- Existing tokens require re-login: sentry auth login
@MathurAditya724 MathurAditya724 marked this pull request as ready for review March 11, 2026 19:35
@MathurAditya724 MathurAditya724 requested review from BYK and betegon and removed request for BYK March 11, 2026 19:35
MathurAditya724 and others added 4 commits March 12, 2026 01:11
- 403 error now throws ApiError (preserving status/detail/endpoint)
  instead of CliError, so upstream handlers can still match on status
- Add --dry-run / -n flag consistent with project create and other
  mutating commands — validates inputs and shows what would be deleted
- Extract resolveDeleteTarget() to reduce func() complexity
- Add 2 new dry-run tests (human + JSON output)
…teTarget

Replace the custom resolveDeleteTarget() with the shared
resolveOrgProjectTarget() from resolve-target.ts. Only the auto-detect
guard remains delete-specific — all other resolution modes (explicit,
project-search, org-all) are handled by the shared infrastructure.

This also gains resolveEffectiveOrg() region routing for the explicit
case, which the custom function was missing.
const SCOPES = [
"project:read",
"project:write",
"project:admin",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what would happen if someone doesn't have this permission? would it face trouble signing in?

betegon and others added 2 commits March 13, 2026 18:21
Port deleteProject into src/lib/api/projects.ts and re-export from
the barrel file, aligning with main's split of api-client into
domain modules under src/lib/api/.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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 1 potential issue.

Fix All in Cursor

Bugbot Autofix prepared a fix for the issue found in the latest run.

  • ✅ Fixed: New OAuth scope may break login for non-admin users
    • Removed project:admin from global OAuth SCOPES to prevent potentially breaking authentication for non-admin users, and updated the delete command's 403 error to direct users to contact their org admin instead.

Create PR

Or push these changes by commenting:

@cursor push 3eb69e6f5d
Preview (3eb69e6f5d)
diff --git a/src/commands/project/delete.ts b/src/commands/project/delete.ts
--- a/src/commands/project/delete.ts
+++ b/src/commands/project/delete.ts
@@ -176,8 +176,8 @@
       if (error instanceof ApiError && error.status === 403) {
         throw new ApiError(
           `Permission denied: You don't have permission to delete '${orgSlug}/${project.slug}'.\n\n` +
-            "Project deletion requires the 'project:admin' scope.\n" +
-            "  Re-authenticate:  sentry auth login",
+            "Project deletion requires the 'project:admin' permission.\n" +
+            "Contact your organization admin to grant you project admin access.",
           403,
           error.detail,
           error.endpoint

diff --git a/src/lib/oauth.ts b/src/lib/oauth.ts
--- a/src/lib/oauth.ts
+++ b/src/lib/oauth.ts
@@ -52,7 +52,6 @@
 const SCOPES = [
   "project:read",
   "project:write",
-  "project:admin",
   "org:read",
   "event:read",
   "event:write",

diff --git a/test/commands/project/delete.test.ts b/test/commands/project/delete.test.ts
--- a/test/commands/project/delete.test.ts
+++ b/test/commands/project/delete.test.ts
@@ -185,7 +185,7 @@
       const apiErr = error as ApiError;
       expect(apiErr.status).toBe(403);
       expect(apiErr.message).toContain("project:admin");
-      expect(apiErr.message).toContain("sentry auth login");
+      expect(apiErr.message).toContain("organization admin");
     }
   });

This Bugbot Autofix run was free. To enable autofix for future PRs, go to the Cursor dashboard.

Convert project delete from manual stdout.write/JSON.stringify to
the return-based OutputConfig pattern used by project create and
other commands. Adds formatProjectDeleted formatter in human.ts,
jsonTransform to preserve JSON contract, and role-aware 403 errors.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
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.

2 participants