mirror of
https://github.com/freedomofpress/dangerzone.git
synced 2025-04-28 18:02:38 +02:00
Finish making macOS installer
This commit is contained in:
parent
7b6bab5f6b
commit
fa524d78b6
4 changed files with 70 additions and 94 deletions
18
BUILD.md
18
BUILD.md
|
@ -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.
|
|
@ -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__":
|
||||||
|
|
|
@ -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()
|
|
9
install/macos/entitlements.plist
Normal file
9
install/macos/entitlements.plist
Normal 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>
|
Loading…
Reference in a new issue