Dashboard › cli › Distillation
6d012524-c39a-40ee-86d2-9da074027413["lore_tm_v1_IiUXahyfXjh-x-95f3a3-lu3hwdRT8ohDtGWYkPmAl0","lore_tm_v1_BTMSxGrWjCNW_eiyTuHUHDgwLw0PspAh7ETO8ZYqFoM","lore_tm_v1_qQSTDLgieoEQBizs5cHkM_HtGmcCOMbI6erFBG6AcRo","lore_tm_v1_8vOBJckNjCj15gbdoBb56xwIfDrnEQ0YCoM-F0m2DRg","lore_tm_v1_DdBQG1RP5m6qPPQJHwMEbO-NmBA6WlHYZG8QBW8N9_A"]
packages/cli/src/commands/cli/setup.ts:485-525: detectShell(env.SHELL, homeDir, env.XDG_CONFIG_HOME) runs first; when flags.method exists, bestEffort("Recording installation info", ...) calls setInstallInfo({ method, path: binaryPath, version: CLI_VERSION }) and emits Recorded installation method: ${method} only when !flags.install; when flags.channel exists, bestEffort("Recording release channel", ...) calls setReleaseChannel(channel) and emits Recorded release channel: ${channel} only when !flags.install; PATH modification proceeds unless flags["no-modify-path"].packages/cli/src/commands/cli/upgrade.ts:1023-1094: destructures { target, offline, source }; starts startChangelogFetch({ channel, currentVersion: CLI_VERSION, targetVersion: target, offline, source }) before download; an offline-fallback --check still yields kind: "target" and is guarded by flags.check, which calls buildCheckResultWithChangelog() with target, versionArg, method, channel, flags, offline, and changelogPromise.packages/cli/src/commands/cli/upgrade.ts:1050-1092: an upgrade is skipped only when CLI_VERSION === target && !flags.force && !channelChanged, returning action: "up-to-date", current/target versions, channel, method, forced: false, and optional offline: true; isDowngrade(CLI_VERSION, target) selects Downgrading versus Upgrading debug output; isNightlyVersion(target) && method !== "curl" routes through migrateToStandaloneForNightly(), otherwise executeStandardUpgrade().packages/cli/src/commands/cli/upgrade.ts:1067-1077: migrateToStandaloneForNightly({ method, target, versionArg, noAgentSkills: flags["no-agent-skills"], json: flags.json, source }).packages/cli/src/commands/cli/upgrade.ts:1078-1091: executeStandardUpgrade({ method, channel, versionArg, target, execPath: this.process.execPath, entryPath: this.process.argv?.[1], pathEnv: this.process.env.PATH, offline, json: flags.json, noAgentSkills: flags["no-agent-skills"], source }).resolveContext() in packages/cli/src/commands/cli/upgrade.ts:836-852: resolveChannelAndVersion(version) supplies channel and versionArg; currentChannel = getReleaseChannel(); channelChanged = channel !== currentChannel; the method is flags.method ?? (await detectInstallationMethod()); validateMethod(method, versionArg, channel, flags.offline) runs before returning { channel, versionArg, channelChanged, method }.persistChannel() in packages/cli/src/commands/cli/upgrade.ts:854-868: it must run after offline target resolution because setReleaseChannel() clears the version-check cache on channel changes and could prevent resolveOfflineTarget() reading cached data; it persists when channelChanged || CHANNEL_VERSIONS.has(version ?? "").packages/cli/src/commands/cli/upgrade.ts:870-875: startChangelogFetch() is best-effort, runs in parallel with binary download, resolves to a changelog or undefined, and swallows errors so changelog failure never blocks upgrade.packages/cli/src/lib/upgrade.ts:605-632: customFetch(\${getGitHubReleasesUrl(source)}?per_page=${CHANGELOG_MAX_RELEASES}`, { headers: getGitHubHeaders() }); transport errors log Failed to fetch releases for changelogand return[]; non-OK responses return []; JSON parse failures log Non-JSON response from GitHub releasesand return[]; non-array JSON logs GitHub releases response is not an arraywithtypeof dataand returns[]; valid arrays are passed to normalizeChangelogReleases(data as GitHubRelease[], source, false)`.fetchStableChangelog() in packages/cli/src/lib/upgrade.ts:634-660: accepts optional prefetchedReleases to avoid a duplicate API request from the delta-upgrade path; otherwise calls fetchReleasesForChangelog(source) with a larger per_page for wider version jumps; prefetched data is normalized via normalizeChangelogReleases(prefetchedReleases, source, true); empty releases return null; otherwise it calls buildChangelogSummaryForSource(releases, fromVersion, toVersion, { maxItems, source }).packages/cli/src/lib/upgrade.ts:662-685: buildNightlyChangelogSummary(commits, fromVersion, toVersion, maxItems?) calls parseCommitMessages(commits) then buildSummaryFromSections(sections, fromVersion, toVersion, maxItems); nightly changelogs use the GitHub Commits API because versions encode a Unix timestamp in the prerelease identifier X.Y.Z-dev.<unix-seconds>, allowing timestamp-based listing without git tags.downloadBinaryToTemp() in packages/cli/src/lib/upgrade.ts:1160-1249: signature is downloadBinaryToTemp(version: string, downloadTag?: string, offline?: OfflineMode, setMessage?: SetMessage, source: UpgradeSource = PRIMARY_UPGRADE_SOURCE): Promise<DownloadResult>; downloadTag defaults conceptually to version, while NIGHTLY_TAG ("nightly") targets rolling prerelease assets; the compatibility API has a biome-ignore lint/nursery/useMaxParams because source preserves one selected repository across the download.getCurlInstallPaths() supplies tempPath and lockPath; acquireLock(lockPath) runs before work; leftover tempPath is removed with unlinkSync(tempPath) under a grandfathered silent catch associated with #1531; any outer failure calls releaseLock(lockPath) and rethrows.downloadBinaryToTemp(): tryDeltaUpgrade(version, tempPath, !!offline, setMessage, source) runs first; a successful result preserves deltaResult.patchBytes; if no delta exists in offline mode, explicit offline throws UpgradeError("offline_cache_miss", "Cannot upgrade to ${version} in offline mode β no pre-downloaded update is available. Run \sentry cli upgrade` without `--offline` to download the update directly."), while implicit network fallback throws UpgradeError("offline_cache_miss", "Cannot upgrade to ${version} β the network is unavailable and no pre-downloaded update was found. Check your internet connection and try again."); online fallback logs Downloading full binaryand callsdownloadFullBinary(version, downloadTag, tempPath, setMessage, source)`.packages/cli/src/lib/upgrade.ts:1222-1230: on Windows with Bun 1.3.9 (CLI-1D3), Bun.file(path).writer() may return before the file is visible by path, causing Bun.spawn to fail with Executable not found in $PATH: "...sentry.exe.download"; waitForBinaryVisible(tempPath) polls with exponential backoff and the verified size is logged as Binary verified (${formatBytes(verifiedSize)}).clearPatchCache() is best-effort because patches based on the old binary are useless after either delta or full update; on non-Windows platforms chmodSync(tempPath, 0o755) sets executable permission; return value is { tempBinaryPath: tempPath, lockPath, patchBytes }.packages/cli/src/commands/cli/upgrade.ts:1094-1106: after const changelog = await changelogPromise, output includes action: downgrade ? "downgraded" : "upgraded", currentVersion: CLI_VERSION, targetVersion: target, channel, method, forced: flags.force, optional offline: true, warnings, and changelog.e565b1afb39a341605adc883de8812851de7d581: packages/cli/src/lib/upgrade.ts:1309 documents brew upgrade getsentry/tools/sentry; executeUpgradeHomebrew() begins at line 1316 and can throw brew upgrade failed with exit code ${code} at line 1330; it is invoked at line 1426.packages/cli/src/commands/cli/upgrade.ts:256-262, Homebrew pins are classified using persisted channel, so persisted stable rejects an exact nightly such as 0.99.0-dev.123 before target-based standalone routing at :1067-1077; persisted nightly permits an exact stable pin, :331-333 validates through standalone GitHub, but :1078-1091 retains Homebrew and packages/cli/src/lib/upgrade.ts:1309-1318,1425-1427 runs unpinned brew upgrade getsentry/tools/sentry; output at commands/cli/upgrade.ts:1094-1100 can then claim the requested pin.lookupMethod using isNightlyVersion(target) rather than channel === "nightly".upgrade --method brew 0.99.0-dev.123, assert GHCR resolution and standalone installation, and assert brew is never spawned. 2. Persist nightly, invoke upgrade --method brew 1.2.3, and assert unsupported_operation before any fetch or spawn. 3. Persist nightly, invoke an npm stable pin, and assert validation uses the exact npm endpoint rather than GitHub.packages/cli/src/commands/cli/upgrade.ts:836-851; persistChannel() at :860-867 only persists explicit nightly/stable selectors; nevertheless pinned-nightly migration passes channel: "nightly" to setup at :796-805, and setup persists it at packages/cli/src/commands/cli/setup.ts:507-518; the invocation still uses the old channel for changelog at commands/cli/upgrade.ts:1025-1032 and result output at :1094-1100.packages/cli/test/commands/cli/upgrade.test.ts:1128-1199 tests npm migration output but does not assert persisted channel, result channel, or changelog endpoint.src/lib/upgrade.ts:118-137.src/lib/upgrade.ts:696-740.404 advances source selection; transport, TLS, authorization, rate-limit, malformed-success, and all other HTTP failures terminate selection.src/lib/delta-upgrade.ts:450-469; the verified source-neutral cache and repository probe match the intended design.c3d7791d84ebb5ad57a949129d66f9147973d239432b7695c3f1d034a1956351, and all 16 changed source and test paths were inspected. Tests were not executed because doing so would require working-tree contents rather than immutable Git objects.DO-NOT-MERGE.