Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
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
4 changes: 3 additions & 1 deletion azure_pipelines/pr-validation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,9 @@ jobs:
inputs:
Comment thread
mipetriu marked this conversation as resolved.
targetType: 'inline'
script: |
sh spm-integration-test.sh "${BRANCH_NAME}"
# visionOS slices are validated in visionos-validation.yml (which installs
# the visionOS SDK). This fast PR job does not, so skip them here.
sh spm-integration-test.sh "${BRANCH_NAME}" --skip-visionos
continueOnError: false

- task: Bash@3
Expand Down
63 changes: 61 additions & 2 deletions spm-integration-test.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
BRANCH_NAME="$1"
INCLUDE_VISIONOS=false
# visionOS device + simulator slices are included by default so the published
# xcframework never ships out of sync with Package.swift's .visionOS() platform.
# Use --skip-visionos on fast paths (e.g. regular PR validation) that do not have
# the visionOS SDK installed. --include-visionos is kept as a no-op alias for
# backward compatibility with existing callers.
INCLUDE_VISIONOS=true

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just curious about flipping the default here. Both callers in the repo already pass a flag explicitly - pr-validation.yml now passes --skip-visionos and visionos-validation.yml passes --include-visionos --skip-sample-app - so the new default doesn't add any coverage, but it does break anyone running the script locally without the visionOS SDK installed. I guess the real regression guard is the slice verification below, so keeping INCLUDE_VISIONOS=false would give us the same protection with less surprise? :)

SKIP_SAMPLE_APP=false

# Parse optional flags
Expand All @@ -8,6 +13,9 @@ for arg in "$@"; do
--include-visionos)
INCLUDE_VISIONOS=true
;;
--skip-visionos)
INCLUDE_VISIONOS=false
;;
--skip-sample-app)
SKIP_SAMPLE_APP=true
;;
Expand All @@ -19,6 +27,21 @@ current_date=$(date +"%Y-%m-%d %H:%M:%S")

set -e

# xcodebuild steps below run with -quiet and redirect output to build.log, so a
# failure would otherwise exit with no actionable context in the CI log. On a
# non-zero exit, dump build.log so the underlying xcodebuild error is visible.
# This script is invoked via `sh`, so use a POSIX-compatible EXIT trap that
# checks the status rather than a bash-only ERR trap.
on_exit()
{
status=$?
if [ "$status" -ne 0 ]; then
echo "** Build step failed (exit $status). Contents of build.log: **"
cat build.log 2>/dev/null || echo "(build.log not found)"
fi
}
trap on_exit EXIT

# Build framework

echo "Building framework"
Expand All @@ -35,11 +58,47 @@ if [ "$INCLUDE_VISIONOS" = true ]; then
xcodebuild -sdk xros -configuration Release -workspace MSAL.xcworkspace -scheme "MSAL (iOS Framework)" archive SKIP_INSTALL=NO BUILD_LIBRARY_FOR_DISTRIBUTION=YES -archivePath archive/visionOS CODE_SIGNING_ALLOWED=NO -quiet > build.log 2>&1
XCFRAMEWORK_ARGS="$XCFRAMEWORK_ARGS -framework archive/visionOSSimulator.xcarchive/Products/Library/Frameworks/MSAL.framework -framework archive/visionOS.xcarchive/Products/Library/Frameworks/MSAL.framework"
else
echo "Skipping visionOS (use --include-visionos to include)"
echo "Skipping visionOS (use default, or pass --include-visionos, to include; --skip-visionos to opt out)"
fi

xcodebuild -create-xcframework $XCFRAMEWORK_ARGS -output framework/MSAL.xcframework > build.log 2>&1

if [ "$INCLUDE_VISIONOS" = true ]; then
echo "Verifying visionOS slices are present in MSAL.xcframework"
if [ ! -f framework/MSAL.xcframework/Info.plist ]; then
echo "** ERROR: framework/MSAL.xcframework/Info.plist not found; xcframework creation likely failed. See build.log above. **"
exit 1
fi
python3 - <<'PY'
import plistlib, sys

plist_path = "framework/MSAL.xcframework/Info.plist"
with open(plist_path, "rb") as f:
info = plistlib.load(f)

libraries = info.get("AvailableLibraries", [])
Comment thread
mipetriu marked this conversation as resolved.

def has_slice(platform, simulator):
for lib in libraries:
is_sim = lib.get("SupportedPlatformVariant") == "simulator"
if lib.get("SupportedPlatform") == platform and is_sim == simulator:
return True
return False

missing = []
if not has_slice("xros", False):
missing.append("visionOS device (xros)")
if not has_slice("xros", True):
missing.append("visionOS simulator (xros-simulator)")

if missing:
sys.stderr.write("** ERROR: MSAL.xcframework is missing required slices: " + ", ".join(missing) + " **\n")
sys.exit(1)

print("Verified visionOS device + simulator slices are present in MSAL.xcframework")
PY
fi

echo "Creating MSAL.zip"
zip -r MSAL.zip framework/MSAL.xcframework -y -v

Expand Down