Finish making macOS installer

This commit is contained in:
Micah Lee 2020-02-10 14:50:24 -08:00
parent 7b6bab5f6b
commit fa524d78b6
No known key found for this signature in database
GPG key ID: 403C2657CD994F73
4 changed files with 70 additions and 94 deletions

View file

@ -51,19 +51,23 @@ Run from source tree:
pipenv run ./dev_scripts/dangerzone 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 ```sh
pipenv run ./install/macos/build_app.py pipenv run ./install/macos/build_app.py
``` ```
This will create `dist/Dangerzone.app`. 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:
Once you have an app bundle, create a `.pkg` for distribution:
```sh ```sh
pipenv run install/macos/build_pkg.py # this requires codesigning certificates npm install --global create-dmg
pipenv run install/macos/build_pkg.py --without-codesign # this doesn't 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.

View file

@ -4,7 +4,8 @@ import os
import inspect import inspect
import subprocess import subprocess
import shutil import shutil
import argparse
import glob
root = os.path.dirname( root = os.path.dirname(
os.path.dirname( os.path.dirname(
@ -18,6 +19,16 @@ def run(cmd):
def main(): 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") build_path = os.path.join(root, "build")
dist_path = os.path.join(root, "dist") dist_path = os.path.join(root, "dist")
app_path = os.path.join(dist_path, "Dangerzone.app") app_path = os.path.join(dist_path, "Dangerzone.app")
@ -32,7 +43,44 @@ def main():
run(["pyinstaller", "install/macos/pyinstaller.spec", "--clean"]) run(["pyinstaller", "install/macos/pyinstaller.spec", "--clean"])
shutil.rmtree(os.path.join(dist_path, "dangerzone")) 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__": if __name__ == "__main__":

View file

@ -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()

View file

@ -0,0 +1,9 @@
<?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>
<!-- Required for binaries built with PyInstaller -->
<key>com.apple.security.cs.allow-unsigned-executable-memory</key>
<true/>
</dict>
</plist>