diff --git a/bundle/src/bundle_meta.rs b/bundle/src/bundle_meta.rs index cbd85cba..e6b4ec48 100644 --- a/bundle/src/bundle_meta.rs +++ b/bundle/src/bundle_meta.rs @@ -115,6 +115,8 @@ impl From for BundleMetaV0_5_29 { #[cfg_attr(feature = "wasm", derive(Tsify))] pub struct BundleMetaDebugProps { pub command_line: String, + #[serde(default)] + pub trunk_envs: HashMap, } #[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)] diff --git a/bundle/src/bundler.rs b/bundle/src/bundler.rs index faa237f4..0976c852 100644 --- a/bundle/src/bundler.rs +++ b/bundle/src/bundler.rs @@ -394,6 +394,7 @@ mod tests { bundle_upload_id_v2: String::with_capacity(0), debug_props: BundleMetaDebugProps { command_line: String::with_capacity(0), + trunk_envs: HashMap::new(), }, variant: Some("variant".to_string()), base_props: BundleMetaBaseProps { diff --git a/cli/src/context.rs b/cli/src/context.rs index 201d6ef4..75694b2f 100644 --- a/cli/src/context.rs +++ b/cli/src/context.rs @@ -16,7 +16,7 @@ use bundle::{ QuarantineBulkTestStatus, TestCollectionProps, bin_parse, }; use codeowners::{CodeOwners, OwnersSource}; -use constants::{ENVS_TO_GET, TRUNK_PR_NUMBER_ENV}; +use constants::{ENVS_TO_GET, TRUNK_API_TOKEN_ENV, TRUNK_ENVS_TO_CAPTURE, TRUNK_PR_NUMBER_ENV}; use context::{ bazel_bep::{ binary_parser::BazelBepBinParser, @@ -67,12 +67,22 @@ lazy_static! { // This function is used to gather debug properties for the bundle meta. // It will trigger EXC_BAD_ACCESS on arm64-darwin builds when compiled under cdylib pub fn gather_debug_props(args: Vec, token: String) -> BundleMetaDebugProps { + let trunk_envs: HashMap = TRUNK_ENVS_TO_CAPTURE + .iter() + .filter_map(|&env_var| { + env::var(env_var) + .map(|env_var_value| (env_var.to_string(), env_var_value)) + .ok() + }) + .collect(); + BundleMetaDebugProps { command_line: COMMAND_REGEX .replace(&args.join(" "), "") .replace(&token, "") .trim() .to_string(), + trunk_envs, } } @@ -952,6 +962,8 @@ fn parse_num_tests(file_sets: &[FileSet]) -> usize { #[cfg(test)] mod tests { + use std::collections::HashMap; + use std::env; use bundle::BundleMetaDebugProps; #[cfg(target_os = "macos")] @@ -976,6 +988,7 @@ mod tests { upload_args.clone(), BundleMetaDebugProps { command_line: "test".to_string(), + trunk_envs: HashMap::new(), }, ) .unwrap(); @@ -988,6 +1001,7 @@ mod tests { upload_args.clone(), BundleMetaDebugProps { command_line: "test".to_string(), + trunk_envs: HashMap::new(), }, ) .unwrap(); @@ -1000,6 +1014,7 @@ mod tests { upload_args, BundleMetaDebugProps { command_line: "test".to_string(), + trunk_envs: HashMap::new(), }, ) .unwrap(); @@ -1115,4 +1130,41 @@ mod tests { let debug_props = super::gather_debug_props(args, "token".to_string()); assert_eq!(debug_props.command_line, "trunk flakytests"); } + + #[test] + fn test_gather_debug_props_trunk_envs() { + unsafe { + env::set_var("TRUNK_REPO_URL", "https://github.com/example/repo"); + env::set_var("TRUNK_API_TOKEN", "supersecret"); + env::set_var("TRUNK_VARIANT", "my-variant"); + } + + let args: Vec = vec!["trunk".into(), "upload".into()]; + let debug_props = super::gather_debug_props(args, "irrelevant".to_string()); + + // TRUNK_REPO_URL is in the allowlist, should be captured + assert_eq!( + debug_props + .trunk_envs + .get("TRUNK_REPO_URL") + .map(String::as_str), + Some("https://github.com/example/repo") + ); + // TRUNK_API_TOKEN is intentionally excluded from the allowlist + assert!(!debug_props.trunk_envs.contains_key("TRUNK_API_TOKEN")); + // TRUNK_VARIANT is in the allowlist, should be captured + assert_eq!( + debug_props + .trunk_envs + .get("TRUNK_VARIANT") + .map(String::as_str), + Some("my-variant") + ); + + unsafe { + env::remove_var("TRUNK_REPO_URL"); + env::remove_var("TRUNK_API_TOKEN"); + env::remove_var("TRUNK_VARIANT"); + } + } } diff --git a/constants/src/lib.rs b/constants/src/lib.rs index 5d9f7661..365f7828 100644 --- a/constants/src/lib.rs +++ b/constants/src/lib.rs @@ -48,6 +48,35 @@ pub const TRUNK_TEST_PROCESS_EXIT_CODE_ENV: &str = "TRUNK_TEST_PROCESS_EXIT_CODE pub const TRUNK_VALIDATION_REPORT_ENV: &str = "TRUNK_VALIDATION_REPORT"; pub const TRUNK_SHOW_FAILURE_MESSAGES_ENV: &str = "TRUNK_SHOW_FAILURE_MESSAGES"; pub const TRUNK_DEBUG_ENV: &str = "TRUNK_DEBUG"; + +// TRUNK_* environment variables to capture in bundle metadata for debugging. +// TRUNK_API_TOKEN_ENV is intentionally omitted. +pub const TRUNK_ENVS_TO_CAPTURE: &[&str] = &[ + TRUNK_PUBLIC_API_ADDRESS_ENV, + TRUNK_API_CLIENT_RETRY_COUNT_ENV, + TRUNK_ORG_URL_SLUG_ENV, + TRUNK_TEST_COLLECTION_SHORT_ID_ENV, + TRUNK_REPO_ROOT_ENV, + TRUNK_REPO_URL_ENV, + TRUNK_REPO_HEAD_SHA_ENV, + TRUNK_REPO_HEAD_BRANCH_ENV, + TRUNK_REPO_HEAD_COMMIT_EPOCH_ENV, + TRUNK_REPO_HEAD_AUTHOR_NAME_ENV, + TRUNK_PR_NUMBER_ENV, + TRUNK_QUARANTINED_TESTS_DISK_CACHE_TTL_SECS_ENV, + TRUNK_CODEOWNERS_PATH_ENV, + TRUNK_CODEOWNERS_TYPE_ENV, + TRUNK_VARIANT_ENV, + TRUNK_USE_UNCLONED_REPO_ENV, + TRUNK_DISABLE_QUARANTINING_ENV, + TRUNK_ALLOW_EMPTY_TEST_RESULTS_ENV, + TRUNK_DRY_RUN_ENV, + TRUNK_TEST_PROCESS_EXIT_CODE_ENV, + TRUNK_VALIDATION_REPORT_ENV, + TRUNK_SHOW_FAILURE_MESSAGES_ENV, + TRUNK_DEBUG_ENV, +]; + pub const ENVS_TO_GET: &[&str] = &[ "CI", "GIT_BRANCH", diff --git a/context-js/tests/parse_compressed_bundle.test.ts b/context-js/tests/parse_compressed_bundle.test.ts index 749a50f1..5c391e5c 100644 --- a/context-js/tests/parse_compressed_bundle.test.ts +++ b/context-js/tests/parse_compressed_bundle.test.ts @@ -200,6 +200,7 @@ const VERSION_TESTS = [ num_tests: faker.number.int(100), num_files: faker.number.int(100), command_line: "trunk-analytics-cli upload --token=***", + trunk_envs: {}, }, { schema: "V0_7_7", @@ -210,6 +211,7 @@ const VERSION_TESTS = [ bundle_upload_id_v2: "SOME ID", variant: null, internal_bundled_file: null, + trunk_envs: {}, }, { schema: "V0_7_8", @@ -221,6 +223,7 @@ const VERSION_TESTS = [ variant: null, internal_bundled_file: null, failed_tests: [], + trunk_envs: {}, }, ] as const satisfies VersionedBundle[]; @@ -377,6 +380,7 @@ describe("context-js", () => { bundle_upload_id_v2: "SOME ID", variant: "some-variant", internal_bundled_file: null, + trunk_envs: {}, } as const satisfies VersionedBundle; const metaInfoJson = JSON.stringify( versionedBundle, diff --git a/test_report/src/report.rs b/test_report/src/report.rs index a3254d4b..f1455673 100644 --- a/test_report/src/report.rs +++ b/test_report/src/report.rs @@ -636,6 +636,7 @@ impl MutTestReport { .and_then(|v| v.parse::().ok()); let debug_props = BundleMetaDebugProps { command_line: self.0.borrow().command.clone(), + trunk_envs: HashMap::new(), }; let test_run_result = trunk_analytics_cli::test_command::TestRunResult { command: self.0.borrow().command.clone(),