Dashboard › cli › Distillation
aa9a2e54-589e-4ab1-bca7-30a4affd0c6a["lore_tm_v1_tn_a0fxf3J0tdJu9XGInye6sncTZCIofy_uMQgJbxI8","lore_tm_v1__50S9iwskdXG7jILH6wHMxOnlaM1WCpduveskQby5t4","lore_tm_v1_gNLbkjpL5gPTEf02Pq22X0QdM8xZuXFSYyjRDXNfhAc","lore_tm_v1_EiGMsUC5rNRA2f2rEbsmc_Sz63L7-4u3o0ETlh98Ql8","lore_tm_v1_9eIFVIVftROYk1DBZ2SMYAG2bmqqkE6LdJK1swp9wWo","lore_tm_v1_0NTKVhVaj7s5sGJ9ISfIrVqZUieUt_TIO9aSWCbKeVY","lore_tm_v1_I5lFf9fa87GvdjAF3E3xLMIQh-wpLW1Wacby230Yt0E","lore_tm_v1_p12ri7tFvxHOLtTCDWnwTjIrZErBzUxEJqR9ntjY1yY","lore_tm_v1_J_KqCLelysiplfUBvDpWZ29R9WwaAn3H4YbgY-Zblts","lore_tm_v1_kQcU9GGTK3G8mO6ATS8sLKpxXZ49vi5r9aAIqJdxwxg","lore_tm_v1_yj7iDl8HWrncYa4i2AvlFz0WdZz-Ph1D-Qlz7nOpm4Q"]
Date: September 9, 2026
resolveUpgradeSource() to return the successful probe Response to the caller so the caller βnever repeats the request.βpackages/cli/src/lib/binary.ts added UpgradeSource with readonly githubRepo, ghcrRepo, and tagPrefix; UPGRADE_SOURCES is ordered as 1. { githubRepo: "getsentry/toolkit", ghcrRepo: "getsentry/toolkit", tagPrefix: "cli@" }, then 2. { githubRepo: "getsentry/cli", ghcrRepo: "getsentry/cli", tagPrefix: "" }; PRIMARY_UPGRADE_SOURCE is UPGRADE_SOURCES[0].packages/cli/src/lib/binary.ts changed getBinaryDownloadUrl(version, source = PRIMARY_UPGRADE_SOURCE) to use https://github.com/${source.githubRepo}/releases/download/${source.tagPrefix}${version}/${getPlatformBinaryName()} and added source-aware getGitHubReleasesUrl(), getGitHubReleaseByTagUrl(), getGitHubLatestReleaseUrl(), and getGitHubRepositoryUrl(). Prefixed sources discover latest releases via ?per_page=100; unprefixed sources use /latest; tag URLs encode the source-prefixed tag.packages/cli/src/lib/binary.ts added ResolveUpgradeSourceOptions (getProbeUrl, optional fetch, optional signal), ResolvedUpgradeSource (source, response), and resolveUpgradeSource(). It defaults to CA-aware customFetch, sends getGitHubHeaders(), preserves AbortError, maps TLS certificate failures through buildTlsErrorDetail(), maps other connection failures to UpgradeError("network_error", ...), rejects non-404 HTTP failures immediately, and reports "No CLI upgrade source was found: every source returned HTTP 404" if all sources miss.packages/cli/src/lib/binary.ts documentation changed version ordering from Bun.semver.order to semver.compare, retaining numeric SemVer handling for stable X.Y.Z and nightly X.Y.Z-dev.<unix-seconds> versions.packages/cli/src/lib/ghcr.ts changed GHCR_REPO from hard-coded "getsentry/cli" to PRIMARY_UPGRADE_SOURCE.ghcrRepo and made GHCR operations source-aware: getAnonymousToken(sourceOrSignal = PRIMARY_UPGRADE_SOURCE, signal?), fetchManifest(token, tag, signal?, source = PRIMARY_UPGRADE_SOURCE), fetchNightlyManifest(token, signal?, source = PRIMARY_UPGRADE_SOURCE), downloadNightlyBlob(token, digest, signal?, source = PRIMARY_UPGRADE_SOURCE), internal fetchTagPage(token, lastTag?, signal?, source = PRIMARY_UPGRADE_SOURCE), listTags(token, prefix?, signal?, source = PRIMARY_UPGRADE_SOURCE), and downloadLayerBlob(token, digest, signal?, source = PRIMARY_UPGRADE_SOURCE).packages/cli/src/lib/custom-ca.ts defines customFetch(input, init?): it calls bare fetch(input, init) when getCustomTlsOptions() returns no options and otherwise calls fetch(input, { ...init, ...tlsOpts }); non-authenticated fetch sites should use it, while authenticated API calls use fetchWithTimeout() in sentry-client.ts.packages/cli/test/helpers.tsβs useTestConfigDir() teardown to βAlways restore the previous value β never delete.β Deleting process.env.SENTRY_CONFIG_DIR caused cross-file failures when later-loaded module code or hooks observed undefined.preload.ts always sets SENTRY_CONFIG_DIR, so savedConfigDir is always defined in practice; the teardown intentionally omits an else branch to avoid the delete process.env anti-pattern.useTestConfigDir(prefix = "sentry-test-", options?) saves process.env[CONFIG_DIR_ENV_VAR], closes the database, resets resetAuthTokenCache(), resetAuthRowCache(), resetHasStoredCredsCache(), and resetIdentityFingerprintCache(), creates an isolated config directory, and points SENTRY_CONFIG_DIR to it in beforeEach; afterEach repeats database/cache cleanup, restores the saved value when defined, and calls cleanupTestDir(dir).binpatchβs OciClient stores injected registry, repo, userAgent, and fetch; fetchWithRetry() uses REQUEST_TIMEOUT, retries through MAX_RETRIES, combines timeout and external cancellation via buildSignal(), stops for external abort or non-retryable errors, and throws BinpatchError("network_error", ...).binpatchβs githubReleaseSource(config) requests ${releasesUrl}?per_page=${MAX_STABLE_CHAIN_DEPTH + 2} using the configured fetch, user agent, signal, and optional instrument("fetch-releases", ...); it reports "network", "no_patches", or "malformed_chain" and returns null as applicable, downloads all patch URLs concurrently with Promise.all(), and returns patches, exact cumulative byte size, expected SHA-256, and ordered steps.binpatchβs ghcrSource obtains an anonymous token, concurrently fetches the target manifest and lists PATCH_TAG_PREFIX tags, requires a ${binaryName}.gz layer, and reports "malformed_chain" if absent; caught BinpatchError is reported as "network" and returns null, while other errors are rethrown.packages/cli/test/lib/delta-upgrade.test.ts with source-selection coverage.test/lib/delta-upgrade.test.ts produced 85 tests: 82 passed and 3 failed. Vitest 4.1.10 also warned that test.poolOptions was removed and its former options are now top-level.fetchRecentReleases > uses the selected legacy GitHub repository expected https://api.github.com/repos/getsentry/cli/releases?per_page=12 but received https://api.github.com/repos/getsentry/toolkit/releases?per_page=12 at packages/cli/test/lib/delta-upgrade.test.ts:855; 2. resolveStableChain > keeps stable resolution on the selected legacy source had the same expected/received mismatch at line 993; 3. resolveNightlyChain > keeps nightly resolution on the selected legacy source expected https://ghcr.io/v2/getsentry/cli/tags/list?n=100 but received https://ghcr.io/v2/getsentry/toolkit/tags/list?n=100 at line 1242. Evidence shows the selected legacy UpgradeSource was not propagated into stable-release and nightly-tag requests, causing both paths to fall back to PRIMARY_UPGRADE_SOURCE.