Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/assemble-xcframework-sentryobjc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,9 @@ jobs:
- name: Validate XCFramework structure
run: |
./scripts/validate-xcframework-format.sh "SentryObjC-Static.xcframework"
./scripts/validate-xcframework-architectures.sh --xcframework "SentryObjC-Static.xcframework"
./scripts/validate-xcframework-format.sh "SentryObjC-Dynamic.xcframework"
./scripts/validate-xcframework-architectures.sh --xcframework "SentryObjC-Dynamic.xcframework"
shell: bash

- name: Zip XCFrameworks
Expand Down
4 changes: 3 additions & 1 deletion .github/workflows/assemble-xcframework-variant.yml
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,9 @@ jobs:
shell: bash

- name: Validate XCFramework structure
run: ./scripts/validate-xcframework-format.sh "${{env.XCFRAMEWORK_NAME}}.xcframework"
run: |
./scripts/validate-xcframework-format.sh "${{env.XCFRAMEWORK_NAME}}.xcframework"
./scripts/validate-xcframework-architectures.sh --xcframework "${{env.XCFRAMEWORK_NAME}}.xcframework"
shell: bash
env:
XCFRAMEWORK_NAME: ${{ env.XCFRAMEWORK_NAME }}
Expand Down
7 changes: 7 additions & 0 deletions scripts/build-xcframework-local.sh
Original file line number Diff line number Diff line change
Expand Up @@ -12,41 +12,47 @@ mkdir XCFrameworkBuildPath
if [ "$variants" = "DynamicOnly" ] || [ "$variants" = "AllVariants" ]; then
./scripts/build-xcframework-variant.sh "Sentry" "-Dynamic" "mh_dylib" "" "$sdks" "arm64e"
./scripts/validate-xcframework-format.sh "Sentry-Dynamic.xcframework"
./scripts/validate-xcframework-architectures.sh --xcframework "Sentry-Dynamic.xcframework"
./scripts/compress-xcframework.sh "$signed" Sentry-Dynamic
mv Sentry-Dynamic.xcframework.zip XCFrameworkBuildPath/Sentry-Dynamic.xcframework.zip
fi

if [ "$variants" = "DynamicWithARM64eOnly" ] || [ "$variants" = "AllVariants" ]; then
./scripts/build-xcframework-variant.sh "Sentry" "-Dynamic-WithARM64e" "mh_dylib" "" "$sdks" ""
./scripts/validate-xcframework-format.sh "Sentry-Dynamic-WithARM64e.xcframework"
./scripts/validate-xcframework-architectures.sh --xcframework "Sentry-Dynamic-WithARM64e.xcframework"
./scripts/compress-xcframework.sh "$signed" Sentry-Dynamic-WithARM64e
mv Sentry-Dynamic-WithARM64e.xcframework.zip XCFrameworkBuildPath/Sentry-Dynamic-WithARM64e.xcframework.zip
fi

if [ "$variants" = "StaticOnly" ] || [ "$variants" = "AllVariants" ]; then
./scripts/build-xcframework-variant.sh "Sentry" "" "staticlib" "" "$sdks" ""
./scripts/validate-xcframework-format.sh "Sentry.xcframework"
./scripts/validate-xcframework-architectures.sh --xcframework "Sentry.xcframework"
./scripts/compress-xcframework.sh "$signed" Sentry
mv Sentry.xcframework.zip XCFrameworkBuildPath/Sentry.xcframework.zip
fi

if [ "$variants" = "SwiftUIOnly" ] || [ "$variants" = "AllVariants" ]; then
./scripts/build-xcframework-variant.sh "SentrySwiftUI" "" "mh_dylib" "" "$sdks" ""
./scripts/validate-xcframework-format.sh "SentrySwiftUI.xcframework"
./scripts/validate-xcframework-architectures.sh --xcframework "SentrySwiftUI.xcframework"
./scripts/compress-xcframework.sh "$signed" SentrySwiftUI
mv SentrySwiftUI.xcframework.zip XCFrameworkBuildPath/SentrySwiftUI.xcframework.zip
fi

if [ "$variants" = "WithoutUIKitOnly" ] || [ "$variants" = "AllVariants" ]; then
./scripts/build-xcframework-variant.sh "Sentry" "-WithoutUIKitOrAppKit" "mh_dylib" "WithoutUIKit" "$sdks" "arm64e"
./scripts/validate-xcframework-format.sh "Sentry-WithoutUIKitOrAppKit.xcframework"
./scripts/validate-xcframework-architectures.sh --xcframework "Sentry-WithoutUIKitOrAppKit.xcframework"
./scripts/compress-xcframework.sh "$signed" Sentry-WithoutUIKitOrAppKit
mv Sentry-WithoutUIKitOrAppKit.xcframework.zip XCFrameworkBuildPath/Sentry-WithoutUIKitOrAppKit.xcframework.zip
fi

if [ "$variants" = "WithoutUIKitWithARM64eOnly" ] || [ "$variants" = "AllVariants" ]; then
./scripts/build-xcframework-variant.sh "Sentry" "-WithoutUIKitOrAppKit-WithARM64e" "mh_dylib" "WithoutUIKit" "$sdks" ""
./scripts/validate-xcframework-format.sh "Sentry-WithoutUIKitOrAppKit-WithARM64e.xcframework"
./scripts/validate-xcframework-architectures.sh --xcframework "Sentry-WithoutUIKitOrAppKit-WithARM64e.xcframework"
./scripts/compress-xcframework.sh "$signed" Sentry-WithoutUIKitOrAppKit-WithARM64e
mv Sentry-WithoutUIKitOrAppKit-WithARM64e.xcframework.zip XCFrameworkBuildPath/Sentry-WithoutUIKitOrAppKit-WithARM64e.xcframework.zip
fi
Expand Down Expand Up @@ -90,6 +96,7 @@ if [ "$variants" = "SentryObjCOnly" ] || [ "$variants" = "AllVariants" ]; then

