From 3f230103944da94c9ac539cc3f5d539c0cc8d0f8 Mon Sep 17 00:00:00 2001 From: deeplow Date: Thu, 30 Mar 2023 16:04:23 +0100 Subject: [PATCH] Redo macOS build-app.py and add --codesign-only opt Redoes the build-app.py script to add an option to sign only an already- produced app bundle. --- install/macos/build-app.py | 180 +++++++++++++++++++++---------------- 1 file changed, 105 insertions(+), 75 deletions(-) diff --git a/install/macos/build-app.py b/install/macos/build-app.py index 839a753..505f4f6 100755 --- a/install/macos/build-app.py +++ b/install/macos/build-app.py @@ -19,6 +19,28 @@ def run(cmd): subprocess.run(cmd, cwd=root, check=True) +def build_app_bundle(): + """ + Builds the Dangerzone.app bundle and saves it in dist/Dangerzone.app + """ + print("○ Deleting old build and dist") + if os.path.exists(build_path): + shutil.rmtree(build_path) + if os.path.exists(dist_path): + shutil.rmtree(dist_path) + + print("○ Building app bundle") + run(["pyinstaller", "install/pyinstaller/pyinstaller.spec", "--clean"]) + shutil.rmtree(os.path.join(dist_path, "dangerzone")) + + os.symlink( + "dangerzone", + os.path.join(app_path, "Contents/MacOS/dangerzone-cli"), + ) + + print(f"○ Finished build app: {app_path}") + + def codesign(path, entitlements, identity): run( [ @@ -37,96 +59,104 @@ def codesign(path, entitlements, identity): ) +def sign_app_bundle(build_path, dist_path, app_path): + """ + Signs the app bundle stored in dist/Dangerzone.app, + producing a Dangerzone.dmg file + """ + print(f"○ Signing app bundle in {app_path}") + + # Detect if create-dmg is installed + if not os.path.exists(app_path): + print(f"ERROR: Dangerzone.app not found in {app_path}.") + exit(1) + + dmg_path = os.path.join(dist_path, "Dangerzone.dmg") + icon_path = os.path.join(root, "install", "macos", "dangerzone.icns") + + print("○ Code signing app bundle") + identity_name_application = ( + # FIXME: Update this line with the proper developer ID, once we know what + # that is. + "Developer ID Application: FREEDOM OF THE PRESS FOUNDATION, 501(c)(3)" + ) + entitlements_plist_path = os.path.join(root, "install/macos/entitlements.plist") + + for path in itertools.chain( + glob.glob(f"{app_path}/**/*.so", recursive=True), + glob.glob(f"{app_path}/**/*.dylib", recursive=True), + glob.glob(f"{app_path}/**/Python3", recursive=True), + [app_path], + ): + codesign(path, entitlements_plist_path, identity_name_application) + print(f"○ Signed app bundle: {app_path}") + + # Detect if create-dmg is installed + if not os.path.exists("/usr/local/bin/create-dmg"): + print("create-dmg is not installed, skipping creating a DMG") + return + + print("○ Creating DMG") + run( + [ + "create-dmg", + "--volname", + "Dangerzone", + "--volicon", + icon_path, + "--window-size", + "400", + "200", + "--icon-size", + "100", + "--icon", + "Dangerzone.app", + "100", + "70", + "--hide-extension", + "Dangerzone.app", + "--app-drop-link", + "300", + "70", + dmg_path, + app_path, + "--identity", + identity_name_application, + ] + ) + print(f"○ Finished building DMG: {dmg_path}") + + def main(): # Parse arguments parser = argparse.ArgumentParser() - parser.add_argument( + codesign_opts = parser.add_mutually_exclusive_group() + codesign_opts.add_argument( "--with-codesign", action="store_true", dest="with_codesign", help="Codesign the app bundle", ) + codesign_opts.add_argument( + "--only-codesign", + action="store_true", + dest="only_codesign", + help="Exclusively codesign the app bundle in dist/Dangerzone.app", + ) args = parser.parse_args() build_path = os.path.join(root, "build") dist_path = os.path.join(root, "dist") app_path = os.path.join(dist_path, "Dangerzone.app") - dmg_path = os.path.join(dist_path, "Dangerzone.dmg") - icon_path = os.path.join(root, "install", "macos", "dangerzone.icns") - - print("○ Deleting old build and dist") - if os.path.exists(build_path): - shutil.rmtree(build_path) - if os.path.exists(dist_path): - shutil.rmtree(dist_path) - - print("○ Building app bundle") - run(["pyinstaller", "install/pyinstaller/pyinstaller.spec", "--clean"]) - shutil.rmtree(os.path.join(dist_path, "dangerzone")) - - os.symlink( - "dangerzone", - os.path.join(app_path, "Contents/MacOS/dangerzone-cli"), - ) - - print(f"○ Finished build app: {app_path}") - - if args.with_codesign: - print("○ Code signing app bundle") - identity_name_application = ( - # FIXME: Update this line with the proper developer ID, once we know what - # that is. - "Developer ID Application: FREEDOM OF THE PRESS FOUNDATION, 501(c)(3)" - ) - entitlements_plist_path = os.path.join(root, "install/macos/entitlements.plist") - - for path in itertools.chain( - glob.glob(f"{app_path}/**/*.so", recursive=True), - glob.glob(f"{app_path}/**/*.dylib", recursive=True), - glob.glob(f"{app_path}/**/Python3", recursive=True), - [app_path], - ): - codesign(path, entitlements_plist_path, identity_name_application) - print(f"○ Signed app bundle: {app_path}") - - # Detect if create-dmg is installed - if not os.path.exists("/usr/local/bin/create-dmg"): - print("create-dmg is not installed, skipping creating a DMG") - return - - print("○ Creating DMG") - run( - [ - "create-dmg", - "--volname", - "Dangerzone", - "--volicon", - icon_path, - "--window-size", - "400", - "200", - "--icon-size", - "100", - "--icon", - "Dangerzone.app", - "100", - "70", - "--hide-extension", - "Dangerzone.app", - "--app-drop-link", - "300", - "70", - dmg_path, - app_path, - "--identity", - identity_name_application, - ] - ) - - print(f"○ Finished building DMG: {dmg_path}") + if args.only_codesign: + sign_app_bundle(build_path, dist_path, app_path) else: - print("○ Skipping code signing") + build_app_bundle(build_path, dist_path, app_path) + if args.with_codesign: + sign_app_bundle(build_path, dist_path, app_path) + else: + print("○ Skipping code signing") if __name__ == "__main__":