diff --git a/.github/actions/sign/action.yml b/.github/actions/sign/action.yml new file mode 100644 index 0000000..4e8ff8d --- /dev/null +++ b/.github/actions/sign/action.yml @@ -0,0 +1,179 @@ +# This file incorporates work covered by the following copyright and permission notice: +# +# Copyright (c) Mikael Hermansson and Godot Jolt contributors. +# Copyright (c) Dragos Daian. +# +# Permission is hereby granted, free of charge, to any person obtaining a copy of +# this software and associated documentation files (the "Software"), to deal in +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +# the Software, and to permit persons to whom the Software is furnished to do so, +# subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +# FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +# IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +# CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +name: GDExtension Sign +description: Sign Mac GDExtension + +inputs: + FRAMEWORK_PATH: + description: The path of the artifact. Eg. bin/addons/my_addon/bin/libmy_addon.macos.template_release.universal.framework + required: true + SIGN_FLAGS: + description: The extra flags to use. Eg. --deep + required: false + APPLE_CERT_BASE64: + required: true + description: Base64 file from p12 certificate. + APPLE_CERT_PASSWORD: + required: true + description: Password set when creating p12 certificate from .cer certificate. + APPLE_DEV_PASSWORD: + required: true + description: Apple App-Specific Password. Eg. abcd-abcd-abcd-abcd + APPLE_DEV_ID: + required: true + description: Email used for Apple Id. Eg. email@provider.com + APPLE_DEV_TEAM_ID: + required: true + description: Apple Team Id. Eg. 1ABCD23EFG + APPLE_DEV_APP_ID: + required: true + description: | + Certificate name from get info -> Common name . Eg. Developer ID Application: Common Name (1ABCD23EFG) +outputs: + zip_path: + value: ${{ steps.sign.outputs.path }} + + +runs: + using: composite + steps: + - name: Sign + id: sign + shell: pwsh + run: | + #!/usr/bin/env pwsh + + # Copyright (c) Mikael Hermansson and Godot Jolt contributors. + + # Permission is hereby granted, free of charge, to any person obtaining a copy of + # this software and associated documentation files (the "Software"), to deal in + # the Software without restriction, including without limitation the rights to + # use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + # the Software, and to permit persons to whom the Software is furnished to do so, + # subject to the following conditions: + + # The above copyright notice and this permission notice shall be included in all + # copies or substantial portions of the Software. + + # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + # FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + # COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + # IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + # CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + # Taken from https://github.com/godot-jolt/godot-jolt/blob/master/scripts/ci_sign_macos.ps1 + + Set-StrictMode -Version Latest + $ErrorActionPreference = "Stop" + + $CodesignPath = Get-Command codesign | Resolve-Path + + $CertificateBase64 = "${{inputs.APPLE_CERT_BASE64}}" + $CertificatePassword = "${{inputs.APPLE_CERT_PASSWORD}}" + $CertificatePath = [IO.Path]::ChangeExtension((New-TemporaryFile), "p12") + + $Keychain = "ephemeral.keychain" + $KeychainPassword = (New-Guid).ToString().Replace("-", "") + + $DevId = "${{ inputs.APPLE_DEV_ID }}" + $DevTeamId = "${{ inputs.APPLE_DEV_TEAM_ID }}" + $DevPassword = "${{ inputs.APPLE_DEV_PASSWORD }}" + $DeveloperIdApplication = "${{ inputs.APPLE_DEV_APP_ID }}" + + if (!$CertificateBase64) { throw "No certificate provided" } + if (!$CertificatePassword) { throw "No certificate password provided" } + if (!$DevId) { throw "No Apple Developer ID provided" } + if (!$DeveloperIdApplication) { throw "No Apple Developer ID Application provided" } + if (!$DevTeamId) { throw "No Apple Team ID provided" } + if (!$DevPassword) { throw "No Apple Developer password provided" } + + Write-Output "Decoding certificate..." + + $Certificate = [Convert]::FromBase64String($CertificateBase64) + + Write-Output "Writing certificate to disk..." + + [IO.File]::WriteAllBytes($CertificatePath, $Certificate) + + Write-Output "Creating keychain..." + + security create-keychain -p $KeychainPassword $Keychain + + Write-Output "Setting keychain as default..." + + security default-keychain -s $Keychain + + Write-Output "Importing certificate into keychain..." + security import $CertificatePath ` + -k ~/Library/Keychains/$Keychain ` + -P $CertificatePassword ` + -T $CodesignPath + Write-Output "Check identities..." + + security find-identity + + Write-Output "Granting access to keychain..." + + security set-key-partition-list -S "apple-tool:,apple:" -s -k $KeychainPassword $Keychain + + $Framework = "${{ inputs.FRAMEWORK_PATH }}" + $SignFlags = "${{ inputs.SIGN_FLAGS }}" + $Archive = [IO.Path]::ChangeExtension((New-TemporaryFile), "zip") + + Write-Output "Signing '$Framework'..." + + & $CodesignPath --verify --timestamp --verbose "$SignFlags" --sign $DeveloperIdApplication "$Framework" + + Write-Output "Verifying signing..." + + & $CodesignPath --verify -dvvv "$Framework" + + Get-ChildItem -Force -Recurse -Path "$Framework" + + Write-Output "Archiving framework to '$Archive'..." + + ditto -ck -rsrc --sequesterRsrc --keepParent "$Framework" "$Archive" + + Write-Output "Submitting archive for notarization..." + + $output = xcrun notarytool submit "$Archive" ` + --apple-id $DevId ` + --team-id $DevTeamId ` + --password $DevPassword ` + --wait + echo $output + $matches = $output -match '((\d|[a-z])+-(\d|[a-z])+-(\d|[a-z])+-(\d|[a-z])+-(\d|[a-z])+)' + if ($output) { + $id_res = $matches[0].Substring(6) + } + xcrun notarytool log $id_res ` + --apple-id $DevId ` + --team-id $DevTeamId ` + --password $DevPassword ` + developer_log.json + get-content developer_log.json + + echo "path=$Archive" >> $env:GITHUB_OUTPUT + + diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 83c9c9d..6129a21 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -60,6 +60,18 @@ jobs: run: | brew install scons python3 Dev/Cpp/build.py platform=macos + - name: Sign binaries + env: + APPLE_CERT_BASE64: ${{ secrets.MACOS_CERT_BASE64 }} + uses: ./.github/actions/sign + with: + FRAMEWORK_PATH: Dev/Cpp/bin/macos/libeffekseer.framework + APPLE_CERT_BASE64: ${{ secrets.MACOS_CERT_BASE64 }} + APPLE_CERT_PASSWORD: ${{ secrets.MACOS_CERT_PASSWORD }} + APPLE_DEV_ID: ${{ secrets.MACOS_DEV_ID }} + APPLE_DEV_TEAM_ID: ${{ secrets.MACOS_DEV_TEAM_ID }} + APPLE_DEV_APP_ID: ${{ secrets.MACOS_DEV_APP_ID }} + APPLE_DEV_PASSWORD: ${{ secrets.MACOS_DEV_APP_PASSWORD }} - name: Upload binaries uses: actions/upload-artifact@v4 with: diff --git a/Dev/Cpp/bin/mac/libeffekseer.framework/Resources/Info.plist b/Dev/Cpp/bin/mac/libeffekseer.framework/Resources/Info.plist new file mode 100644 index 0000000..147af59 --- /dev/null +++ b/Dev/Cpp/bin/mac/libeffekseer.framework/Resources/Info.plist @@ -0,0 +1,32 @@ + + + + + CFBundleInfoDictionaryVersion + 6.0 + CFBundleDevelopmentRegion + en + CFBundleExecutable + libeffekseer + CFBundleName + EffekseerForGodot4 + CFBundleDisplayName + EffekseerForGodot4 + CFBundleIdentifier + io.github.effekseer.EffekseerForGodot4 + NSHumanReadableCopyright + Unlicensed + CFBundleVersion + 1.0.0 + CFBundleShortVersionString + 1.0.0 + CFBundlePackageType + FMWK + CSResourcesFileMapped + + DTPlatformName + macosx + LSMinimumSystemVersion + 10.12 + + diff --git a/Dev/Cpp/build.py b/Dev/Cpp/build.py index a4d9c1b..5371cc5 100644 --- a/Dev/Cpp/build.py +++ b/Dev/Cpp/build.py @@ -54,7 +54,7 @@ def import_generate_bindings(arch: str): import_generate_bindings("64") subprocess.run(["scons", "platform=macos", "arch=universal"] + options, check=True) - os.rename(f"{output_dir}/macos/libeffekseer.universal.dylib", f"{output_dir}/macos/libeffekseer.dylib") + os.rename(f"{output_dir}/macos/libeffekseer.universal.dylib", f"{output_dir}/macos/libeffekseer.framework/libeffekseer") elif "platform=android" in sys.argv: os.makedirs(f"{output_dir}/android", exist_ok = True) diff --git a/Dev/Godot/addons/effekseer/effekseer.gdextension b/Dev/Godot/addons/effekseer/effekseer.gdextension index 86c9748..31eddce 100644 --- a/Dev/Godot/addons/effekseer/effekseer.gdextension +++ b/Dev/Godot/addons/effekseer/effekseer.gdextension @@ -8,7 +8,7 @@ windows.x86_32 = "res://addons/effekseer/bin/windows/libeffekseer.x86_32.dll" windows.arm64 = "res://addons/effekseer/bin/windows/libeffekseer.arm64.dll" linux.x86_32 = "res://addons/effekseer/bin/linux/libeffekseer.x86_32.so" linux.x86_64 = "res://addons/effekseer/bin/linux/libeffekseer.x86_64.so" -macos = "res://addons/effekseer/bin/macos/libeffekseer.dylib" +macos = "res://addons/effekseer/bin/macos/libeffekseer.framework" ios = "res://addons/effekseer/bin/ios/libeffekseer.xcframework" android.arm32 = "res://addons/effekseer/bin/android/libeffekseer.arm32.so" android.arm64 = "res://addons/effekseer/bin/android/libeffekseer.arm64.so"