Improve macOS version information in telemetry (#37185)

macOS versions are currently reported as `macOS 26.0.0`.
But this makes it impossible to differentiate amongst macOS Beta
releases which have the same version number (`X.0.0`) but are different
builds.

This PR adds build number info to `os_version` for macOS Betas and
[Rapid Security Response](https://support.apple.com/en-us/102657)
release that have identical version numbers to stable release, but have
different builds numbers. We can differentiate them because the build
numbers end with a letter.

| Version | Before | After |
| - | - | - | 
| macOS Sonoma 14.7.8 | 14.7.8 | 14.7.8 |
| macOS Sequoia 15.6.1 | 15.6.1 | 15.6.1 |
| mcOS Ventura 13.3.1 | 13.3.1 | 13.3.1 |
| macOS Ventura 13.3.1 (a) |  13.3.1 | 13.3.1 (Build 22E772610a) |
| macOS Tahoe 26.0.0 (Beta1) | 26.0.0 | 26.0.0 (Build 25A5316a) |
| macOS Tahoe 26.0.0 (Beta5) | 26.0.0 | 26.0.0 (Build 25A5349a) | 

This should cause minimal telemetry changes and only impacting a macOS
betas and a couple specific older macOS versions, but will allow
differentiation between macOS beta releases in GitHub issues.

Alternatives:
1. Leave as-is (can't differentiate between macOS beta builds)
2. Always include build number info (impacts telemetry; more consistent
going forward; differentiates non-final Release Candidates which don't
include a trailing letter)

I couldn't find a cocoa method to retrieve macOS build number, so I
switched dependencies from `cocoa` to `objc2-foundation` in the client
crate. We already depend upon this crate as a dependency of
`blade-graphics` so I matched the features of that and so workspace-hack
doesn't change.

https://github.com/zed-industries/zed/blob/1ebc69a44708f344449c0c9d47e33b414277adec/tooling/workspace-hack/Cargo.toml#L355

Release Notes:

- N/A
This commit is contained in:
Peter Tripp
2025-09-05 12:40:47 -04:00
committed by GitHub
parent 91ab0636ec
commit 638320b21e
4 changed files with 40 additions and 14 deletions
Generated
+1 -1
View File
@@ -3070,7 +3070,6 @@ dependencies = [
"clock",
"cloud_api_client",
"cloud_llm_client",
"cocoa 0.26.0",
"collections",
"credentials_provider",
"derive_more",
@@ -3083,6 +3082,7 @@ dependencies = [
"http_client_tls",
"httparse",
"log",
"objc2-foundation",
"parking_lot",
"paths",
"postage",
+25
View File
@@ -537,6 +537,31 @@ nbformat = { git = "https://github.com/ConradIrwin/runtimed", rev = "7130c80421
nix = "0.29"
num-format = "0.4.4"
objc = "0.2"
objc2-foundation = { version = "0.3", default-features = false, features = [
"NSArray",
"NSAttributedString",
"NSBundle",
"NSCoder",
"NSData",
"NSDate",
"NSDictionary",
"NSEnumerator",
"NSError",
"NSGeometry",
"NSNotification",
"NSNull",
"NSObjCRuntime",
"NSObject",
"NSProcessInfo",
"NSRange",
"NSRunLoop",
"NSString",
"NSURL",
"NSUndoManager",
"NSValue",
"objc2-core-foundation",
"std"
] }
open = "5.0.0"
ordered-float = "2.1.1"
palette = { version = "0.7.5", default-features = false, features = ["std"] }
+1 -1
View File
@@ -75,7 +75,7 @@ util = { workspace = true, features = ["test-support"] }
windows.workspace = true
[target.'cfg(target_os = "macos")'.dependencies]
cocoa.workspace = true
objc2-foundation.workspace = true
[target.'cfg(any(target_os = "windows", target_os = "macos"))'.dependencies]
tokio-native-tls = "0.3"
+13 -12
View File
@@ -84,6 +84,10 @@ static DOTNET_PROJECT_FILES_REGEX: LazyLock<Regex> = LazyLock::new(|| {
Regex::new(r"^(global\.json|Directory\.Build\.props|.*\.(csproj|fsproj|vbproj|sln))$").unwrap()
});
#[cfg(target_os = "macos")]
static MACOS_VERSION_REGEX: LazyLock<Regex> =
LazyLock::new(|| Regex::new(r"(\s*\(Build [^)]*[0-9]\))").unwrap());
pub fn os_name() -> String {
#[cfg(target_os = "macos")]
{
@@ -108,19 +112,16 @@ pub fn os_name() -> String {
pub fn os_version() -> String {
#[cfg(target_os = "macos")]
{
use cocoa::base::nil;
use cocoa::foundation::NSProcessInfo;
unsafe {
let process_info = cocoa::foundation::NSProcessInfo::processInfo(nil);
let version = process_info.operatingSystemVersion();
gpui::SemanticVersion::new(
version.majorVersion as usize,
version.minorVersion as usize,
version.patchVersion as usize,
)
use objc2_foundation::NSProcessInfo;
let process_info = NSProcessInfo::processInfo();
let version_nsstring = unsafe { process_info.operatingSystemVersionString() };
// "Version 15.6.1 (Build 24G90)" -> "15.6.1 (Build 24G90)"
let version_string = version_nsstring.to_string().replace("Version ", "");
// "15.6.1 (Build 24G90)" -> "15.6.1"
// "26.0.0 (Build 25A5349a)" -> unchanged (Beta or Rapid Security Response; ends with letter)
MACOS_VERSION_REGEX
.replace_all(&version_string, "")
.to_string()
}
}
#[cfg(any(target_os = "linux", target_os = "freebsd"))]
{