Dashboard › cli › Distillation
5199d6ef-4b75-480f-bd22-cf7fc8a00077["lore_tm_v1_JT_H5nKfCuFjMgz7GAkGGyPD0lYctYE_LxxaJlh2YX4","lore_tm_v1_es4uaY_JvxOAZNJJgQQt7_tHGuWrXZCTIFvS8I52_QA","lore_tm_v1_C-9jZ_ZQcBLyQJyMAZwzTIRXVUEoxQiG1dBpVF7SosU","lore_tm_v1_icfGzQDoZGmqGYPiuoIAwKN8b-K6wKBofxDDcY4sWOE","lore_tm_v1_QYef-fgUHnUQKzZlqnpohUb9_XIUhDEJMmiM_VDsNUE","lore_tm_v1_xEhVdi6P16zaDqR8yZWnG857btBtLBKo8cqCnLpjHc8"]
packages/cli/src/lib/upgrade.ts lines 433–454 define fetchLatestFromGitHubWithSource(signal?, sources = UPGRADE_SOURCES): Promise<ResolvedUpgradeVersion>: it calls resolveUpgradeSource({ getProbeUrl: getGitHubLatestReleaseUrl, signal, sources }), parses the successful response with extractReleaseVersions(data, source), strips VERSION_PREFIX_REGEX from the first tag, throws UpgradeError("network_error", "No version found in GitHub release") when absent, and returns { version, source }.fetchLatestFromGitHub(signal?, source?) in packages/cli/src/lib/upgrade.ts returns only the version from fetchLatestFromGitHubWithSource; an explicit source is wrapped as [source], otherwise it uses UPGRADE_SOURCES.fetchLatestFromNpm() requests ${NPM_REGISTRY_URL}/latest with Accept: "application/json" through fetchWithUpgradeError(..., "npm registry"); non-OK responses throw UpgradeError("network_error", \Failed to fetch from npm: ${response.status}`), a missing data.versionthrows"No version found in npm registry", and success returns data.version`.fetchLatestNightlyVersionWithSource(signal?, sources = UPGRADE_SOURCES) throws AbortError if already aborted, resolves the rolling "nightly" manifest through resolveNightlyManifest(), extracts its version with getNightlyVersion(resolved.manifest), and returns that version together with the selected source.resolveNightlyManifest(tag, signal, sources) probes each source’s GitHub repository via resolveUpgradeSource({ getProbeUrl: getGitHubRepositoryUrl, signal, sources: [source] }), advances only when the source is not found, then calls getAnonymousToken(source, signal) and fetchManifest(token, tag, signal, source). A manifest error containing tag "${tag}": HTTP 404 advances to the next source; other errors abort. Exhaustion throws UpgradeError("network_error", "No CLI upgrade source was found: every source returned HTTP 404").isUpgradeSourceNotFound(error) recognizes an UpgradeError whose message includes "every source returned HTTP 404".fetchLatestNightlyVersion(signal?, source?) returns only the version from fetchLatestNightlyVersionWithSource; an explicit source is wrapped as [source], preventing fallback to other sources.fetchLatestVersion(method, channel = "stable") selects fetchLatestNightlyVersion() for the nightly channel, fetchLatestFromGitHub() for stable "curl" or "brew", and fetchLatestFromNpm() for other stable installation methods.resolveLatestUpgradeVersion(channel, signal?) returns a source-bearing resolution: nightly uses fetchLatestNightlyVersionWithSource(signal) and stable uses fetchLatestFromGitHubWithSource(signal).resolveExistingUpgradeVersion(version) validates pinned standalone versions against ordered sources. Nightlies resolve the GHCR tag nightly-${version} through resolveNightlyManifest(..., UPGRADE_SOURCES); stable versions probe getGitHubReleaseByTagUrl(version, source). It returns { version, source }, returns null only when every source is not found, and rethrows other failures.packages/cli/src/lib/binary.ts defines InstallationMethod as "curl" | "brew" | "npm" | "pnpm" | "bun" | "yarn" | "unknown" and places it beside installation constants to avoid a circular dependency between upgrade.ts and db/install-info.ts.UpgradeSource has readonly githubRepo, ghcrRepo, and tagPrefix. Ordered UPGRADE_SOURCES contains: 1. { githubRepo: "getsentry/toolkit", ghcrRepo: "getsentry/toolkit", tagPrefix: "cli@" }; 2. { githubRepo: "getsentry/cli", ghcrRepo: "getsentry/cli", tagPrefix: "" }. PRIMARY_UPGRADE_SOURCE = UPGRADE_SOURCES[0].parseInstallationMethod(value) lowercases input and accepts "curl", "brew", "npm", "pnpm", "bun", and "yarn"; invalid input throws Invalid method: ${value}. Must be one of: ${VALID_METHODS.join(", ")}.isMusl() in packages/cli/src/lib/binary.ts returns false off Linux and caches its Linux result. Detection order is: 1. check /lib/ld-musl-${muslArch}.so.1, where x64 maps to x86_64 and other supported architecture maps to aarch64; 2. run ldd --version, concatenate stdout and stderr, and search case-insensitively for "musl". If ldd fails or is absent, it assumes glibc and caches false.getPlatformBinaryName() builds sentry-<os>-<arch>[-musl][.exe]: OS is darwin, windows, or linux; architecture is arm64 only when process.arch === "arm64", otherwise x64; musl adds -musl; Windows adds .exe.getBinaryDownloadUrl(version, source = PRIMARY_UPGRADE_SOURCE) produces https://github.com/${source.githubRepo}/releases/download/${source.tagPrefix}${version}/${getPlatformBinaryName()}.packages/cli/src/lib/binary.ts are source-aware: getGitHubReleasesUrl() returns https://api.github.com/repos/${source.githubRepo}/releases; getGitHubReleaseByTagUrl() appends /tags/${encodeURIComponent(source.tagPrefix + version)}; getGitHubLatestReleaseUrl() uses ?per_page=100 for prefixed repositories and /latest for unprefixed repositories; getGitHubRepositoryUrl() returns https://api.github.com/repos/${source.githubRepo}.ResolveUpgradeSourceOptions accepts getProbeUrl(source), optional fetch defaulting to customFetch, optional shared signal, and optional ordered sources defaulting to UPGRADE_SOURCES.fetchUpgradeProbe(source, options) sends getGitHubHeaders() and options.signal. It preserves an error named "AbortError", maps TLS certificate errors to UpgradeError("network_error", buildTlsErrorDetail(error)), and maps other fetch failures to UpgradeError("network_error", \Failed to connect to GitHub: ${stringifyUnknown(error)}`)`.resolveUpgradeSource() returns the successful probe response so the caller never repeats the request.resolveUpgradeSource(options) probes sources in order, returns { source, response } on the first response.ok, advances only on HTTP 404, aborts other HTTP statuses with UpgradeError("network_error", \Failed to fetch from GitHub: HTTP ${response.status}`), and throws "No CLI upgrade source was found: every source returned HTTP 404"` if all sources return 404.isNightlyVersion(version) identifies nightlies using version.includes("-dev."); compareVersions(a, b) delegates to semverCompare() and returns -1 | 0 | 1; isDowngrade(current, target) is true when compareVersions(current, target) === 1.packages/cli/package.json lines 95–122 list dependencies/dev dependencies: "@sentry/api": "^0.256.0", "@sentry/core": "10.63.0", "@sentry/node": "10.65.0", "@sentry/node-core": "10.63.0", "@sentry/sqlish": "^1.0.1", "@sentry/symbolic": "13.7.0", "@spotlightjs/spotlight": "^4.11.7", "@stricli/auto-complete": "^1.2.8", "@stricli/core": "1.2.8", "@types/http-cache-semantics": "^4.2.0", "@types/node": "^22.20.0", "@types/picomatch": "^4.0.3", "@types/pngjs": "^6.0.5", "@types/qrcode-terminal": "^0.12.2", "@types/react": "^19.2.17", "@types/semver": "^7.7.1", "@vitest/coverage-v8": "^4.1.9", "binpatch": "^0.4.2", "chalk": "^5.6.2", "cli-highlight": "^2.1.11", "consola": "^3.4.2", "esbuild": "^0.28.1", "fast-check": "^4.8.0", "fflate": "^0.8.3", "fossilize": "^0.10.1", "hono": "^4.12.34", "http-cache-semantics": "^4.2.0", and "ignore": "^7.0.5".packages/cli/src/lib/delta-upgrade.ts was changed from hard-coded GITHUB_RELEASES_URL and GHCR_REPO usage to source-aware getGitHubReleasesUrl, PRIMARY_UPGRADE_SOURCE, and UpgradeSource.getPrimaryUpgradeSource() was added to packages/cli/src/lib/delta-upgrade.ts; it returns PRIMARY_UPGRADE_SOURCE and throws Error("No primary upgrade source is configured") if absent.stableSource(source) passes getGitHubReleasesUrl(source) to githubReleaseSource, while nightlySource(source) passes source.ghcrRepo to ghcrSource.fetchRecentReleases(signal?, source = getPrimaryUpgradeSource()) now requests ${getGitHubReleasesUrl(source)}?per_page=12 with Accept: "application/vnd.github.v3+json" and User-Agent: sentry-cli/${CLI_VERSION}.packages/cli/src/lib/delta-upgrade.ts: resolveStableChain(..., source = getPrimaryUpgradeSource()), optional source in resolveNightlyChain(opts), resolveStableDelta(..., source = getPrimaryUpgradeSource()), resolveNightlyDelta(..., source = getPrimaryUpgradeSource()), attemptDeltaUpgrade(..., source = getPrimaryUpgradeSource()), prefetchNightlyPatches(..., source = getPrimaryUpgradeSource()), and prefetchStablePatches(..., source = getPrimaryUpgradeSource()).resolveNightlyChain(opts) now constructs OciClient with repo: source.ghcrRepo rather than the former global GHCR_REPO; attemptDeltaUpgrade() chooses nightlySource(source) or stableSource(source) and therefore keeps all chain resolution and patch requests on the selected release source.packages/cli/test/lib/delta-upgrade.test.ts changed the default fetchRecentReleases() expectation from api.github.com/repos/getsentry/cli/releases to api.github.com/repos/getsentry/toolkit/releases, reflecting Toolkit as the primary source.fetchRecentReleases(undefined, LEGACY_UPGRADE_SOURCE) test expects exactly https://api.github.com/repos/getsentry/cli/releases?per_page=12.resolveStableChain("0.13.0", "0.14.0", undefined, LEGACY_UPGRADE_SOURCE) test returns null on HTTP 404, requests exactly https://api.github.com/repos/getsentry/cli/releases?per_page=12, and verifies no URL contains getsentry/toolkit.resolveNightlyChain() legacy-source test uses token "test-token", current version "0.0.0-dev.100", target version "0.0.0-dev.101", fullGzSize: 100_000, and source: LEGACY_UPGRADE_SOURCE; it returns null for an empty tag list and requests exactly https://ghcr.io/v2/getsentry/cli/tags/list?n=100, never getsentry/toolkit.