From 0aee9a510e8b62e69bd6393c0241193c5c39a47f Mon Sep 17 00:00:00 2001 From: Burak Yigit Kaya Date: Mon, 2 Feb 2026 14:40:30 +0000 Subject: [PATCH 1/7] refactor: move feedback and upgrade under `sentry cli` command MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Group CLI meta-commands under a new `cli` subcommand to avoid collision with the existing Sentry Feedback feature (user feedback on issues). Commands changed: - `sentry feedback` → `sentry cli feedback` - `sentry upgrade` → `sentry cli upgrade` - Removed `sentry update` alias --- .../docs/commands/{ => cli}/feedback.md | 16 ++++------ docs/src/content/docs/commands/cli/index.md | 13 +++++++++ .../docs/commands/{ => cli}/upgrade.md | 22 +++++++------- docs/src/content/docs/commands/index.md | 2 +- plugins/sentry-cli/skills/sentry-cli/SKILL.md | 29 ++++++++++++------- src/app.ts | 9 ++---- src/commands/{ => cli}/feedback.ts | 8 ++--- src/commands/cli/index.ts | 16 ++++++++++ src/commands/{ => cli}/upgrade.ts | 22 +++++++------- src/lib/version-check.ts | 2 +- test/commands/upgrade.test.ts | 4 +-- 11 files changed, 86 insertions(+), 57 deletions(-) rename docs/src/content/docs/commands/{ => cli}/feedback.md (67%) create mode 100644 docs/src/content/docs/commands/cli/index.md rename docs/src/content/docs/commands/{ => cli}/upgrade.md (76%) rename src/commands/{ => cli}/feedback.ts (88%) create mode 100644 src/commands/cli/index.ts rename src/commands/{ => cli}/upgrade.ts (82%) diff --git a/docs/src/content/docs/commands/feedback.md b/docs/src/content/docs/commands/cli/feedback.md similarity index 67% rename from docs/src/content/docs/commands/feedback.md rename to docs/src/content/docs/commands/cli/feedback.md index 34488887..065aef54 100644 --- a/docs/src/content/docs/commands/feedback.md +++ b/docs/src/content/docs/commands/cli/feedback.md @@ -1,18 +1,14 @@ --- -title: feedback +title: cli feedback description: Send feedback about the Sentry CLI --- Send feedback about your experience with the CLI. -## Commands - -### `sentry feedback` - -Submit feedback about the CLI directly to the Sentry team. +## Usage ```bash -sentry feedback +sentry cli feedback ``` **Arguments:** @@ -25,13 +21,13 @@ sentry feedback ```bash # Send positive feedback -sentry feedback i love this tool +sentry cli feedback i love this tool # Report an issue -sentry feedback the issue view is confusing +sentry cli feedback the issue view is confusing # Suggest an improvement -sentry feedback would be great to have a search command +sentry cli feedback would be great to have a search command ``` ## Notes diff --git a/docs/src/content/docs/commands/cli/index.md b/docs/src/content/docs/commands/cli/index.md new file mode 100644 index 00000000..61325cb9 --- /dev/null +++ b/docs/src/content/docs/commands/cli/index.md @@ -0,0 +1,13 @@ +--- +title: cli +description: CLI-related commands for managing the Sentry CLI itself +--- + +Commands for managing the Sentry CLI itself, including sending feedback and upgrading to newer versions. + +## Commands + +| Command | Description | +|---------|-------------| +| [`feedback`](./feedback/) | Send feedback about the CLI | +| [`upgrade`](./upgrade/) | Update the CLI to the latest version | diff --git a/docs/src/content/docs/commands/upgrade.md b/docs/src/content/docs/commands/cli/upgrade.md similarity index 76% rename from docs/src/content/docs/commands/upgrade.md rename to docs/src/content/docs/commands/cli/upgrade.md index 37e27f23..345f9e1f 100644 --- a/docs/src/content/docs/commands/upgrade.md +++ b/docs/src/content/docs/commands/cli/upgrade.md @@ -1,5 +1,5 @@ --- -title: upgrade +title: cli upgrade description: Update the Sentry CLI to the latest version --- @@ -8,14 +8,12 @@ Self-update the Sentry CLI to the latest or a specific version. ## Usage ```bash -sentry upgrade # Update to latest version -sentry upgrade 0.5.0 # Update to specific version -sentry upgrade --check # Check for updates without installing -sentry upgrade --method npm # Force using npm to upgrade +sentry cli upgrade # Update to latest version +sentry cli upgrade 0.5.0 # Update to specific version +sentry cli upgrade --check # Check for updates without installing +sentry cli upgrade --method npm # Force using npm to upgrade ``` -**Alias:** `sentry update` - ## Options | Option | Description | @@ -41,7 +39,7 @@ The CLI auto-detects how it was installed and uses the same method to upgrade: ### Check for updates ```bash -sentry upgrade --check +sentry cli upgrade --check ``` ``` @@ -49,13 +47,13 @@ Installation method: curl Current version: 0.4.0 Latest version: 0.5.0 -Run 'sentry upgrade' to update. +Run 'sentry cli upgrade' to update. ``` ### Upgrade to latest ```bash -sentry upgrade +sentry cli upgrade ``` ``` @@ -71,7 +69,7 @@ Successfully upgraded to 0.5.0. ### Upgrade to specific version ```bash -sentry upgrade 0.5.0 +sentry cli upgrade 0.5.0 ``` ### Force installation method @@ -79,5 +77,5 @@ sentry upgrade 0.5.0 If auto-detection fails or you want to switch installation methods: ```bash -sentry upgrade --method npm +sentry cli upgrade --method npm ``` diff --git a/docs/src/content/docs/commands/index.md b/docs/src/content/docs/commands/index.md index cbb6182b..45aae5d5 100644 --- a/docs/src/content/docs/commands/index.md +++ b/docs/src/content/docs/commands/index.md @@ -10,12 +10,12 @@ The Sentry CLI provides commands for interacting with various Sentry resources. | Command | Description | |---------|-------------| | [`auth`](./auth/) | Authentication management | +| [`cli`](./cli/) | CLI-related commands (feedback, upgrade) | | [`org`](./org/) | Organization operations | | [`project`](./project/) | Project operations | | [`issue`](./issue/) | Issue tracking | | [`event`](./event/) | Event inspection | | [`api`](./api/) | Direct API access | -| [`feedback`](./feedback/) | Send feedback about the CLI | ## Global Options diff --git a/plugins/sentry-cli/skills/sentry-cli/SKILL.md b/plugins/sentry-cli/skills/sentry-cli/SKILL.md index 0633a528..aee7c0ae 100644 --- a/plugins/sentry-cli/skills/sentry-cli/SKILL.md +++ b/plugins/sentry-cli/skills/sentry-cli/SKILL.md @@ -364,11 +364,11 @@ sentry api /organizations/ --include sentry api /projects/my-org/my-project/issues/ --paginate ``` -### Upgrade +### CLI -Update the Sentry CLI to the latest version +Commands for managing the Sentry CLI itself -#### `sentry upgrade ` +#### `sentry cli upgrade ` Update the Sentry CLI to the latest version @@ -376,27 +376,36 @@ Update the Sentry CLI to the latest version - `--check - Check for updates without installing` - `--method - Installation method to use (curl, npm, pnpm, bun, yarn)` -### Feedback +**Examples:** -Send feedback about the CLI +```bash +# Update to latest version +sentry cli upgrade + +# Update to specific version +sentry cli upgrade 0.5.0 + +# Check for updates without installing +sentry cli upgrade --check +``` -#### `sentry feedback ` +#### `sentry cli feedback ` Send feedback about the CLI **Examples:** ```bash -sentry feedback +sentry cli feedback # Send positive feedback -sentry feedback i love this tool +sentry cli feedback i love this tool # Report an issue -sentry feedback the issue view is confusing +sentry cli feedback the issue view is confusing # Suggest an improvement -sentry feedback would be great to have a search command +sentry cli feedback would be great to have a search command ``` ## Output Formats diff --git a/src/app.ts b/src/app.ts index 6d4b32ff..0200ccc8 100644 --- a/src/app.ts +++ b/src/app.ts @@ -8,13 +8,12 @@ import { } from "@stricli/core"; import { apiCommand } from "./commands/api.js"; import { authRoute } from "./commands/auth/index.js"; +import { cliRoute } from "./commands/cli/index.js"; import { eventRoute } from "./commands/event/index.js"; -import { feedbackCommand } from "./commands/feedback.js"; import { helpCommand } from "./commands/help.js"; import { issueRoute } from "./commands/issue/index.js"; import { orgRoute } from "./commands/org/index.js"; import { projectRoute } from "./commands/project/index.js"; -import { upgradeCommand } from "./commands/upgrade.js"; import { CLI_VERSION } from "./lib/constants.js"; import { CliError, getExitCode } from "./lib/errors.js"; import { error as errorColor } from "./lib/formatters/colors.js"; @@ -24,16 +23,12 @@ export const routes = buildRouteMap({ routes: { help: helpCommand, auth: authRoute, + cli: cliRoute, org: orgRoute, project: projectRoute, issue: issueRoute, event: eventRoute, api: apiCommand, - upgrade: upgradeCommand, - feedback: feedbackCommand, - }, - aliases: { - update: "upgrade", }, defaultCommand: "help", docs: { diff --git a/src/commands/feedback.ts b/src/commands/cli/feedback.ts similarity index 88% rename from src/commands/feedback.ts rename to src/commands/cli/feedback.ts index 64c93fd1..6173d445 100644 --- a/src/commands/feedback.ts +++ b/src/commands/cli/feedback.ts @@ -4,15 +4,15 @@ * Allows users to submit feedback about the CLI. * All arguments after 'feedback' are joined into a single message. * - * @example sentry feedback i love this tool - * @example sentry feedback the issue view is confusing + * @example sentry cli feedback i love this tool + * @example sentry cli feedback the issue view is confusing */ // biome-ignore lint/performance/noNamespaceImport: Sentry SDK recommends namespace import import * as Sentry from "@sentry/bun"; import { buildCommand } from "@stricli/core"; -import type { SentryContext } from "../context.js"; -import { ValidationError } from "../lib/errors.js"; +import type { SentryContext } from "../../context.js"; +import { ValidationError } from "../../lib/errors.js"; export const feedbackCommand = buildCommand({ docs: { diff --git a/src/commands/cli/index.ts b/src/commands/cli/index.ts new file mode 100644 index 00000000..bf7ed31d --- /dev/null +++ b/src/commands/cli/index.ts @@ -0,0 +1,16 @@ +import { buildRouteMap } from "@stricli/core"; +import { feedbackCommand } from "./feedback.js"; +import { upgradeCommand } from "./upgrade.js"; + +export const cliRoute = buildRouteMap({ + routes: { + feedback: feedbackCommand, + upgrade: upgradeCommand, + }, + docs: { + brief: "CLI-related commands", + fullDescription: + "Commands for managing the Sentry CLI itself, including sending feedback " + + "and upgrading to newer versions.", + }, +}); diff --git a/src/commands/upgrade.ts b/src/commands/cli/upgrade.ts similarity index 82% rename from src/commands/upgrade.ts rename to src/commands/cli/upgrade.ts index 45a139cb..79f0cbaa 100644 --- a/src/commands/upgrade.ts +++ b/src/commands/cli/upgrade.ts @@ -1,13 +1,13 @@ /** - * sentry upgrade + * sentry cli upgrade * * Self-update the Sentry CLI to the latest or a specific version. */ import { buildCommand } from "@stricli/core"; -import type { SentryContext } from "../context.js"; -import { CLI_VERSION } from "../lib/constants.js"; -import { UpgradeError } from "../lib/errors.js"; +import type { SentryContext } from "../../context.js"; +import { CLI_VERSION } from "../../lib/constants.js"; +import { UpgradeError } from "../../lib/errors.js"; import { detectInstallationMethod, executeUpgrade, @@ -16,7 +16,7 @@ import { parseInstallationMethod, VERSION_PREFIX_REGEX, versionExists, -} from "../lib/upgrade.js"; +} from "../../lib/upgrade.js"; type UpgradeFlags = { readonly check: boolean; @@ -30,10 +30,10 @@ export const upgradeCommand = buildCommand({ "Check for updates and upgrade the Sentry CLI to the latest or a specific version.\n\n" + "By default, detects how the CLI was installed (npm, curl, etc.) and uses the same method to upgrade.\n\n" + "Examples:\n" + - " sentry upgrade # Update to latest version\n" + - " sentry upgrade 0.5.0 # Update to specific version\n" + - " sentry upgrade --check # Check for updates without installing\n" + - " sentry upgrade --method npm # Force using npm to upgrade", + " sentry cli upgrade # Update to latest version\n" + + " sentry cli upgrade 0.5.0 # Update to specific version\n" + + " sentry cli upgrade --check # Check for updates without installing\n" + + " sentry cli upgrade --method npm # Force using npm to upgrade", }, parameters: { positional: { @@ -94,7 +94,9 @@ export const upgradeCommand = buildCommand({ if (CLI_VERSION === target) { stdout.write("\nYou are already on the target version.\n"); } else { - const cmd = version ? `sentry upgrade ${target}` : "sentry upgrade"; + const cmd = version + ? `sentry cli upgrade ${target}` + : "sentry cli upgrade"; stdout.write(`\nRun '${cmd}' to update.\n`); } return; diff --git a/src/lib/version-check.ts b/src/lib/version-check.ts index 82ab21d0..abeb2b6a 100644 --- a/src/lib/version-check.ts +++ b/src/lib/version-check.ts @@ -133,7 +133,7 @@ function getUpdateNotificationImpl(): string | null { return null; } - return `\n${muted("Update available:")} ${cyan(CLI_VERSION)} → ${cyan(latestVersion)} Run ${cyan('"sentry upgrade"')} to update.\n`; + return `\n${muted("Update available:")} ${cyan(CLI_VERSION)} → ${cyan(latestVersion)} Run ${cyan('"sentry cli upgrade"')} to update.\n`; } catch (error) { // DB access failed - report to Sentry but don't crash CLI Sentry.captureException(error); diff --git a/test/commands/upgrade.test.ts b/test/commands/upgrade.test.ts index 06eb48f0..ca7d4730 100644 --- a/test/commands/upgrade.test.ts +++ b/test/commands/upgrade.test.ts @@ -1,11 +1,11 @@ /** * Upgrade Command Tests * - * Tests for the sentry upgrade command registration and module exports. + * Tests for the sentry cli upgrade command registration and module exports. */ import { describe, expect, test } from "bun:test"; -import { upgradeCommand } from "../../src/commands/upgrade.js"; +import { upgradeCommand } from "../../src/commands/cli/upgrade.js"; describe("upgradeCommand", () => { test("is exported and defined", () => { From bd6380393440608d5fe65197c750b80c69e1fbcc Mon Sep 17 00:00:00 2001 From: Burak Yigit Kaya Date: Mon, 2 Feb 2026 14:45:19 +0000 Subject: [PATCH 2/7] chore: regenerate SKILL.md --- plugins/sentry-cli/skills/sentry-cli/SKILL.md | 40 +++---------------- 1 file changed, 6 insertions(+), 34 deletions(-) diff --git a/plugins/sentry-cli/skills/sentry-cli/SKILL.md b/plugins/sentry-cli/skills/sentry-cli/SKILL.md index aee7c0ae..ddc36945 100644 --- a/plugins/sentry-cli/skills/sentry-cli/SKILL.md +++ b/plugins/sentry-cli/skills/sentry-cli/SKILL.md @@ -364,9 +364,13 @@ sentry api /organizations/ --include sentry api /projects/my-org/my-project/issues/ --paginate ``` -### CLI +### Cli -Commands for managing the Sentry CLI itself +CLI-related commands + +#### `sentry cli feedback ` + +Send feedback about the CLI #### `sentry cli upgrade ` @@ -376,38 +380,6 @@ Update the Sentry CLI to the latest version - `--check - Check for updates without installing` - `--method - Installation method to use (curl, npm, pnpm, bun, yarn)` -**Examples:** - -```bash -# Update to latest version -sentry cli upgrade - -# Update to specific version -sentry cli upgrade 0.5.0 - -# Check for updates without installing -sentry cli upgrade --check -``` - -#### `sentry cli feedback ` - -Send feedback about the CLI - -**Examples:** - -```bash -sentry cli feedback - -# Send positive feedback -sentry cli feedback i love this tool - -# Report an issue -sentry cli feedback the issue view is confusing - -# Suggest an improvement -sentry cli feedback would be great to have a search command -``` - ## Output Formats ### JSON Output From cac05364ed4b967e819e5cc510558e0a39589512 Mon Sep 17 00:00:00 2001 From: Burak Yigit Kaya Date: Mon, 2 Feb 2026 14:48:07 +0000 Subject: [PATCH 3/7] test: fix version check test for new cli upgrade path --- test/lib/version-check.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/lib/version-check.test.ts b/test/lib/version-check.test.ts index 0316d801..9bfae97b 100644 --- a/test/lib/version-check.test.ts +++ b/test/lib/version-check.test.ts @@ -82,7 +82,7 @@ describe("getUpdateNotification", () => { expect(notification).not.toBeNull(); expect(notification).toContain("Update available:"); expect(notification).toContain("99.0.0"); - expect(notification).toContain("sentry upgrade"); + expect(notification).toContain("sentry cli upgrade"); }); }); From 470382d8c5def490a7a41916415441d8312cb218 Mon Sep 17 00:00:00 2001 From: Burak Yigit Kaya Date: Mon, 2 Feb 2026 15:06:06 +0000 Subject: [PATCH 4/7] test: add tests for cli command group to improve patch coverage --- test/commands/cli.test.ts | 227 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 227 insertions(+) create mode 100644 test/commands/cli.test.ts diff --git a/test/commands/cli.test.ts b/test/commands/cli.test.ts new file mode 100644 index 00000000..cd6218ef --- /dev/null +++ b/test/commands/cli.test.ts @@ -0,0 +1,227 @@ +/** + * CLI Route Tests + * + * Tests for the sentry cli command group. + */ + +import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test"; +import { feedbackCommand } from "../../src/commands/cli/feedback.js"; +import { cliRoute } from "../../src/commands/cli/index.js"; +import { upgradeCommand } from "../../src/commands/cli/upgrade.js"; + +describe("cliRoute", () => { + test("is exported and defined", () => { + expect(cliRoute).toBeDefined(); + }); +}); + +describe("feedbackCommand", () => { + test("is exported and defined", () => { + expect(feedbackCommand).toBeDefined(); + }); +}); + +describe("upgradeCommand", () => { + test("is exported and defined", () => { + expect(upgradeCommand).toBeDefined(); + }); +}); + +// Test the feedback command func directly +describe("feedbackCommand.func", () => { + test("throws ValidationError for empty message", async () => { + // Access func through loader + const func = await feedbackCommand.loader(); + const mockContext = { + stdout: { write: mock(() => true) }, + stderr: { write: mock(() => true) }, + }; + + await expect(func.call(mockContext, {}, "")).rejects.toThrow( + "Please provide a feedback message." + ); + }); + + test("throws ValidationError for whitespace-only message", async () => { + const func = await feedbackCommand.loader(); + const mockContext = { + stdout: { write: mock(() => true) }, + stderr: { write: mock(() => true) }, + }; + + await expect(func.call(mockContext, {}, " ")).rejects.toThrow( + "Please provide a feedback message." + ); + }); + + test("writes telemetry disabled message when Sentry is disabled", async () => { + const func = await feedbackCommand.loader(); + const stderrWrite = mock(() => true); + const mockContext = { + stdout: { write: mock(() => true) }, + stderr: { write: stderrWrite }, + }; + + // Sentry is disabled in test environment (no DSN) + await func.call(mockContext, {}, "test", "feedback"); + + expect(stderrWrite).toHaveBeenCalledWith( + "Feedback not sent: telemetry is disabled.\n" + ); + expect(stderrWrite).toHaveBeenCalledWith( + "Unset SENTRY_CLI_NO_TELEMETRY to enable feedback.\n" + ); + }); +}); + +// Test the upgrade command func +describe("upgradeCommand.func", () => { + let originalFetch: typeof globalThis.fetch; + + beforeEach(() => { + originalFetch = globalThis.fetch; + }); + + afterEach(() => { + globalThis.fetch = originalFetch; + }); + + test("throws UpgradeError for unknown installation method", async () => { + // Mock fetch for GitHub API + globalThis.fetch = (async () => + new Response(JSON.stringify({ tag_name: "v1.0.0" }), { + status: 200, + headers: { "Content-Type": "application/json" }, + })) as typeof fetch; + + const func = await upgradeCommand.loader(); + const mockContext = { + stdout: { write: mock(() => true) }, + stderr: { write: mock(() => true) }, + }; + + // In test environment, detectInstallationMethod returns "unknown" + await expect(func.call(mockContext, { check: false })).rejects.toThrow( + "Could not detect installation method" + ); + }); + + test("shows installation info with specified method", async () => { + globalThis.fetch = (async () => + new Response(JSON.stringify({ tag_name: "v0.0.0-dev" }), { + status: 200, + headers: { "Content-Type": "application/json" }, + })) as typeof fetch; + + const func = await upgradeCommand.loader(); + const stdoutWrite = mock(() => true); + const mockContext = { + stdout: { write: stdoutWrite }, + stderr: { write: mock(() => true) }, + }; + + // Use method flag to bypass detection (curl uses GitHub) + await func.call(mockContext, { check: false, method: "curl" }); + + expect(stdoutWrite).toHaveBeenCalledWith("Installation method: curl\n"); + expect(stdoutWrite).toHaveBeenCalledWith( + expect.stringContaining("Current version:") + ); + expect(stdoutWrite).toHaveBeenCalledWith("\nAlready up to date.\n"); + }); + + test("check mode shows update available", async () => { + // curl uses GitHub API which returns { tag_name: "vX.X.X" } + globalThis.fetch = (async () => + new Response(JSON.stringify({ tag_name: "v99.0.0" }), { + status: 200, + headers: { "Content-Type": "application/json" }, + })) as typeof fetch; + + const func = await upgradeCommand.loader(); + const stdoutWrite = mock(() => true); + const mockContext = { + stdout: { write: stdoutWrite }, + stderr: { write: mock(() => true) }, + }; + + await func.call(mockContext, { check: true, method: "curl" }); + + expect(stdoutWrite).toHaveBeenCalledWith( + "\nRun 'sentry cli upgrade' to update.\n" + ); + }); + + test("check mode with version shows versioned command", async () => { + globalThis.fetch = (async () => + new Response(JSON.stringify({ tag_name: "v99.0.0" }), { + status: 200, + headers: { "Content-Type": "application/json" }, + })) as typeof fetch; + + const func = await upgradeCommand.loader(); + const stdoutWrite = mock(() => true); + const mockContext = { + stdout: { write: stdoutWrite }, + stderr: { write: mock(() => true) }, + }; + + await func.call(mockContext, { check: true, method: "curl" }, "2.0.0"); + + expect(stdoutWrite).toHaveBeenCalledWith("Target version: 2.0.0\n"); + expect(stdoutWrite).toHaveBeenCalledWith( + "\nRun 'sentry cli upgrade 2.0.0' to update.\n" + ); + }); + + test("check mode shows already on target when versions match", async () => { + globalThis.fetch = (async () => + new Response(JSON.stringify({ tag_name: "v0.0.0-dev" }), { + status: 200, + headers: { "Content-Type": "application/json" }, + })) as typeof fetch; + + const func = await upgradeCommand.loader(); + const stdoutWrite = mock(() => true); + const mockContext = { + stdout: { write: stdoutWrite }, + stderr: { write: mock(() => true) }, + }; + + await func.call(mockContext, { check: true, method: "curl" }); + + expect(stdoutWrite).toHaveBeenCalledWith( + "\nYou are already on the target version.\n" + ); + }); + + test("throws UpgradeError when specified version does not exist", async () => { + // First call: fetch latest (returns 99.0.0) + // Second call: check if version exists (returns 404) + let callCount = 0; + globalThis.fetch = (async () => { + callCount += 1; + if (callCount === 1) { + // Latest version check + return new Response(JSON.stringify({ tag_name: "v99.0.0" }), { + status: 200, + headers: { "Content-Type": "application/json" }, + }); + } + // Version exists check - return 404 + return new Response("Not Found", { status: 404 }); + }) as typeof fetch; + + const func = await upgradeCommand.loader(); + const stdoutWrite = mock(() => true); + const mockContext = { + stdout: { write: stdoutWrite }, + stderr: { write: mock(() => true) }, + }; + + // Specify a version that doesn't exist + await expect( + func.call(mockContext, { check: false, method: "curl" }, "999.0.0") + ).rejects.toThrow("Version 999.0.0 not found"); + }); +}); From 0fc797c804b93629dd3d356f81f2e77682871e5b Mon Sep 17 00:00:00 2001 From: Burak Yigit Kaya Date: Mon, 2 Feb 2026 15:08:17 +0000 Subject: [PATCH 5/7] test: remove slow test that calls detectInstallationMethod --- test/commands/cli.test.ts | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) diff --git a/test/commands/cli.test.ts b/test/commands/cli.test.ts index cd6218ef..9ee6eb38 100644 --- a/test/commands/cli.test.ts +++ b/test/commands/cli.test.ts @@ -86,25 +86,10 @@ describe("upgradeCommand.func", () => { globalThis.fetch = originalFetch; }); - test("throws UpgradeError for unknown installation method", async () => { - // Mock fetch for GitHub API - globalThis.fetch = (async () => - new Response(JSON.stringify({ tag_name: "v1.0.0" }), { - status: 200, - headers: { "Content-Type": "application/json" }, - })) as typeof fetch; - - const func = await upgradeCommand.loader(); - const mockContext = { - stdout: { write: mock(() => true) }, - stderr: { write: mock(() => true) }, - }; - - // In test environment, detectInstallationMethod returns "unknown" - await expect(func.call(mockContext, { check: false })).rejects.toThrow( - "Could not detect installation method" - ); - }); + // Note: We skip testing "unknown installation method" case because + // detectInstallationMethod() runs actual shell commands (npm list, etc.) + // which can be slow/flaky in CI. The unknown method handling is tested + // indirectly through the upgrade.ts unit tests in lib/upgrade.test.ts. test("shows installation info with specified method", async () => { globalThis.fetch = (async () => From a3e09907e614d090d73740541ae166a9f3544875 Mon Sep 17 00:00:00 2001 From: Burak Yigit Kaya Date: Mon, 2 Feb 2026 16:00:07 +0000 Subject: [PATCH 6/7] test: remove redundant upgrade.test.ts (covered by cli.test.ts) --- test/commands/upgrade.test.ts | 14 -------------- 1 file changed, 14 deletions(-) delete mode 100644 test/commands/upgrade.test.ts diff --git a/test/commands/upgrade.test.ts b/test/commands/upgrade.test.ts deleted file mode 100644 index ca7d4730..00000000 --- a/test/commands/upgrade.test.ts +++ /dev/null @@ -1,14 +0,0 @@ -/** - * Upgrade Command Tests - * - * Tests for the sentry cli upgrade command registration and module exports. - */ - -import { describe, expect, test } from "bun:test"; -import { upgradeCommand } from "../../src/commands/cli/upgrade.js"; - -describe("upgradeCommand", () => { - test("is exported and defined", () => { - expect(upgradeCommand).toBeDefined(); - }); -}); From a0631bb985c39a494824e3ed0853d93f57917b84 Mon Sep 17 00:00:00 2001 From: Burak Yigit Kaya Date: Mon, 2 Feb 2026 16:09:57 +0000 Subject: [PATCH 7/7] test: remove trivial 'is exported' tests from cli.test.ts --- test/commands/cli.test.ts | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/test/commands/cli.test.ts b/test/commands/cli.test.ts index 9ee6eb38..7b658e00 100644 --- a/test/commands/cli.test.ts +++ b/test/commands/cli.test.ts @@ -6,28 +6,8 @@ import { afterEach, beforeEach, describe, expect, mock, test } from "bun:test"; import { feedbackCommand } from "../../src/commands/cli/feedback.js"; -import { cliRoute } from "../../src/commands/cli/index.js"; import { upgradeCommand } from "../../src/commands/cli/upgrade.js"; -describe("cliRoute", () => { - test("is exported and defined", () => { - expect(cliRoute).toBeDefined(); - }); -}); - -describe("feedbackCommand", () => { - test("is exported and defined", () => { - expect(feedbackCommand).toBeDefined(); - }); -}); - -describe("upgradeCommand", () => { - test("is exported and defined", () => { - expect(upgradeCommand).toBeDefined(); - }); -}); - -// Test the feedback command func directly describe("feedbackCommand.func", () => { test("throws ValidationError for empty message", async () => { // Access func through loader