for linkage in Static Dynamic; do
./scripts/validate-xcframework-format.sh "SentryObjC-${linkage}.xcframework"
./scripts/validate-xcframework-architectures.sh --xcframework "SentryObjC-${linkage}.xcframework"
./scripts/compress-xcframework.sh "$signed" "SentryObjC-${linkage}"
mv "SentryObjC-${linkage}.xcframework.zip" "XCFrameworkBuildPath/SentryObjC-${linkage}.xcframework.zip"
done
Expand Down
1 change: 1 addition & 0 deletions scripts/compress-xcframework.sh
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ if [[ "$should_sign" == true ]]; then
echo "Signing $framework"
# This is Sentry's certificate name, and should not change
codesign --sign "$sentry_certificate" --timestamp --options runtime --deep --force "$framework_path"
codesign --verify --deep --strict --verbose=2 "$framework_path"
fi

echo "Compressing $framework"
Expand Down
142 changes: 142 additions & 0 deletions scripts/validate-xcframework-architectures.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
#!/bin/bash
set -euo pipefail

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
# shellcheck source=./ci-utils.sh disable=SC1091
source "$SCRIPT_DIR/ci-utils.sh"

XCFRAMEWORK_PATH=""

usage() {
log_notice "Usage: $0 --xcframework <path>"
log_notice " --xcframework <path> XCFramework bundle to validate (required)"
exit 1
}

while [[ $# -gt 0 ]]; do
case "$1" in
--xcframework)
if [ $# -lt 2 ]; then
usage
fi
XCFRAMEWORK_PATH="$2"
shift 2
;;
*)
usage
;;
esac
done

if [ -z "$XCFRAMEWORK_PATH" ]; then
log_error "Error: --xcframework is required"
usage
fi

if [ ! -d "$XCFRAMEWORK_PATH" ]; then
log_error "XCFramework path does not exist: $XCFRAMEWORK_PATH"
exit 1
fi

info_plist_path="$XCFRAMEWORK_PATH/Info.plist"
if [ ! -f "$info_plist_path" ]; then
log_error "Missing XCFramework Info.plist: $info_plist_path"
exit 1
fi

normalize_archs() {
local archs="$1"

printf "%s\n" "$archs" | tr " " "\n" | sed "/^$/d" | sort | paste -sd " " -
}

binary_path_for_library() {
local library_identifier="$1"
local library_path="$2"
local library_full_path="$XCFRAMEWORK_PATH/$library_identifier/$library_path"
local framework_name=""
local binary_path=""

if [[ "$library_full_path" == *.framework ]]; then
framework_name="$(basename "$library_full_path" .framework)"
binary_path="$library_full_path/$framework_name"
if [ -e "$binary_path" ]; then
printf "%s\n" "$binary_path"
return 0
fi

binary_path="$library_full_path/Versions/A/$framework_name"
if [ -e "$binary_path" ]; then
printf "%s\n" "$binary_path"
return 0
fi

log_error "Missing framework binary for $library_identifier: $library_full_path" >&2
return 1
fi

if [ -f "$library_full_path" ]; then
printf "%s\n" "$library_full_path"
return 0
fi

log_error "Unsupported or missing library path for $library_identifier: $library_full_path" >&2
return 1
}

validate_library_architectures() {
local library_identifier="$1"
local library_path="$2"
local expected_archs="$3"
local binary_path=""
local actual_archs=""
local normalized_expected_archs=""
local normalized_actual_archs=""

if ! binary_path="$(binary_path_for_library "$library_identifier" "$library_path")"; then
return 1
fi

if ! actual_archs="$(lipo -archs "$binary_path" 2>/dev/null)"; then
log_error "Could not read architectures for $library_identifier: $binary_path"
return 1
fi

normalized_expected_archs="$(normalize_archs "$expected_archs")"
normalized_actual_archs="$(normalize_archs "$actual_archs")"

if [ "$normalized_expected_archs" != "$normalized_actual_archs" ]; then
log_error "$library_identifier architecture mismatch: expected [$normalized_expected_archs], got [$normalized_actual_archs]"
log_error "Binary: $binary_path"
return 1
fi

log_notice "$library_identifier architectures: $normalized_actual_archs"
}

begin_group "Validate XCFramework architectures: $XCFRAMEWORK_PATH"

xcframework_json="$(plutil -convert json -o - "$info_plist_path")"
validation_errors=0

while IFS=$'\t' read -r library_identifier library_path expected_archs; do
if [ -z "$library_identifier" ]; then
continue
fi

if ! validate_library_architectures "$library_identifier" "$library_path" "$expected_archs"; then
validation_errors=$((validation_errors + 1))
fi
done < <(
printf "%s\n" "$xcframework_json" \
| jq -r '.AvailableLibraries[] | [.LibraryIdentifier, .LibraryPath, (.SupportedArchitectures | join(" "))] | @tsv'
)
Comment thread
philprime marked this conversation as resolved.
Outdated
Comment thread
philprime marked this conversation as resolved.
Outdated

end_group

if [ "$validation_errors" -ne 0 ]; then
log_error "XCFramework architecture validation failed with $validation_errors error(s)."
exit 1
fi

log_notice "XCFramework architecture validation passed."
Loading