diff --git a/.github/workflows/Release.yml b/.github/workflows/Release.yml new file mode 100644 index 00000000..687800cf --- /dev/null +++ b/.github/workflows/Release.yml @@ -0,0 +1,52 @@ +name: "SDWebImage Release" + +on: + push: + # Pattern matched against refs/tags + tags: + - '*' + +jobs: + Release: + name: Release XCFramework + runs-on: macos-14 + env: + DEVELOPER_DIR: /Applications/Xcode_15.2.app + PROJECT_NAME: SDWebImage.xcodeproj + SCHEME_NAME: SDWebImage XCFramework + steps: + - name: Checkout + uses: actions/checkout@v3 + + - name: Build dynamic XCFramework + run: | + set -o pipefail + export MACH_O_TYPE=mh_dylib + xcodebuild build -project "${{ env.PROJECT_NAME }}" -scheme "${{ env.SCHEME_NAME }}" + rm -rf ~/Library/Developer/Xcode/DerivedData/ + + - name: Archive dynamic XCFramework + run: | + cd "${{ github.workspace }}" + zip -y -r SDWebImage-dynamic.xcframework.zip build/SDWebImage.xcframework + rm -rf build + + - name: Build static XCFramework + run: | + set -o pipefail + export MACH_O_TYPE=staticlib + xcodebuild build -project "${{ env.PROJECT_NAME }}" -scheme "${{ env.SCHEME_NAME }}" + rm -rf ~/Library/Developer/Xcode/DerivedData/ + + - name: Archive static XCFramework + run: | + cd "${{ github.workspace }}" + zip -y -r SDWebImage-static.xcframework.zip build/SDWebImage.xcframework + rm -rf build + + - uses: softprops/action-gh-release@v0.1.15 + env: + GITHUB_TOKEN: "${{ secrets.GITHUB_TOKEN }}" + GITHUB_REPOSITORY: "${{ github.repository }}" + with: + files: ["${{ github.workspace }}/SDWebImage-dynamic.xcframework.zip", "${{ github.workspace }}/SDWebImage-static.xcframework.zip"] diff --git a/Certificate/SDWebImage Signing Certificate.cer b/Certificate/SDWebImage Signing Certificate.cer new file mode 100644 index 00000000..463f0982 Binary files /dev/null and b/Certificate/SDWebImage Signing Certificate.cer differ diff --git a/Certificate/SDWebImage Signing Certificate.pem b/Certificate/SDWebImage Signing Certificate.pem new file mode 100644 index 00000000..84e12cba --- /dev/null +++ b/Certificate/SDWebImage Signing Certificate.pem @@ -0,0 +1,9 @@ +-----BEGIN RSA PUBLIC KEY----- +MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtAQgkh+tXn5fT3+pWuyZ +LvIwPoSObko1CbZ8IBOAaPsDQXuinv2BPQ85z2ccjoM4RIJ9MSNK9iMkW3NOQRIy +BVHO8bSi8HQSvm3pt3CEjCwP0o3wd1fGA/P/hHOO5Mu7iJ4isBbsgMXT0pjx0Zjg +HkeR046UyCAm3cYX20lA483NpVH8g7U1LI7YfbMy66KPI0joFnLQ09FGSaVsVdeS +JqaCBCB8IsYjOUPB1vwEvwCxv96APZ58cFwdeSYIzLdTtv3F6pkVpfEKLcV1KE3N +nmHIIiik2UJFUidUnmQJ72HcFIF1tirrZcRr301UCZanI2nei76XtEn//jMW9+2o +ZwIDAQAB +-----END RSA PUBLIC KEY----- diff --git a/Configs/Dynamic.xcconfig b/Configs/Dynamic.xcconfig new file mode 100644 index 00000000..067e0b2e --- /dev/null +++ b/Configs/Dynamic.xcconfig @@ -0,0 +1 @@ +MACH_O_TYPE = mh_dylib \ No newline at end of file diff --git a/Configs/Module-Shared.xcconfig b/Configs/Module-Shared.xcconfig index 2d9dfdce..4d401d13 100644 --- a/Configs/Module-Shared.xcconfig +++ b/Configs/Module-Shared.xcconfig @@ -88,12 +88,6 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE // Warns about potentially unreachable code. CLANG_WARN_UNREACHABLE_CODE = YES -// The path to a file specifying code-signing entitlements. -CODE_SIGN_ENTITLEMENTS = - -// The name, also known as the *common name*, of a valid code-signing certificate in a keychain within your keychain path. A missing or invalid certificate will cause a build error. -CODE_SIGN_IDENTITY = - // This setting defines the current version of the project. The value must be a integer or floating point number, such as `57` or `365.8`. CURRENT_PROJECT_VERSION = 1 @@ -197,9 +191,6 @@ PRODUCT_BUNDLE_IDENTIFIER = $(PRODUCT_BUNDLE_IDENTIFIER_PREFIX).${PRODUCT_NAME:r // This is the basename of the product generated by the target. PRODUCT_NAME = $(TARGET_NAME) -// Must contain a profile name (or UUID). A missing or invalid profile will cause a build error. Use in conjunction with [DEVELOPMENT_TEAM] to fully specify provisioning profile. -PROVISIONING_PROFILE_SPECIFIER = - // Activating this setting will cause Xcode to run the `Clang` static analysis tool on qualifying source files during every build. RUN_CLANG_STATIC_ANALYZER = YES diff --git a/Configs/Static.xcconfig b/Configs/Static.xcconfig new file mode 100644 index 00000000..731865fe --- /dev/null +++ b/Configs/Static.xcconfig @@ -0,0 +1 @@ +MACH_O_TYPE = staticlib \ No newline at end of file diff --git a/SDWebImage.xcodeproj/project.pbxproj b/SDWebImage.xcodeproj/project.pbxproj index 7c0332dd..696c6138 100644 --- a/SDWebImage.xcodeproj/project.pbxproj +++ b/SDWebImage.xcodeproj/project.pbxproj @@ -13,6 +13,7 @@ buildPhases = ( 326CA51322BA1A270033A92F /* Build Frameworks */, 326CA51422BA25F70033A92F /* Create XCFramework */, + 32F4EC0E2BEA18C400EAADD2 /* Sign XCFramework */, ); dependencies = ( ); @@ -1161,6 +1162,24 @@ shellPath = /bin/sh; shellScript = "sh ${SRCROOT}/Scripts/create-xcframework.sh\n"; }; + 32F4EC0E2BEA18C400EAADD2 /* Sign XCFramework */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = "Sign XCFramework"; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "sh ${SRCROOT}/Scripts/sign-xcframework.sh\n"; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -1342,7 +1361,6 @@ 326CA50D22BA14EF0033A92F /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; @@ -1350,7 +1368,6 @@ 326CA50E22BA14EF0033A92F /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - CODE_SIGN_STYLE = Automatic; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; diff --git a/Scripts/build-frameworks.sh b/Scripts/build-frameworks.sh index 82a7dd32..590dfa6b 100755 --- a/Scripts/build-frameworks.sh +++ b/Scripts/build-frameworks.sh @@ -5,6 +5,8 @@ set -o pipefail XCODE_VERSION=$(xcodebuild -version | head -n 1| awk -F ' ' '{print $2}') XCODE_VERSION_MAJOR=$(echo $XCODE_VERSION | awk -F '.' '{print $1}') +XCODE_VERSION_MINOR=$(echo $XCODE_VERSION | awk -F '.' '{print $2}') +XCODE_VERSION_PATCH=$(echo $XCODE_VERSION | awk -F '.' '{print $3}') if [ -z "$SRCROOT" ] then SRCROOT=$(pwd) @@ -18,7 +20,7 @@ then PLATFORMS+=("macCatalyst") fi -if [ $XCODE_VERSION_MAJOR -ge 15 ] +if [[ ($XCODE_VERSION_MAJOR -gt 15) || ($XCODE_VERSION_MAJOR -eq 15 && $XCODE_VERSION_MINOR -ge 2) ]] then PLATFORMS+=("visionOS") PLATFORMS+=("visionOSSimulator") @@ -39,5 +41,11 @@ do DESTINATION="generic/platform=${CURRENT_PLATFORM_OS} Simulator" fi - xcodebuild build -project "SDWebImage.xcodeproj" -destination "${DESTINATION}" -scheme "SDWebImage" -configuration "Release" -derivedDataPath "${SRCROOT}/build/DerivedData" CONFIGURATION_BUILD_DIR="${SRCROOT}/build/${CURRENT_PLATFORM}/" + if [[ $MACH_O_TYPE == "staticlib" ]]; then + XCCCONFIG_PATH="${SRCROOT}/Configs/Static.xcconfig" + else + XCCCONFIG_PATH="${SRCROOT}/Configs/Dynamic.xcconfig" + fi + + xcodebuild build -project "SDWebImage.xcodeproj" -destination "${DESTINATION}" -scheme "SDWebImage" -configuration "Release" -xcconfig "${XCCCONFIG_PATH}" -derivedDataPath "${SRCROOT}/build/DerivedData" CONFIGURATION_BUILD_DIR="${SRCROOT}/build/${CURRENT_PLATFORM}/" done diff --git a/Scripts/create-xcframework.sh b/Scripts/create-xcframework.sh index 660b6d64..e03e216b 100755 --- a/Scripts/create-xcframework.sh +++ b/Scripts/create-xcframework.sh @@ -5,6 +5,8 @@ set -o pipefail XCODE_VERSION=$(xcodebuild -version | head -n 1| awk -F ' ' '{print $2}') XCODE_VERSION_MAJOR=$(echo $XCODE_VERSION | awk -F '.' '{print $1}') +XCODE_VERSION_MINOR=$(echo $XCODE_VERSION | awk -F '.' '{print $2}') +XCODE_VERSION_PATCH=$(echo $XCODE_VERSION | awk -F '.' '{print $3}') if [ -z "$SRCROOT" ] then SRCROOT=$(pwd) @@ -25,7 +27,7 @@ then PLATFORMS+=("macCatalyst") fi -if [ $XCODE_VERSION_MAJOR -ge 15 ] +if [[ ($XCODE_VERSION_MAJOR -gt 15) || ($XCODE_VERSION_MAJOR -eq 15 && $XCODE_VERSION_MINOR -ge 2) ]] then PLATFORMS+=("visionOS") PLATFORMS+=("visionOSSimulator") @@ -38,5 +40,5 @@ do done # Combine XCFramework +echo "Create XCFramework" xcodebuild -create-xcframework $COMMAND_ARGS -output "${SRCROOT}/build/SDWebImage.xcframework" -open -a Finder "${SRCROOT}/build/SDWebImage.xcframework" diff --git a/Scripts/sign-xcframework.sh b/Scripts/sign-xcframework.sh new file mode 100755 index 00000000..7b5ab374 --- /dev/null +++ b/Scripts/sign-xcframework.sh @@ -0,0 +1,36 @@ +#!/bin/bash + +set -e +set -o pipefail + +if [ -z "$SRCROOT" ] +then + SRCROOT=$(pwd) +fi + +# Self-sign XCFramework +if [ -z CODESIGN_KEY_BASE64 ]; then + echo "Ignore Codesign XCFramework! You must sign SDWebImage before shipping to App Store. See: https://developer.apple.com/support/third-party-SDK-requirements" + exit 0 +fi + +KEYCHAIN=~/Library/Keychains/ios.keychain +KEYCHAIN_PASSWORD=SDWebImage +CODESIGN_IDENTIFY_NAME=SDWebImage\ Signing\ Certificate +KEY_PASSWORD="" + +echo $CODESIGN_KEY_BASE64 | base64 -D > "$(PWD)/Certificate/${CODESIGN_IDENTIFY_NAME}.p12" + +security create-keychain -p "$KEYCHAIN_PASSWORD" ios.keychain +security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN + +security import "$(PWD)/Certificate/${CODESIGN_IDENTIFY_NAME}.cer" -k $KEYCHAIN -T /usr/bin/codesign -T /usr/bin/security +security import "$(PWD)/Certificate/${CODESIGN_IDENTIFY_NAME}.p12" -k $KEYCHAIN -P "$KEY_PASSWORD" -T /usr/bin/codesign -T /usr/bin/security +security list-keychains -s ios.keychain +security set-key-partition-list -S "apple-tool:,apple:" -k "$KEYCHAIN_PASSWORD" $KEYCHAIN + +echo "Codesign XCFramework" +/usr/bin/codesign --force --timestamp -v --sign "SDWebImage Signing Certificate" "${SRCROOT}/build/SDWebImage.xcframework" + +rm -rf "$(PWD)/Certificate/${CODESIGN_IDENTIFY_NAME}.p12" +security delete-keychain ios.keychain \ No newline at end of file