From 6e6a97fddc981ff1261d5dbbd73097607db6c574 Mon Sep 17 00:00:00 2001 From: Evan Debenham Date: Thu, 3 Feb 2022 18:26:54 -0500 Subject: [PATCH] v1.2.0: added utilities for macOS notarizing --- desktop/build.gradle | 8 +++- desktop/macos-entitlements.plist | 14 +++++++ desktop/notarize.sh | 67 ++++++++++++++++++++++++++++++++ ios/build.gradle | 2 +- 4 files changed, 88 insertions(+), 3 deletions(-) create mode 100644 desktop/macos-entitlements.plist create mode 100755 desktop/notarize.sh diff --git a/desktop/build.gradle b/desktop/build.gradle index b36b80f07..c0d59d26b 100644 --- a/desktop/build.gradle +++ b/desktop/build.gradle @@ -23,7 +23,7 @@ task debug(type: JavaExec) { task release(type: Jar) { //FIXME this is now needed as of gradle 7.0, due to our weird sourceSets setup. Should see if there's a better way to do this - setDuplicatesStrategy(DuplicatesStrategy.INCLUDE) + setDuplicatesStrategy(DuplicatesStrategy.EXCLUDE) from sourceSets.main.output dependsOn configurations.runtimeClasspath from { configurations.runtimeClasspath.findAll { it.name.endsWith('jar') }.collect { zipTree(it) } } @@ -93,7 +93,11 @@ runtime { javaHome = file("./build/jdks/mac/jdk-16.0.1+9/Contents/Home/").getAbsolutePath() jpackage { jpackageHome = file("./build/jdks/mac/jdk-16.0.1+9/Contents/Home/") - imageOptions = ["--icon", file("./src/main/assets/icons/mac.icns"), "--java-options", "-XstartOnFirstThread"] + imageOptions = ["--icon", file("./src/main/assets/icons/mac.icns"), + "--java-options", "-XstartOnFirstThread", + //append .apple because com.shatteredpixel.shatteredpixeldungeon was taken =( + "--mac-package-identifier", appPackageName + ".apple", + "--mac-package-name", "ShattererdPD"] installerType = "dmg" installerName = appName diff --git a/desktop/macos-entitlements.plist b/desktop/macos-entitlements.plist new file mode 100644 index 000000000..15b01bef7 --- /dev/null +++ b/desktop/macos-entitlements.plist @@ -0,0 +1,14 @@ + + + + + com.apple.security.cs.allow-jit + + com.apple.security.cs.allow-unsigned-executable-memory + + com.apple.security.cs.disable-library-validation + + com.apple.security.cs.allow-dyld-environment-variables + + + \ No newline at end of file diff --git a/desktop/notarize.sh b/desktop/notarize.sh new file mode 100755 index 000000000..71b1370a7 --- /dev/null +++ b/desktop/notarize.sh @@ -0,0 +1,67 @@ +#!/bin/sh + +# This shell script helps automate the process of notarizing +# It is based on the guide found here: https://www.joelotter.com/2020/08/14/macos-java-notarization.html +# requires xcode tools, script may take a minute or two to run as it uploads results to apple + +# usage is: "notarize.sh " +# There is no input validation to check your arguments! +APP="$1" +PLIST=`PWD`"/$2" #need absolute path +CERT="$3" +USER="$4" +PASS="$5" + +#first sign the naked dylib in /Contents/runtime/Contents/MacOS/libjli.dylib +codesign --force --options runtime --timestamp --sign "$CERT" \ + --entitlements "$PLIST" "${APP}/Contents/runtime/Contents/MacOS/libjli.dylib" + +#then iterate over each jar and sign all .dylib files within it +# to do this we have to unzip each JAR, sign the files and re-zip =/ +# several commands are piped to dev/null to cut down on console spam +pushd "${APP}"/Contents/app/ > /dev/null +rm -rf jar/ +for JAR in *.jar; do + + mkdir jar + mv "$JAR" jar/ + pushd jar/ > /dev/null + unzip "${JAR}" > /dev/null + rm "${JAR}" + + for LIB in `find . -name '*.dylib'`; do + codesign --force --options runtime --timestamp --sign "$CERT" \ + --entitlements "$PLIST" "${LIB}" + done + + zip -r "../${JAR}" * > /dev/null + popd > /dev/null + rm -rf jar/ + +done +popd > /dev/null + +#finally do one more deep sign on the whole .app +codesign --deep --force --options runtime --timestamp --sign "$CERT" \ + --entitlements "$PLIST" "${APP}" + +#zip it up and send it to apple! +rm -rf "${APP}".zip +zip -r "${APP}".zip "${APP}" > /dev/null + +echo "Uploading to apple, this may take a minute." + +xcrun altool -t osx -f "${APP}".zip \ + --primary-bundle-id com.shatteredpixel.shatteredpixeldungeon.apple --notarize-app \ + --username "$USER" \ + --password "$PASS" + +rm -rf "${APP}".zip + +echo "Upload finished, if it worked, wait for an email and then run: xcrun stapler staple \"${APP}\"" + +# If notarizing failed, you can run this command to get info: +# xcrun altool --notarization-info \ +# --username "$USER" \ +# --password "$PASS" + diff --git a/ios/build.gradle b/ios/build.gradle index 8369fec7b..f3f099854 100644 --- a/ios/build.gradle +++ b/ios/build.gradle @@ -25,7 +25,7 @@ task updateRoboVMProps(){ //parse out just #.#.# from version name, this is an apple requirement props.setProperty ('appShortVersionName', (appVersionName =~ /\d+\.\d+\.\d+/)[0]) - props.setProperty ('appMainclass', "com.shatteredpixel.shatteredpixeldungeon.ios.IOSLauncher") + props.setProperty ('appMainclass', appPackageName + ".ios.IOSLauncher") props.setProperty ('appExecutable', "IOSLauncher") file("robovm.properties").withWriter { props.store(it, "Dynamically generated, do not commit to version control!") }