-
Notifications
You must be signed in to change notification settings - Fork 48
feat: report $release_id from POSTHOG_RELEASE_ID #239
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
7ece8c7
feat: report $release_id from POSTHOG_RELEASE_ID
ablaszkiewicz 367960b
feat: report $release_id only on $exception events
ablaszkiewicz e92b578
feat: add release_id client option (build-time), env var stays the fa…
ablaszkiewicz dd6df5f
fix: normalize the release_id option so a blank value falls back to t…
ablaszkiewicz File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| cargo/posthog-rs: minor | ||
| --- | ||
|
|
||
| Report a `$release_id` on `$exception` events, from an explicit `release_id` client option or the `POSTHOG_RELEASE_ID` environment variable. This is the native counterpart to injecting `$release_id` into a web bundle: `posthog-cli release resolve` creates the release and prints its id, and that id reaches the SDK one of two ways. Set the `release_id` option — typically `option_env!("POSTHOG_RELEASE_ID")` — to bake it into the binary at build time, so a shipped binary self-identifies with nothing to set at runtime. Or leave it unset and let the SDK read `POSTHOG_RELEASE_ID` from the environment at runtime, so a deploy supplies it without a rebuild. An explicit option wins over the environment. Either way the SDK stamps it only on exceptions — that is where the server resolves a release — the value is read once, an unset or blank value changes nothing, and a `before_send` hook can still drop the property. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,95 @@ | ||
| //! The release id the SDK reports as `$release_id`, from an explicit `release_id` option or the | ||
| //! `POSTHOG_RELEASE_ID` environment variable. | ||
| //! | ||
| //! This is the native counterpart to injecting `$release_id` into a web bundle. A native build has | ||
| //! no bundle to inject, so the CLI's `release resolve` prints the created release's id and it | ||
| //! reaches the app one of two ways: baked in at build time (set the `release_id` option to | ||
| //! `option_env!("POSTHOG_RELEASE_ID")`, so a shipped binary self-identifies with nothing to set at | ||
| //! runtime), or read from `POSTHOG_RELEASE_ID` in the environment at runtime (so a deploy can | ||
| //! supply it without a rebuild). An explicit option wins over the environment. Either way the SDK | ||
| //! stamps it on `$exception` events, so the server resolves the release by a direct id lookup — no | ||
| //! release name or version has to match anything the app reports. | ||
|
|
||
| use std::sync::OnceLock; | ||
|
|
||
| /// The environment variable the release id is read from. | ||
| const RELEASE_ID_ENV: &str = "POSTHOG_RELEASE_ID"; | ||
|
|
||
| /// The release id from `POSTHOG_RELEASE_ID`, read once. `None` when the variable is unset or blank. | ||
| pub(crate) fn release_id() -> Option<&'static str> { | ||
| static CACHE: OnceLock<Option<String>> = OnceLock::new(); | ||
| CACHE | ||
| .get_or_init(|| normalize(std::env::var(RELEASE_ID_ENV).ok())) | ||
| .as_deref() | ||
| } | ||
|
Comment on lines
+19
to
+24
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should this be a proc macro? if we want to bake the env var into the binary at build time, this won't work |
||
|
|
||
| /// Trim the raw value and treat a blank string as unset, so `POSTHOG_RELEASE_ID=` (or whitespace) | ||
| /// does not send an empty `$release_id`. | ||
| fn normalize(raw: Option<String>) -> Option<String> { | ||
| raw.map(|v| v.trim().to_string()).filter(|v| !v.is_empty()) | ||
| } | ||
|
|
||
| /// Resolve the release id from the two sources, explicit option first, environment fallback second. | ||
| /// A `config` value set in code (typically a build-time `option_env!("POSTHOG_RELEASE_ID")`) wins | ||
| /// over `env` (the runtime `POSTHOG_RELEASE_ID`), so a deploy-time override is opt-in, not implicit. | ||
| /// The option is normalized like the environment value, so a blank `release_id("")` — e.g. | ||
| /// `option_env!("POSTHOG_RELEASE_ID").unwrap_or_default()` in a build that never set it — falls back | ||
| /// to the environment instead of sending an empty id. | ||
| pub(crate) fn resolve_release_id(config: Option<&str>, env: Option<&str>) -> Option<String> { | ||
| normalize(config.map(str::to_string)).or_else(|| env.map(str::to_string)) | ||
| } | ||
|
|
||
| #[cfg(test)] | ||
| mod tests { | ||
| use super::{normalize, resolve_release_id}; | ||
|
|
||
| #[test] | ||
| fn an_explicit_config_id_wins_over_the_environment() { | ||
| assert_eq!( | ||
| resolve_release_id(Some("from-config"), Some("from-env")).as_deref(), | ||
| Some("from-config") | ||
| ); | ||
| } | ||
|
|
||
| #[test] | ||
| fn the_environment_is_used_when_no_config_id_is_set() { | ||
| assert_eq!( | ||
| resolve_release_id(None, Some("from-env")).as_deref(), | ||
| Some("from-env") | ||
| ); | ||
| } | ||
|
|
||
| #[test] | ||
| fn a_blank_config_id_falls_back_to_the_environment() { | ||
| // A build that never set POSTHOG_RELEASE_ID can pass an empty option (e.g. | ||
| // `option_env!(...).unwrap_or_default()`); it must not shadow the runtime env value. | ||
| assert_eq!( | ||
| resolve_release_id(Some(" "), Some("from-env")).as_deref(), | ||
| Some("from-env") | ||
| ); | ||
| } | ||
|
|
||
| #[test] | ||
| fn no_config_and_no_environment_is_none() { | ||
| assert_eq!(resolve_release_id(None, None), None); | ||
| } | ||
|
|
||
| #[test] | ||
| fn an_unset_variable_is_none() { | ||
| assert_eq!(normalize(None), None); | ||
| } | ||
|
|
||
| #[test] | ||
| fn a_blank_value_is_none() { | ||
| // `POSTHOG_RELEASE_ID=` or an all-whitespace value must not send an empty release id. | ||
| assert_eq!(normalize(Some(" ".to_string())), None); | ||
| } | ||
|
|
||
| #[test] | ||
| fn a_value_is_trimmed() { | ||
| assert_eq!( | ||
| normalize(Some(" 01a03d94-7dd8-0000-e1cb-2a269e5ea0b5 ".to_string())).as_deref(), | ||
| Some("01a03d94-7dd8-0000-e1cb-2a269e5ea0b5") | ||
| ); | ||
| } | ||
| } | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just a thought - we could fall back to attempting to derive a release id from the git HEAD (
git rev-parse --verify 'HEAD^{commit}')expecting cases where
gitis not found or we're not running in a.gitrepo