From d8a3d62eaa9bbee23fd55d80abd5b5be216d72d7 Mon Sep 17 00:00:00 2001 From: TastyHeadphones <76083688+TastyHeadphones@users.noreply.github.com> Date: Sun, 27 Sep 2026 17:33:13 +0900 Subject: [PATCH] Fail closed in make-xcframeworks.sh The release script ignored xcodebuild/codesign failures (piped without pipefail) and left stale *.xcframework dirs in place, so a failed run could still zip old frameworks and exit 0. Enable pipefail, clear previous outputs up front, and require each xcframework to exist before signing/zipping. Fixes #2733 --- scripts/make-xcframeworks.sh | 136 +++++++++++++++-------------------- 1 file changed, 59 insertions(+), 77 deletions(-) diff --git a/scripts/make-xcframeworks.sh b/scripts/make-xcframeworks.sh index 2e3e536bb..693f12d05 100755 --- a/scripts/make-xcframeworks.sh +++ b/scripts/make-xcframeworks.sh @@ -1,91 +1,73 @@ -rm -rf .build -mkdir .build +#!/usr/bin/env bash +# Fail closed: any archive/build/sign failure must abort before zipping. +set -euo pipefail products=(RxSwift RxRelay RxCocoa RxTest RxBlocking) -BUILD_PATH=`realpath .build` - -for product in ${products[@]}; do - PROJECT_NAME="$product" - - # Generate iOS framework - xcodebuild -workspace Rx.xcworkspace -configuration Release -archivePath "${BUILD_PATH}/${PROJECT_NAME}-iphoneos.xcarchive" -destination "generic/platform=iOS" SKIP_INSTALL=NO SWIFT_SERIALIZE_DEBUGGING_OPTIONS=NO BUILD_LIBRARIES_FOR_DISTRIBUTION=YES -scheme $PROJECT_NAME archive | xcbeautify - # Generate iOS Simulator framework - xcodebuild -workspace Rx.xcworkspace -configuration Release -archivePath "${BUILD_PATH}/${PROJECT_NAME}-iossimulator.xcarchive" -destination "generic/platform=iOS Simulator" SKIP_INSTALL=NO SWIFT_SERIALIZE_DEBUGGING_OPTIONS=NO BUILD_LIBRARIES_FOR_DISTRIBUTION=YES -scheme $PROJECT_NAME archive | xcbeautify - - # Generate macOS framework - xcodebuild -workspace Rx.xcworkspace -configuration Release -archivePath "${BUILD_PATH}/${PROJECT_NAME}-macosx.xcarchive" -destination "generic/platform=macOS,name=Any Mac" SKIP_INSTALL=NO SWIFT_SERIALIZE_DEBUGGING_OPTIONS=NO BUILD_LIBRARIES_FOR_DISTRIBUTION=YES -scheme $PROJECT_NAME archive | xcbeautify - - # Generate maccatalyst framework - xcodebuild -workspace Rx.xcworkspace -configuration Release -archivePath "${BUILD_PATH}/${PROJECT_NAME}-maccatalyst.xcarchive" -destination "generic/platform=macOS,variant=Mac Catalyst" SKIP_INSTALL=NO BUILD_LIBRARIES_FOR_DISTRIBUTION=YES -scheme $PROJECT_NAME archive | xcbeautify +rm -rf .build +rm -rf "${products[@]/%/.xcframework}" +rm -f ./RxSwift.xcframework.zip +mkdir .build - # Generate tvOS framework - xcodebuild -workspace Rx.xcworkspace -configuration Release -archivePath "${BUILD_PATH}/${PROJECT_NAME}-appletvos.xcarchive" -destination "generic/platform=tvOS" SKIP_INSTALL=NO SWIFT_SERIALIZE_DEBUGGING_OPTIONS=NO BUILD_LIBRARIES_FOR_DISTRIBUTION=YES -scheme $PROJECT_NAME archive | xcbeautify +BUILD_PATH=$(realpath .build) - # Generate tvOS Simulator framework - xcodebuild -workspace Rx.xcworkspace -configuration Release -archivePath "${BUILD_PATH}/${PROJECT_NAME}-appletvsimulator.xcarchive" -destination "generic/platform=tvOS Simulator" SKIP_INSTALL=NO SWIFT_SERIALIZE_DEBUGGING_OPTIONS=NO BUILD_LIBRARIES_FOR_DISTRIBUTION=YES -scheme $PROJECT_NAME archive | xcbeautify +archive() { + local project_name=$1 + local archive_suffix=$2 + shift 2 + xcodebuild -workspace Rx.xcworkspace -configuration Release \ + -archivePath "${BUILD_PATH}/${project_name}-${archive_suffix}.xcarchive" \ + SKIP_INSTALL=NO SWIFT_SERIALIZE_DEBUGGING_OPTIONS=NO BUILD_LIBRARIES_FOR_DISTRIBUTION=YES \ + -scheme "$project_name" archive "$@" | xcbeautify +} - # Generate visionOS framework - xcodebuild -workspace Rx.xcworkspace -configuration Release -archivePath "${BUILD_PATH}/${PROJECT_NAME}-visionos.xcarchive" -destination "generic/platform=visionOS" SKIP_INSTALL=NO SWIFT_SERIALIZE_DEBUGGING_OPTIONS=NO BUILD_LIBRARIES_FOR_DISTRIBUTION=YES -scheme $PROJECT_NAME archive | xcbeautify +create_xcframework() { + local project_name=$1 + shift + local args=() + local suffix + for suffix in "$@"; do + args+=( + -framework "${BUILD_PATH}/${project_name}-${suffix}.xcarchive/Products/Library/Frameworks/${project_name}.framework" + -debug-symbols "${BUILD_PATH}/${project_name}-${suffix}.xcarchive/dSYMs/${project_name}.framework.dSYM" + ) + done + xcodebuild -create-xcframework "${args[@]}" -output "./${project_name}.xcframework" | xcbeautify +} - # Generate visionOS simulator framework - xcodebuild -workspace Rx.xcworkspace -configuration Release -archivePath "${BUILD_PATH}/${PROJECT_NAME}-visionossimulator.xcarchive" -destination "generic/platform=visionOS Simulator" SKIP_INSTALL=NO SWIFT_SERIALIZE_DEBUGGING_OPTIONS=NO BUILD_LIBRARIES_FOR_DISTRIBUTION=YES -scheme $PROJECT_NAME archive | xcbeautify +for product in "${products[@]}"; do + PROJECT_NAME="$product" - # RxTest doesn't work on watchOS - if [[ "$product" != "RxTest" ]]; then - # Generate watchOS framework - xcodebuild -workspace Rx.xcworkspace -configuration Release -archivePath "${BUILD_PATH}/${PROJECT_NAME}-watchos.xcarchive" -destination "generic/platform=watchOS" SKIP_INSTALL=NO SWIFT_SERIALIZE_DEBUGGING_OPTIONS=NO BUILD_LIBRARIES_FOR_DISTRIBUTION=YES -scheme $PROJECT_NAME archive | xcbeautify + archive "$PROJECT_NAME" iphoneos -destination "generic/platform=iOS" + archive "$PROJECT_NAME" iossimulator -destination "generic/platform=iOS Simulator" + archive "$PROJECT_NAME" macosx -destination "generic/platform=macOS,name=Any Mac" + archive "$PROJECT_NAME" maccatalyst -destination "generic/platform=macOS,variant=Mac Catalyst" + archive "$PROJECT_NAME" appletvos -destination "generic/platform=tvOS" + archive "$PROJECT_NAME" appletvsimulator -destination "generic/platform=tvOS Simulator" + archive "$PROJECT_NAME" visionos -destination "generic/platform=visionOS" + archive "$PROJECT_NAME" visionossimulator -destination "generic/platform=visionOS Simulator" - # Generate watchOS Simulator framework - xcodebuild -workspace Rx.xcworkspace -configuration Release -archivePath "${BUILD_PATH}/${PROJECT_NAME}-watchsimulator.xcarchive" -destination "generic/platform=watchOS Simulator" SKIP_INSTALL=NO SWIFT_SERIALIZE_DEBUGGING_OPTIONS=NO BUILD_LIBRARIES_FOR_DISTRIBUTION=YES -scheme $PROJECT_NAME archive | xcbeautify + # RxTest doesn't work on watchOS + if [[ "$product" != "RxTest" ]]; then + archive "$PROJECT_NAME" watchos -destination "generic/platform=watchOS" + archive "$PROJECT_NAME" watchsimulator -destination "generic/platform=watchOS Simulator" + create_xcframework "$PROJECT_NAME" \ + iphoneos iossimulator macosx maccatalyst \ + watchos watchsimulator appletvos appletvsimulator \ + visionos visionossimulator + else + create_xcframework "$PROJECT_NAME" \ + iphoneos iossimulator macosx maccatalyst \ + appletvos appletvsimulator visionos visionossimulator + fi - # Generate XCFramework - xcodebuild -create-xcframework \ - -framework "${BUILD_PATH}/${PROJECT_NAME}-iphoneos.xcarchive/Products/Library/Frameworks/${PROJECT_NAME}.framework" \ - -debug-symbols "${BUILD_PATH}/${PROJECT_NAME}-iphoneos.xcarchive/dSYMs/${PROJECT_NAME}.framework.dSYM" \ - -framework "${BUILD_PATH}/${PROJECT_NAME}-iossimulator.xcarchive/Products/Library/Frameworks/${PROJECT_NAME}.framework" \ - -debug-symbols "${BUILD_PATH}/${PROJECT_NAME}-iossimulator.xcarchive/dSYMs/${PROJECT_NAME}.framework.dSYM" \ - -framework "${BUILD_PATH}/${PROJECT_NAME}-macosx.xcarchive/Products/Library/Frameworks/${PROJECT_NAME}.framework" \ - -debug-symbols "${BUILD_PATH}/${PROJECT_NAME}-macosx.xcarchive/dSYMs/${PROJECT_NAME}.framework.dSYM" \ - -framework "${BUILD_PATH}/${PROJECT_NAME}-maccatalyst.xcarchive/Products/Library/Frameworks/${PROJECT_NAME}.framework" \ - -debug-symbols "${BUILD_PATH}/${PROJECT_NAME}-maccatalyst.xcarchive/dSYMs/${PROJECT_NAME}.framework.dSYM" \ - -framework "${BUILD_PATH}/${PROJECT_NAME}-watchos.xcarchive/Products/Library/Frameworks/${PROJECT_NAME}.framework" \ - -debug-symbols "${BUILD_PATH}/${PROJECT_NAME}-watchos.xcarchive/dSYMs/${PROJECT_NAME}.framework.dSYM" \ - -framework "${BUILD_PATH}/${PROJECT_NAME}-watchsimulator.xcarchive/Products/Library/Frameworks/${PROJECT_NAME}.framework" \ - -debug-symbols "${BUILD_PATH}/${PROJECT_NAME}-watchsimulator.xcarchive/dSYMs/${PROJECT_NAME}.framework.dSYM" \ - -framework "${BUILD_PATH}/${PROJECT_NAME}-appletvos.xcarchive/Products/Library/Frameworks/${PROJECT_NAME}.framework" \ - -debug-symbols "${BUILD_PATH}/${PROJECT_NAME}-appletvos.xcarchive/dSYMs/${PROJECT_NAME}.framework.dSYM" \ - -framework "${BUILD_PATH}/${PROJECT_NAME}-appletvsimulator.xcarchive/Products/Library/Frameworks/${PROJECT_NAME}.framework" \ - -debug-symbols "${BUILD_PATH}/${PROJECT_NAME}-appletvsimulator.xcarchive/dSYMs/${PROJECT_NAME}.framework.dSYM" \ - -framework "${BUILD_PATH}/${PROJECT_NAME}-visionos.xcarchive/Products/Library/Frameworks/${PROJECT_NAME}.framework" \ - -debug-symbols "${BUILD_PATH}/${PROJECT_NAME}-visionos.xcarchive/dSYMs/${PROJECT_NAME}.framework.dSYM" \ - -framework "${BUILD_PATH}/${PROJECT_NAME}-visionossimulator.xcarchive/Products/Library/Frameworks/${PROJECT_NAME}.framework" \ - -debug-symbols "${BUILD_PATH}/${PROJECT_NAME}-visionossimulator.xcarchive/dSYMs/${PROJECT_NAME}.framework.dSYM" \ - -output "./${PROJECT_NAME}.xcframework" | xcbeautify - else - # Generate XCFramework - xcodebuild -create-xcframework \ - -framework "${BUILD_PATH}/${PROJECT_NAME}-iphoneos.xcarchive/Products/Library/Frameworks/${PROJECT_NAME}.framework" \ - -debug-symbols "${BUILD_PATH}/${PROJECT_NAME}-iphoneos.xcarchive/dSYMs/${PROJECT_NAME}.framework.dSYM" \ - -framework "${BUILD_PATH}/${PROJECT_NAME}-iossimulator.xcarchive/Products/Library/Frameworks/${PROJECT_NAME}.framework" \ - -debug-symbols "${BUILD_PATH}/${PROJECT_NAME}-iossimulator.xcarchive/dSYMs/${PROJECT_NAME}.framework.dSYM" \ - -framework "${BUILD_PATH}/${PROJECT_NAME}-macosx.xcarchive/Products/Library/Frameworks/${PROJECT_NAME}.framework" \ - -debug-symbols "${BUILD_PATH}/${PROJECT_NAME}-macosx.xcarchive/dSYMs/${PROJECT_NAME}.framework.dSYM" \ - -framework "${BUILD_PATH}/${PROJECT_NAME}-maccatalyst.xcarchive/Products/Library/Frameworks/${PROJECT_NAME}.framework" \ - -debug-symbols "${BUILD_PATH}/${PROJECT_NAME}-maccatalyst.xcarchive/dSYMs/${PROJECT_NAME}.framework.dSYM" \ - -framework "${BUILD_PATH}/${PROJECT_NAME}-appletvos.xcarchive/Products/Library/Frameworks/${PROJECT_NAME}.framework" \ - -debug-symbols "${BUILD_PATH}/${PROJECT_NAME}-appletvos.xcarchive/dSYMs/${PROJECT_NAME}.framework.dSYM" \ - -framework "${BUILD_PATH}/${PROJECT_NAME}-appletvsimulator.xcarchive/Products/Library/Frameworks/${PROJECT_NAME}.framework" \ - -debug-symbols "${BUILD_PATH}/${PROJECT_NAME}-appletvsimulator.xcarchive/dSYMs/${PROJECT_NAME}.framework.dSYM" \ - -framework "${BUILD_PATH}/${PROJECT_NAME}-visionos.xcarchive/Products/Library/Frameworks/${PROJECT_NAME}.framework" \ - -debug-symbols "${BUILD_PATH}/${PROJECT_NAME}-visionos.xcarchive/dSYMs/${PROJECT_NAME}.framework.dSYM" \ - -framework "${BUILD_PATH}/${PROJECT_NAME}-visionossimulator.xcarchive/Products/Library/Frameworks/${PROJECT_NAME}.framework" \ - -debug-symbols "${BUILD_PATH}/${PROJECT_NAME}-visionossimulator.xcarchive/dSYMs/${PROJECT_NAME}.framework.dSYM" \ - -output "./${PROJECT_NAME}.xcframework" | xcbeautify - fi + if [[ ! -d "./${PROJECT_NAME}.xcframework" ]]; then + echo "error: expected ./${PROJECT_NAME}.xcframework was not created" >&2 + exit 1 + fi - # Code sign the binary - codesign --timestamp -v --sign "Apple Distribution: Shai Mishali (272EB7D3H3)" "./${PROJECT_NAME}.xcframework" + # Code sign the binary + codesign --timestamp -v --sign "Apple Distribution: Shai Mishali (272EB7D3H3)" "./${PROJECT_NAME}.xcframework" done # Zip all frameworks to a single ZIP