chore(sentry): rename OPENHUMAN_SENTRY_DSN → OPENHUMAN_CORE_SENTRY_DSN (#1186)

This commit is contained in:
CodeGhost21
2026-05-04 22:57:43 +05:30
committed by GitHub
parent 995669fc0a
commit b574256f75
8 changed files with 116 additions and 23 deletions
+6 -2
View File
@@ -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@<version>+<sha>`) via `option_env!("OPENHUMAN_BUILD_SHA")`.
# CI sets this automatically; leave blank locally (release tag falls back
+5 -4
View File
@@ -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" \
+8 -5
View File
@@ -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@<version>+<short_sha>`).
OPENHUMAN_BUILD_SHA: ${{ github.sha }}
+8 -6
View File
@@ -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."
));
}
}
+12 -2
View File
@@ -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()),
+7 -1
View File
@@ -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();
+67 -2
View File
@@ -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();
+3 -1
View File
@@ -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<String>,