Skip to content

docs: add v3→v4 migration guide (sentry-cli → sentry)#1201

Open
BYK wants to merge 24 commits into
mainfrom
byk/docs/v3-to-v4-migration
Open

docs: add v3→v4 migration guide (sentry-cli → sentry)#1201
BYK wants to merge 24 commits into
mainfrom
byk/docs/v3-to-v4-migration

Conversation

@BYK

@BYK BYK commented Jul 6, 2026

Copy link
Copy Markdown
Member

Adds a migration guide for the upcoming major release (v3 → v4), where the legacy Rust sentry-cli is replaced by the new TypeScript sentry CLI.

New page: docs/src/content/docs/migrating-from-v3.md (wired into the Getting Started sidebar, between Installation and Self-Hosted).

Covers

  • The renamesentry-clisentry binary, @sentry/clisentry npm package, with install/uninstall steps for npm/brew/curl/npx.
  • Command changes, grouped for quick scanning:
    • Still work unchanged (info, send-event, send-envelope, bash-hook, sourcemaps, debug-files, react-native …).
    • Renamed groups (plural → singular: releasesrelease, projectsproject, …) with a note that bare plurals still work as list shortcuts.
    • Moved (loginauth login, updatecli upgrade, uninstallcli uninstall, deploysrelease deploys, upload-dif/upload-dsymdebug-files upload, difutildebug-files, upload-proguardproguard upload).
    • Removed (send-metric).
  • A copy-paste sentry-cli() shim that transparently translates every moved/renamed command to its v4 form, so existing scripts and muscle memory keep working during migration (the user-requested "practical alternatives").
  • Output & scripting (--json instead of screen-scraping, NO_COLOR/SENTRY_PLAIN_OUTPUT), OAuth device-flow auth (tokens still honored), semantic exit codes, debug-ID-first sourcemaps, and config/.sentryclirc backward-compat.

All command mappings were verified against the actual v4 route map (src/app.ts), src/commands/, and the existing exit-codes/configuration docs. cd docs && pnpm run build passes (page renders, no broken links).

Note: I inferred the release will be branded v4; if it lands under a different version the title/headings are a trivial find-replace.

Adds docs/src/content/docs/migrating-from-v3.md covering the major-release
upgrade from the legacy Rust sentry-cli (v3) to the new TypeScript sentry CLI
(v4):

- The binary/package rename (sentry-cli → sentry, @sentry/cli → sentry) with
  install steps.
- Command changes grouped into still-works / renamed (plural→singular) / moved
  (login→auth login, update→cli upgrade, deploys→release deploys, upload-dif→
  debug-files upload, upload-proguard→proguard upload, difutil→debug-files) /
  removed (send-metric).
- A copy-paste `sentry-cli()` compatibility shim that transparently translates
  moved/renamed commands so existing scripts keep working.
- Output/scripting (--json), OAuth auth, semantic exit codes, debug-ID-first
  sourcemaps, and config backward-compat notes.

Wires the page into the Getting Started sidebar. `astro build` passes.
@github-actions github-actions Bot added the risk: low PR risk score: low label Jul 6, 2026
@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor
PR Preview Action v1.8.1

QR code for preview link

🚀 View preview at
https://cli.sentry.dev/_preview/pr-1201/

Built to branch gh-pages at 2026-07-14 14:00 UTC.
Preview will be ready when the GitHub Pages deployment is complete.

@github-actions

github-actions Bot commented Jul 6, 2026

Copy link
Copy Markdown
Contributor

Codecov Results 📊

✅ Patch coverage is 100.00%. Project has 5342 uncovered lines.
✅ Project coverage is 81.81%. Comparing base (base) to head (head).

Coverage diff
@@            Coverage Diff             @@
##          main       #PR       +/-##
==========================================
+ Coverage    81.81%    81.81%        —%
==========================================
  Files          423       423         —
  Lines        29374     29374         —
  Branches     19131     19131         —
==========================================
+ Hits         24032     24032         —
- Misses        5342      5342         —
- Partials      1990      1989        -1

