Dashboard › cli › Distillation
ad31fd9d-1663-47dc-867f-5ecfde9de4c9["lore_tm_v1_4L1Wlp6yLesXFUjQmZY-JVV3YHY0V7OHIORp0IXfGEM","lore_tm_v1_iak4WPawMzPJGtPS1h4TMnVwBFiomHnF2mx7bcF-eW8","lore_tm_v1_aMuVy8L7I8j5L2DeAKkxQvgXJgjVQKQQ2STfD2bJU-4","lore_tm_v1_DPAVh-4NzbxvSSAMdREEp1Cef34RePFQESLSzZ_1WE8","lore_tm_v1_5OOmwXD7fNgC6xMHWpZKt3DoKGsLcxzRIzxbJJC-W1s"]
packages/cli/src/lib/release-notes.ts:543-585 defines CHANGELOG_MAX_RELEASES = 30; fetchReleasesForChangelog() requests ${GITHUB_RELEASES_URL}?per_page=30, returns releases newest-first, and returns [] on fetch failure, non-OK HTTP response, invalid JSON, or a non-array response. The comments contrast this with delta-upgrade’s cap of 12 and state 30 covers approximately 6+ months of weekly releases.packages/cli/src/lib/release-notes.ts:602-613 defines fetchStableChangelog(fromVersion, toVersion, maxItems?, prefetchedReleases?); it uses prefetchedReleases when supplied to avoid a duplicate API request, otherwise calls fetchReleasesForChangelog(), returns null for an empty release list, and delegates to buildChangelogSummary().packages/cli/src/lib/release-notes.ts:620-628 defines buildNightlyChangelogSummary(commits, fromVersion, toVersion, maxItems?), which parses commit messages with parseCommitMessages() and delegates to buildSummaryFromSections().packages/cli/src/lib/release-notes.ts:642-694 defines fetchNightlyChangelog(): extracts Unix timestamps from nightly versions; returns null when either timestamp is invalid; uses since = fromTs + 1 second because GitHub’s since is inclusive; uses until = toTs + 1 second because GitHub’s until is exclusive; requests the main branch with per_page=100; and returns null on fetch failure, non-OK response, invalid JSON, or an empty/non-array commit response.packages/cli/src/lib/release-notes.ts:696-738 defines FetchChangelogOptions with channel: "stable" | "nightly", fromVersion, toVersion, optional maxItems, and optional stable-only prefetchedReleases. fetchChangelog() dispatches nightly requests to fetchNightlyChangelog() and stable requests to fetchStableChangelog(), catches all errors, and returns null; it is intended to run in parallel with binary download for zero added latency.feat/toolkit-bridge-upgrade was based on origin/main with 4 modified files: packages/cli/src/lib/binary.ts, packages/cli/test/lib/binary.test.ts, packages/cli/test/lib/ghcr.test.ts, and packages/cli/test/lib/install-script.test.ts; the diff contained exactly 232 insertions and 5 deletions.packages/cli/src/lib/binary.ts added UpgradeSource with readonly githubRepo, ghcrRepo, and tagPrefix; ordered UPGRADE_SOURCES checks { githubRepo: "getsentry/toolkit", ghcrRepo: "getsentry/toolkit", tagPrefix: "cli@" } first and legacy { githubRepo: "getsentry/cli", ghcrRepo: "getsentry/cli", tagPrefix: "" } second. PRIMARY_UPGRADE_SOURCE is UPGRADE_SOURCES[0].getBinaryDownloadUrl(version, source = PRIMARY_UPGRADE_SOURCE) now constructs https://github.com/${source.githubRepo}/releases/download/${source.tagPrefix}${version}/${getPlatformBinaryName()}, replacing the prior hard-coded getsentry/cli release URL.getGitHubReleasesUrl(source = PRIMARY_UPGRADE_SOURCE) constructs https://api.github.com/repos/${source.githubRepo}/releases; GITHUB_RELEASES_URL now represents the primary source and therefore resolves to https://api.github.com/repos/getsentry/toolkit/releases.resolveUpgradeSource(fetchFn = customFetch, signal?) probes each ordered source at ${getGitHubReleasesUrl(source)}/latest with getGitHubHeaders() and the abort signal. It selects the first successful source, falls through only on HTTP 404, aborts immediately on every other HTTP or network failure, and throws UpgradeError("network_error", "No CLI upgrade source was found: every source returned HTTP 404") after all sources return 404.packages/cli/test/lib/binary.test.ts added source-order and resolution tests: Toolkit succeeds after exactly 1 request; Toolkit 404 falls back to legacy CLI after exactly 2 ordered requests; HTTP 401, 403, 429, and 500 do not fall back; TypeError("fetch failed") does not fall back; and two 404 responses throw an error containing No CLI upgrade source was found.packages/cli/test/lib/ghcr.test.ts added tests expecting getAnonymousToken(UPGRADE_SOURCES[0]) to request scope repository:getsentry/toolkit:pull and resolve "toolkit-token", and expecting fetchNightlyManifest("token", undefined, UPGRADE_SOURCES[0]) to request /v2/getsentry/toolkit/manifests/nightly.packages/cli/test/lib/install-script.test.ts added a test that parses UPGRADE_SOURCES=(...) from the install script and requires its whitespace-separated repositories to exactly equal UPGRADE_SOURCES.map((source) => source.githubRepo).packages/cli/src/lib/binary.ts:105-130 confirmed the ordered Toolkit-first/legacy-second UPGRADE_SOURCES and PRIMARY_UPGRADE_SOURCE = UPGRADE_SOURCES[0]; packages/cli/src/lib/binary.ts:234-290 confirmed source-aware binary/release URLs and 404-only resolveUpgradeSource() fallback behavior.packages/cli/src/lib/binary.ts:161-225 detects musl by first checking /lib/ld-musl-${muslArch}.so.1, then parsing combined stdout/stderr from ldd --version; it caches the result. getPlatformBinaryName() emits sentry-<os>-<arch>[-musl][.exe], mapping Darwin to darwin, Windows to windows, everything else to linux, arm64 distinctly, and other architectures to x64.packages/cli/src/lib/ghcr.ts implementation still had hard-coded export const GHCR_REPO = "getsentry/cli" and source-unaware signatures: getAnonymousToken(signal?), fetchManifest(token, tag, signal?), fetchNightlyManifest(token), downloadNightlyBlob(token, digest, signal?), listTags(token, prefix?, signal?), and downloadLayerBlob(token, digest, signal?). This did not yet match the newly added source-aware GHCR tests.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 immediately propagates caller-triggered external aborts and does not retry HTTP responses.packages/cli/src/lib/ghcr.ts:318-413 manually handles GHCR blob redirects: the authenticated first request uses redirect: "manual"; direct HTTP 200 is accepted; HTTP 301, 302, 307, or 308 requires a Location header; the redirect is fetched without Authorization; and failures map to specific UpgradeError("network_error", ...) messages. The Azure redirect request intentionally has no 30-second timeout because full nightly binaries are approximately 30 MB and that timeout would require sustained approximately 8 Mbps.packages/cli/src/lib/ghcr.ts:416-498 uses TAGS_PAGE_SIZE = 100; tag listing paginates with last=<encoded-last-tag>, optionally filters by prefix, stops on an empty page or a page shorter than 100, and returns accumulated tags.packages/cli/src/lib/delta-upgrade.ts still imported GITHUB_RELEASES_URL and GHCR_REPO. stableSource() passed releasesUrl: GITHUB_RELEASES_URL to githubReleaseSource(), while nightlySource() passed repo: GHCR_REPO to ghcrSource(), so stable operations now defaulted to Toolkit but nightly and patch operations still targeted legacy getsentry/cli.fetchRecentReleases(signal?) in packages/cli/src/lib/delta-upgrade.ts:155-179 requests ${GITHUB_RELEASES_URL}?per_page=12, returns [] on non-OK HTTP, non-array JSON, or fetch failure, and otherwise returns the release array.resolveNightlyChain() in packages/cli/src/lib/delta-upgrade.ts:278-350 constructs OciClient with repo: GHCR_REPO, obtains tags using PATCH_TAG_PREFIX unless preloadedTags are supplied, rejects empty chains or chains deeper than MAX_NIGHTLY_CHAIN_DEPTH, fetches all manifests concurrently, and preserves 3 detailed validation failure reasons: version-mismatch, missing-layer, and size-exceeded.