Dashboard › cli › Distillation
6f3c4df6-88d7-40c1-a25b-37986f702619["lore_tm_v1_Z4mZArxQMYMJAlh-2SpLXL7q1Ki_CASaIGunNrxz6FA","lore_tm_v1_hjKOzc8dMip1--V96jIeUp3NgOy7b197jOZGiTA10f4","lore_tm_v1_JcopPUV2OWFTa68pRiX0isR9swghukdoi9u6iAW5SOg","lore_tm_v1_M4vgrHjwBxWUqwn6zkj6grcTRI9PsTqG9QaFbFXGrkA","lore_tm_v1_XDV0TvNhbvxbP5Sdw2oziPQYkS2S76vpeZ4G0K9A328","lore_tm_v1_C3msGIao8B_-ibvX_hEqbVbWlxeYwP01rkleMieMiKE","lore_tm_v1_rm3lX_593zW54CKFLq5n5QJrla0OpedzZEk8jzF5NYA","lore_tm_v1_b67470BtUX7EfNvFjaQcwCq4koUjvQApyECZ0xOrVrY"]
packages/cli/src/lib/release-notes.ts sets CHANGELOG_MAX_RELEASES = 30; this exceeds delta-upgradeβs 12-release cap, stays below GitHubβs per_page maximum of 100, and is intended to cover approximately 6+ months of weekly releases.fetchReleasesForChangelog() requests ${GITHUB_RELEASES_URL}?per_page=${CHANGELOG_MAX_RELEASES} with getGitHubHeaders() and returns [] on network failure, non-OK HTTP response, invalid JSON, or a non-array response.fetchStableChangelog(fromVersion, toVersion, maxItems?, prefetchedReleases?) uses caller-provided prefetchedReleases when available to avoid a duplicate API call; otherwise it calls fetchReleasesForChangelog(), returning null when no releases are available.packages/cli/src/lib/ghcr.ts uses GHCR_REQUEST_TIMEOUT = 10_000, GHCR_MAX_RETRIES = 1, and GHCR_BLOB_TIMEOUT = 30_000.fetchWithRetry() retries timeout/abort, econnreset, econnrefused, generic network, and fetch failed errors, but does not retry HTTP-level failures or caller-triggered external aborts; exhausted attempts throw UpgradeError("network_error", "<context>: <message>").packages/cli/src/lib/ghcr.ts currently exports GHCR_REPO = "getsentry/cli" and GHCR_TAG = "nightly"; GHCR_REGISTRY is https://ghcr.io, and OCI_MANIFEST_TYPE is application/vnd.oci.image.manifest.v1+json.OciLayer fields are digest, mediaType, size, and optional annotations; OciManifest fields are schemaVersion, optional mediaType, optional config, layers, and optional annotations.getAnonymousToken(signal?) currently requests ${GHCR_REGISTRY}/token?scope=repository:${GHCR_REPO}:pull, uses the CLI user agent, and throws UpgradeError("network_error", ...) for non-OK responses or a missing token field.fetchManifest(token, tag, signal?) currently requests ${GHCR_REGISTRY}/v2/${GHCR_REPO}/manifests/${tag} with Bearer authorization and the OCI manifest accept header; fetchNightlyManifest(token) wraps it with GHCR_TAG.getNightlyVersion(manifest) reads manifest.annotations?.version and throws UpgradeError("network_error", "Nightly manifest has no version annotation") when absent.findLayerByFilename(manifest, filename) matches org.opencontainers.image.title; failure throws UpgradeError("version_not_found", "No nightly build found for <filename>").downloadNightlyBlob(token, digest, signal?) accepts direct HTTP 200 responses or manually handles HTTP 301, 302, 307, and 308; it requires a Location header and follows the redirect without the Authorization header.downloadNightlyBlob() applies the 30-second timeout only to the initial GHCR request, not the Azure blob stream, because a roughly 30 MB binary would otherwise require sustained throughput of about 8 Mbps; the redirected request retains only the user-agent and external signal.TAGS_PAGE_SIZE = 100; listTags(token, prefix?, signal?) repeatedly calls /v2/${GHCR_REPO}/tags/list?n=100, adds &last=<encoded-tag> after each full page, optionally filters by prefix, and stops on an empty or partial page.downloadLayerBlob(token, digest, signal?) delegates to downloadNightlyBlob() and returns the fully buffered ArrayBuffer; it is intended for small patch payloads around 50β500 KB.packages/cli/src/lib/delta-upgrade.ts uses binpatch for patch discovery/application, including githubReleaseSource, ghcrSource, OciClient, resolveAndApply, applyPatchChainInMemory, MAX_NIGHTLY_CHAIN_DEPTH, PATCH_TAG_PREFIX, and SIZE_THRESHOLD_RATIO.makeCache(join(getConfigDir(), "patch-cache")); cache tracing keys are patch-chain:${fromVersion}-${toVersion}, with cache.key, cache.hit, and cache.item_size span attributes.stableSource() currently configures githubReleaseSource() with releasesUrl: GITHUB_RELEASES_URL, getPlatformBinaryName(), user agent sentry-cli/${CLI_VERSION}, customFetch, and the tracing instrument hook.nightlySource() currently configures ghcrSource() with registry https://ghcr.io, repo: GHCR_REPO, platform binary name, target tags nightly-${version}, compareVersions, user agent sentry-cli/${CLI_VERSION}, customFetch, and tracing.canAttemptDelta(targetVersion) returns false for CLI_VERSION === "0.0.0-dev", channel changes between stable and nightly, or downgrades.fetchRecentReleases(signal?) requests ${GITHUB_RELEASES_URL}?per_page=12; it returns [] for non-OK responses, non-array JSON, or caught errors.downloadStablePatch(url, signal?) returns a Uint8Array only for an OK response and otherwise returns null, including on caught errors.validateChainStep() preserves 3 detailed failure reasons around binpatch validation: version-mismatch with expected/actual versions, missing-layer with layerName, and size-exceeded with layerSize and budget; this is more granular than binpatchβs malformed | over_budget.resolveNightlyChain() rejects empty chains and chains exceeding MAX_NIGHTLY_CHAIN_DEPTH; its per-step size budget is opts.fullGzSize * SIZE_THRESHOLD_RATIO - totalSize, and it requires the chain to finish at opts.targetVersion with a nonempty expected SHA-256.applyPatchChain() records patches.count and patches.total_bytes, applies patches with applyPatchChainInMemory(), and throws on SHA-256 mismatch with both actual and expected hashes in the message.delta.source on successful resolution or offline_miss, records telemetry_reason when unavailable, and preserves the resolved source so apply failures can still stamp source attribution on the error span.attemptDeltaUpgrade() captures failures to Sentry at warning level with delta.from_version, delta.to_version, and delta.channel; it logs a warning, marks delta.result = "error", records delta.error, and returns null to fall back to a full download.upgrade.delta.patch_bytes and upgrade.delta.chain_length, each tagged with stable or nightly channel.steps to the patch cache; exported wrappers are prefetchNightlyPatches() and prefetchStablePatches().fetchNightlyChangelog() extracts Unix timestamps from nightly versions, adds 1 second to both boundaries because GitHub since is inclusive and until is exclusive, and requests up to 100 commits from https://api.github.com/repos/getsentry/cli/commits?sha=main&since=${sinceDate}&until=${untilDate}&per_page=100.fetchNightlyChangelog() returns null for invalid nightly timestamps, network failure, non-OK HTTP status, malformed JSON, or an empty/non-array commit response.FetchChangelogOptions contains channel: "stable" | "nightly", fromVersion, toVersion, optional maxItems, and optional stable-only prefetchedReleases.fetchChangelog(opts) dispatches nightly upgrades to fetchNightlyChangelog() and stable upgrades to fetchStableChangelog(); it is best-effort, catches every failure, and returns null, and is designed to run in parallel with binary download for zero added latency.maybePrefetchPatches(channel, latestVersion, signal) runs only when latestVersion is newer than CLI_VERSION; it prefetches the corresponding stable/nightly delta patches, catches prefetch errors, then opportunistically calls cleanupPatchCache() and separately catches cleanup errors.checkForUpdateInBackgroundImpl() is nonblocking and uses a detached Sentry span named version-check with operation version.check and forceTransaction: true.checkForUpdateInBackgroundImpl() reports database-access failures through Sentry.captureException(), but records non-abort network/JSON failures as version_check.error and version_check.error_type span attributes rather than creating Sentry Issues.setVersionCheckInfo(latestVersion), prefetches delta patches for offline upgrade use, clears pendingAbortController in finally, and explicitly ends the span.abortPendingVersionCheck() aborts the pending controller and resets pendingAbortController to null.