Generated by Codecov Action

Comment thread docs/src/content/docs/migrating-from-v3.md Outdated
Addresses the "will SentryCli().setCommits still work?" question on the guide:

- migrating-from-v3.md: new "Node.js wrapper (SentryCli class)" section — the v4
  package has no SentryCli class; it's usable as a library via createSentrySDK().
  Includes a full v3→v4 method mapping table and notes sourcemaps are now
  debug-ID-first / decoupled from releases.

- codemods/sentry-v3-to-v4.cjs: a jscodeshift transform that rewrites the
  @sentry/cli import, `new SentryCli(configFile, options)` → createSentrySDK
  (authToken→token), the releases.* method chain → release.*/sourcemap.*, and
  execute() → run(). Where option *shapes* changed (e.g. uploadSourceMaps
  include → sourcemap.upload directory), it inserts `// TODO(sentry-v4): …`
  breadcrumbs instead of guessing.

- test/codemods/sentry-v3-to-v4.test.ts: 10 cases covering import/require,
  constructor, the release flow, setCommits/uploadSourceMaps/newDeploy reshaping,
  execute→run, and literal-inlining vs spread. Wired into test:unit.

- codemods/README.md: usage. biome.jsonc: force-ignore the .cjs (its module
  graph trips Biome's type-analysis limit, same as custom-ca.ts). jscodeshift,
  @types/jscodeshift, tslib added as devDependencies.
@github-actions github-actions Bot added risk: high PR risk score: high and removed risk: low PR risk score: low labels Jul 6, 2026
Comment thread codemods/sentry-v3-to-v4.cjs Outdated

@szokeasaurusrex szokeasaurusrex left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Added some comments.

Most of them are small; my biggest concern is about the lack of mention about whether any of the command line flags need to be changed

Comment thread docs/src/content/docs/migrating-from-v3.md Outdated
Comment thread docs/src/content/docs/migrating-from-v3.md Outdated
Comment thread docs/src/content/docs/migrating-from-v3.md Outdated
Comment thread docs/src/content/docs/migrating-from-v3.md Outdated
Comment thread docs/src/content/docs/migrating-from-v3.md Outdated
Comment thread docs/src/content/docs/migrating-from-v3.md
Comment thread docs/src/content/docs/migrating-from-v3.md Outdated
Comment thread docs/src/content/docs/migrating-from-v3.md
Comment thread docs/src/content/docs/migrating-from-v3.md
Comment thread docs/src/content/docs/migrating-from-v3.md
@szokeasaurusrex

Copy link
Copy Markdown
Member

Had the clanker take a quick look at the differences between the two CLI's APIs for some of the more important commands; seems like the new CLI lacks support for several flags that were supported in the old CLI.

The full investigation is here.

Migration guide (per @szokeasaurusrex review):
- Add a "Global flags and options" section — the key gap: v4 keeps
  --org/--project/--log-level/-v as globals but drops per-command
  --auth-token/--url/--header (now SENTRY_AUTH_TOKEN / SENTRY_URL|SENTRY_HOST /
  SENTRY_CUSTOM_HEADERS) and --quiet. The shim now translates
  --auth-token/--url/--header into those env vars per-call.
- Drop the `orgs` alias (v3 only had `organizations`) and the send-metric
  "Removed" row (metrics were removed back in v3.0, not a v3→v4 change).
- Correct the sourcemaps section: v3 command is `sentry-cli sourcemaps upload`
  (not `releases files … upload-sourcemaps`); sourcemaps were debug-ID-first
  since v2 — drop the false "now debug-ID-first" framing; document the
  single-<directory> positional + dropped flags instead.
- Clarify SENTRY_TOKEN is a v4 alias (not a v3 carryover); note upload-dif/dsym/
  proguard were already soft-deprecated hidden aliases in v3; align the
  renamed-groups rows; fix the "open an issue" link to getsentry/cli.

Codemod (per Cursor Bugbot):
- Gate the .execute()→.run() and .releases.* rewrites on a tracked SentryCli
  instance so unrelated .execute()/.releases APIs (DB clients, etc.) are left
  alone. Add regression tests for both.
Comment thread docs/src/content/docs/migrating-from-v3.md Outdated
Comment thread codemods/sentry-v3-to-v4.cjs Outdated
Comment thread codemods/sentry-v3-to-v4.cjs Outdated
@BYK

BYK commented Jul 6, 2026

Copy link
Copy Markdown
Member Author

Thanks @szokeasaurusrex — all addressed in the latest push:

Factual fixes

  • Dropped the orgs alias everywhere (v3 only had organizations).
  • Removed the send-metric "Removed" row + shim case — it was removed back in v3.0, not a v3→v4 change.
  • Corrected the sourcemaps section: v3 command is sentry-cli sourcemaps upload (not releases files … upload-sourcemaps), and dropped the false "now debug-ID-first" framing (it's been debug-ID-first since v2). Now documents the real deltas: single <directory> positional + the dropped flags.
  • Clarified SENTRY_TOKEN is a v4 alias, not a v3 carryover.
  • Noted upload-dif/upload-dsym/upload-proguard were already soft-deprecated hidden aliases in v3.
  • Fixed the "open an issue" link → getsentry/cli; aligned the renamed-group rows.

The big one (flags) — new Global flags and options section documenting which globals survive (--org/--project/--log-level/-v) vs. which moved to env vars (--auth-tokenSENTRY_AUTH_TOKEN, --urlSENTRY_URL/SENTRY_HOST, --headerSENTRY_CUSTOM_HEADERS) vs. dropped (--quiet). The shim now translates the env-var-backed flags automatically, and there's a caution to verify per-command flags via sentry <cmd> --help.

Codemod (Bugbot) — the .execute().run() and .releases.* rewrites are now gated on a tracked SentryCli instance, so unrelated .execute() APIs (DB clients, etc.) are left alone. Added regression tests.

One correction on the gist: sentry debug-files upload does exist now (built recently), so that "no equivalent" note reflects an older 0.38.0.

…ions

Two more review findings on the codemod:

- HIGH (Sentry bot): `new SentryCli(myVar)` with a single non-object argument
  silently dropped it (only ObjectExpression args were kept), losing the user's
  config. Now the arg is preserved as `createSentrySDK(myVar)` with a TODO noting
  the v3 configFile-vs-options ambiguity (v3's first param was a configFile path,
  removed in v4).

- Medium (Bugbot): `newDeploy(v, o)` spread v3 fields like `env`/`name` into
  `release.deploy(...)`, but v4 takes those as part of the positional
  `orgVersionEnvironmentName` (org/version/env/name), not option keys. The
  codemod no longer spreads the options for deploy and emits a TODO explaining
  the reshaping; the guide's mapping row is corrected to match.

Also fixed `addTodo` to attach to `*Declaration` nodes (e.g. `const cli = …`),
not just `*Statement`, so the constructor TODO actually lands. +2 tests (13 total).
Comment thread codemods/sentry-v3-to-v4.cjs Outdated
Comment thread codemods/sentry-v3-to-v4.cjs Outdated
…pre-replace

- When constructor options are a variable/expression (not an inline object),
  the codemod can't rename `authToken`→`token` in place, so it now emits a TODO
  to do it manually (Cursor Bugbot: "authToken not renamed in variables").
- Emit all TODO breadcrumbs before `path.replace()` rather than after, so the
  comment always attaches to the original node's statement (Sentry bot).
- +1 test (14 total).
Comment thread codemods/sentry-v3-to-v4.cjs Outdated
Cursor Bugbot: always renaming the binding to `createSentrySDK` could leave
dangling references (re-exports, passing the module around) or duplicate
declarations (multiple requires in one scope).

Now the codemod only changes the module specifier (`@sentry/cli` → `sentry`) and
keeps the user's local name; `new <name>(…)` becomes `<name>(…)` since v4's
default export is the createSentrySDK factory, not a class. Every reference to
the binding stays valid. +1 test (custom name + `export {}` reference); 15 total.
@BYK

BYK commented Jul 7, 2026

Copy link
Copy Markdown
Member Author

Two more codemod findings from the latest review, both addressed in bd6263352:

  • "Codemod breaks custom import names" — the codemod no longer forces the createSentrySDK binding. It keeps your local name and only changes the module specifier (@sentry/clisentry), rewriting new <name>(…)<name>(…) (v4's default export is the createSentrySDK factory, not a class). Re-exports, passing the module around, and multiple requires all stay valid — no dangling refs or duplicate declarations. Added a test with export { Sentry }.

  • "authToken not renamed in variables" — intended behavior: authTokentoken is renamed in place when the options are an inline object literal; when they're a variable/expression defined elsewhere the codemod can't reach in, so it emits a // TODO(sentry-v4): … authToken → token breadcrumb instead of silently doing nothing. Covered by the "flags authToken rename when options is a variable" test.

Comment thread codemods/sentry-v3-to-v4.cjs Outdated
Comment thread codemods/sentry-v3-to-v4.cjs Outdated
Comment thread docs/src/content/docs/migrating-from-v3.md Outdated
…aders

Three more Cursor Bugbot findings:

- authToken shorthand: `{ authToken }` now expands to `{ token: authToken }`
  (was printing a bare `{ token }`, referencing a nonexistent binding).
- execute→run: adds a TODO noting the argv tokens are raw v3 CLI args that may
  need remapping to v4 command names (releases→release, new→create, …).
- shim: multiple `--header` flags now merge into one semicolon-separated
  SENTRY_CUSTOM_HEADERS (v4's expected format) instead of overwriting.

+2 codemod tests (16 total).
@BYK

BYK commented Jul 7, 2026

Copy link
Copy Markdown
Member Author

Latest Bugbot review — all three addressed in e42fc0073:

  • Execute rewrite keeps broken argv — the execute()run() rewrite now emits a // TODO(sentry-v4) noting the argv tokens are raw v3 CLI args that may need remapping to v4 command names (releasesrelease, newcreate, loginauth login, …). The codemod can't reliably remap arbitrary argv arrays, so it flags rather than guesses.
  • authToken shorthand key rename{ authToken } shorthand now expands to { token: authToken } (keeps referencing the original binding) instead of printing a bare { token }.
  • Shim drops repeated headers — the shim now merges multiple --header flags into one semicolon-separated SENTRY_CUSTOM_HEADERS (X-A: 1; X-B: 2), which is v4's expected format, instead of overwriting.

Codemod tests: 16, all green.

Comment thread docs/src/content/docs/migrating-from-v3.md Outdated
Comment thread codemods/sentry-v3-to-v4.cjs Outdated
Comment thread codemods/sentry-v3-to-v4.cjs Outdated
Make the flag documentation accurate and complete against the v4 command surface
(verified from the generated SDK):

- Sourcemaps: list the flags v4 `sourcemap upload` keeps vs. the full set of v3
  flags that are NOT present (added --note, --wait-for, --debug-id-reference);
  note `sourcemap inject` also drops --release and takes a single <directory>.
- Global-flags caution: call out notable per-command drops — `release
  set-commits --ignore-missing` and `release deploy` env/name being positional.
Comment thread codemods/sentry-v3-to-v4.cjs Outdated
Comment thread codemods/sentry-v3-to-v4.cjs Outdated
sentry[bot]: in the 2+ arg constructor branch, a `null`/`undefined` second
argument was assigned to `options` (a truthy AST node), so the codemod emitted
a misleading "update authToken" TODO. Now `new SentryCli(cfg, null)` → `X()`
with no options and no TODO, mirroring the single-arg null handling. Adds a
fixture (18 total).
@BYK

BYK commented Jul 13, 2026

Copy link
Copy Markdown
Member Author
  • Incorrect TODO on new SentryCli(cfg, null) (sentry[bot], codemod.ts:171) — fixed. A null/undefined second arg was being assigned to options (a truthy AST node), triggering a bogus authToken TODO. Now both the configFile and the null options are dropped → SentryCli() with no TODO. Added a fixture (18 total).

The three Cursor findings still showing (codemod.ts:49 spread, docs deploy-env-flags, docs --url) are the same persistent threads from earlier commits, re-associated with each push — they were already addressed (newDeploy has no spread; deploys new prints the new syntax + returns instead of forwarding flags; --url is only translated in the leading global-flag run). Verified via the committed fixtures and a functional shim test.

Comment thread docs/src/content/docs/migrating-from-v3.md
Cursor Bugbot (High): the leading-flag loop broke on any unrecognized token,
including still-valid v4 globals (`--org`/`--project`/`--log-level`/`--fields`/
`-v`/`--json`). If one preceded `--auth-token`/`--url`/`--header`, translation
never ran and the removed flags were forwarded to `sentry`.

Now those globals are consumed (with their values) into a `lead` prefix that is
re-applied before the translated command, so env-flag translation still runs and
scanning stops only at the real command word. Command-level `--url` stays
untouched. Verified with a functional harness (leading `--org` + `--auth-token`;
global vs command `--url`; `--log-level` + `releases new`).
@BYK

BYK commented Jul 13, 2026

Copy link
Copy Markdown
Member Author
  • Shim drops leading global flags (High) — fixed. The leading-flag loop now recognizes the still-valid v4 globals (--org/--project/--log-level/--fields/-v/--json) and consumes them (with their values) into a lead prefix that's re-applied before the translated command. So --auth-token/--url/--header are still translated even when another global precedes them, and scanning stops only at the real command word.

Verified with a functional harness:

  • --org acme --auth-token X releases listSENTRY_AUTH_TOKEN=X + sentry --org acme release list
  • --url https://self releases listSENTRY_URL=… + sentry release list
  • --auth-token X foo --url http://ySENTRY_AUTH_TOKEN=X + sentry foo --url http://y (command-level --url preserved)
  • --log-level debug releases new 1.0.0sentry --log-level debug release new 1.0.0

Comment thread docs/src/content/docs/migrating-from-v3.md Outdated
…ass env)

Cursor Bugbot (High): the SDK's typed `release.deploy` collapses
version/environment/name into a single `orgVersionEnvironmentName` positional and
forwards it as one argv token, so it can't supply the required `<environment>` —
`deploy({ orgVersionEnvironmentName: "1.0.0" })` fails at runtime with a
missing-environment error.

Both the codemod and guide now migrate `newDeploy` to the raw `run(...)` escape
hatch instead: the codemod emits `sdk.run("release", "deploy", <version>)` with a
TODO to add the environment/name positionals + url/started/finished/time flags;
the guide row shows `sdk.run("release", "deploy", v, env, name, "--url", url)`.
@BYK

BYK commented Jul 13, 2026

Copy link
Copy Markdown
Member Author
  • Broken deploy SDK migration (High) — fixed. You're right: the typed sdk.release.deploy collapses version/environment/name into a single orgVersionEnvironmentName positional and forwards it as one argv token (invoke([...], {...}, [params.orgVersionEnvironmentName])), so it can't supply the required <environment> — the call fails at runtime.

    Both the codemod and guide now use the raw run(...) escape hatch for deploys:

    • Codemod: cli.releases.newDeploy("1.0.0", {...})cli.run("release", "deploy", "1.0.0") + a TODO to add the <environment>/[name] positionals and --url/--started/--finished/--time flags.
    • Guide row: sdk.run("release", "deploy", v, env, name, "--url", url).

Comment thread docs/src/content/docs/migrating-from-v3.md
Comment thread docs/src/content/docs/migrating-from-v3.md
Comment thread codemods/sentry-v3-to-v4/scripts/codemod.ts
…ploys

Three findings:
- Codemod (High, sentry[bot]): `uploadSourceMaps` no longer spreads the v3
  options — `include` is a path array but v4 `sourcemap.upload` takes a single
  `directory` string, so spreading emitted an invalid `include` key. Now emits
  `sourcemap.upload({ release })` + a TODO to set `directory`.
- Shim (High): value-taking leading flags used `shift 2`, which hangs the shell
  when the value is missing (bash leaves `$#` unchanged). Now `shift 2 2>/dev/null
  || shift` — verified value-less `--org`/`--auth-token` no longer loop.
- Shim (High): v3 nested deploys under `releases`, so `releases deploys …` fell
  through to `release deploys …` with invalid v3 subcommands/flags. Both the
  top-level `deploys` and `releases deploys` now surface the manual-migration
  note (create uses positional environment/name in v4).
@BYK

BYK commented Jul 13, 2026

Copy link
Copy Markdown
Member Author

Three more, all fixed:

  • uploadSourceMaps fails to rename include→directory (High, sentry[bot]) — the codemod no longer spreads the v3 options. include is a path array but v4 sourcemap.upload takes a single directory string, so spreading emitted an invalid include key. Now emits sdk.sourcemap.upload({ release }) + a TODO to set directory (one upload per directory).
  • Shim loops on bare flags (High) — value-taking leading flags used shift 2, which hangs the shell when the value is missing. Changed to shift 2 2>/dev/null || shift; verified value-less --org/--auth-token complete instead of looping.
  • Shim breaks releases deploys (High) — v3 nested deploys under releases, so releases deploys … fell through to release deploys … with invalid v3 subcommands/flags. Both top-level deploys and releases deploys now print the manual-migration note (v4 create uses positional environment/name). Verified releases deploys 1.0.0 new -e prod → note + exit 64.

Comment thread docs/src/content/docs/migrating-from-v3.md Outdated
…igration

Cursor Bugbot: the blanket deploy rejection also refused `deploys`/`deploys list`
(and `releases deploys … list`), which map cleanly to `release deploys`. A small
`_scli_deploys` helper (reused by the top-level `deploys` and nested `releases
deploys` paths) now drops a trailing v3 `list` and runs `release deploys`; only
an invocation containing `new` (create — env/name became positionals) prints the
manual-migration note. Verified list/create for both paths.
@BYK

BYK commented Jul 13, 2026

Copy link
Copy Markdown
Member Author
  • Shim rejects listable deploys (Medium) — fixed. A small _scli_deploys helper (shared by the top-level deploys and nested releases deploys paths) now maps bare/list to sentry release deploys (dropping the v3 list token); only an invocation containing new prints the manual-migration note. Verified:
    • deploys 1.0.0 list / releases deploys 1.0.0 listsentry release deploys 1.0.0
    • deploys 1.0.0 new -e prod / releases deploys 1.0.0 new … → note + exit 64
    • releases listsentry release list; value-less --org no longer hangs

BYK added a commit that referenced this pull request Jul 14, 2026
…1202)

## Problem

The `sentry docs` PR-preview link was returning **404** for new PRs
(e.g. #1201), while older previews still worked. Root cause:

- `docs-preview.yml` triggered on `pull_request` `[opened, synchronize,
reopened]` — **never `closed`** — so `rossjrw/pr-preview-action`'s
auto-cleanup never ran.
- **46 stale previews** (each a full copy of the docs site) accumulated
in `gh-pages`, pushing the **GitHub Pages build over its size/time
limits**. Builds started failing intermittently (`Page build failed`),
so newly-deployed previews 404'd while previously-published ones kept
serving.

## Fix (pattern ported from `getsentry/loreai`)

**`docs-preview.yml`**
- Add `closed` to the `pull_request` types and **remove the
`pull_request` paths filter** — a `closed` event must always fire so the
preview can be removed.
- A `dorny/paths-filter` step + a central **`gate`** step decide:
- `build` → push, or a docs PR being opened/updated (fork PRs still
build to surface compile errors).
- `deploy` → build, **or any `closed` event** (cleanup), never for fork
PRs.
- On close, `pr-preview-action` `action: auto` **removes** the preview —
the actual cleanup that was missing.

**`cleanup-doc-previews.yml` (new)**
- Weekly (`cron`) + `workflow_dispatch` **safety net**: sweeps
`gh-pages` for `_preview/pr-<n>` dirs whose PR is no longer `OPEN` and
removes them. Uses a **blobless, no-checkout clone + index rewrite**, so
it never downloads the (large) preview file contents. Catches anything
the on-close path misses (e.g. PRs closed while the workflow was broken
— exactly how we got here).

## Already done out-of-band
The 46 already-stale previews were pruned from `gh-pages` directly
(blobless index rewrite) to **unblock the failing Pages build
immediately** — previews now serve again (verified `pr-1201` → 200).
This PR prevents recurrence.

## Validation
- Both workflows: valid YAML; `actionlint` clean (only a pre-existing
SC2088 on the unchanged `--url-prefix "~/"` line, a deliberate Sentry
URL prefix).
- Gate logic walked through for push / docs-PR open+sync / non-docs PR /
close / fork / fork-close.
Independent flag-compat review found real gaps beyond the common path:

- Shim + guide: v3 `--allow-failure` / `SENTRY_ALLOW_FAILURE` (made any command
  exit 0) is not implemented in v4 and would be rejected as unknown. The shim now
  strips it and emulates the old "never fail" behavior; the Dropped section
  documents it. Verified: failing command → rc=3 normally, rc=0 with the
  flag/env; flag is not forwarded to `sentry`.
- Codemod: the constructor now emits a TODO for v3 `SentryCliOptions` with no v4
  equivalent (apiKey, url, dsn, silent, customHeader, headers, org, project,
  vcsRemote) — previously `apiKey` (auth-critical) was dropped silently. Added a
  `constructor-apikey` fixture (19 total).
- Codemod: `setCommits` TODO now names the actually-dropped `ignoreMissing`/
  `ignoreEmpty` keys instead of a generic hint.
- Guide Dropped section: added `--silent` (alias of `--quiet`), `set-commits`
  `--ignore-empty`, `SENTRY_API_KEY`/`SENTRY_VCS_REMOTE` no longer honored, and
  the self-hosted-only note for `SENTRY_CUSTOM_HEADERS`.
@BYK

BYK commented Jul 14, 2026

Copy link
Copy Markdown
Member Author

Ran an independent flag-compatibility review pass. The common path (--auth-token/--url/--header → env vars, dual-meaning command-level --url, shim parsing, sourcemap flag deltas) all verified correct. Fixed the real gaps it surfaced:

  • --allow-failure / SENTRY_ALLOW_FAILURE (v3 global that forced exit 0) — not implemented in v4, so the shim would have passed it through and errored. The shim now strips it and emulates the old "never fail" behavior, and the Dropped section documents it. Verified: failing cmd → rc=3 normally, rc=0 with the flag/env, and it's never forwarded to sentry.
  • Codemod constructor — v3 SentryCliOptions beyond authToken (esp. auth-critical apiKey, plus url/dsn/silent/customHeader/org/project/vcsRemote) were passed through silently. Now flagged with a TODO. Added a fixture (19 total).
  • setCommits TODO now names the actually-dropped ignoreMissing/ignoreEmpty keys.
  • Guide Dropped section — added --silent, set-commits --ignore-empty, SENTRY_API_KEY/SENTRY_VCS_REMOTE no-longer-honored, and the self-hosted-only note for SENTRY_CUSTOM_HEADERS.

Comment thread .github/workflows/ci.yml
Comment thread codemods/sentry-v3-to-v4/scripts/codemod.ts
… `live`

Two sentry[bot] findings:
- CI (High): `ci-status` didn't include `codemod-test` in `needs`/result checks,
  so a codemod-test failure wouldn't block merge — defeating the job. Added it to
  `needs`, the failure/cancel result scan, and the skipped-cascade guard (using
  the existing `changes.outputs.codemod` filter).
- Codemod (Medium): the `execute(args, live)` → `run(...args)` transform dropped
  the `live` arg silently. (The bot framed it as dry-run→live, but v3 `live`
  actually controls output handling, not execution — verified in @sentry/cli
  helper.js: `live:true`/`'rejectOnError'` inherit stdio, `live:false`/absent
  capture+return stdout.) v4 `run()` always captures/returns output, so the TODO
  now calls out the dropped `live` and the streamed-stdio behavior change.
@BYK

BYK commented Jul 14, 2026

Copy link
Copy Markdown
Member Author

Two more findings addressed:

  • ci-status didn't gate on codemod-test (High) — fixed. Added codemod-test to the ci-status needs array, the failure/cancel result scan, and a skipped-cascade guard (mirroring the code/skill checks, using the existing changes.outputs.codemod filter). A codemod-test failure now blocks merge.
  • execute(args, live)run(...) drops live (Medium) — the TODO now calls this out. One correction: live isn't a dry-run toggle — in @sentry/cli's helper.js, live:true/'rejectOnError' inherit stdio (stream output), while live:false/absent captures and returns stdout. v4 run() always captures/returns (the live:false behavior), so the TODO notes that callers who passed live:true/'rejectOnError' for streamed stdio should adjust. No behavior is silently changed toward "live" — if anything it matches v3's default.

Comment thread docs/src/content/docs/migrating-from-v3.md
Comment thread codemods/sentry-v3-to-v4/scripts/codemod.ts Outdated
Two more findings:
- Shim (High): bare plurals only mapped to `list` when zero args remained, so
  `sentry-cli projects --json` became `project --json` → `project`'s default
  `view` (not `list`), and `releases --json` dropped the subcommand. Now a
  remaining leading flag (or no args) still inserts `list` and forwards the
  flags. Verified `projects --json` → `project list --json`, `projects list
  --json` stays single-`list`, and subcommands (`new`/`view`) still route.
- Codemod (Medium): CJS binding detection missed `const X =
  require("@sentry/cli").default` — the require's parent is a member_expression,
  not the declarator, so the file was skipped. Now walks up through the member
  expression to the declarator. Added a `require-default` fixture (20 total).

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

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 is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 44c8a84. Configure here.

Comment thread codemods/sentry-v3-to-v4/scripts/codemod.ts
Comment thread codemods/sentry-v3-to-v4/scripts/codemod.ts Outdated
Cursor Bugbot (Medium): the constructor TODO wrongly listed `url`/`org`/`project`
as having no v4 equivalent — they're first-class `SentryOptions` keys
(sdk-types.ts), so the hint could push users to strip working options. Narrowed
the unmapped set to the keys that genuinely need attention: apiKey (→ token),
dsn (→ SENTRY_DSN), silent/customHeader/headers/vcsRemote (dropped). The
`{ token, org }` fixture now emits no TODO; the apiKey/silent fixture keeps it.
@BYK

BYK commented Jul 14, 2026

Copy link
Copy Markdown
Member Author
  • Codemod mislabels valid SDK options (Medium) — fixed. token/url/org/project are first-class SentryOptions keys, so I narrowed the constructor TODO to only the genuinely-unmapped v3 keys: apiKey (→ token), dsn (→ SENTRY_DSN), and silent/customHeader/headers/vcsRemote (dropped). new SentryCli(null, { authToken, org }) now migrates cleanly with no TODO; only unmapped keys are flagged.

Sentry bot (High): `import * as X from "@sentry/cli"; new X.default()` wasn't
recognized as a constructor (the filter only matched bare `bindings.has(c.text())`,
never a `member_expression`), so the file was left partially migrated. Namespace
import names are now tracked separately (`nsBindings`) and the constructor filter
also accepts `new <ns>.default(...)`. The existing `new ` drop preserves the
`X.default` callee. Added a `namespace-default` fixture (21 total).
@BYK

BYK commented Jul 14, 2026

Copy link
Copy Markdown
Member Author
  • new X.default() namespace imports not migrated (High) — fixed. Namespace-import names (import * as X from "@sentry/cli") are now tracked separately, and the constructor detection also matches new X.default(...) (where X.default is the v3 class). import * as Sentry + new Sentry.default({ authToken }) now migrates fully to Sentry.default({ token }) with executerun. Added a namespace-default fixture.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk: high PR risk score: high

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants