From fa524d78b6977aa61ac0fb74e3338b28584005ba Mon Sep 17 00:00:00 2001 From: Micah Lee Date: Mon, 10 Feb 2020 14:50:24 -0800 Subject: [PATCH] Finish making macOS installer --- BUILD.md | 18 ++++--- install/macos/build_app.py | 52 ++++++++++++++++++- install/macos/build_pkg.py | 85 -------------------------------- install/macos/entitlements.plist | 9 ++++ 4 files changed, 70 insertions(+), 94 deletions(-) delete mode 100755 install/macos/build_pkg.py create mode 100644 install/macos/entitlements.plist diff --git a/BUILD.md b/BUILD.md index 4f558a7..7752241 100644 --- a/BUILD.md +++ b/BUILD.md @@ -51,19 +51,23 @@ Run from source tree: pipenv run ./dev_scripts/dangerzone ``` -Create an app bundle: +To create an app bundle and DMG for distribution, use the `build_app.py` script ```sh pipenv run ./install/macos/build_app.py ``` -This will create `dist/Dangerzone.app`. - -Once you have an app bundle, create a `.pkg` for distribution: +If you want to build for distribution, you'll need a codesigning certificate, and you'll also need to have [create-dmg](https://github.com/sindresorhus/create-dmg) installed: ```sh -pipenv run install/macos/build_pkg.py # this requires codesigning certificates -pipenv run install/macos/build_pkg.py --without-codesign # this doesn't +npm install --global create-dmg +brew install graphicsmagick imagemagick ``` -This will create `dist/Dangerzone-[version].pkg`. +And then run `build_app.py --with-codesign`: + +```sh +pipenv run ./install/macos/build_app.py --with-codesign +``` + +The output is in the `dist` folder. \ No newline at end of file diff --git a/install/macos/build_app.py b/install/macos/build_app.py index 7529012..20d0410 100755 --- a/install/macos/build_app.py +++ b/install/macos/build_app.py @@ -4,7 +4,8 @@ import os import inspect import subprocess import shutil - +import argparse +import glob root = os.path.dirname( os.path.dirname( @@ -18,6 +19,16 @@ def run(cmd): def main(): + # Parse arguments + parser = argparse.ArgumentParser() + parser.add_argument( + "--with-codesign", + action="store_true", + dest="with_codesign", + help="Codesign the app bundle", + ) + 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") @@ -32,7 +43,44 @@ def main(): run(["pyinstaller", "install/macos/pyinstaller.spec", "--clean"]) shutil.rmtree(os.path.join(dist_path, "dangerzone")) - print("○ Finished: {}".format(app_path)) + print(f"○ Finished build app: {app_path}") + + if args.with_codesign: + print("○ Code signing app bundle") + identity_name_application = ( + "Developer ID Application: FIRST LOOK PRODUCTIONS, INC. (P24U45L8P5)" + ) + entitlements_plist_path = os.path.join(root, "install/macos/entitlements.plist") + + run( + [ + "codesign", + "--deep", + "-s", + identity_name_application, + "-o", + "runtime", + "--entitlements", + entitlements_plist_path, + app_path, + ] + ) + + # Detect if create-dmg is installed + if not os.path.exists("/usr/local/bin/create-dmg"): + print("Error: create-dmg is not installed") + return + + print("○ Creating DMG") + run(["create-dmg", app_path, "--identity", identity_name_application]) + dmg_filename = glob.glob(f"{root}/*.dmg")[0] + shutil.move(dmg_filename, dist_path) + dmg_filename = glob.glob(f"{dist_path}/*.dmg")[0] + + print(f"○ Finished building DMG: {dmg_filename}") + + else: + print("○ Skipping code signing") if __name__ == "__main__": diff --git a/install/macos/build_pkg.py b/install/macos/build_pkg.py deleted file mode 100755 index c09d95e..0000000 --- a/install/macos/build_pkg.py +++ /dev/null @@ -1,85 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -import os -import sys -import inspect -import subprocess -import shutil -import argparse - - -root = os.path.dirname( - os.path.dirname( - os.path.dirname(os.path.abspath(inspect.getfile(inspect.currentframe()))) - ) -) - - -def run(cmd): - subprocess.run(cmd, cwd=root, check=True) - - -def main(): - # Parse arguments - parser = argparse.ArgumentParser() - parser.add_argument( - "--without-codesign", - action="store_true", - dest="without_codesign", - help="Skip codesigning", - ) - 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") - - # Make sure Dangerzone.app already exists - if not os.path.exists(app_path): - print("○ App bundle doesn't exist yet, should be in: {}".format(app_path)) - return - - # Import dangerzone to get the version - sys.path.insert(0, root) - import dangerzone - - version = dangerzone.dangerzone_version - - pkg_path = os.path.join(dist_path, "Dangerzone-{}.pkg".format(version)) - - identity_name_application = "Developer ID Application: FIRST LOOK PRODUCTIONS, INC." - identity_name_installer = "Developer ID Installer: FIRST LOOK PRODUCTIONS, INC." - - if args.without_codesign: - # Skip codesigning - print("○ Creating an installer") - run( - ["productbuild", "--component", app_path, "/Applications", pkg_path,] - ) - - else: - # Package with codesigning - print("○ Codesigning app bundle") - run(["codesign", "--deep", "-s", identity_name_application, app_path]) - - print("○ Creating an installer") - run( - [ - "productbuild", - "--sign", - identity_name_installer, - "--component", - app_path, - "/Applications", - pkg_path, - ] - ) - - print("○ Cleaning up") - shutil.rmtree(app_path) - - print("○ Finished: {}".format(pkg_path)) - - -if __name__ == "__main__": - main() diff --git a/install/macos/entitlements.plist b/install/macos/entitlements.plist new file mode 100644 index 0000000..1eeeeaa --- /dev/null +++ b/install/macos/entitlements.plist @@ -0,0 +1,9 @@ + + + + + + com.apple.security.cs.allow-unsigned-executable-memory + + + \ No newline at end of file