mirror of
https://github.com/tinyhumansai/openhuman.git
synced 2026-07-27 21:08:00 +00:00
feat(sentry): split errors into per-surface projects (react, core, tauri) (#1032)
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
975614d0ec
commit
e943a1ad1b
@@ -464,6 +464,8 @@ jobs:
|
||||
CORE_MANIFEST: ${{ steps.core-paths.outputs.core_manifest }}
|
||||
CORE_BIN_NAME: ${{ steps.core-paths.outputs.core_bin_name }}
|
||||
OPENHUMAN_APP_ENV: ${{ inputs.build_target == 'staging' && 'staging' || 'production' }}
|
||||
# Core (Rust openhuman sidecar) Sentry DSN — separate Sentry project
|
||||
# from the React frontend and the Tauri shell.
|
||||
OPENHUMAN_SENTRY_DSN: ${{ vars.OPENHUMAN_CORE_SENTRY_DSN }}
|
||||
# Sentry release tracking (#405): `option_env!("OPENHUMAN_BUILD_SHA")`
|
||||
# in src/main.rs bakes the short SHA into the release tag
|
||||
@@ -511,7 +513,17 @@ jobs:
|
||||
# (`vite build`) bakes Sentry + debug flags into the final bundle.
|
||||
# Vite is invoked via tauri.conf.json's beforeBuildCommand during
|
||||
# `cargo tauri build`, so these env vars must be present here.
|
||||
# React frontend Sentry DSN — separate Sentry project.
|
||||
VITE_SENTRY_DSN: ${{ vars.OPENHUMAN_REACT_SENTRY_DSN }}
|
||||
# Tauri shell (desktop host) Sentry DSN — separate Sentry project
|
||||
# from the React frontend and the Rust core. Baked into the shell
|
||||
# binary via `option_env!("OPENHUMAN_TAURI_SENTRY_DSN")` at compile
|
||||
# time so the released desktop app reports to its own project.
|
||||
OPENHUMAN_TAURI_SENTRY_DSN: ${{ vars.OPENHUMAN_TAURI_SENTRY_DSN }}
|
||||
# Bake the build SHA into the Tauri shell so its Sentry release tag
|
||||
# (`openhuman@<version>+<sha>`) matches the React bundle and core
|
||||
# sidecar — events across all three surfaces group under one release.
|
||||
OPENHUMAN_BUILD_SHA: ${{ needs.prepare-build.outputs.sha }}
|
||||
VITE_DEBUG: ${{ vars.VITE_DEBUG }}
|
||||
# Sentry release tracking (#405) — must match the Vite build triggered
|
||||
# by Tauri so source maps uploaded there resolve correctly against the
|
||||
@@ -522,7 +534,12 @@ jobs:
|
||||
needs.prepare-build.outputs.sha }}
|
||||
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||
SENTRY_ORG: ${{ vars.SENTRY_ORG }}
|
||||
SENTRY_PROJECT: ${{ vars.SENTRY_PROJECT_FRONTEND }}
|
||||
# SENTRY_PROJECT here is consumed by sentry-vite-plugin during the
|
||||
# Vite build that runs inside `cargo tauri build` (beforeBuildCommand)
|
||||
# — it uploads frontend source maps to the React Sentry project.
|
||||
# Core and Tauri-shell debug symbols are uploaded to their own
|
||||
# projects in the dedicated steps below.
|
||||
SENTRY_PROJECT: ${{ vars.SENTRY_PROJECT_REACT }}
|
||||
MACOSX_DEPLOYMENT_TARGET: ${{ matrix.settings.platform == 'macos-latest' && '10.15' || '' }}
|
||||
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY_PASSWORD || secrets.UPDATER_PRIVATE_KEY_PASSWORD }}
|
||||
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_SIGNING_PRIVATE_KEY || secrets.UPDATER_PRIVATE_KEY }}
|
||||
@@ -540,9 +557,11 @@ jobs:
|
||||
# Upload Rust debug info to Sentry so backend + Tauri-shell stack traces
|
||||
# symbolicate in production. The frontend source maps are handled by
|
||||
# sentry-vite-plugin in the build step above; this is the Rust half.
|
||||
# Keyed by debug-ID, so it's safe to run per-matrix-target without
|
||||
# collisions — Sentry merges artifacts across platforms.
|
||||
- name: Upload Rust debug symbols to Sentry
|
||||
# Core sidecar and Tauri shell go to **separate Sentry projects**
|
||||
# (matching their separate DSNs) so events show up in the right place.
|
||||
# Symbols are keyed by debug-ID, so it's safe to run per-matrix-target
|
||||
# without collisions — Sentry merges artifacts across platforms.
|
||||
- name: Upload core sidecar debug symbols to Sentry
|
||||
if:
|
||||
needs.prepare-build.outputs.release_enabled == 'true' && env.SENTRY_AUTH_TOKEN
|
||||
!= ''
|
||||
@@ -550,24 +569,53 @@ jobs:
|
||||
env:
|
||||
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||
SENTRY_ORG: ${{ vars.SENTRY_ORG }}
|
||||
SENTRY_PROJECT: ${{ vars.SENTRY_PROJECT }}
|
||||
SENTRY_PROJECT: ${{ vars.SENTRY_PROJECT_CORE }}
|
||||
# Must match the release tag the running core binary reports
|
||||
# (`openhuman@<version>+<sha>`, see `build_release_tag` in
|
||||
# src/main.rs). If this drifts, DIFs attach to a different
|
||||
# release than events and stack traces stay un-symbolicated.
|
||||
SENTRY_RELEASE:
|
||||
openhuman@${{ needs.prepare-build.outputs.version }}+${{
|
||||
needs.prepare-build.outputs.sha }}
|
||||
VERSION: ${{ needs.prepare-build.outputs.version }}
|
||||
MATRIX_TARGET: ${{ matrix.settings.target }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
# Core crate deps (sidecar symbols) + Tauri shell deps (app binary
|
||||
# symbols) both live under the per-target release dir. upload-dif
|
||||
# scans recursively.
|
||||
for deps_dir in \
|
||||
"target/${MATRIX_TARGET}/release/deps" \
|
||||
"app/src-tauri/target/${MATRIX_TARGET}/release/deps"; do
|
||||
if [ -d "$deps_dir" ]; then
|
||||
echo "==> Uploading symbols from $deps_dir"
|
||||
bash scripts/upload_sentry_symbols.sh "$VERSION" "$deps_dir"
|
||||
else
|
||||
echo "==> Skipping $deps_dir (not present)"
|
||||
fi
|
||||
done
|
||||
deps_dir="target/${MATRIX_TARGET}/release/deps"
|
||||
if [ -d "$deps_dir" ]; then
|
||||
echo "==> Uploading core symbols from $deps_dir to ${SENTRY_PROJECT}"
|
||||
bash scripts/upload_sentry_symbols.sh "$VERSION" "$deps_dir"
|
||||
else
|
||||
echo "==> Skipping $deps_dir (not present)"
|
||||
fi
|
||||
- name: Upload Tauri shell debug symbols to Sentry
|
||||
if:
|
||||
needs.prepare-build.outputs.release_enabled == 'true' && env.SENTRY_AUTH_TOKEN
|
||||
!= ''
|
||||
shell: bash
|
||||
env:
|
||||
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||
SENTRY_ORG: ${{ vars.SENTRY_ORG }}
|
||||
SENTRY_PROJECT: ${{ vars.SENTRY_PROJECT_TAURI }}
|
||||
# Must match the release tag the running shell binary reports
|
||||
# (`openhuman@<version>+<sha>`, see `build_sentry_release_tag` in
|
||||
# app/src-tauri/src/lib.rs). If this drifts, DIFs attach to a
|
||||
# different release than events and stack traces stay
|
||||
# un-symbolicated.
|
||||
SENTRY_RELEASE:
|
||||
openhuman@${{ needs.prepare-build.outputs.version }}+${{
|
||||
needs.prepare-build.outputs.sha }}
|
||||
VERSION: ${{ needs.prepare-build.outputs.version }}
|
||||
MATRIX_TARGET: ${{ matrix.settings.target }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
deps_dir="app/src-tauri/target/${MATRIX_TARGET}/release/deps"
|
||||
if [ -d "$deps_dir" ]; then
|
||||
echo "==> Uploading Tauri shell symbols from $deps_dir to ${SENTRY_PROJECT}"
|
||||
bash scripts/upload_sentry_symbols.sh "$VERSION" "$deps_dir"
|
||||
else
|
||||
echo "==> Skipping $deps_dir (not present)"
|
||||
fi
|
||||
|
||||
# tauri-action previously uploaded non-macOS installer assets directly
|
||||
# to the release. Replicate that for Linux + Windows here (macOS goes
|
||||
|
||||
Generated
+300
-1
@@ -18,7 +18,7 @@ dependencies = [
|
||||
"futures-util",
|
||||
"log",
|
||||
"mac-notification-sys",
|
||||
"nix",
|
||||
"nix 0.29.0",
|
||||
"notify-rust",
|
||||
"objc2",
|
||||
"objc2-app-kit",
|
||||
@@ -29,6 +29,7 @@ dependencies = [
|
||||
"rusqlite",
|
||||
"rustls",
|
||||
"semver",
|
||||
"sentry",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tar",
|
||||
@@ -47,6 +48,15 @@ dependencies = [
|
||||
"zip 2.4.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "addr2line"
|
||||
version = "0.25.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1b5d307320b3181d6d7954e663bd7c774a838b8220fe0593c86d9fb09f498b4b"
|
||||
dependencies = [
|
||||
"gimli",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "adler2"
|
||||
version = "2.0.1"
|
||||
@@ -302,6 +312,43 @@ version = "1.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
|
||||
|
||||
[[package]]
|
||||
name = "aws-lc-rs"
|
||||
version = "1.16.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ec6fb3fe69024a75fa7e1bfb48aa6cf59706a101658ea01bfd33b2b248a038f"
|
||||
dependencies = [
|
||||
"aws-lc-sys",
|
||||
"zeroize",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aws-lc-sys"
|
||||
version = "0.40.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f50037ee5e1e41e7b8f9d161680a725bd1626cb6f8c7e901f91f942850852fe7"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"cmake",
|
||||
"dunce",
|
||||
"fs_extra",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "backtrace"
|
||||
version = "0.3.76"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bb531853791a215d7c62a30daf0dde835f381ab5de4589cfe7c649d2cbe92bd6"
|
||||
dependencies = [
|
||||
"addr2line",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"miniz_oxide",
|
||||
"object",
|
||||
"rustc-demangle",
|
||||
"windows-link 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.21.7"
|
||||
@@ -485,6 +532,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1e928d4b69e3077709075a938a05ffbedfa53a84c8f766efbf8220bb1ff60e1"
|
||||
dependencies = [
|
||||
"find-msvc-tools",
|
||||
"jobserver",
|
||||
"libc",
|
||||
"shlex",
|
||||
]
|
||||
|
||||
@@ -902,6 +951,16 @@ dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "debugid"
|
||||
version = "0.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bef552e6f588e446098f6ba40d89ac146c8c7b64aade83c051ee00bb5d2bc18d"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "deranged"
|
||||
version = "0.5.8"
|
||||
@@ -1391,6 +1450,12 @@ dependencies = [
|
||||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fs_extra"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c"
|
||||
|
||||
[[package]]
|
||||
name = "futf"
|
||||
version = "0.1.5"
|
||||
@@ -1408,6 +1473,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "07bbe89c50d7a535e539b8c17bc0b49bdb77747034daa8087407d655f3f7cc1d"
|
||||
dependencies = [
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1637,6 +1703,12 @@ dependencies = [
|
||||
"wasip3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gimli"
|
||||
version = "0.32.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e629b9b98ef3dd8afe6ca2bd0f89306cec16d43d907889945bc5d6687f2f13c7"
|
||||
|
||||
[[package]]
|
||||
name = "gio"
|
||||
version = "0.18.4"
|
||||
@@ -1803,6 +1875,25 @@ dependencies = [
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.4.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f44da3a8150a6703ed5d34e164b875fd14c2cdab9af1252a9a1020bde2bdc54"
|
||||
dependencies = [
|
||||
"atomic-waker",
|
||||
"bytes",
|
||||
"fnv",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"http",
|
||||
"indexmap 2.13.0",
|
||||
"slab",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.12.3"
|
||||
@@ -1863,6 +1954,17 @@ version = "0.4.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
|
||||
|
||||
[[package]]
|
||||
name = "hostname"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "617aaa3557aef3810a6369d0a99fac8a080891b68bd9f9812a1eeda0c0730cbd"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"libc",
|
||||
"windows-link 0.2.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "html5ever"
|
||||
version = "0.29.1"
|
||||
@@ -1924,6 +2026,12 @@ version = "1.10.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6dbf3de79e51f3d586ab4cb9d5c3e2c14aa28ed23d180cf89b4df0454a69cc87"
|
||||
|
||||
[[package]]
|
||||
name = "httpdate"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
|
||||
|
||||
[[package]]
|
||||
name = "hyper"
|
||||
version = "1.8.1"
|
||||
@@ -1934,6 +2042,7 @@ dependencies = [
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"h2",
|
||||
"http",
|
||||
"http-body",
|
||||
"httparse",
|
||||
@@ -2316,6 +2425,16 @@ dependencies = [
|
||||
"syn 2.0.117",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jobserver"
|
||||
version = "0.1.34"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9afb3de4395d6b3e67a780b6de64b51c978ecf11cb9a462c66be7d4ca9039d33"
|
||||
dependencies = [
|
||||
"getrandom 0.3.4",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "js-sys"
|
||||
version = "0.3.92"
|
||||
@@ -2683,6 +2802,18 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nix"
|
||||
version = "0.30.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "74523f3a35e05aba87a1d978330aef40f67b0304ac79c1c00b294c9830543db6"
|
||||
dependencies = [
|
||||
"bitflags 2.11.0",
|
||||
"cfg-if",
|
||||
"cfg_aliases",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nodrop"
|
||||
version = "0.1.14"
|
||||
@@ -2954,9 +3085,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d87d638e33c06f577498cbcc50491496a3ed4246998a7fbba7ccb98b1e7eab22"
|
||||
dependencies = [
|
||||
"bitflags 2.11.0",
|
||||
"block2",
|
||||
"objc2",
|
||||
"objc2-cloud-kit",
|
||||
"objc2-core-data",
|
||||
"objc2-core-foundation",
|
||||
"objc2-core-graphics",
|
||||
"objc2-core-image",
|
||||
"objc2-core-location",
|
||||
"objc2-core-text",
|
||||
"objc2-foundation",
|
||||
"objc2-quartz-core",
|
||||
"objc2-user-notifications",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2988,6 +3128,15 @@ dependencies = [
|
||||
"objc2-security",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "object"
|
||||
version = "0.37.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ff76201f031d8863c38aa7f905eca4f53abbfa15f609db4277d44cd8938f33fe"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.21.4"
|
||||
@@ -3044,6 +3193,22 @@ dependencies = [
|
||||
"pin-project-lite",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "os_info"
|
||||
version = "3.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e4022a17595a00d6a369236fdae483f0de7f0a339960a53118b818238e132224"
|
||||
dependencies = [
|
||||
"android_system_properties",
|
||||
"log",
|
||||
"nix 0.30.1",
|
||||
"objc2",
|
||||
"objc2-foundation",
|
||||
"objc2-ui-kit",
|
||||
"serde",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "osakit"
|
||||
version = "0.3.1"
|
||||
@@ -3553,6 +3718,7 @@ version = "0.11.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "434b42fec591c96ef50e21e886936e66d3cc3f737104fdb9b737c40ffb94c098"
|
||||
dependencies = [
|
||||
"aws-lc-rs",
|
||||
"bytes",
|
||||
"getrandom 0.3.4",
|
||||
"lru-slab",
|
||||
@@ -3854,8 +4020,10 @@ checksum = "ab3f43e3283ab1488b624b44b0e988d0acea0b3214e694730a055cb6b2efa801"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2",
|
||||
"http",
|
||||
"http-body",
|
||||
"http-body-util",
|
||||
@@ -3866,6 +4034,7 @@ dependencies = [
|
||||
"log",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"quinn",
|
||||
"rustls",
|
||||
"rustls-pki-types",
|
||||
"rustls-platform-verifier",
|
||||
@@ -3923,6 +4092,12 @@ dependencies = [
|
||||
"ordered-multimap",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
version = "0.1.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "2.1.2"
|
||||
@@ -3957,6 +4132,7 @@ version = "0.23.37"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "758025cb5fccfd3bc2fd74708fd4682be41d99e5dff73c377c0646c6012c73a4"
|
||||
dependencies = [
|
||||
"aws-lc-rs",
|
||||
"log",
|
||||
"once_cell",
|
||||
"ring",
|
||||
@@ -4021,6 +4197,7 @@ version = "0.103.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df33b2b81ac578cabaf06b89b0631153a3f416b0a886e8a7a1707fb51abbd1ef"
|
||||
dependencies = [
|
||||
"aws-lc-rs",
|
||||
"ring",
|
||||
"rustls-pki-types",
|
||||
"untrusted",
|
||||
@@ -4171,6 +4348,103 @@ dependencies = [
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sentry"
|
||||
version = "0.47.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb25f439f97d26fea01d717fa626167ceffcd981addaa670001e70505b72acbb"
|
||||
dependencies = [
|
||||
"cfg_aliases",
|
||||
"httpdate",
|
||||
"reqwest 0.13.2",
|
||||
"rustls",
|
||||
"sentry-backtrace",
|
||||
"sentry-contexts",
|
||||
"sentry-core",
|
||||
"sentry-panic",
|
||||
"sentry-tracing",
|
||||
"tokio",
|
||||
"ureq",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sentry-backtrace"
|
||||
version = "0.47.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46a8c2c1bd5c1f735e84f28b48e7d72efcaafc362b7541bc8253e60e8fcdffc6"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"regex",
|
||||
"sentry-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sentry-contexts"
|
||||
version = "0.47.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b88a90baa654d7f0e1f4b667f6b434293d9f72c71bef16b197c76af5b7d5803"
|
||||
dependencies = [
|
||||
"hostname",
|
||||
"libc",
|
||||
"os_info",
|
||||
"rustc_version",
|
||||
"sentry-core",
|
||||
"uname",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sentry-core"
|
||||
version = "0.47.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0ac170a5bba8bec6e3339c90432569d89641fa7a3d3e4f44987d24f0762e6adf"
|
||||
dependencies = [
|
||||
"rand 0.9.2",
|
||||
"sentry-types",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sentry-panic"
|
||||
version = "0.47.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6127d3d304ba5ce0409401e85aae538e303a569f8dbb031bf64f9ba0f7174346"
|
||||
dependencies = [
|
||||
"sentry-backtrace",
|
||||
"sentry-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sentry-tracing"
|
||||
version = "0.47.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "27701acc51e68db5281802b709010395bfcbcb128b1d0a4e5873680d3b47ff0c"
|
||||
dependencies = [
|
||||
"bitflags 2.11.0",
|
||||
"sentry-backtrace",
|
||||
"sentry-core",
|
||||
"tracing-core",
|
||||
"tracing-subscriber",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sentry-types"
|
||||
version = "0.47.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56780cb5597d676bf22e6c11d1f062eb4def46390ea3bfb047bcbcf7dfd19bdb"
|
||||
dependencies = [
|
||||
"debugid",
|
||||
"hex",
|
||||
"rand 0.9.2",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror 2.0.18",
|
||||
"time",
|
||||
"url",
|
||||
"uuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.228"
|
||||
@@ -5428,6 +5702,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "db97caf9d906fbde555dd62fa95ddba9eecfd14cb388e4f491a66d74cd5fb79a"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"valuable",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-subscriber"
|
||||
version = "0.3.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cb7f578e5945fb242538965c2d0b04418d38ec25c79d160cd279bf0731c8d319"
|
||||
dependencies = [
|
||||
"tracing-core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -5499,6 +5783,15 @@ dependencies = [
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uname"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b72f89f0ca32e4db1c04e2a72f5345d59796d4866a1ee0609084569f73683dc8"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unic-char-property"
|
||||
version = "0.9.0"
|
||||
@@ -5670,6 +5963,12 @@ dependencies = [
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "valuable"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba73ea9cf16a25df0c8caa16c51acb937d5712a8429db78a3ee29d5dcacd3a65"
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
|
||||
@@ -90,6 +90,14 @@ zip = { version = "2", default-features = false, features = ["deflate"] }
|
||||
log = "0.4"
|
||||
env_logger = "0.11"
|
||||
|
||||
# Sentry for the Tauri shell (desktop host) process — separate Sentry project
|
||||
# from the React frontend and the Rust core sidecar. DSN is baked at compile
|
||||
# time via `option_env!("OPENHUMAN_TAURI_SENTRY_DSN")` in `lib.rs::run()` and
|
||||
# can be overridden at runtime via the same env var. Feature set mirrors the
|
||||
# core sidecar (`Cargo.toml` at repo root) minus `tracing` since the shell
|
||||
# uses `log` + `env_logger`.
|
||||
sentry = { version = "0.47.0", default-features = false, features = ["backtrace", "contexts", "panic", "reqwest", "rustls"] }
|
||||
|
||||
# Used by the imessage_scanner module.
|
||||
anyhow = "1.0"
|
||||
parking_lot = "0.12"
|
||||
|
||||
@@ -870,6 +870,56 @@ fn teardown_cef_prewarm<R: tauri::Runtime>(app: &AppHandle<R>) -> Result<(), Str
|
||||
}
|
||||
|
||||
pub fn run() {
|
||||
// Initialize Sentry for the Tauri shell (desktop host) process before any
|
||||
// other startup work. Reads `OPENHUMAN_TAURI_SENTRY_DSN` at runtime first,
|
||||
// then falls back to the value baked in at compile time via the release
|
||||
// workflow. Missing/empty DSN ⇒ `sentry::init` returns a no-op guard.
|
||||
//
|
||||
// The guard is held for the entire lifetime of `run()` so events queued
|
||||
// during shutdown still flush. Only invoked here (and not in `main.rs`)
|
||||
// so renderer/GPU CEF helper subprocesses (re-exec'd via
|
||||
// `tauri::cef_entry_point`) and the `OpenHuman core …` in-process core
|
||||
// path do NOT spin up a second client — those have their own reporting
|
||||
// surfaces.
|
||||
let _sentry_guard = sentry::init(sentry::ClientOptions {
|
||||
dsn: std::env::var("OPENHUMAN_TAURI_SENTRY_DSN")
|
||||
.ok()
|
||||
.filter(|s| !s.is_empty())
|
||||
.or_else(|| option_env!("OPENHUMAN_TAURI_SENTRY_DSN").map(|s| s.to_string()))
|
||||
.filter(|s| !s.is_empty())
|
||||
.and_then(|s| s.parse().ok()),
|
||||
release: Some(std::borrow::Cow::Owned(build_sentry_release_tag())),
|
||||
environment: Some(std::borrow::Cow::Owned(resolve_sentry_environment())),
|
||||
send_default_pii: false,
|
||||
before_send: Some(std::sync::Arc::new(|mut event| {
|
||||
// Strip server_name (hostname) to avoid leaking machine identity.
|
||||
event.server_name = None;
|
||||
event.user = None;
|
||||
Some(event)
|
||||
})),
|
||||
sample_rate: 1.0,
|
||||
..sentry::ClientOptions::default()
|
||||
});
|
||||
|
||||
// Optional smoke trigger for verifying the Sentry pipeline end-to-end.
|
||||
// Run with `OPENHUMAN_TAURI_SENTRY_TEST=panic` to fire a panic, or
|
||||
// `=message` to send a captured-message event. No-op when unset.
|
||||
if let Ok(mode) = std::env::var("OPENHUMAN_TAURI_SENTRY_TEST") {
|
||||
match mode.as_str() {
|
||||
"panic" => panic!("OPENHUMAN_TAURI_SENTRY_TEST=panic — local Sentry smoke test"),
|
||||
"message" => {
|
||||
sentry::capture_message(
|
||||
"OPENHUMAN_TAURI_SENTRY_TEST=message — local Sentry smoke test",
|
||||
sentry::Level::Error,
|
||||
);
|
||||
let _ = sentry::Hub::current().client().map(|c| c.flush(None));
|
||||
}
|
||||
other => log::warn!(
|
||||
"OPENHUMAN_TAURI_SENTRY_TEST={other:?} — unknown mode (use 'panic' or 'message')"
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
let daemon_mode = is_daemon_mode();
|
||||
|
||||
let default_filter = std::env::var("RUST_LOG").unwrap_or_else(|_| "info".to_string());
|
||||
@@ -1575,6 +1625,48 @@ pub fn run_core_from_args(args: &[String]) -> Result<(), String> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Sentry release / environment resolution (Tauri shell)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/// Canonical release tag: `openhuman@<version>[+<short_sha>]`.
|
||||
///
|
||||
/// Mirrors `build_release_tag` in the core sidecar's `src/main.rs` and the
|
||||
/// `SENTRY_RELEASE` value computed in `app/vite.config.ts` so events from
|
||||
/// every surface (React frontend, core sidecar, Tauri shell) group under the
|
||||
/// same release in Sentry and benefit from the same source-map / debug-info
|
||||
/// upload.
|
||||
fn build_sentry_release_tag() -> String {
|
||||
let version = env!("CARGO_PKG_VERSION");
|
||||
let sha = option_env!("OPENHUMAN_BUILD_SHA").unwrap_or("").trim();
|
||||
let sha_short: String = sha.chars().take(12).collect();
|
||||
if sha_short.is_empty() {
|
||||
format!("openhuman@{version}")
|
||||
} else {
|
||||
format!("openhuman@{version}+{sha_short}")
|
||||
}
|
||||
}
|
||||
|
||||
/// Resolve the Sentry environment tag from `OPENHUMAN_APP_ENV` (runtime) or
|
||||
/// `VITE_OPENHUMAN_APP_ENV` (compile-time fallback). Defaults to
|
||||
/// `production` so unmarked release builds don't pollute the dev/staging
|
||||
/// streams.
|
||||
fn resolve_sentry_environment() -> String {
|
||||
if let Ok(value) = std::env::var("OPENHUMAN_APP_ENV") {
|
||||
let trimmed = value.trim();
|
||||
if !trimmed.is_empty() {
|
||||
return trimmed.to_string();
|
||||
}
|
||||
}
|
||||
if let Some(value) = option_env!("VITE_OPENHUMAN_APP_ENV") {
|
||||
let trimmed = value.trim();
|
||||
if !trimmed.is_empty() {
|
||||
return trimmed.to_string();
|
||||
}
|
||||
}
|
||||
"production".to_string()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
+13
-3
@@ -39,12 +39,22 @@ function maybeSentryPlugin(): PluginOption | null {
|
||||
project: process.env.SENTRY_PROJECT,
|
||||
release: { name: computeSentryRelease() },
|
||||
sourcemaps: {
|
||||
// Vite emits hashed asset files under dist/assets/ — upload every
|
||||
// Vite emits hashed asset files into `app/dist/assets/`. Upload every
|
||||
// .js / .map the build produces.
|
||||
assets: ["../dist/**/*.js", "../dist/**/*.map"],
|
||||
//
|
||||
// `assets` is resolved by sentry-vite-plugin against `process.cwd()`,
|
||||
// not the Vite `root` — so a relative path like `../dist/**` would
|
||||
// miss when `pnpm tauri build` runs with cwd=`app/` and silently emit
|
||||
// `Didn't find any matching sources for debug ID upload`. Use absolute
|
||||
// paths anchored at this config file's directory (`app/`) to be
|
||||
// immune to whatever cwd the parent process sets.
|
||||
assets: [
|
||||
resolve(__dirname, "dist/**/*.js"),
|
||||
resolve(__dirname, "dist/**/*.map"),
|
||||
],
|
||||
// Never ship raw .map files to end users; the upload keeps a copy
|
||||
// server-side for symbolication while the bundled app strips them.
|
||||
filesToDeleteAfterUpload: ["../dist/**/*.map"],
|
||||
filesToDeleteAfterUpload: [resolve(__dirname, "dist/**/*.map")],
|
||||
},
|
||||
// Release tagging + commits are handled by sentry-cli / the plugin
|
||||
// itself when AUTH_TOKEN and CI env (GITHUB_SHA etc.) are present.
|
||||
|
||||
@@ -169,7 +169,14 @@ upload_symbols() {
|
||||
exit 1
|
||||
fi
|
||||
|
||||
local release_name="openhuman@${version}"
|
||||
# Honor SENTRY_RELEASE if set so DIFs attach to the same release name
|
||||
# the running binaries report (`openhuman@<version>+<sha>`). Without this,
|
||||
# CI uploads to `openhuman@<version>` while events are tagged
|
||||
# `openhuman@<version>+<sha>` — a different release, so Sentry never
|
||||
# joins frames to symbols and stack traces stay un-symbolicated.
|
||||
# Falls back to the bare-version tag for local invocations that don't
|
||||
# set SENTRY_RELEASE.
|
||||
local release_name="${SENTRY_RELEASE:-openhuman@${version}}"
|
||||
|
||||
log_info "Uploading Rust debug symbols for release: ${release_name}"
|
||||
log_info "Symbols path: ${symbols_path}"
|
||||
@@ -180,12 +187,18 @@ upload_symbols() {
|
||||
# Use --ignore-missing for shallow clones or CI environments
|
||||
sentry-cli releases set-commits --auto --ignore-missing "${release_name}" || true
|
||||
|
||||
# Upload debug symbols
|
||||
# Upload debug symbols + source bundles. `--include-sources` makes
|
||||
# `sentry-cli` package the referenced source files into a `.src.zip`
|
||||
# alongside the DIF, so Sentry renders surrounding source lines in
|
||||
# Rust stack traces instead of bare `function + 0xNNN`. CI runs from a
|
||||
# full workspace checkout, so the source paths embedded in the DWARF
|
||||
# resolve and the bundle is built correctly.
|
||||
log_info "Uploading debug symbols..."
|
||||
local upload_args=(
|
||||
"upload-dif"
|
||||
"--org" "${SENTRY_ORG}"
|
||||
"--project" "${SENTRY_PROJECT}"
|
||||
"--include-sources"
|
||||
"--log-level=warning"
|
||||
)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user