CLI

Build-time and CI tooling: upload debug symbols and symbolication artifacts, and report deployments. Node 18+; installing globally exposes the bugwatch bin, or run everything with npx @newinstance/bugwatch-cli.

Auth: --token flag or BUGWATCH_AUTH_TOKEN env (flag wins), value KEYID:secret. --api-url / BUGWATCH_API_URL defaults to https://api.newinstance.cloud. The key travels only in the x-api-key header, never in URLs or logs; output shows a redacted form like sk_l…3456.

Commandslink

CommandPurposeScope
symbols upload <path>Binary debug symbols: a .dSYM, a directory (recursive, depth 4), an .xcarchive (its dSYMs folder is walked), a pre-made .zip (uploaded as-is), or Android ELF .so filessymbols:upload
artifacts upload <path>Text artifacts: R8/ProGuard mapping, JS source map, Dart symbols. --release, --platform, --type required; optional --build-idsymbols:upload
deploy startCreate a deployment; prints the id and persists itdeploy:write
deploy run --stage <key> -- <cmd…>Run a command as a stage: mark running, stream logs, mark resultdeploy:write
deploy finish / deploy fail [--summary <text>] [--stage <key>]Close the deployment; --summary defaults to "deployment failed"deploy:write

symbols upload flags: --platform (default ios; also macos, tvos, watchos, visionos, catalyst, android), --release, --build-number, --bundle-id, --distribution, --environment, --commit, --upload-source (default cli; xcode-cloud and local-xcode exist for those flows).

The two upload commands validate input by magic bytes: passing a mapping.txt or .map to symbols upload fails with UNRECOGNIZED_ARCHIVE. Packing a dSYM needs a macOS runner with zip; a pre-made .zip skips that requirement.

How uploads worklink

  1. Presign, 2. stream the file straight to object storage with flat memory, 3. complete. The key is sent only on steps 1 and 3, never to the storage host; the server verifies size and sha256 (CHECKSUM_MISMATCH on tamper). Retries: 3 attempts on 5xx, 429 and network errors with 500/1000/1500 ms backoff; 4xx never retries; the stream reopens per attempt and temp zips are always cleaned up. A duplicate sha256 skips the transfer entirely and exits 0. artifacts upload is idempotent per release, platform and type: re-uploading replaces the previous file. Server cap for symbol archives: 2 GB.

Verify: the CLI prints an uploadId; poll GET /api/v1/bugwatch/debug-symbols/uploads/{id} (scope symbols:read) until the status leaves QUEUED and PROCESSING.

Deployments in CIlink

export BUGWATCH_AUTH_TOKEN="sk_live_KEYID:secret"

npx @newinstance/bugwatch-cli deploy start --release "2.4.1"
npx @newinstance/bugwatch-cli deploy run --stage migrate -- ./scripts/migrate.sh
npx @newinstance/bugwatch-cli deploy run --stage deploy  -- ./scripts/deploy.sh
npx @newinstance/bugwatch-cli deploy finish
  • deploy start auto-detects repo, branch, commit and triggeredBy on GitHub Actions, GitLab CI and CodeBuild, defaults release to the commit SHA, persists the id to .bugwatch-deploy, and on GitHub Actions also appends BUGWATCH_DEPLOY_ID to $GITHUB_ENV. Id resolution order everywhere: --id, then BUGWATCH_DEPLOY_ID, then .bugwatch-deploy.
  • deploy run passes the child output through to your console while shipping it as NDJSON batches (every 2 s or 64 KB) to the stage-logs endpoint; a failed stage attaches the last 50 lines as an error summary (truncated to 2000 chars). Its exit code is the child command's (127 if it cannot spawn); missing --stage or command is exit 1.
  • Deploy reporting is deliberately non-fatal: start, finish and fail exit 0 even with no token, no id, or an API error, and deploy run still executes your command unreported. Your pipeline never breaks because telemetry did.

Exit codeslink

0 accepted (or duplicate skip), 1 usage or input error, 2 upload failure after retries.

Troubleshootinglink

  • Frames still unresolved: the dSYM must come from the exact crashing build; compare dwarfdump --uuid MyApp.dSYM with the event's binary images. Upload the whole .xcarchive so framework dSYMs come along. Simulator builds produce no dSYM; the build setting must be DWARF with dSYM File.
  • Mapping uploaded but stacks unreadable: the --release string must equal the release the SDK reports at runtime.

All commands call the endpoints documented in Source Maps & Symbols and Deployments (CI/CD); the CLI is sugar over those endpoints.