diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ce54cdad5..a0c836824 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -148,7 +148,7 @@ jobs: - name: Check docs sections id: check-sections run: | - if git diff --quiet DEVELOPMENT.md docs/src/content/docs/contributing.md docs/src/content/docs/self-hosted.md; then + if git diff --quiet README.md DEVELOPMENT.md docs/src/content/docs/contributing.md docs/src/content/docs/self-hosted.md docs/src/content/docs/getting-started.mdx; then echo "Docs sections are up to date" else echo "stale=true" >> "$GITHUB_OUTPUT" @@ -159,7 +159,7 @@ jobs: run: | git config user.name "github-actions[bot]" git config user.email "github-actions[bot]@users.noreply.github.com" - git add plugins/sentry-cli/skills/sentry-cli/ DEVELOPMENT.md docs/src/content/docs/contributing.md docs/src/content/docs/self-hosted.md + git add plugins/sentry-cli/skills/sentry-cli/ README.md DEVELOPMENT.md docs/src/content/docs/contributing.md docs/src/content/docs/self-hosted.md docs/src/content/docs/getting-started.mdx git diff --cached --quiet || (git commit -m "chore: regenerate docs" && git push) - name: Fail for fork PRs with stale generated files if: (steps.check-skill.outputs.stale == 'true' || steps.check-sections.outputs.stale == 'true') && steps.token.outcome != 'success' diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 854ab19d8..1dfa1a5b1 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -69,15 +69,20 @@ When creating your Sentry OAuth application: ## Environment Variables -| Variable | Description | Default | -| ----------------------- | ---------------------------------------------------------------- | -------------------- | -| `SENTRY_CLIENT_ID` | Sentry OAuth app client ID | (required for build) | -| `SENTRY_HOST` | Sentry instance URL (for self-hosted, takes precedence) | `https://sentry.io` | -| `SENTRY_URL` | Alias for `SENTRY_HOST` | `https://sentry.io` | -| `SENTRY_AUTH_TOKEN` | API token for non-interactive use (lower priority than stored OAuth by default) | — | -| `SENTRY_FORCE_ENV_TOKEN`| Force env token to take priority over stored OAuth token | — | -| `SENTRY_CLI_NO_TELEMETRY`| Disable CLI telemetry (error tracking) | — | -| `SENTRY_LOG_LEVEL` | Diagnostic log level (`error`, `warn`, `log`, `info`, `debug`, `trace`) | `info` | +The table below lists the most common development variables. For the complete reference, see the generated [Configuration](https://cli.sentry.dev/configuration/) page. + + +| Variable | Description | Default | +|----------|-------------|---------| +| `SENTRY_AUTH_TOKEN` | API token for non-interactive use (lower priority than stored OAuth by default) | — | +| `SENTRY_FORCE_ENV_TOKEN` | Force env token to take priority over stored OAuth token | — | +| `SENTRY_HOST` | Sentry instance URL (for self-hosted, takes precedence) | `https://sentry.io` | +| `SENTRY_URL` | Alias for `SENTRY_HOST` | `https://sentry.io` | +| `SENTRY_CLIENT_ID` | Sentry OAuth app client ID | (required for build) | +| `SENTRY_CONFIG_DIR` | Override credentials/cache directory | `~/.sentry/` | +| `SENTRY_LOG_LEVEL` | Diagnostic log level (`error`, `warn`, `log`, `info`, `debug`, `trace`) | `info` | +| `SENTRY_CLI_NO_TELEMETRY` | Disable CLI telemetry (error tracking) | — | + ## Building diff --git a/README.md b/README.md index 6a9c3c6c9..80cb3e7c0 100644 --- a/README.md +++ b/README.md @@ -76,7 +76,9 @@ Credentials are stored in `~/.sentry/` with restricted permissions (mode 600). ## Library Usage -Use Sentry CLI programmatically in Node.js (≥22) or Bun without spawning a subprocess: + +Use Sentry CLI programmatically in Node.js (≥22.12) or Bun without spawning a subprocess: + ```typescript import createSentrySDK from "sentry"; @@ -115,7 +117,9 @@ Errors are thrown as `SentryError` with `.exitCode` and `.stderr`. ### Prerequisites -- [Bun](https://bun.sh) v1.0+ + +- [Bun](https://bun.sh) v1.3+ + ### Setup @@ -137,13 +141,17 @@ bun run --env-file=.env.local src/bin.ts --help ### Scripts + ```bash -bun run build # Build for current platform -bun run typecheck # Type checking -bun run lint # Check for issues -bun run lint:fix # Auto-fix issues -bun test # Run tests +bun run build # Build for current platform +bun run typecheck # Type checking +bun run lint # Check for issues +bun run lint:fix # Auto-fix issues +bun run test:unit # Run unit tests +bun run test:e2e # Run end-to-end tests +bun run generate:docs # Regenerate command docs and skills ``` + See [DEVELOPMENT.md](DEVELOPMENT.md) for detailed setup and [CONTRIBUTING.md](CONTRIBUTING.md) for contribution guidelines. diff --git a/docs/src/content/docs/contributing.md b/docs/src/content/docs/contributing.md index 816bbe0e9..c4ee61408 100644 --- a/docs/src/content/docs/contributing.md +++ b/docs/src/content/docs/contributing.md @@ -9,7 +9,9 @@ We welcome contributions to the Sentry CLI! This guide will help you get started ### Prerequisites -- [Bun](https://bun.sh) runtime (v1.0 or later) + +- [Bun](https://bun.sh) runtime (v1.3 or later) + - Git ### Getting Started diff --git a/docs/src/content/docs/getting-started.mdx b/docs/src/content/docs/getting-started.mdx index 3f697471e..b71060cd7 100644 --- a/docs/src/content/docs/getting-started.mdx +++ b/docs/src/content/docs/getting-started.mdx @@ -36,6 +36,16 @@ The `--version` flag takes precedence over `SENTRY_VERSION` if both are set. The chosen channel is persisted so that `sentry cli upgrade` automatically tracks the same channel on future updates. +#### Supported Platforms + +{/* GENERATED:START platform-support */} +| OS | Architectures | Notes | +|----|---------------|-------| +| **macOS** | x64, arm64 (Apple Silicon) | | +| **Linux** | x64, arm64 | glibc and musl (Alpine) | +| **Windows** | x64 | Via Git Bash, MSYS2, or WSL | +{/* GENERATED:END platform-support */} + ### Homebrew ```bash diff --git a/docs/src/content/docs/self-hosted.md b/docs/src/content/docs/self-hosted.md index 5f768338f..eb9c23d18 100644 --- a/docs/src/content/docs/self-hosted.md +++ b/docs/src/content/docs/self-hosted.md @@ -67,12 +67,16 @@ If you pass a self-hosted Sentry URL as a command argument (e.g., an issue or ev ## Relevant Environment Variables + | Variable | Description | |----------|-------------| | `SENTRY_HOST` | Base URL of your Sentry instance (takes precedence over `SENTRY_URL`) | | `SENTRY_URL` | Alias for `SENTRY_HOST` | | `SENTRY_CLIENT_ID` | Client ID of your public OAuth application | +| `SENTRY_CUSTOM_HEADERS` | Custom HTTP headers for proxy/IAP (semicolon-separated `Name: Value` pairs) | +| `SENTRY_FORCE_ENV_TOKEN` | Force env token over stored OAuth token | | `SENTRY_ORG` | Default organization slug | | `SENTRY_PROJECT` | Default project slug (supports `org/project` format) | + See [Configuration](./configuration/) for the full environment variable reference. diff --git a/docs/src/fragments/commands/event.md b/docs/src/fragments/commands/event.md index aee035756..bad1c71ce 100644 --- a/docs/src/fragments/commands/event.md +++ b/docs/src/fragments/commands/event.md @@ -2,6 +2,34 @@ ## Examples +### Listing Events + +```bash +# List events for an issue (using short ID) +sentry event list PROJ-ABC + +# List events for an issue (using numeric ID) +sentry event list 123456789 + +# Filter by search query +sentry event list PROJ-ABC --query "browser:Chrome" + +# Include full event bodies (stacktraces) +sentry event list PROJ-ABC --full + +# Limit results and time range +sentry event list PROJ-ABC --limit 50 --period 24h + +# Paginate through results +sentry event list PROJ-ABC -c next +sentry event list PROJ-ABC -c prev + +# Output as JSON +sentry event list PROJ-ABC --json +``` + +### Viewing Events + ```bash sentry event view abc123def456abc123def456abc12345 ``` diff --git a/docs/src/fragments/commands/release.md b/docs/src/fragments/commands/release.md index a3b862501..4f2a16943 100644 --- a/docs/src/fragments/commands/release.md +++ b/docs/src/fragments/commands/release.md @@ -31,6 +31,15 @@ sentry release deploy 1.0.0 staging "Deploy #42" # Propose a version from git HEAD sentry release create $(sentry release propose-version) +# List deploys for a release +sentry release deploys 1.0.0 +sentry release deploys my-org/1.0.0 + +# Delete a release +sentry release delete my-org/1.0.0 +sentry release delete my-org/1.0.0 --yes # Skip confirmation +sentry release delete my-org/1.0.0 --dry-run # Preview without deleting + # Output as JSON sentry release list --json sentry release view 1.0.0 --json diff --git a/plugins/sentry-cli/skills/sentry-cli/references/event.md b/plugins/sentry-cli/skills/sentry-cli/references/event.md index ac3d7e197..006edff3d 100644 --- a/plugins/sentry-cli/skills/sentry-cli/references/event.md +++ b/plugins/sentry-cli/skills/sentry-cli/references/event.md @@ -20,6 +20,15 @@ View details of a specific event - `--spans - Span tree depth limit (number, "all" for unlimited, "no" to disable) - (default: "3")` - `-f, --fresh - Bypass cache, re-detect projects, and fetch fresh data` +**Examples:** + +```bash +sentry event view abc123def456abc123def456abc12345 + +# Open in browser +sentry event view abc123def456abc123def456abc12345 -w +``` + ### `sentry event list ` List events for an issue @@ -55,10 +64,27 @@ List events for an issue **Examples:** ```bash -sentry event view abc123def456abc123def456abc12345 +# List events for an issue (using short ID) +sentry event list PROJ-ABC -# Open in browser -sentry event view abc123def456abc123def456abc12345 -w +# List events for an issue (using numeric ID) +sentry event list 123456789 + +# Filter by search query +sentry event list PROJ-ABC --query "browser:Chrome" + +# Include full event bodies (stacktraces) +sentry event list PROJ-ABC --full + +# Limit results and time range +sentry event list PROJ-ABC --limit 50 --period 24h + +# Paginate through results +sentry event list PROJ-ABC -c next +sentry event list PROJ-ABC -c prev + +# Output as JSON +sentry event list PROJ-ABC --json ``` All commands also support `--json`, `--fields`, `--help`, `--log-level`, and `--verbose` flags. diff --git a/plugins/sentry-cli/skills/sentry-cli/references/release.md b/plugins/sentry-cli/skills/sentry-cli/references/release.md index dc21a4ff0..ae7b65fc6 100644 --- a/plugins/sentry-cli/skills/sentry-cli/references/release.md +++ b/plugins/sentry-cli/skills/sentry-cli/references/release.md @@ -121,6 +121,15 @@ sentry release deploy 1.0.0 staging "Deploy #42" # Propose a version from git HEAD sentry release create $(sentry release propose-version) +# List deploys for a release +sentry release deploys 1.0.0 +sentry release deploys my-org/1.0.0 + +# Delete a release +sentry release delete my-org/1.0.0 +sentry release delete my-org/1.0.0 --yes # Skip confirmation +sentry release delete my-org/1.0.0 --dry-run # Preview without deleting + # Output as JSON sentry release list --json sentry release view 1.0.0 --json diff --git a/script/generate-docs-sections.ts b/script/generate-docs-sections.ts index d195ebaa8..6ae6902fa 100644 --- a/script/generate-docs-sections.ts +++ b/script/generate-docs-sections.ts @@ -6,9 +6,11 @@ * between and markers. * * Sections: - * - contributing.md: project structure tree (from route tree + filesystem) - * - DEVELOPMENT.md: OAuth scopes bullet list (from oauth.ts) - * - self-hosted.md: OAuth scopes inline list (from oauth.ts) + * - contributing.md: project structure tree, dev prerequisites + * - DEVELOPMENT.md: OAuth scopes, env var table + * - self-hosted.md: OAuth scopes, env var table + * - README.md: dev prerequisites, library prerequisites, dev scripts + * - getting-started.mdx: platform support table * * Unlike generate-command-docs.ts (which produces gitignored files from scratch), * this script edits committed files in-place between marker pairs. @@ -29,11 +31,14 @@ if (!(await Bun.file(SKILL_CONTENT_PATH).exists())) { await Bun.write(SKILL_CONTENT_PATH, SKILL_CONTENT_STUB); } +import type { EnvVarEntry } from "../src/lib/env-registry.js"; import type { RouteInfo, RouteMap } from "../src/lib/introspect.js"; const { routes } = await import("../src/app.js"); const { extractAllRoutes } = await import("../src/lib/introspect.js"); const { OAUTH_SCOPES } = await import("../src/lib/oauth.js"); +const { ENV_VAR_REGISTRY } = await import("../src/lib/env-registry.js"); +const pkg = await Bun.file("package.json").json(); const isCheck = process.argv.includes("--check"); @@ -41,6 +46,29 @@ const isCheck = process.argv.includes("--check"); // Marker Replacement // --------------------------------------------------------------------------- +/** + * Supported marker comment styles. + * HTML: `<!-- GENERATED:START name -->` (for .md files) + * MDX: JSX comment `GENERATED:START name` (for .mdx files) + */ +type MarkerStyle = "html" | "mdx"; + +function markerTags( + sectionName: string, + style: MarkerStyle +): { startTag: string; endTag: string } { + if (style === "mdx") { + return { + startTag: `{/* GENERATED:START ${sectionName} */}`, + endTag: `{/* GENERATED:END ${sectionName} */}`, + }; + } + return { + startTag: ``, + endTag: ``, + }; +} + /** * Replace content between named marker pairs in a string. * @@ -55,10 +83,10 @@ const isCheck = process.argv.includes("--check"); function replaceMarkerSection( content: string, sectionName: string, - generated: string + generated: string, + style: MarkerStyle = "html" ): string { - const startTag = ``; - const endTag = ``; + const { startTag, endTag } = markerTags(sectionName, style); const startIdx = content.indexOf(startTag); const endIdx = content.indexOf(endTag); @@ -224,6 +252,185 @@ function generateScopesInline(scopes: readonly string[]): string { return scopes.map((s) => `\`${s}\``).join(", "); } +// --------------------------------------------------------------------------- +// Section: Prerequisites (README.md, contributing.md) +// --------------------------------------------------------------------------- + +const BUN_VERSION_RE = /bun@(\d+\.\d+)/; +const SEMVER_RE = /(\d+\.\d+)/; + +/** + * Extract the Bun major.minor version from the `packageManager` field. + * `bun@1.3.13` → `1.3` + */ +function extractBunVersion(): string { + const pm: string = pkg.packageManager ?? ""; + const match = pm.match(BUN_VERSION_RE); + return match ? match[1] : "1.3"; +} + +/** Extract the Node.js minimum version from `engines.node` (e.g., `>=22.12` → `22.12`). */ +function extractNodeVersion(): string { + const constraint: string = pkg.engines?.node ?? ">=22.12"; + const match = constraint.match(SEMVER_RE); + return match ? match[1] : "22.12"; +} + +/** Generate dev prerequisite line for README.md and contributing.md. */ +function generateDevPrereq(): string { + return `- [Bun](https://bun.sh) v${extractBunVersion()}+`; +} + +/** Also used by contributing.md (same content, different phrasing). */ +function generateDevPrereqContributing(): string { + return `- [Bun](https://bun.sh) runtime (v${extractBunVersion()} or later)`; +} + +/** Generate the library-usage prerequisite line for README.md. */ +function generateLibraryPrereq(): string { + return `Use Sentry CLI programmatically in Node.js (≥${extractNodeVersion()}) or Bun without spawning a subprocess:`; +} + +// --------------------------------------------------------------------------- +// Section: Dev Scripts (README.md) +// --------------------------------------------------------------------------- + +/** + * Generate the development scripts block for README.md. + * + * These are a curated subset of package.json scripts — not all scripts + * are user-facing. The list is hardcoded because script descriptions + * aren't machine-readable from package.json. + */ +function generateDevScripts(): string { + const scripts: [string, string][] = [ + ["bun run build", "Build for current platform"], + ["bun run typecheck", "Type checking"], + ["bun run lint", "Check for issues"], + ["bun run lint:fix", "Auto-fix issues"], + ["bun run test:unit", "Run unit tests"], + ["bun run test:e2e", "Run end-to-end tests"], + ["bun run generate:docs", "Regenerate command docs and skills"], + ]; + const maxCmd = Math.max(...scripts.map(([cmd]) => cmd.length)); + const lines = scripts.map(([cmd, desc]) => `${cmd.padEnd(maxCmd)} # ${desc}`); + return `\`\`\`bash\n${lines.join("\n")}\n\`\`\``; +} + +// --------------------------------------------------------------------------- +// Section: Env Var Tables (DEVELOPMENT.md, self-hosted.md) +// --------------------------------------------------------------------------- + +/** + * Generate the DEVELOPMENT.md env var table from registry entries + * tagged with `devGuide`. + */ +function generateDevEnvVarsTable(): string { + const entries = ENV_VAR_REGISTRY.filter( + (e: EnvVarEntry) => e.devGuide !== undefined + ); + const lines: string[] = [ + "| Variable | Description | Default |", + "|----------|-------------|---------|", + ]; + for (const entry of entries) { + const name = `\`${entry.name}\``; + const desc = entry.devGuide ?? ""; + let defaultCol = "—"; + if (entry.name === "SENTRY_CLIENT_ID") { + defaultCol = "(required for build)"; + } else if (entry.defaultValue) { + defaultCol = `\`${entry.defaultValue}\``; + } + lines.push(`| ${name} | ${desc} | ${defaultCol} |`); + } + return lines.join("\n"); +} + +/** Short descriptions for the self-hosted env var table, ordered for self-hosted context. */ +const SELF_HOSTED_TABLE_ENTRIES: readonly [string, string][] = [ + [ + "SENTRY_HOST", + "Base URL of your Sentry instance (takes precedence over `SENTRY_URL`)", + ], + ["SENTRY_URL", "Alias for `SENTRY_HOST`"], + ["SENTRY_CLIENT_ID", "Client ID of your public OAuth application"], + [ + "SENTRY_CUSTOM_HEADERS", + "Custom HTTP headers for proxy/IAP (semicolon-separated `Name: Value` pairs)", + ], + ["SENTRY_FORCE_ENV_TOKEN", "Force env token over stored OAuth token"], + ["SENTRY_ORG", "Default organization slug"], + ["SENTRY_PROJECT", "Default project slug (supports `org/project` format)"], +]; + +/** + * Generate the self-hosted.md env var table. + * + * Uses a curated order (URL vars first) rather than registry order, + * but validates at generation time that every entry in the table + * has `selfHosted: true` in the registry. + */ +function generateSelfHostedEnvVarsTable(): string { + const selfHostedNames = new Set( + ENV_VAR_REGISTRY.filter((e: EnvVarEntry) => e.selfHosted === true).map( + (e: EnvVarEntry) => e.name + ) + ); + for (const [name] of SELF_HOSTED_TABLE_ENTRIES) { + if (!selfHostedNames.has(name)) { + throw new Error( + `Self-hosted table entry "${name}" is not tagged selfHosted in env-registry.ts` + ); + } + } + if (selfHostedNames.size !== SELF_HOSTED_TABLE_ENTRIES.length) { + const missing = [...selfHostedNames].filter( + (n) => !SELF_HOSTED_TABLE_ENTRIES.some(([name]) => name === n) + ); + throw new Error( + `Registry entries tagged selfHosted but missing from self-hosted table: ${missing.join(", ")}` + ); + } + + const lines: string[] = [ + "| Variable | Description |", + "|----------|-------------|", + ]; + for (const [name, desc] of SELF_HOSTED_TABLE_ENTRIES) { + lines.push(`| \`${name}\` | ${desc} |`); + } + return lines.join("\n"); +} + +// --------------------------------------------------------------------------- +// Section: Platform Support (getting-started.mdx) +// --------------------------------------------------------------------------- + +/** + * Platform support table rows. + * + * Derived from ALL_TARGETS in script/build.ts. Update this when + * adding or removing build targets. + */ +const PLATFORM_ROWS: readonly [string, string, string][] = [ + ["macOS", "x64, arm64 (Apple Silicon)", ""], + ["Linux", "x64, arm64", "glibc and musl (Alpine)"], + ["Windows", "x64", "Via Git Bash, MSYS2, or WSL"], +]; + +/** Generate the platform support table for getting-started.mdx. */ +function generatePlatformSupport(): string { + const lines: string[] = [ + "| OS | Architectures | Notes |", + "|----|---------------|-------|", + ]; + for (const [os, archs, notes] of PLATFORM_ROWS) { + lines.push(`| **${os}** | ${archs} | ${notes} |`); + } + return lines.join("\n"); +} + // --------------------------------------------------------------------------- // Section Definitions // --------------------------------------------------------------------------- @@ -232,6 +439,8 @@ type SectionDef = { filePath: string; sectionName: string; generate: () => string; + /** Marker comment style. Defaults to `"html"`. */ + markerStyle?: MarkerStyle; }; // --------------------------------------------------------------------------- @@ -242,6 +451,7 @@ const routeMap = routes as unknown as RouteMap; const routeInfos = extractAllRoutes(routeMap); const sections: SectionDef[] = [ + // -- Existing sections -- { filePath: "docs/src/content/docs/contributing.md", sectionName: "project-structure", @@ -257,6 +467,46 @@ const sections: SectionDef[] = [ sectionName: "oauth-scopes", generate: () => generateScopesInline(OAUTH_SCOPES), }, + // -- Prerequisites (version numbers from package.json) -- + { + filePath: "README.md", + sectionName: "dev-prereq", + generate: generateDevPrereq, + }, + { + filePath: "README.md", + sectionName: "library-prereq", + generate: generateLibraryPrereq, + }, + { + filePath: "docs/src/content/docs/contributing.md", + sectionName: "dev-prereq", + generate: generateDevPrereqContributing, + }, + // -- Dev scripts (README.md) -- + { + filePath: "README.md", + sectionName: "dev-scripts", + generate: generateDevScripts, + }, + // -- Env var tables -- + { + filePath: "DEVELOPMENT.md", + sectionName: "dev-env-vars", + generate: generateDevEnvVarsTable, + }, + { + filePath: "docs/src/content/docs/self-hosted.md", + sectionName: "self-hosted-env-vars", + generate: generateSelfHostedEnvVarsTable, + }, + // -- Platform support (getting-started.mdx) -- + { + filePath: "docs/src/content/docs/getting-started.mdx", + sectionName: "platform-support", + generate: generatePlatformSupport, + markerStyle: "mdx", + }, ]; let staleCount = 0; @@ -267,7 +517,8 @@ for (const section of sections) { const updated = replaceMarkerSection( original, section.sectionName, - generated + generated, + section.markerStyle ?? "html" ); if (updated !== original) { diff --git a/src/lib/env-registry.ts b/src/lib/env-registry.ts index 9082f4d7b..7881faaaa 100644 --- a/src/lib/env-registry.ts +++ b/src/lib/env-registry.ts @@ -26,6 +26,10 @@ export type EnvVarEntry = { topLevel?: boolean; /** Short one-line description used in the branded help summary. Falls back to `description` when absent. */ briefDescription?: string; + /** Include in the self-hosted.md env var table. */ + selfHosted?: boolean; + /** Include in the DEVELOPMENT.md env var table. One-line description for the table cell. */ + devGuide?: string; }; /** @@ -44,6 +48,8 @@ export const ENV_VAR_REGISTRY: readonly EnvVarEntry[] = [ example: "sntrys_YOUR_TOKEN_HERE", topLevel: true, briefDescription: "Auth token used for API requests (CI, scripts).", + devGuide: + "API token for non-interactive use (lower priority than stored OAuth by default)", }, { name: "SENTRY_TOKEN", @@ -57,6 +63,8 @@ export const ENV_VAR_REGISTRY: readonly EnvVarEntry[] = [ example: "1", topLevel: true, briefDescription: "Prefer the env-var token over a stored OAuth login.", + selfHosted: true, + devGuide: "Force env token to take priority over stored OAuth token", }, // -- Targeting -- { @@ -66,6 +74,7 @@ export const ENV_VAR_REGISTRY: readonly EnvVarEntry[] = [ example: "my-org", topLevel: true, briefDescription: "Default organization slug.", + selfHosted: true, }, { name: "SENTRY_PROJECT", @@ -74,6 +83,7 @@ export const ENV_VAR_REGISTRY: readonly EnvVarEntry[] = [ example: "my-org/my-project", topLevel: true, briefDescription: "Default project slug (or `org/project`).", + selfHosted: true, }, { name: "SENTRY_DSN", @@ -83,6 +93,16 @@ export const ENV_VAR_REGISTRY: readonly EnvVarEntry[] = [ topLevel: true, briefDescription: "DSN used to auto-detect org + project.", }, + // -- Release -- + { + name: "SENTRY_RELEASE", + description: + "Explicit release version for `sentry release propose-version`. When set, " + + "the command returns this value immediately without checking CI environment " + + "variables or local git history. Useful in CI pipelines where the release " + + "version is determined by a prior step.", + example: "1.0.0", + }, // -- URL -- { name: "SENTRY_HOST", @@ -92,18 +112,24 @@ export const ENV_VAR_REGISTRY: readonly EnvVarEntry[] = [ defaultValue: "https://sentry.io", topLevel: true, briefDescription: "Base URL of your Sentry instance (self-hosted).", + selfHosted: true, + devGuide: "Sentry instance URL (for self-hosted, takes precedence)", }, { name: "SENTRY_URL", description: "Alias for `SENTRY_HOST`. If both are set, `SENTRY_HOST` takes precedence.", defaultValue: "https://sentry.io", + selfHosted: true, + devGuide: "Alias for `SENTRY_HOST`", }, { name: "SENTRY_CLIENT_ID", description: "Client ID of a public OAuth application on your Sentry instance. **Required for [self-hosted Sentry](./self-hosted/)** (26.1.0+) to use `sentry auth login` with the device flow. See the [Self-Hosted guide](./self-hosted/#1-create-a-public-oauth-application) for how to create one.", example: "your-oauth-client-id", + selfHosted: true, + devGuide: "Sentry OAuth app client ID", }, // -- Custom headers -- { @@ -116,6 +142,7 @@ export const ENV_VAR_REGISTRY: readonly EnvVarEntry[] = [ "(e.g., Google IAP, Cloudflare Access).\n\n" + "Can also be set persistently with `sentry cli defaults headers`.", example: '"X-IAP-Token: my-proxy-token"', + selfHosted: true, }, // -- Paths -- { @@ -124,6 +151,7 @@ export const ENV_VAR_REGISTRY: readonly EnvVarEntry[] = [ "Override the directory where the CLI stores its database (credentials, caches, defaults). Defaults to `~/.sentry/`.", example: "/path/to/config", defaultValue: "~/.sentry/", + devGuide: "Override credentials/cache directory", }, { name: "SENTRY_INSTALL_DIR", @@ -183,12 +211,15 @@ export const ENV_VAR_REGISTRY: readonly EnvVarEntry[] = [ defaultValue: "info", topLevel: true, briefDescription: "Log verbosity (error, warn, info, debug, trace).", + devGuide: + "Diagnostic log level (`error`, `warn`, `log`, `info`, `debug`, `trace`)", }, { name: "SENTRY_CLI_NO_TELEMETRY", description: "Disable CLI telemetry (error tracking for the CLI itself). The CLI sends anonymized error reports to help improve reliability — set this to opt out.", example: "1", + devGuide: "Disable CLI telemetry (error tracking)", }, { name: "SENTRY_CLI_NO_UPDATE_CHECK", diff --git a/test/lib/db/auth.test.ts b/test/lib/db/auth.test.ts index 0166aec2f..ec6909cd8 100644 --- a/test/lib/db/auth.test.ts +++ b/test/lib/db/auth.test.ts @@ -447,7 +447,9 @@ describe("hasStoredAuthCredentials memoization", () => { // Write directly to DB without going through setAuthToken // (simulates a code path the cache doesn't know about). const db = getDatabase(); - db.query("INSERT OR REPLACE INTO auth (id, token) VALUES (1, 'sneaky')").run(); + db.query( + "INSERT OR REPLACE INTO auth (id, token) VALUES (1, 'sneaky')" + ).run(); // Cache still returns stale false expect(hasStoredAuthCredentials()).toBe(false);