These are instructions for building, running, and testing the Rust CLI locally. Note that any changes are tightly coupled with Trunk Flaky Test services.
- Install a nightly version of Cargo using rustup
- Run
trunk tools install
cargo buildThe CLI will be built to target/debug/trunk-analytics-cli
For detailed build instructions for each supported package, see their respective README files:
- Python Bindings: See context-py/README.md
- JavaScript/TypeScript Bindings: See context-js/README.md
- Ruby Gem (RSpec Plugin): See rspec-trunk-flaky-tests/README.md
cargo build
./target/debug/trunk-analytics-cli upload --org-url-slug=trunk-io --token=${API_TOKEN} --junit-paths=junit.xmlYou can generate sample junit files by running
cargo run --bin junit-mock .You can change the API endpoint by setting TRUNK_PUBLIC_API_ADDRESS=https://api.trunk.io. To use localhost, you should use TRUNK_PUBLIC_API_ADDRESS=http://localhost:9010 DEBUG_STRIP_VERSION_PREFIX=true
This project uses nextest for running Rust tests. It provides faster test execution, better output, and more reliable test runs.
Install nextest:
cargo install cargo-nextest --lockedRun tests with nextest:
# Run all tests
cargo nextest run
# Run tests with CI profile (includes JUnit output)
cargo nextest run --profile ci
# Run tests for a specific package
cargo nextest run -p <package-name>You can also use the standard cargo test command if you really want:
cargo testThe tracing library is used for:
- Sentry reporting: Errors and warnings are automatically sent to Sentry for monitoring and debugging
- Debug logging: Internal debug information that helps with development and troubleshooting
Important: Tracing output does not surface to users unless they use the --verbose flag. By default, no tracing messages are shown in the console. They are primarily for Sentry reporting and debugging.
--org-url-slug (env TRUNK_ORG_URL_SLUG) is declared as a non-optional String on UploadArgs, which makes it a hard requirement for both upload and test. Keep it that way: the slug is what attributes a run to an organization across every kind of telemetry we collect.
- Sentry:
setup_loggerincli/src/main.rsattaches it as anorg_url_slugtag on everytracing::error!()event forwarded to Sentry, alongsidecommand_nameandrepo_root. Those tags are how Trunk narrows Sentry to a single customer's CI runs when someone reports a failing upload — without the slug, an error report can't be tied back to an organization and we have to ask the user to reproduce. - Our own upload telemetry: the slug is stored on the bundle as
base_props.organd scopes theUploadMetricswe report to the telemetry endpoint at the end of a run (cli/src/upload_command.rs,ApiClient::telemetry_upload_metrics). Timing, quarantine outcome, and failure-reason metrics are only useful if we know which org they came from.
The slug also travels with the upload requests, builds the org-scoped links we print for uploads and tests (api/src/urls.rs), and backs the settings-page hint shown on unauthorized errors (cli/src/error_report.rs).
validate is the one exception. It runs entirely locally and does not accept the flag, so Cli::org_url_slug() returns the placeholder "not used" for that subcommand — errors from validate land in Sentry with that placeholder tag rather than a real org.
The superconsole library is used for surfacing information to users. This is the primary mechanism for displaying:
- Progress messages
- Status updates
- Final results
- User-facing error messages
When errors occur:
- Always capture errors with
tracing::error!()- This ensures errors are logged to Sentry for monitoring - Surface blocking errors to users via
superconsole- If an error blocks execution, it should be displayed to the user through the display system (seecli/src/error_report.rsfor examples)
The pattern is:
- Use
tracingfor observability and debugging (Sentry + optional verbose output) - Use
superconsolefor user-facing communication - Errors that block execution should use both:
tracingfor logging andsuperconsolefor user display