Dashboard › cli › Distillation
5e2375cd-e6b7-4b70-b6c0-847df5c61fef["lore_tm_v1_JTWic-QCLuxJ7S4XjqFlSiKHQJ3NU_nKsyUOOC3Sgvs","lore_tm_v1_cDnvtexD63SHtgEdq3UZ7YbPjBjTyt8HkqEanTTRoLE","lore_tm_v1_SJ7ix0JF1xinVYwzvElSikacOS8R5_yHi3VHQVFRbG4","lore_tm_v1_xAQ14ut2uU8Q6oriWTa-bsyCDGAwnEFWf89_SQP3Nhg","lore_tm_v1_BdBD8wE-KrjPHX-gmU3TSxjrYfCfumPbes4VG-n5Xr0","lore_tm_v1_vWm8DQo151cXGu45DVRQ4g8XwuybWkt4Bnwv9MCzK_M","lore_tm_v1_4nnnqIfsNVFJtVKg2qcJWNQ6CgvI4_HMpPYXLBs06LE","lore_tm_v1_p8_CSTUj-C9N-WGEPfBlqP3KhLANAGjUowaGopsfwDc","lore_tm_v1_gqTw2cng_sTYYRy2JTHP1c2T-Y88vBUHKwpVesXybp0","lore_tm_v1_yj49JF-8NCstzfh1JlXX8Lc7bUAnnx6FIWEgsqCTNuQ"]
packages/cli/src/lib/ghcr.ts implements anonymous OCI downloads for nightly CLI binaries from ghcr.io/getsentry/cli; GHCR_REPO = "getsentry/cli", GHCR_TAG = "nightly", registry URL is https://ghcr.io, and manifest media type is application/vnd.oci.image.manifest.v1+json.packages/cli/src/lib/ghcr.ts configures GHCR_REQUEST_TIMEOUT = 10_000, GHCR_MAX_RETRIES = 1, and GHCR_BLOB_TIMEOUT = 30_000.isRetryableError() in packages/cli/src/lib/ghcr.ts retries TimeoutError, AbortError, and messages containing timeout, econnreset, econnrefused, network, or fetch failed; HTTP-level failures are not retried, and caller-triggered external aborts stop immediately.buildSignal() combines AbortSignal.timeout(timeout) with an optional caller signal via AbortSignal.any; exhausted GHCR fetch attempts throw UpgradeError("network_error", ...).getAnonymousToken(signal?) requests https://ghcr.io/token?scope=repository:getsentry/cli:pull, supplies User-Agent, rejects non-OK responses or a missing token, and returns the anonymous bearer token.fetchManifest(token, tag, signal?) requests https://ghcr.io/v2/getsentry/cli/manifests/${tag} with bearer authorization and the OCI manifest Accept header; fetchNightlyManifest(token) wraps it using 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 the OCI layer annotation org.opencontainers.image.title; a miss throws UpgradeError("version_not_found", \No nightly build found for ${filename}`)`.downloadNightlyBlob(token, digest, signal?) handles GHCR blob delivery in 2 stages: 1. authenticated request with redirect: "manual" and a 30-second timeout; 2. follow HTTP 301, 302, 307, or 308 Location without the Authorization header. This avoids Azure Blob Storage returning 404 when a GHCR bearer token is forwarded.downloadNightlyBlob() intentionally has no internal timeout because a full nightly binary is approximately 30 MB and a 30-second streaming timeout would require sustained throughput of approximately 8 Mbps; only the optional caller signal is passed.downloadNightlyBlob() also accepts a direct HTTP 200 GHCR response; missing redirect Location, failed blob-storage responses, and unexpected GHCR status codes become UpgradeError("network_error", ...).packages/cli/src/lib/ghcr.ts uses TAGS_PAGE_SIZE = 100 and /v2/${GHCR_REPO}/tags/list?n=100, adding &last=${encodeURIComponent(lastTag)} for subsequent pages; listTags(token, prefix?, signal?) optionally filters with startsWith(prefix) and stops on an empty or short page.downloadLayerBlob(token, digest, signal?) reuses downloadNightlyBlob() and returns response.arrayBuffer(); it is intended for small patch payloads around 50β500 KB.packages/cli/src/commands/cli/upgrade.ts treats nightly and stable positional values as channel selectors; its help example is sentry cli upgrade nightly # Switch to nightly channel and update.executeStandardUpgrade() in packages/cli/src/commands/cli/upgrade.ts passes NIGHTLY_TAG to executeUpgrade() only when channel === "nightly" and no specific versionArg was requested; a pinned version uses its own release tag.executeStandardUpgrade() logs Applied delta patch (${formatBytes(downloadResult.patchBytes)} downloaded).executeStandardUpgrade() computes the destination with resolveUpgradeInstallDir(dirname(getCurlInstallPaths().installPath), pathEnv), runs runSetupOnNewBinary() with install: true, and always calls releaseLock(downloadResult.lockPath) in finally; for package-manager upgrades it resolves the updated executable using resolveUpdatedCliPath(execPath, entryPath, pathEnv) and runs setup with install: false.migrateToStandaloneForNightly() migrates brew, npm, pnpm, bun, or yarn installations to a standalone curl-style binary because nightlies are standalone-only: 1. download to a temporary path, 2. install to determineInstallDir(homedir(), process.env), 3. run setup for completions, PATH, and metadata, 4. warn that the old package-manager binary may still shadow the new one.migrateToStandaloneForNightly() calls executeUpgrade("curl", target, downloadTag, undefined, setMessage), where downloadTag is NIGHTLY_TAG for the latest nightly and undefined for a pinned nightly; a missing result throws UpgradeError("execution_failed", "Failed to download nightly binary").runSetupOnNewBinary() with method: "curl", channel: "nightly", install: true, ensureAuthScopes: !json, and the supplied noAgentSkills; it releases the download lock in finally.npm uninstall -g sentry, pnpm remove -g sentry, bun remove -g sentry, yarn global remove sentry, and brew uninstall getsentry/tools/sentry.resolveContext() derives channel and versionArg via resolveChannelAndVersion(version), compares against getReleaseChannel() to set channelChanged, detects the installation method unless flags.method is provided, and calls validateMethod(method, versionArg, channel, flags.offline).persistChannel() must run after offline target resolution because setReleaseChannel() clears the version-check cache; it persists when the channel changed or the positional version is nightly or stable.startChangelogFetch() skips work in offline mode or when current and target versions match; otherwise it calls fetchChangelog({ channel, fromVersion, toVersion }) and swallows errors so changelog failure never blocks an upgrade.--check before any actual upgrade, and skips an already-current target unless --force is set or the release channel changed.channel === "nightly" && method !== "curl" invokes migrateToStandaloneForNightly(); all other cases invoke executeStandardUpgrade().action ("downgraded" or "upgraded"), currentVersion, targetVersion, channel, method, forced, optional offline, optional migration warnings, and optional changelog.packages/cli/src/lib/version-check.ts selects fetchLatestNightlyVersion(signal) for the nightly channel and fetchLatestFromGitHub(signal) otherwise.packages/cli/install downloads nightlies from GHCR only when requested_version == "nightly"; it requires no jq and parses token, manifest version, and layer digest with awk.packages/cli/install nightly flow is ordered as: 1. obtain an anonymous token from https://ghcr.io/token?scope=repository:getsentry/cli:pull; 2. fetch https://ghcr.io/v2/getsentry/cli/manifests/nightly with bearer authorization and OCI manifest Accept; 3. extract the version annotation; 4. locate sentry-${os}-${arch}${libc_suffix}${suffix}.gz and its digest; 5. obtain the GHCR blob redirect URL without curl -L; 6. download without authorization and pipe through gunzip into $tmp_binary.curl -s -w '\n%{redirect_url}' -o /dev/null -H "Authorization: Bearer $GHCR_TOKEN" "https://ghcr.io/v2/getsentry/cli/blobs/${digest}" | tail -1; it then runs curl -sf "$redir_url" | gunzip > "$tmp_binary".packages/cli/install resolves an omitted version from https://api.github.com/repos/getsentry/cli/releases/latest, strips a leading v, constructs https://github.com/getsentry/cli/releases/download/${version}/${filename}, tries ${url}.gz first, and falls back to the raw binary. The compressed asset is documented as approximately 60% smaller, about 37 MB versus 99 MB.packages/cli/install checks for libstdc++; when running as root with apk, it installs libstdc++ libgcc using apk add --no-cache, while a non-root user is instructed to run apk add libstdc++ libgcc.packages/cli/install supports only windows-x64 on Windows, adds .exe, writes to ${TMPDIR:-${TMP:-${TEMP:-/tmp}}}/sentry-install-$$${suffix}, registers trap 'rm -f "$tmp_binary"' EXIT, and applies chmod +x.packages/cli/install delegates placement and configuration to "$tmp_binary" cli setup $setup_args; setup_args begins with --install --method curl --channel nightly for a nightly request and --channel stable otherwise, with optional --no-modify-path, --no-completions, and --no-agent-skills.SENTRY_INIT=1, packages/cli/install optionally launches the setup wizard after installation and reconnects stdin to the real terminal so interactive prompting works when invoked through curl | bash.packages/cli/test/lib/delta-upgrade.test.ts contains dedicated suites for resolveStableChain, resolveNightlyChain, attemptDeltaUpgrade, prefetchNightlyPatches, and prefetchStablePatches; explicit prefetch examples use nightly 0.14.0-dev.123 and stable 0.14.0.