Merge pull request #1271 from micahflee/1215_macos_codesign

Fix macOS packaging, code signing, and notarization
This commit is contained in:
Micah Lee 2021-02-07 14:49:50 -08:00 committed by GitHub
commit 09a8cecfae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 170 additions and 48 deletions

View File

@ -1,10 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.inherit</key>
<true/>
</dict>
</plist>

View File

@ -2,9 +2,9 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<!-- Enable app sandbox -->
<!-- Disable app sandbox :( -->
<key>com.apple.security.app-sandbox</key>
<true/>
<false/>
<!-- Required for running PyInstaller python code with hardened runtime -->
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>

View File

@ -5,6 +5,7 @@ import subprocess
import argparse
import shutil
import glob
import itertools
root = os.path.dirname(
os.path.dirname(
@ -15,6 +16,24 @@ root = os.path.dirname(
)
def codesign(path, entitlements, identity):
run(
[
"codesign",
"--sign",
identity,
"--entitlements",
str(entitlements),
"--timestamp",
"--deep",
str(path),
"--force",
"--options",
"runtime",
]
)
def run(cmd, cwd=None):
subprocess.run(cmd, cwd=cwd, check=True)
@ -39,7 +58,7 @@ def main():
if os.path.exists(os.path.join(desktop_dir, "macOS")):
shutil.rmtree(os.path.join(desktop_dir, "macOS"))
print("○ Building onionshare-cli")
print("○ Build onionshare-cli")
run(["poetry", "install"], cli_dir)
run(["poetry", "build"], cli_dir)
whl_filename = glob.glob(os.path.join(cli_dir, "dist", "*.whl"))[0]
@ -49,50 +68,163 @@ def main():
print("○ Create app bundle")
run(["briefcase", "create"], desktop_dir)
app_path = os.path.join(desktop_dir, "macOS", "OnionShare", "OnionShare.app")
print("○ Delete unused Qt5 frameworks from app bundle")
for framework in [
"Qt3DAnimation",
"Qt3DCore",
"Qt3DExtras",
"Qt3DInput",
"Qt3DLogic",
"Qt3DQuick",
"Qt3DQuickAnimation",
"Qt3DQuickExtras",
"Qt3DQuickInput",
"Qt3DQuickRender",
"Qt3DQuickScene2D",
"Qt3DRender",
"QtBluetooth",
"QtBodymovin",
"QtCharts",
"QtConcurrent",
"QtDataVisualization",
"QtDesigner",
"QtDesignerComponents",
"QtGamepad",
"QtHelp",
"QtLocation",
"QtMultimedia",
"QtMultimediaQuick",
"QtMultimediaWidgets",
"QtNfc",
"QtOpenGL",
"QtPdf",
"QtPdfWidgets",
"QtPositioning",
"QtPositioningQuick",
"QtPurchasing",
"QtQuick",
"QtQuick3D",
"QtQuick3DAssetImport",
"QtQuick3DRender",
"QtQuick3DRuntimeRender",
"QtQuick3DUtils",
"QtQuickControls2",
"QtQuickParticles",
"QtQuickShapes",
"QtQuickTemplates2",
"QtQuickTest",
"QtQuickWidgets",
"QtRemoteObjects",
"QtRepParser",
"QtScript",
"QtScriptTools",
"QtScxml",
"QtSensors",
"QtSerialBus",
"QtSerialPort",
"QtSql",
"QtSvg",
"QtTest",
"QtTextToSpeech",
"QtUiPlugin",
"QtVirtualKeyboard",
"QtWebChannel",
"QtWebEngine",
"QtWebEngineCore",
"QtWebEngineWidgets",
"QtWebSockets",
"QtWebView",
"QtXml",
"QtXmlPatterns",
]:
shutil.rmtree(
os.path.join(
app_path,
"Contents",
"Resources",
"app_packages",
"PySide2",
"Qt",
"lib",
f"{framework}.framework",
)
)
try:
os.remove(
os.path.join(
app_path,
"Contents",
"Resources",
"app_packages",
"PySide2",
f"{framework}.abi3.so",
)
)
os.remove(
os.path.join(
app_path,
"Contents",
"Resources",
"app_packages",
"PySide2",
f"{framework}.pyi",
)
)
except FileNotFoundError:
pass
shutil.rmtree(
os.path.join(
app_path,
"Contents",
"Resources",
"app_packages",
"PySide2",
"Designer.app",
)
)
print(f"○ Unsigned app bundle: {app_path}")
if args.with_codesign:
identity_name_application = "Developer ID Application: Micah Lee (N9B95FDWH4)"
entitlements_child_filename = os.path.join(
desktop_dir, "package", "macos", "ChildEntitlements.plist"
)
entitlements_filename = os.path.join(
entitlements_plist_path = os.path.join(
desktop_dir, "package", "macos", "Entitlements.plist"
)
print("○ Code signing app bundle")
run(
print("○ Code sign app bundle")
for path in itertools.chain(
glob.glob(
f"{app_path}/Contents/Resources/app_packages/**/*.dylib", recursive=True
),
glob.glob(
f"{app_path}/Contents/Resources/app_packages/**/*.so", recursive=True
),
glob.glob(
f"{app_path}/Contents/Resources/Support/**/*.dylib", recursive=True
),
glob.glob(f"{app_path}/Contents/Resources/Support/**/*.so", recursive=True),
glob.glob(
f"{app_path}/Contents/Resources/app_packages/PySide2/Qt/lib/**/Versions/5/*",
recursive=True,
),
[
"codesign",
"--deep",
"-s",
identity_name_application,
"--force",
"--entitlements",
entitlements_child_filename,
"--timestamp",
f"{app_path}/Contents/Resources/app_packages/PySide2/pyside2-lupdate",
f"{app_path}/Contents/Resources/app_packages/PySide2/rcc",
f"{app_path}/Contents/Resources/app_packages/PySide2/uic",
f"{app_path}/Contents/Resources/Support/bin/python3",
app_path,
]
)
run(
[
"codesign",
"-s",
identity_name_application,
"--force",
"--entitlements",
entitlements_filename,
"--timestamp",
app_path,
]
)
],
):
codesign(path, entitlements_plist_path, identity_name_application)
codesign(app_path, entitlements_plist_path, identity_name_application)
print(f"○ Signed app bundle: {app_path}")
if not os.path.exists("/usr/local/bin/create-dmg"):
print("○ Error: create-dmg is not installed")
return
print("○ Creating DMG")
print("○ Create DMG")
dmg_path = os.path.join(desktop_dir, "macOS", "OnionShare.dmg")
run(
[

View File

@ -37,10 +37,10 @@ import requests
def main():
dmg_url = "https://archive.torproject.org/tor-package-archive/torbrowser/10.0.2/TorBrowser-10.0.2-osx64_en-US.dmg"
dmg_filename = "TorBrowser-10.0.2-osx64_en-US.dmg"
dmg_url = "https://archive.torproject.org/tor-package-archive/torbrowser/10.0.10/TorBrowser-10.0.10-osx64_en-US.dmg"
dmg_filename = "TorBrowser-10.0.10-osx64_en-US.dmg"
expected_dmg_sha256 = (
"ac8d28f6f8d92e220f72ef7b0cb2bba45d5e0d4b243dc50806e33e08278e7730"
"7ed73e94ccdfab76b8d96ddbac7828d3a7c77dd73b54c34e55666f3b6274d12a"
)
# Build paths

View File

@ -34,10 +34,10 @@ import requests
def main():
exe_url = "https://archive.torproject.org/tor-package-archive/torbrowser/10.0.2/torbrowser-install-10.0.2_en-US.exe"
exe_url = "https://archive.torproject.org/tor-package-archive/torbrowser/10.0.10/torbrowser-install-10.0.10_en-US.exe"
exe_filename = "torbrowser-install-10.0.2_en-US.exe"
expected_exe_sha256 = (
"c685c550fc420c39cbe40e453f2201789af5f64e7b024c9339c2a3bd01e61c2d"
"6cbd14a7232e4ae7f2718d9b7f377e1a7bb96506da21f1ac6f689a22fc5e53fe"
)
# Build paths
root_path = os.path.dirname(