From 003673b7ff7c9aee6b1c89ceef5e79acad2d2ece Mon Sep 17 00:00:00 2001 From: marionbarker Date: Wed, 4 Feb 2026 08:51:57 -0800 Subject: [PATCH 1/3] include all submodule SHA in LoopWorkspace build details --- Common/Models/BuildDetails.swift | 15 +++++++++ Loop/Managers/DeviceDataManager.swift | 6 ++++ Scripts/capture-build-details.sh | 46 +++++++++++++++++++++++++++ 3 files changed, 67 insertions(+) diff --git a/Common/Models/BuildDetails.swift b/Common/Models/BuildDetails.swift index 4a1a1894fc..b71e265885 100644 --- a/Common/Models/BuildDetails.swift +++ b/Common/Models/BuildDetails.swift @@ -65,5 +65,20 @@ class BuildDetails { var workspaceGitBranch: String? { return dict["com-loopkit-LoopWorkspace-git-branch"] as? String } + + /// Returns a dictionary of submodule details. + /// The keys are the submodule names, and the values are tuples (branch, commitSHA). + var submodules: [String: (branch: String, commitSHA: String)] { + guard let subs = dict["com-loopkit-Loop-submodules"] as? [String: [String: Any]] else { + return [:] + } + var result = [String: (branch: String, commitSHA: String)]() + for (name, info) in subs { + let branch = info["branch"] as? String ?? String(localized: "Unknown") + let commitSHA = info["commit_sha"] as? String ?? String(localized: "Unknown") + result[name] = (branch: branch, commitSHA: commitSHA) + } + return result + } } diff --git a/Loop/Managers/DeviceDataManager.swift b/Loop/Managers/DeviceDataManager.swift index 2751f18f50..3d6cd0d887 100644 --- a/Loop/Managers/DeviceDataManager.swift +++ b/Loop/Managers/DeviceDataManager.swift @@ -1700,6 +1700,10 @@ extension DeviceDataManager: DeviceSupportDelegate { deviceLogReport = entries.map { "* \($0.timestamp) \($0.managerIdentifier) \($0.deviceIdentifier ?? "") \($0.type) \($0.message)" }.joined(separator: "\n") } + let submodulesInfo = BuildDetails.default.submodules.map { key, value in + "\n* \(key): \(value.branch) \(value.commitSHA)" + }.joined(separator: ",") + let report = [ "## Build Details", "* appNameAndVersion: \(Bundle.main.localizedNameAndVersion)", @@ -1711,6 +1715,8 @@ extension DeviceDataManager: DeviceSupportDelegate { "* sourceRoot: \(BuildDetails.default.sourceRoot ?? "N/A")", "* buildDateString: \(BuildDetails.default.buildDateString ?? "N/A")", "* xcodeVersion: \(BuildDetails.default.xcodeVersion ?? "N/A")", + "* submodules: [\(submodulesInfo)", + "* ]", "", "## FeatureFlags", "\(FeatureFlags)", diff --git a/Scripts/capture-build-details.sh b/Scripts/capture-build-details.sh index 07aab04a17..2393e5afa4 100755 --- a/Scripts/capture-build-details.sh +++ b/Scripts/capture-build-details.sh @@ -100,3 +100,49 @@ then fi popd . > /dev/null fi + +# --- Root repo details --- +# Retrieve current branch (or tag) and commit SHA. +git_branch=$(git symbolic-ref --short -q HEAD || echo "") +git_tag=$(git describe --tags --exact-match 2>/dev/null || echo "") +git_commit_sha=$(git log -1 --format="%h" --abbrev=7) +git_branch_or_tag="${git_branch:-${git_tag}}" +if [ -z "${git_branch_or_tag}" ]; then + git_branch_or_tag="detached" +fi + +plutil -replace com-loopkit-Loop-branch -string "${git_branch_or_tag}" "${info_plist_path}" +plutil -replace com-loopkit-Loop-commit-sha -string "${git_commit_sha}" "${info_plist_path}" + +# --- Submodule details --- +# Remove an existing submodules key if it exists, then create an empty dictionary. +# (Using PlistBuddy, which is available on macOS) +submodules_key="com-loopkit-Loop-submodules" +if /usr/libexec/PlistBuddy -c "Print :${submodules_key}" "${info_plist_path}" 2>/dev/null; then + /usr/libexec/PlistBuddy -c "Delete :${submodules_key}" "${info_plist_path}" +fi +/usr/libexec/PlistBuddy -c "Add :${submodules_key} dict" "${info_plist_path}" + +# Gather submodule details. +# We use git submodule foreach to output lines in the form: +# submodule_name|branch_or_tag|commit_sha +submodules_info=$(git submodule foreach --quiet ' + sub_git_branch=$(git symbolic-ref --short -q HEAD || echo "") + sub_git_tag=$(git describe --tags --exact-match 2>/dev/null || echo "") + sub_git_commit_sha=$(git log -1 --format="%h" --abbrev=7) + sub_git_branch_or_tag="${sub_git_branch:-${sub_git_tag}}" + if [ -z "${sub_git_branch_or_tag}" ]; then + sub_git_branch_or_tag="detached" + fi + echo "$name|$sub_git_branch_or_tag|$sub_git_commit_sha" +') + +# For each line, add a dictionary entry for that submodule. +echo "${submodules_info}" | while IFS="|" read -r submodule_name sub_branch sub_sha; do + # Create a dictionary for this submodule + /usr/libexec/PlistBuddy -c "Add :${submodules_key}:${submodule_name} dict" "${info_plist_path}" + /usr/libexec/PlistBuddy -c "Add :${submodules_key}:${submodule_name}:branch string ${sub_branch}" "${info_plist_path}" + /usr/libexec/PlistBuddy -c "Add :${submodules_key}:${submodule_name}:commit_sha string ${sub_sha}" "${info_plist_path}" +done + +echo "BuildDetails.plist has been updated at: ${info_plist_path}" \ No newline at end of file From 1922ace8d4db1860cbc47eb29ecbcd4f9132f79d Mon Sep 17 00:00:00 2001 From: marionbarker Date: Wed, 4 Feb 2026 15:29:24 -0800 Subject: [PATCH 2/3] alphabetize submodules, make output compatible with parser --- Loop/Managers/DeviceDataManager.swift | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Loop/Managers/DeviceDataManager.swift b/Loop/Managers/DeviceDataManager.swift index 3d6cd0d887..f1f9dc79ed 100644 --- a/Loop/Managers/DeviceDataManager.swift +++ b/Loop/Managers/DeviceDataManager.swift @@ -1700,9 +1700,12 @@ extension DeviceDataManager: DeviceSupportDelegate { deviceLogReport = entries.map { "* \($0.timestamp) \($0.managerIdentifier) \($0.deviceIdentifier ?? "") \($0.type) \($0.message)" }.joined(separator: "\n") } - let submodulesInfo = BuildDetails.default.submodules.map { key, value in - "\n* \(key): \(value.branch) \(value.commitSHA)" - }.joined(separator: ",") + let submodulesInfo = BuildDetails.default.submodules + .sorted(by: { $0.key < $1.key }) + .map { key, value in + "* \(key): \(value.branch), \(value.commitSHA)" + } + .joined(separator: "\n") let report = [ "## Build Details", @@ -1715,8 +1718,10 @@ extension DeviceDataManager: DeviceSupportDelegate { "* sourceRoot: \(BuildDetails.default.sourceRoot ?? "N/A")", "* buildDateString: \(BuildDetails.default.buildDateString ?? "N/A")", "* xcodeVersion: \(BuildDetails.default.xcodeVersion ?? "N/A")", - "* submodules: [\(submodulesInfo)", - "* ]", + "* Workspace branch: \(BuildDetails.default.workspaceGitBranch ?? "N/A")", + "* Workspace SHA: \(BuildDetails.default.workspaceGitRevision ?? "N/A")", + "* Submodule name: branch, SHA", + "\(submodulesInfo)", "", "## FeatureFlags", "\(FeatureFlags)", From 3b8681708bb6775a1e079b4b74046441186bc2ad Mon Sep 17 00:00:00 2001 From: marionbarker Date: Wed, 4 Feb 2026 15:31:47 -0800 Subject: [PATCH 3/3] remove redundant build detail lines --- Loop/Managers/DeviceDataManager.swift | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Loop/Managers/DeviceDataManager.swift b/Loop/Managers/DeviceDataManager.swift index f1f9dc79ed..e928c5e2d0 100644 --- a/Loop/Managers/DeviceDataManager.swift +++ b/Loop/Managers/DeviceDataManager.swift @@ -1711,10 +1711,6 @@ extension DeviceDataManager: DeviceSupportDelegate { "## Build Details", "* appNameAndVersion: \(Bundle.main.localizedNameAndVersion)", "* profileExpiration: \(BuildDetails.default.profileExpirationString)", - "* gitRevision: \(BuildDetails.default.gitRevision ?? "N/A")", - "* gitBranch: \(BuildDetails.default.gitBranch ?? "N/A")", - "* workspaceGitRevision: \(BuildDetails.default.workspaceGitRevision ?? "N/A")", - "* workspaceGitBranch: \(BuildDetails.default.workspaceGitBranch ?? "N/A")", "* sourceRoot: \(BuildDetails.default.sourceRoot ?? "N/A")", "* buildDateString: \(BuildDetails.default.buildDateString ?? "N/A")", "* xcodeVersion: \(BuildDetails.default.xcodeVersion ?? "N/A")",