fix(release): align export compliance flag and backfill missing framework dsyms

This commit is contained in:
Haitao Pan 2026-03-25 11:55:50 +08:00
parent b86692e5ab
commit df61476416
7 changed files with 62 additions and 11 deletions

View File

@ -3,7 +3,7 @@
Date: 2026-03-24
App: XWorkmate
Platforms: iOS, macOS
Related setting: `ITSAppUsesNonExemptEncryption = YES`
Related setting: `ITSAppUsesNonExemptEncryption = NO`
## Purpose
@ -11,10 +11,10 @@ This note is a practical drafting aid for App Store Connect export compliance an
## Recommended App Store Connect Position
- The app should be treated as using encryption beyond a pure "Apple OS only" transport case.
- The safer declaration path is:
- The app should be treated as using standard encryption algorithms for transport, authentication, and credential protection.
- The recommended declaration path is:
- App uses standard encryption algorithms.
- `ITSAppUsesNonExemptEncryption` remains `YES`.
- `ITSAppUsesNonExemptEncryption` is `NO` (no non-exempt encryption declared in Info.plist).
- If the app is distributed in France, the publisher should assume the France-specific encryption documentation path applies unless counsel or a qualified compliance reviewer confirms otherwise.
## Implementation Basis
@ -87,4 +87,3 @@ This app uses standard cryptographic algorithms and secure transport protocols,
- [`ios/Runner/Info.plist`](/Users/shenlan/workspaces/cloud-neutral-toolkit/XWorkmate.svc.plus/ios/Runner/Info.plist)
- [`macos/Runner/Info.plist`](/Users/shenlan/workspaces/cloud-neutral-toolkit/XWorkmate.svc.plus/macos/Runner/Info.plist)

View File

@ -12,7 +12,7 @@ This document is a practical filling guide for the App Store Connect encryption
- Select: `代替在 Apple 操作系统中使用或访问加密,或与这些操作同时使用的标准加密算法`
- English meaning: standard cryptographic algorithms used in addition to or alongside Apple operating system encryption
- `ITSAppUsesNonExemptEncryption`:
- Set to: `YES`
- Set to: `NO`
- France distribution:
- If France is included in sales regions, select: `是 / Yes`
@ -102,4 +102,3 @@ This app uses standard cryptographic algorithms and secure transport protocols,
- [`lib/runtime/runtime_bootstrap.dart`](/Users/shenlan/workspaces/cloud-neutral-toolkit/XWorkmate.svc.plus/lib/runtime/runtime_bootstrap.dart)
- [`lib/runtime/secure_config_store.dart`](/Users/shenlan/workspaces/cloud-neutral-toolkit/XWorkmate.svc.plus/lib/runtime/secure_config_store.dart)
- [`lib/runtime/secret_store.dart`](/Users/shenlan/workspaces/cloud-neutral-toolkit/XWorkmate.svc.plus/lib/runtime/secret_store.dart)

View File

@ -290,7 +290,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n/bin/sh \"${PROJECT_DIR}/../scripts/ensure-framework-dsyms.sh\"\n";
showEnvVarsInLog = 0;
};
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {

View File

@ -25,7 +25,7 @@
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>ITSAppUsesNonExemptEncryption</key>
<true/>
<false/>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSLocalNetworkUsageDescription</key>

View File

@ -422,7 +422,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n/bin/sh \"${PROJECT_DIR}/../scripts/ensure-framework-dsyms.sh\"\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */

View File

@ -21,7 +21,7 @@
<key>CFBundleVersion</key>
<string>$(FLUTTER_BUILD_NUMBER)</string>
<key>ITSAppUsesNonExemptEncryption</key>
<true/>
<false/>
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
<key>LSApplicationCategoryType</key>

View File

@ -0,0 +1,53 @@
#!/usr/bin/env bash
set -euo pipefail
# Keep release/profile uploads resilient by generating missing framework dSYMs
# after embed phases. This is a no-op for debug builds.
if [[ "${CONFIGURATION:-}" != "Release" && "${CONFIGURATION:-}" != "Profile" ]]; then
exit 0
fi
if [[ -z "${FRAMEWORKS_FOLDER_PATH:-}" || -z "${TARGET_BUILD_DIR:-}" ]]; then
exit 0
fi
if [[ -z "${DWARF_DSYM_FOLDER_PATH:-}" ]]; then
exit 0
fi
frameworks_dir="${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}"
if [[ ! -d "${frameworks_dir}" ]]; then
exit 0
fi
mkdir -p "${DWARF_DSYM_FOLDER_PATH}"
for framework_path in "${frameworks_dir}"/*.framework; do
[[ -d "${framework_path}" ]] || continue
framework_name="$(basename "${framework_path}" .framework)"
binary_path="${framework_path}/${framework_name}"
[[ -f "${binary_path}" ]] || continue
# Most Flutter and pod frameworks already produce dSYMs in normal archive
# flow. Keep this pass narrow to known stragglers observed in distribution.
case "${framework_name}" in
objective_c|App|A) ;;
*) continue ;;
esac
dsym_path="${DWARF_DSYM_FOLDER_PATH}/${framework_name}.framework.dSYM"
if [[ -d "${dsym_path}" ]]; then
continue
fi
if ! xcrun dwarfdump --uuid "${binary_path}" >/dev/null 2>&1; then
continue
fi
echo "Generating missing dSYM for ${framework_name}.framework"
if ! xcrun dsymutil "${binary_path}" -o "${dsym_path}" >/dev/null 2>&1; then
echo "warning: Failed to generate dSYM for ${framework_name}.framework" >&2
rm -rf "${dsym_path}" || true
fi
done