All notable changes to bugsee-cli are documented here. The format follows
Keep a Changelog and this project
adheres to Semantic Versioning.
0.7.5 - 2026-08-24
Dependency and security maintenance. No functional changes — the CLI surface, exit codes, stdout JSON shapes, and upload wire format are byte-for-byte identical to 0.7.4, so no integrator needs to move its version floor. Upgrade for the dependency fixes below.
quick-xml0.39.4 -> 0.41.0 (viaplist) — fixes two denial-of-service advisories in XML parsing: RUSTSEC-2026-0194 (quadratic run time when a start tag is checked for duplicate attribute names) and RUSTSEC-2026-0195 (unbounded namespace-declaration allocation inNsReaderenabling memory exhaustion). This code is reachable:build-env read-plistparses XMLInfo.plistfiles throughplist.time0.3.48 -> 0.3.55 (viaplist) — 0.3.48 was yanked upstream and had shipped since before 0.7.4.anyhow1.0.102 -> 1.0.104 — fixes unsoundness inError::downcast_mut(). Not reachable here (this crate only callsdowncast_ref), included for hygiene.- Advisories that do not apply to the shipped binary, for the record:
quinn-protoRUSTSEC-2026-0185 andh2RUSTSEC-2026-0258 are absent from the release build —reqwestis configured withouthttp2, andh2is pulled in only by thewiremockdev-dependency. Verified by inspecting compiled artifacts, not the lockfile.
zip2.4.2 -> 8.6.0 (two major bumps). The upload ZIP is unchanged: entry names, STORED artefacts, method 93 (Z_STANDARD) mappings, and the fixed 1980-01-01 timestamps all produce byte-identical archives to 0.7.4.sha1,sha2, andmd-50.10 -> 0.11 (RustCryptodigest0.11). Content fingerprints, chunk identities, and the md5-derived Java-compatibleBUILD_UUIDs are unchanged.- Routine bumps:
tokio1.52 -> 1.53, plusclap,serde,serde_json,regex,uuid,globset,libc,plist,thiserror,futures-util. - Declared MSRV corrected to 1.88 (
rust-version). The previous1.79was inaccurate and had been for several releases — the locked tree already required 1.88 viagimli,globset,plist, andtime. This documents reality rather than dropping support: no toolchain that could build 0.7.4 loses the ability to build 0.7.5. Only affects building from source; released binaries are unaffected.
indicatif— declared but referenced nowhere in the source. Also prunesconsole,encode_unicode,portable-atomic,unicode-width, and the unmaintainednumber_prefix(RUSTSEC-2025-0119).
- Tag releases were broken. Dependabot's action bumps rewrote pins inside
.github/workflows/release.yml, which cargo-dist generates and itsplanjob verifies; sinceplanis the first job of the release workflow, avX.Y.Ztag push would have failed before building any artefact.[workspace.metadata.dist]now setsallow-dirty = ["ci"]. CI/release only — no effect on the binary.
0.7.4 - 2026-08-11
debug-files upload --type il2cpp-linemap— upload Unity IL2CPPLineNumberMappings.json(+ siblingMethodMap.tsv/il2cppFileRoot.txt) keyed bylibil2cpp/UnityFrameworkmodule UUID(s). Seedocs/unity-il2cpp-linenumber-mappings.md.debug-files upload --type rust— one command for a Cargo project, whatever target it built for. A Rust project's symbols are a.dSYM(Apple), a.pdb(*-pc-windows-msvc), or the ELF binary itself keyed by its GNU build-id (Linux/Android); this discovers whichever is present and routes each to the same upload path its--type-specific command would use.- Discovery is content-based (container magic, not host OS), so a
cross-compiled
target/<triple>/releaseuploads correctly from any host. - Cargo intermediates —
deps/,build/,incremental/,.fingerprint/— are skipped; walking them would register a symbol document per dependency and build script. - Loose ELF binaries are uploaded per-file, keyed by build-id with the
Breakpad transform (the existing
--type elfpath takes AGP's pre-builtnative-debug-symbols.zipand is unchanged). --uuidis rejected: every Rust debug format carries its own identity, and that identity is what the SDK reports for the module at crash time.
- Discovery is content-based (container magic, not host OS), so a
cross-compiled
- Build-configuration preflight for Rust. Each format has a setting that,
when missing, yields an upload that is accepted and then resolves nothing —
no DWARF (
debug = 0), no.dSYM(split-debuginfonot"packed"), no build-id (missing-Wl,--build-id). Near-misses found during the walk are warned about with the exact stanza that fixes them, and a walk that finds nothing uploadable fails with the full recipe instead of a bare "not found". Verified against realcargo build --releaseoutput in both directions.
- Cargo publishes the profile-root
.dSYMas a symlink intodeps/, whichwalkdirdoes not follow — combined with skippingdeps/, a correctly configured macOS build would have been reported as missing its debug info and advised to setsplit-debuginfo, which it already had.
0.7.3 - 2026-07-16
- Security — credential leak in logs. The app token (embedded in
registration paths) and S3 SigV2 signatures (in presigned-PUT query strings)
no longer reach error messages or logs. A transport-error path echoed the full
reqwestURL at the DEFAULT log level — and to thexcode post-actiondaemon log file — leaking both; it now scrubs the URL (without_url()), and the debug-level URL log fields are redacted via a sharedredact_urlhelper.
- Hardening from an adversarial review:
updaterefuses a non-HTTPS download base except loopback, and caps artefact (512 MiB) / metadata (1 MiB) download sizes so a hostile or misconfigured origin can't OOM the host before the SHA-256 check.updatearchive extraction lists and rejects absolute /..-traversal entries before unpacking.sourcemaps injectrejects../ absolute//# sourceMappingURL=targets, so a crafted bundle can't steer it at a file outside the bundle directory.- per-
.sonative-upload staging ZIPs are uniquely named, preventing a path collision under concurrent upload if two libraries shared a build-id. - chunked-upload buffers are bounded to the actual chunk length instead of the
raw server-provided
chunk_size(a largechunk_sizefor a small artefact no longer over-allocates).
0.7.2 - 2026-07-11
- Bumped
symbolic-common/symbolic-debuginfo13.8.0→13.9.0. The ELFcode_idand Mach-Odebug_idthe CLI reads are stable across major-13 minors; the arch/format identifier-pinning tests confirm no drift.
0.7.1 - 2026-07-06
- Bumped
symbolic-common/symbolic-debuginfo13.6.0→13.8.0. The ELFcode_idand Mach-Odebug_idthe CLI reads are stable across major-13 minors, so this stays identifier-compatible with the worker'ssymbolic.
- Pinned
symbolic's identifier extraction with real-bytes fixtures across every arch/format the CLI parses, so a future crate bump that drifted an identifier is caught: ELFcode_idandarchon a real aarch64.so; Mach-Odebug_id+archfor x86_64, arm64, and fat/universal binaries (a new hand-assembled, toolchain-free synthesizer exercises symbolic's multi-arch iteration); and thexcodeIPA main-executable UUID extraction's positive path (previously only itsNonecases were covered).
0.7.0 - 2026-06-25
- Self-hosted install scripts:
curl … https://download.bugsee.com/cli/install.sh | sh(macOS/Linux) andirm …/cli/install.ps1 | iex(Windows PowerShell). They resolve the latest version from the mirror, download + SHA-256-verify the host's binary fromdownload.bugsee.com(no GitHub dependency), and install it — overridable viaBUGSEE_CLI_VERSION/BUGSEE_CLI_INSTALL_DIR/BUGSEE_CLI_BASE_URL. Published at stable URLs by the release mirror.
debug-files upload --type elfnow uploads native symbols per.so, keyed by each library's real GNU build-id (code_id, extracted viasymbolic-debuginfo— identical to the worker's) instead of the build-level--uuid. Each.sois registered + uploaded as its own symbol document (pipelines run in parallel), which (a) stops native symbols from colliding with the ProGuard mapping server-side — both previously shared the build UUID — and (b) enables per-library dedup: an unchanged.so(same build-id) is skipped before its bytes transfer. A.sobuilt without-Wl,--build-idhas nocode_id; it is warned about and skipped (it can't be matched at crash time anyway, so it is never faked with the build UUID).- Bumped
symbolic-common/symbolic-debuginfo13→13.6.0. The ELFcode_idthe native upload reads is stable across major-13 minors, so this stays identifier-compatible with the worker'ssymbolic13.1.1.
upload build-infonow sendsContent-Type: application/octet-streamon the presigned PUT. The appserver signs the build-info URL with that Content-Type, so omitting it made S3 reject the upload with a 403SignatureDoesNotMatch. The artefact and chunk PUTs already set it; this aligns the build-info path with them.
0.6.0 - 2026-06-17
update— self-update the binary in place. Resolves the newest published version WITHIN THE SAME MAJOR as the running binary (minor/patch are non-breaking; a major bump is never auto-adopted), downloads and SHA-256-verifies the release for the host triple, and atomically replaces the current executable (self-replace, so the Windows running-.execase works).--checkreports only;--version X.Y.Zinstalls an exact version.- Release mirror now publishes tiny version pointers for auto-update discovery:
cli/latest/version.txt(absolute latest) andcli/v<major>.x/version.txt(latest within a major). Both advance-only. The per-major pointer is the shared contract the CLI'supdate, the Android Gradle plugin, and the iOS BugseeAgents all read to find the newest non-breaking version.
0.5.0 - 2026-06-17
xcode post-actionCLI flags as alternatives to itsBUGSEE_*environment variables. Every toggle now has a matching--enable-<x>/--disable-<x>pair (build-info, all-actions, all-configurations, dependencies, timings, size-analysis, chunked-upload, size-check), and every size-check threshold a value flag (--size-check-warning-pct/--size-check-fail-pct/--size-check-warning-bytes/--size-check-fail-bytes). A flag passed on the command line overrides the corresponding env var; within a pair the last flag wins; an unset flag falls back to the env var / default.
0.4.0 - 2026-06-17
The release that moves the whole iOS build-publish flow into the CLI: one
xcode post-action command does what the iOS SDK's build script used to do in
process, and dSYM uploads gain recursive discovery + pre-upload dedup.
xcode post-action— run the entire iOS build-publish flow from an Xcode "Run Script" post-action: decode build timings from the.xcactivitylog, package the.appinto a synthetic.ipa, register the build, upload the artefact (when size-analysis is enabled) and the build-info bundle, upload dSYMs, and run an optional in-build size-check. Runs in the background by default (detaches so the archive returns immediately, logging to$PROJECT_TEMP_DIR/bugsee-cli.log);--force-foregroundruns synchronously. Configured throughBUGSEE_*environment variables — seebugsee-cli xcode post-action --help.debug-files upload --type dsymrecursive discovery — point at an Xcode archive'sdSYMs/folder (or a whole DerivedData tree) and every*.dSYMbundle is found and uploaded; no need to enumerate bundles yourself.- dSYM pre-upload dedup — the Mach-O slice UUIDs are declared up front so the
server can skip bundles it already has BEFORE the (possibly large) DWARF bytes
are packed or transferred.
--forcere-uploads. - In-build size-check — fail the build with the new exit code 40
(
SizeCheckFailed) when the artefact grows past a configured threshold (in--force-foreground).
--helpnow documents every command, argument, option, and value-enum variant, including theBUGSEE_*environment variables that configurexcode post-action.
0.3.0 - 2026-06-15
The release that completes the build-time upload unification surface: artefact uploads and JS source maps now both flow through the CLI, so producers (Gradle plugin, fastlane, BugseeAgent) no longer maintain their own HTTP/compression/ retry/chunking stacks.
upload build— register a build and upload its artefact in one shot. Packs the artefact (STORED) plus an optional R8/ProGuard mapping (zstd, method 93) into the normalized upload ZIP, then either single-PUTs it or runs the chunked protocol (--chunked). Emits the build-info bundle from the same registration and prints the resultingbuild_idto stdout.upload build --chunked— full builds chunked-upload protocol (chunk-options → streamed SHA-1 hashing → chunk check → PUT-missing dedup → chunked submit), for artefacts above the single-PUT threshold.sourcemaps inject— embed a deterministic, content-derived UUIDv5 debug-id into JS bundles (//# debugId=plus a defensiveglobalThis._bugseeDebugIdsruntime stub) and into the paired.map(debug_id+debugId). Idempotent and--dry-runaware.debug-files upload --type sourcemaps— discover.mapfiles, key each by its embedded debug-id (precedencedebug_id→debugId→ legacyuuid, or a caller-supplied--uuid), pack as a single zstd entry, and upload through the shared presigned protocol. The worker auto-detects the sourcemap format by content and re-derives the same key.
presigned.rsnow runs entirely on the sharedupload::httplayer (one HTTP client, telemetry header, retry/backoff, and log-truncation implementation across every upload path), and takes an explicitRetryPolicy.
sourcemaps upload— folded intodebug-files upload --type sourcemapsso every symbol/debug artefact uploads through one command surface.
0.2.0 - 2026-06
upload build-info— per-build metadata bundle upload, plus the sharedupload::httplayer (Phase A of the upload unification).pack— build the normalized upload ZIP locally (artefact STORED, mapping zstd method 93) for producers that upload the result themselves.
- Crate made fully
rustfmt+clippyclean to keep CI green onmain.
0.1.1 - 2026
- Homebrew and npm publish channels (the latter via OIDC / Trusted Publishing).
0.1.0 - 2026
- Initial release: debug-file collection, conversion, and upload — dSYM upload
(
debug-files upload --type dsym), dSYM UUID/slice inspection (dsym), and the canonical CI resolvers (vcs-metadata,ios-deps,build-env).