From b574256f7590645eabf27bfe821b023f0123d982 Mon Sep 17 00:00:00 2001 From: CodeGhost21 <164498022+CodeGhost21@users.noreply.github.com> Date: Mon, 4 May 2026 22:57:43 +0530 Subject: [PATCH] =?UTF-8?q?chore(sentry):=20rename=20OPENHUMAN=5FSENTRY=5F?= =?UTF-8?q?DSN=20=E2=86=92=20OPENHUMAN=5FCORE=5FSENTRY=5FDSN=20(#1186)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.example | 8 ++- .github/workflows/build-desktop.yml | 9 +-- .github/workflows/release-packages.yml | 13 ++-- src/core/cli.rs | 14 ++-- src/main.rs | 14 +++- src/openhuman/config/schema/load.rs | 8 ++- src/openhuman/config/schema/load_tests.rs | 69 +++++++++++++++++++- src/openhuman/config/schema/observability.rs | 4 +- 8 files changed, 116 insertions(+), 23 deletions(-) diff --git a/.env.example b/.env.example index 582b09227..ab0f2a13f 100644 --- a/.env.example +++ b/.env.example @@ -149,8 +149,12 @@ OPENHUMAN_SKILLS_WORKING_MEMORY_ENABLED=true # --------------------------------------------------------------------------- # Error Reporting (Sentry) # --------------------------------------------------------------------------- -# [optional] Sentry DSN for Rust core error reporting (no PII is sent) -OPENHUMAN_SENTRY_DSN= +# [optional] Sentry DSN for Rust core error reporting (no PII is sent). +# Reports to the `openhuman-core` Sentry project. The Tauri shell uses a +# separate `OPENHUMAN_TAURI_SENTRY_DSN`; the React frontend uses +# `VITE_SENTRY_DSN`. The legacy unprefixed name `OPENHUMAN_SENTRY_DSN` is +# still accepted as a fallback during the transition. +OPENHUMAN_CORE_SENTRY_DSN= # [optional] Short git SHA baked into the Sentry release tag # (`openhuman@+`) via `option_env!("OPENHUMAN_BUILD_SHA")`. # CI sets this automatically; leave blank locally (release tag falls back diff --git a/.github/workflows/build-desktop.yml b/.github/workflows/build-desktop.yml index 8fc52f8bc..41d4162cc 100644 --- a/.github/workflows/build-desktop.yml +++ b/.github/workflows/build-desktop.yml @@ -341,11 +341,12 @@ jobs: # disabled and the symbols uploaded below have nothing to attach # to. Same DSN as `release-packages.yml` uses for the Linux arm64 # tarball — there is one openhuman-core Sentry project that all - # standalone-CLI surfaces report to. - OPENHUMAN_SENTRY_DSN: ${{ vars.OPENHUMAN_SENTRY_DSN }} + # standalone-CLI surfaces report to. Prefer the namespaced GH + # var, fall back to the legacy unprefixed one during transition. + OPENHUMAN_CORE_SENTRY_DSN: ${{ vars.OPENHUMAN_CORE_SENTRY_DSN || vars.OPENHUMAN_SENTRY_DSN }} run: | - if [ -z "${OPENHUMAN_SENTRY_DSN}" ]; then - echo "::warning::vars.OPENHUMAN_SENTRY_DSN is empty — the standalone CLI artifact will ship without crash reporting." + if [ -z "${OPENHUMAN_CORE_SENTRY_DSN}" ]; then + echo "::warning::vars.OPENHUMAN_CORE_SENTRY_DSN (or legacy vars.OPENHUMAN_SENTRY_DSN) is empty — the standalone CLI artifact will ship without crash reporting." fi cargo build \ --manifest-path "$CORE_MANIFEST" \ diff --git a/.github/workflows/release-packages.yml b/.github/workflows/release-packages.yml index 25f29d13a..5d3615fad 100644 --- a/.github/workflows/release-packages.yml +++ b/.github/workflows/release-packages.yml @@ -53,21 +53,24 @@ jobs: - name: Verify Sentry DSN is present shell: bash env: - OPENHUMAN_SENTRY_DSN: ${{ vars.OPENHUMAN_SENTRY_DSN }} + # Prefer the namespaced GH var; fall back to the legacy unprefixed + # one so the workflow keeps working until the org-level variable + # is renamed. + OPENHUMAN_CORE_SENTRY_DSN: ${{ vars.OPENHUMAN_CORE_SENTRY_DSN || vars.OPENHUMAN_SENTRY_DSN }} run: | # Sentry DSN is baked into the binary at compile time via # `option_env!`. Missing DSN here means the arm64 CLI silently # ships without error reporting — fail the job instead. - if [ -z "${OPENHUMAN_SENTRY_DSN}" ]; then - echo "::error::vars.OPENHUMAN_SENTRY_DSN is empty — the Linux arm64 CLI would ship without error reporting." + if [ -z "${OPENHUMAN_CORE_SENTRY_DSN}" ]; then + echo "::error::vars.OPENHUMAN_CORE_SENTRY_DSN (or legacy vars.OPENHUMAN_SENTRY_DSN) is empty — the Linux arm64 CLI would ship without error reporting." echo "Configure the repository / environment variable before re-running the release." exit 1 fi - echo "OPENHUMAN_SENTRY_DSN is set (length=${#OPENHUMAN_SENTRY_DSN})" + echo "OPENHUMAN_CORE_SENTRY_DSN is set (length=${#OPENHUMAN_CORE_SENTRY_DSN})" - name: Build CLI binary and package tarball env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - OPENHUMAN_SENTRY_DSN: ${{ vars.OPENHUMAN_SENTRY_DSN }} + OPENHUMAN_CORE_SENTRY_DSN: ${{ vars.OPENHUMAN_CORE_SENTRY_DSN || vars.OPENHUMAN_SENTRY_DSN }} # Sentry release tracking (#405): keep the arm64 CLI tag in sync # with the desktop build (`openhuman@+`). OPENHUMAN_BUILD_SHA: ${{ github.sha }} diff --git a/src/core/cli.rs b/src/core/cli.rs index 6f602191b..0a20b5a35 100644 --- a/src/core/cli.rs +++ b/src/core/cli.rs @@ -88,8 +88,9 @@ pub fn run_from_cli_args(args: &[String]) -> Result<()> { /// and prints the event UUID to stdout. Optional `--panic` flag additionally /// triggers a panic so the panic integration is exercised too. /// -/// Requires a DSN resolvable at runtime — either via the `OPENHUMAN_SENTRY_DSN` -/// env var or baked into the binary at build time via `option_env!`. Absent a +/// Requires a DSN resolvable at runtime — either via the +/// `OPENHUMAN_CORE_SENTRY_DSN` env var (or the legacy `OPENHUMAN_SENTRY_DSN` +/// alias) or baked into the binary at build time via `option_env!`. Absent a /// DSN, the command exits non-zero with a diagnostic instead of silently /// producing no telemetry. fn run_sentry_test_command(args: &[String]) -> Result<()> { @@ -119,10 +120,11 @@ fn run_sentry_test_command(args: &[String]) -> Result<()> { println!(" --panic After capturing the event, trigger a panic so the"); println!(" panic integration reports it as a separate event."); println!(); - println!("Requires OPENHUMAN_SENTRY_DSN at runtime, or baked into the binary at"); println!( - "build time via option_env!. On success, prints the event UUID to stdout." + "Requires OPENHUMAN_CORE_SENTRY_DSN (or the legacy OPENHUMAN_SENTRY_DSN alias)" ); + println!("at runtime, or baked into the binary at build time via option_env!. On"); + println!("success, prints the event UUID to stdout."); return Ok(()); } other => return Err(anyhow::anyhow!("unknown sentry-test arg: {other}")), @@ -140,8 +142,8 @@ fn run_sentry_test_command(args: &[String]) -> Result<()> { None => { return Err(anyhow::anyhow!( "Sentry is not initialized in this binary — no DSN is resolvable. \ - Set OPENHUMAN_SENTRY_DSN in the environment (or rebuild with it defined \ - at compile time) and try again." + Set OPENHUMAN_CORE_SENTRY_DSN (or the legacy OPENHUMAN_SENTRY_DSN alias) \ + in the environment (or rebuild with it defined at compile time) and try again." )); } } diff --git a/src/main.rs b/src/main.rs index bd66bc96e..2688d48ed 100644 --- a/src/main.rs +++ b/src/main.rs @@ -24,11 +24,21 @@ fn main() { let _ = dotenvy::dotenv(); // Initialize Sentry as the very first operation so the guard outlives everything. - // If OPENHUMAN_SENTRY_DSN is unset or empty, sentry::init returns a no-op guard. + // Resolves the core Sentry DSN by checking, in order: + // 1. `OPENHUMAN_CORE_SENTRY_DSN` at runtime (preferred, namespaced name) + // 2. `OPENHUMAN_SENTRY_DSN` at runtime (legacy unprefixed name — kept + // so existing CI vars and contributor `.env` files keep working until + // the GH org-level variable can be renamed) + // 3. Each of the same names baked at compile time via `option_env!` + // If none resolve to a non-empty value, `sentry::init` returns a no-op guard. let _sentry_guard = sentry::init(sentry::ClientOptions { - dsn: std::env::var("OPENHUMAN_SENTRY_DSN") + dsn: std::env::var("OPENHUMAN_CORE_SENTRY_DSN") .ok() .filter(|s| !s.is_empty()) + .or_else(|| std::env::var("OPENHUMAN_SENTRY_DSN").ok()) + .filter(|s| !s.is_empty()) + .or_else(|| option_env!("OPENHUMAN_CORE_SENTRY_DSN").map(|s| s.to_string())) + .filter(|s| !s.is_empty()) .or_else(|| option_env!("OPENHUMAN_SENTRY_DSN").map(|s| s.to_string())) .filter(|s| !s.is_empty()) .and_then(|s| s.parse().ok()), diff --git a/src/openhuman/config/schema/load.rs b/src/openhuman/config/schema/load.rs index bc9cd1ae8..0ccc6f988 100644 --- a/src/openhuman/config/schema/load.rs +++ b/src/openhuman/config/schema/load.rs @@ -821,8 +821,14 @@ impl Config { } } + // Prefer the namespaced name. `OPENHUMAN_SENTRY_DSN` is the legacy + // unprefixed name kept as a fallback so existing CI vars and local + // `.env` files keep working until the GH org-level variable can be + // renamed in lock-step. let dsn_value = env - .get("OPENHUMAN_SENTRY_DSN") + .get("OPENHUMAN_CORE_SENTRY_DSN") + .or_else(|| env.get("OPENHUMAN_SENTRY_DSN")) + .or_else(|| option_env!("OPENHUMAN_CORE_SENTRY_DSN").map(|s| s.to_string())) .or_else(|| option_env!("OPENHUMAN_SENTRY_DSN").map(|s| s.to_string())); if let Some(dsn) = dsn_value { let dsn = dsn.trim(); diff --git a/src/openhuman/config/schema/load_tests.rs b/src/openhuman/config/schema/load_tests.rs index 677fba46c..e862447a2 100644 --- a/src/openhuman/config/schema/load_tests.rs +++ b/src/openhuman/config/schema/load_tests.rs @@ -247,7 +247,7 @@ fn apply_env_overrides_web_search_max_results_and_timeout_clamped() { #[test] fn apply_env_overrides_picks_up_sentry_dsn() { let _g = ENV_LOCK.lock().unwrap(); - clear_env(&["OPENHUMAN_SENTRY_DSN"]); + clear_env(&["OPENHUMAN_CORE_SENTRY_DSN", "OPENHUMAN_SENTRY_DSN"]); let mut cfg = Config::default(); unsafe { std::env::set_var("OPENHUMAN_SENTRY_DSN", "https://token@sentry.io/1"); @@ -257,7 +257,41 @@ fn apply_env_overrides_picks_up_sentry_dsn() { cfg.observability.sentry_dsn.as_deref(), Some("https://token@sentry.io/1") ); - clear_env(&["OPENHUMAN_SENTRY_DSN"]); + clear_env(&["OPENHUMAN_CORE_SENTRY_DSN", "OPENHUMAN_SENTRY_DSN"]); +} + +#[test] +fn apply_env_overrides_prefers_core_sentry_dsn_when_both_set() { + let _g = ENV_LOCK.lock().unwrap(); + clear_env(&["OPENHUMAN_CORE_SENTRY_DSN", "OPENHUMAN_SENTRY_DSN"]); + let mut cfg = Config::default(); + unsafe { + std::env::set_var("OPENHUMAN_SENTRY_DSN", "https://legacy@sentry.io/1"); + std::env::set_var("OPENHUMAN_CORE_SENTRY_DSN", "https://new@sentry.io/2"); + } + cfg.apply_env_overrides(); + assert_eq!( + cfg.observability.sentry_dsn.as_deref(), + Some("https://new@sentry.io/2"), + "namespaced var must win over the legacy unprefixed one" + ); + clear_env(&["OPENHUMAN_CORE_SENTRY_DSN", "OPENHUMAN_SENTRY_DSN"]); +} + +#[test] +fn apply_env_overrides_picks_up_core_sentry_dsn_alone() { + let _g = ENV_LOCK.lock().unwrap(); + clear_env(&["OPENHUMAN_CORE_SENTRY_DSN", "OPENHUMAN_SENTRY_DSN"]); + let mut cfg = Config::default(); + unsafe { + std::env::set_var("OPENHUMAN_CORE_SENTRY_DSN", "https://token@sentry.io/3"); + } + cfg.apply_env_overrides(); + assert_eq!( + cfg.observability.sentry_dsn.as_deref(), + Some("https://token@sentry.io/3") + ); + clear_env(&["OPENHUMAN_CORE_SENTRY_DSN", "OPENHUMAN_SENTRY_DSN"]); } // ── EnvLookup seam for resolve_runtime_config_dirs ───────────── @@ -595,6 +629,37 @@ fn env_overlay_sentry_dsn_trims_and_ignores_blank() { ); } +#[test] +fn env_overlay_prefers_namespaced_core_sentry_dsn() { + let mut cfg = Config::default(); + cfg.observability.sentry_dsn = None; + + cfg.apply_env_overlay_with( + &HashMapEnv::new() + .with("OPENHUMAN_SENTRY_DSN", "https://legacy@sentry.io/1") + .with("OPENHUMAN_CORE_SENTRY_DSN", "https://new@sentry.io/2"), + ); + assert_eq!( + cfg.observability.sentry_dsn.as_deref(), + Some("https://new@sentry.io/2"), + "OPENHUMAN_CORE_SENTRY_DSN must win over OPENHUMAN_SENTRY_DSN" + ); +} + +#[test] +fn env_overlay_namespaced_core_sentry_dsn_works_alone() { + let mut cfg = Config::default(); + cfg.observability.sentry_dsn = None; + + cfg.apply_env_overlay_with( + &HashMapEnv::new().with("OPENHUMAN_CORE_SENTRY_DSN", "https://token@sentry.io/3"), + ); + assert_eq!( + cfg.observability.sentry_dsn.as_deref(), + Some("https://token@sentry.io/3") + ); +} + #[test] fn env_overlay_analytics_enabled_parses_truthy_falsy() { let mut cfg = Config::default(); diff --git a/src/openhuman/config/schema/observability.rs b/src/openhuman/config/schema/observability.rs index b4d7117ca..d919fdc9c 100644 --- a/src/openhuman/config/schema/observability.rs +++ b/src/openhuman/config/schema/observability.rs @@ -5,7 +5,9 @@ use serde::{Deserialize, Serialize}; #[derive(Debug, Clone, Serialize, Deserialize, JsonSchema)] pub struct ObservabilityConfig { - /// Sentry DSN for error reporting. Overridden by `OPENHUMAN_SENTRY_DSN` env var. + /// Sentry DSN for error reporting. Overridden by the + /// `OPENHUMAN_CORE_SENTRY_DSN` env var (or its legacy alias + /// `OPENHUMAN_SENTRY_DSN`). #[serde(default)] pub sentry_dsn: Option,