Developer guide
Release symbols and source maps
Upload debug files from the exact build you ship so monitoring stack traces can be resolved to application code.
Build once, identify it, upload, then deploy
Keep the app release value, source commit and debug-file IDs tied to one build. A rebuild can change IDs even when the version string stays the same. Store the release artifacts and their matching symbols together. Upload with the project secret key in your CI secret store, never the app's SDK token or ingest key or a browser-visible environment variable.
Web source maps
Install npm install -D @bugcapsule/cli@0.4.0-beta.2 alongside the web SDK. Configure your bundler to emit source maps, then run:
npm run build
npx --no-install bugcapsule-cli sourcemaps inject dist
npx --no-install bugcapsule-cli sourcemaps upload dist --dry-run \
--url https://api.bugcapsule.com --release shop-web@1.4.0+52 --url-prefix '~/'
npx --no-install bugcapsule-cli sourcemaps upload dist \
--url https://api.bugcapsule.com --release shop-web@1.4.0+52 --url-prefix '~/'
Set BUGCAPSULE_SECRET_KEY through CI secrets before upload. Replace the API URL and release. Injection appends a matching debug ID to the bundle and map; deploy the injected bundle without rebuilding it. If bundles are served under /static/js/, use the matching --url-prefix '~/static/js'. After a successful upload, exclude maps from the public deployment while retaining a private copy. Verify that your deployment does not expose them.
Flutter AOT and obfuscation
OBF_ID=$(bugcapsule symbols new-id)
flutter build apk --release --obfuscate --split-debug-info=build/symbols \
--extra-gen-snapshot-options=--save-obfuscation-map=build/obfuscation.json \
--dart-define=BUGCAPSULE_OBFUSCATION_ID="$OBF_ID"
bugcapsule symbols upload --split-debug-info build/symbols \
--obfuscation-map build/obfuscation.json --obfuscation-id "$OBF_ID" \
--release com.shop.app@1.4.0+52
This example builds Android; use the appropriate Flutter build target for your release. The upload requires an authorized credential with debug-file upload access. Keep the generated obfuscation ID and map associated with the build; do not generate a different ID for upload. Use --dry-run to inspect the upload plan.
Android R8/ProGuard
Apply the SDK's io.github.bugcapsule.gradle plugin. Resolve the published beta plugin through Maven Central:
pluginManagement {
repositories { google(); mavenCentral(); gradlePluginPortal() }
}
plugins { id("io.github.bugcapsule.gradle") version "0.4.1-beta.4" }
bugcapsule {
url.set("https://api.bugcapsule.com")
uploadProguardMapping.set(true)
failOnUploadError.set(true)
}
Use BUGCAPSULE_SECRET_KEY in the build environment. For minified variants the plugin derives a UUID from mapping.txt, embeds bugcapsule-debug-meta.properties and uploads the mapping after assemble/bundle. With no URL or key, upload is skipped even though the ID is embedded. Use uploadBugCapsuleProguardMapping<Variant> to upload explicitly. Test a minified QA build; a successful debug build does not verify R8 behavior.
iOS dSYMs
From the SDK checkout, point the provided script at the archive from the build you shipped:
# BUGCAPSULE_URL and BUGCAPSULE_SECRET_KEY come from CI configuration.
BUGCAPSULE_ALLOW_FAILURE=0 sh scripts/bugcapsule-upload-dsyms.sh /path/to/App.xcarchive/dSYMs
Build with DEBUG_INFORMATION_FORMAT=dwarf-with-dsym. The uploader sends each DWARF file by UUID/architecture. In an Xcode build phase it can use DWARF_DSYM_FOLDER_PATH and skips Debug builds. In Xcode its default tolerates upload errors; set BUGCAPSULE_ALLOW_FAILURE=0 when upload is a release gate.
Verify and diagnose
- Check uploader exit status and that the expected debug files appear in project settings.
- Trigger a QA error from the same built artifact and inspect the event's release, debug images and frames.
- If unresolved, compare event debug IDs/UUIDs, architecture, release and served bundle paths with uploaded files. Uploading symbols from another build cannot repair the mismatch.
- Retain matching symbols for as long as supported app builds can report errors. A capsule's replay verdict is independent of whether its monitoring stack was symbolicated.
Real uploaded native dSYM/ELF symbolication end to end is still an explicit release-validation gate in the reviewed local records. Treat successful upload as one step, not proof of readable native frames.