Dashboard › cli › Distillation
ae1deb1b-d470-49b8-b053-5d33e6594216["lore_tm_v1_SdMcnlqLkW2HQgd3lPd3Ml0aD1h96LXEQVIzFR5WuQs","lore_tm_v1_N4zOUaEWuGOEoXL_YNWh2E4nqd1JNkWqA89vy2VxzkI","lore_tm_v1_9njJ7yYIu_M1AZiDzkcrH451DEc87z_knfwQlZusYvo","lore_tm_v1_GDbKCnDs7tOJ3CfGaoqC53pVAAVMVJaoE4Q6W6CwKl0","lore_tm_v1_cZm971pgcimH9GCU8M1zG5k2HQLRHRvNT-wQjqxhKqA","lore_tm_v1_9kMCT-AwX2mP6gM1L_fYLSUC904QUW3VdMbnoSkPVoo","lore_tm_v1_kAzLcIwll3pjSCiC8GJ9UthFG_FdtfvmPCECfBOpcAw"]
packages/cli/src/lib/release-notes.ts implements stable and nightly release-note parsing and aggregation. It keeps only 3 categories in display order: 1. "features" / ### New Features / feat:, 2. "fixes" / ### Bug Fixes / fix:, 3. "performance" / ### Performance / perf:.ChangeSection contains category: ChangeCategory and raw markdown: string. ChangelogSummary contains fromVersion, toVersion, sections, totalItems, truncated, and originalCount.extractSections(body) uses marked.lexer() and splits only on depth-3 (###) headings. It normalizes headings by stripping EMOJI_RE, trimming, and lowercasing; it retains intervening tokens, including depth-4 scope subheadings and lists, and reconstructs source through each tokenβs raw field in tokensToMarkdown().EMOJI_RE is /[\u{2000}-\u{2BFF}\u{FE00}-\u{FE0F}\u{1F000}-\u{1FFFF}]/gu; AUTHOR_SUFFIX_RE strips suffixes like by @author in [#123](url) or by @author in #123; NIGHTLY_VERSION_RE is /^[\d.]+(?:-\w+)?-dev\.(\d+)$/; CONVENTIONAL_COMMIT_RE is /^(\w+)(?:\([^)]*\))?:\s*(.+)$/; VERSION_PREFIX_RE is /^v/.countListItems(tokens) counts only top-level children of list tokens, not nested sublists. countMarkdownListItems(md) lexes markdown before applying that count.stripAttributions(md) operates line by line and applies AUTHOR_SUFFIX_RE only to lines whose trimmed start begins with - .truncateSectionMarkdown(md, maxItems) walks parsed list tokens, preserves non-list raw markdown, removes whole lists after the budget reaches zero, and truncates a partially retained list by joining kept list-item raw values so nested content and inline formatting survive.applySectionTruncation(sections, maxItems, originalCount) mutates sections in place, replacing markdown with truncated versions when needed. Non-final sections receive Math.min(Math.max(0, budget), Math.max(1, Math.floor((sectionItems / originalCount) * maxItems))); the final section receives the remaining nonnegative budget.applySectionTruncation() recomputes totalItems after truncation and reports truncated: totalItems < originalCount.buildSummaryFromSections() returns null only when sections.length === 0; otherwise it calculates originalCount, optionally truncates when maxItems !== undefined && originalCount > maxItems, and returns the complete ChangelogSummary.mergeSectionsByCategory(releases) extracts sections from each release body, strips author attribution, concatenates same-category markdown with "\n", and emits merged sections in features, fixes, performance order.buildChangelogSummary(releases, fromVersion, toVersion, maxItems?) strips a leading v from each tag_name and includes releases in the range exclusive of fromVersion and inclusive of toVersion; it returns null when no releases are in range.extractNightlyTimestamp(version) extracts and base-10 parses Unix seconds from X.Y.Z-dev.<unix-seconds>, returning null for invalid formats or NaN.parseCommitMessages(commits) ignores any commit containing #skip-changelog, uses only the trimmed first line, accepts scoped or unscoped conventional commits, retains only feat, fix, and perf, and emits each description as - ${description} grouped in category display order.CHANGELOG_MAX_RELEASES = 30, compared with the delta-upgrade release cap of 12; the GitHub API permits up to 100, and the selected 30 is intended to cover approximately 6+ months of weekly releases.fetchReleasesForChangelog() requests ${GITHUB_RELEASES_URL}?per_page=${CHANGELOG_MAX_RELEASES} with getGitHubHeaders() and returns [] for fetch failures, non-OK responses, malformed JSON, or non-array JSON.fetchStableChangelog() uses caller-supplied prefetchedReleases when present to avoid another API request; otherwise it calls fetchReleasesForChangelog().fetchNightlyChangelog() queries https://api.github.com/repos/getsentry/cli/commits?sha=main&since=${sinceDate}&until=${untilDate}&per_page=100. Because GitHub since is inclusive and until is exclusive, both encoded nightly timestamps are offset by +1 second to exclude the current buildβs commit and include the target buildβs commit.fetchNightlyChangelog() returns null for invalid nightly timestamps, request failure, non-OK response, malformed/non-array JSON, or an empty commit list.FetchChangelogOptions has channel: "stable" | "nightly", fromVersion, toVersion, optional maxItems, and optional stable-only prefetchedReleases.fetchChangelog(opts) dispatches nightly to fetchNightlyChangelog() and stable to fetchStableChangelog(). It is best-effort, catches all failures, debug-logs them, returns null, and is designed to run in parallel with binary download with zero added latency.packages/cli/src/lib/binary.ts defines UpgradeSource with readonly githubRepo, ghcrRepo, and tagPrefix.UPGRADE_SOURCES is ordered: 1. { githubRepo: "getsentry/toolkit", ghcrRepo: "getsentry/toolkit", tagPrefix: "cli@" }; 2. { githubRepo: "getsentry/cli", ghcrRepo: "getsentry/cli", tagPrefix: "" }. PRIMARY_UPGRADE_SOURCE is UPGRADE_SOURCES[0].getBinaryDownloadUrl(version, source = PRIMARY_UPGRADE_SOURCE) constructs https://github.com/${source.githubRepo}/releases/download/${source.tagPrefix}${version}/${getPlatformBinaryName()}.getGitHubReleasesUrl(source = PRIMARY_UPGRADE_SOURCE) returns https://api.github.com/repos/${source.githubRepo}/releases; GITHUB_RELEASES_URL is the primary sourceβs URL.resolveUpgradeSource(fetchFn = customFetch, signal?) probes each ordered source at ${getGitHubReleasesUrl(source)}/latest with getGitHubHeaders() and the abort signal. It returns both the chosen source and successful response, so the caller never repeats the request.resolveUpgradeSource() falls through to the next source only for HTTP 404. Any other HTTP result immediately throws UpgradeError("network_error", \Failed to fetch from GitHub: HTTP ${response.status}`); exhausting all sources throws UpgradeError("network_error", "No CLI upgrade source was found: every source returned HTTP 404")`.InstallationMethod is "curl" | "brew" | "npm" | "pnpm" | "bun" | "yarn" | "unknown". User-selectable VALID_METHODS omit "unknown" and preserve the order curl, brew, npm, pnpm, bun, yarn.parseInstallationMethod(value) lowercases input and throws Invalid method: ${value}. Must be one of: ${VALID_METHODS.join(", ")} when it is not one of the 6 valid user-selectable methods.isMusl() applies 2 Linux heuristics in order: 1. existence of /lib/ld-musl-${muslArch}.so.1, where muslArch is "x86_64" for x64 or "aarch64" otherwise; 2. combined stdout/stderr from ldd --version containing "musl" case-insensitively. It caches the result, returns false off Linux, and assumes glibc if ldd fails.getPlatformBinaryName() produces sentry-<os>-<arch>[-musl][.exe], mapping Darwin to "darwin", Win32 to "windows", everything else to "linux", arm64 to "arm64", other architectures to "x64", and adding .exe only on Windows.getGitHubHeaders() returns Accept: "application/vnd.github.v3+json" and "User-Agent": getUserAgent().fetchWithUpgradeError(url, init, serviceName) calls customFetch, rethrows AbortError unchanged, maps TLS certificate errors to UpgradeError("network_error", buildTlsErrorDetail(error)), and maps other connection failures to UpgradeError("network_error", \Failed to connect to ${serviceName}: ${stringifyUnknown(error)}`)`.replaceBinarySync(tempPath, installPath) is intentionally synchronous so its rename sequence cannot be interrupted. Unix atomically renames over the target; Windows first renames the active executable to ${installPath}.old, retries after deleting an existing .old file if necessary, then renames the temporary binary into place.packages/cli/src/lib/delta-upgrade.ts uses binpatch for delta discovery/application and defines DeltaResult as { sha256: string; patchBytes: number; chainLength: number }.makeCache(join(getConfigDir(), "patch-cache")). Cache tracing keys are patch-chain:${fromVersion}-${toVersion}; reads set cache.key, cache.hit, and, on hits, cache.item_size; writes set cache.key and the sum of all chain.patches[].size.stableSource() uses githubReleaseSource() with releasesUrl: GITHUB_RELEASES_URL, binaryName: getPlatformBinaryName(), userAgent: \sentry-cli/${CLI_VERSION}`, fetch: customFetch`, and tracing instrumentation.nightlySource() uses ghcrSource() with registry "https://ghcr.io", repository GHCR_REPO, platform binary name, target tag (version) => \nightly-${version}`, compareVersions, the sentry-cli/${CLI_VERSION}user agent,customFetch`, and tracing instrumentation.canAttemptDelta(targetVersion) rejects delta upgrades when CLI_VERSION === "0.0.0-dev", when current and target differ between stable/nightly formats, or when the operation is a downgrade.fetchRecentReleases(signal?) requests ${GITHUB_RELEASES_URL}?per_page=12 and returns [] for non-OK responses, non-array JSON, or caught failures.downloadStablePatch(url, signal?) fetches with "User-Agent": \sentry-cli/${CLI_VERSION}`and returns aUint8Arrayonly for an OK response; failures and non-OK responses returnnull`.resolveStableDelta() and resolveNightlyDelta() delegate to resolveDelta() with stableSource() and nightlySource() respectively, then return only the resolved result.attemptDeltaUpgrade() selects the channel from isNightlyVersion(targetVersion) and traces under span name/op "upgrade.delta", recording delta.from_version, delta.to_version, and initial "delta.channel".delta.patch_bytes and delta.chain_length on the span and emits Sentry distributions "upgrade.delta.patch_bytes" and "upgrade.delta.chain_length" with the channel attribute. An unavailable result records delta.result = "unavailable"; success status code is 1."delta.from_version", "delta.to_version", and "delta.channel". If chain resolution had identified a source before application failed, the active error span receives "delta.source".attemptDeltaUpgrade() warns Delta upgrade failed (${message}), falling back to full download, records span status code 2, delta.result = "error", and delta.error = message, then returns null.prefetch(source, targetVersion, signal?) exits if delta cannot be attempted or the signal is aborted; otherwise it resolves a chain from CLI_VERSION, exits if no steps or subsequently aborted, and saves the chain and steps in the patch cache.prefetchNightlyPatches() and prefetchStablePatches() call prefetch() with nightlySource() and stableSource() respectively.