Skip to content

Commit

Permalink
Merge #65: [Build] Add distribution packaging functionality
Browse files Browse the repository at this point in the history
c9ab415 [Build] Add distribution packaging functionality (Fuzzbawls)

Pull request description:

  Adds code to the `.spec` file used to create the distribution binaries. Requires `pyinstaller`. The macOS binaries further require the node.js `appdmg` package for `.dmg` creation, and a valid Apple issued developer ID certificate for code signing.

ACKs for top commit:
  Liquid369:
    utACK c9ab415

Tree-SHA512: a2d71bd747e334036159c02dd6e2252418ae29b87c5b557350218853b3e79fdfe1fe92f32217489836c6d5d2882afb9ae870c4af1d81539d787a75a97ef11a3a
  • Loading branch information
Fuzzbawls committed May 17, 2024
2 parents 324371e + c9ab415 commit bb2db92
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 21 deletions.
93 changes: 72 additions & 21 deletions SecurePivxMasternodeTool.spec
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
# -*- mode: python -*-
import sys
import platform
import os.path as os_path
import simplejson as json
import subprocess

os_type = sys.platform
block_cipher = None
Expand All @@ -11,9 +13,30 @@ def libModule(module, source, dest):
m = __import__(module)
module_path = os_path.dirname(m.__file__)
del m
print(f"libModule {(os.path.join(module_path, source), dest)}")
print(f"libModule {(os_path.join(module_path, source), dest)}")
return ( os_path.join(module_path, source), dest )

def is_tool(prog):
for dir in os.environ['PATH'].split(os.pathsep):
if os.path.exists(os.path.join(dir, prog)):
try:
subprocess.call([os.path.join(dir, prog)],
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT)
except(OSError, e):
return False
return True
return False

# Set this to True if codesigning macOS bundles. Requires an Apple issued developer ID certificate.
code_sign = False
codesigner = 'fuzzbawls@pivx.org'

# detect CPU architecture
cpu_arch = platform.processor()
if os_type == 'darwin':
if cpu_arch == 'arm': cpu_arch = 'arm64'
if cpu_arch == 'i386': cpu_arch = 'x86_64'

# look for version string
version_str = ''
Expand Down Expand Up @@ -89,22 +112,23 @@ exe = EXE(pyz,
strip=False,
upx=False,
console=False,
icon = os.path.join(base_dir, 'img', f'spmt.{"icns" if os_type == "darwin" else "ico"}'))

#coll = COLLECT(exe,
# a.binaries,
# a.zipfiles,
# a.datas,
# strip=False,
# upx=True,
# name='app')
target_arch=f'{cpu_arch}',
entitlements_file='contrib/macdeploy/entitlements.plist',
codesign_identity=f'{codesigner if code_sign == True else ""}',
icon = os_path.join(base_dir, 'img', f'spmt.{"icns" if os_type == "darwin" else "ico"}'))

if os_type == 'darwin':
app = BUNDLE(exe,
name='SecurePivxMasternodeTool.app',
icon=os_path.join(base_dir, 'img', 'spmt.icns'),
bundle_identifier=None,
info_plist={'NSHighResolutionCapable': 'True'})
bundle_identifier='io.pivx.spmt',
info_plist={
'NSHighResolutionCapable': 'True',
'CFBundleVersion': version_str,
'CFBundleShortVersionString': version_str,
'NSPrincipalClass': 'NSApplication',
'LSApplicationCategoryType': 'public.app-category.finance'
})


# Prepare bundles
Expand All @@ -121,33 +145,60 @@ os.chdir(dist_path)
if os_type == 'win32':
os.chdir(base_dir)
# Rename dist Dir
dist_path_win = os_path.join(base_dir, 'SPMT-v' + version_str + '-Win64')
dist_path_win = os_path.join(base_dir, f'SPMT-v{version_str}-Win64')
os.rename(dist_path, dist_path_win)
# Create NSIS compressed installer
print('Creating Windows installer (requires NSIS)')
os.system(f'"{os.path.join("c:", "program files (x86)", "NSIS", "makensis.exe")}" {os.path.join(base_dir, "setup.nsi")}')
# Check for NSIS
prog_path = os.environ["ProgramFiles(x86)"]
nsis_bin = os_path.join(prog_path, "NSIS", "makensis.exe")
if os_path.exists(nsis_bin):
# Create NSIS compressed installer
print('Creating Windows installer')
os.system(f'"{nsis_bin}" {os_path.join(base_dir, "setup.nsi")}')
else:
print('NSIS not found, cannot build windows installer.')


if os_type == 'linux':
os.chdir(base_dir)
# Rename dist Dir
dist_path_linux = os_path.join(base_dir, 'SPMT-v' + version_str + '-gnu_linux')
dist_path_linux = os_path.join(base_dir, f'SPMT-v{version_str}-{cpu_arch}-gnu_linux')
os.rename(dist_path, dist_path_linux)
# Compress dist Dir
print('Compressing Linux App Folder')
os.system(f'tar -zcvf SPMT-v{version_str}-x86_64-gnu_linux.tar.gz -C {base_dir} SPMT-v{version_str}-gnu_linux')
os.system(f'tar -zcvf SPMT-v{version_str}-{cpu_arch}-gnu_linux.tar.gz -C {base_dir} SPMT-v{version_str}-{cpu_arch}-gnu_linux')


if os_type == 'darwin':
os.chdir(base_dir)
# Rename dist Dir
dist_path_mac = os_path.join(base_dir, 'SPMT-v' + version_str + '-MacOSX')
dist_path_mac = os_path.join(base_dir, f'SPMT-v{version_str}-{cpu_arch}-MacOS')
os.rename(dist_path, dist_path_mac)
# Remove 'app' folder
print("Removin 'app' folder")
print("Removing 'app' folder")
os.chdir(dist_path_mac)
os.system('rm -rf app')
os.chdir(base_dir)
# Compress dist Dir
print('Compressing Mac App Folder')
os.system(f'tar -zcvf SPMT-v{version_str}-MacOSX.tar.gz -C {base_dir} SPMT-v{version_str}-MacOSX')
os.system(f'tar -zcvf SPMT-v{version_str}-{cpu_arch}-MacOS.tar.gz -C {base_dir} SPMT-v{version_str}-{cpu_arch}-MacOS')

# dmg image creation uses the node.js appdmg package
if is_tool("appdmg"):
# Prepare dmg
print("Preparing distribution dmg installer")
os.chdir(dist_path_mac)
with open(os_path.join(base_dir, 'contrib/macdeploy', 'appdmg.json.in')) as conf:
confdata = conf.read()
confdata = confdata.replace('%version%', version_str)
confdata = confdata.replace('%signer%', f'{codesigner if code_sign == True else ""}')
with open('appdmg.json', 'w') as newconf:
newconf.write(confdata)

os.system(f'sed \"s/PACKAGE_NAME/SPMT {version_str}/\" < \"../contrib/macdeploy/background.svg\" | rsvg-convert -f png -d 72 -p 72 | convert - background.tiff@2x.png')
os.system('convert background.tiff@2x.png -resize 500x320 background.tiff.png')
os.system('tiffutil -cathidpicheck background.tiff.png background.tiff@2x.png -out background.tiff')
os.remove('background.tiff.png')
os.system(f'appdmg appdmg.json ../SPMT-v{version_str}-{cpu_arch}-MacOS.dmg')
os.remove('background.tiff@2x.png')
else:
print("appdmg not found, skipping DMG creation")
13 changes: 13 additions & 0 deletions contrib/macdeploy/appdmg.json.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"title": "SPMT %version%",
"icon": "../img/spmt.icns",
"icon-size": 96,
"background": "background.tiff",
"contents": [
{ "x": 370, "y": 156, "type": "link", "path": "/Applications" },
{ "x": 128, "y": 156, "type": "file", "path": "SecurePivxMasternodeTool.app" }
],
"code-sign": {
"signing-identity": "%signer%"
}
}
34 changes: 34 additions & 0 deletions contrib/macdeploy/background.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions contrib/macdeploy/entitlements.plist
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?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.cs.allow-unsigned-executable-memory</key>
<true/>
<key>com.apple.security.cs.disable-library-validation</key>
<true/>
<key>com.apple.security.automation.apple-events</key>
<true/>
<key>com.apple.security.cs.allow-jit</key>
<true/>
<key>com.apple.security.cs.allow-dyld-environment-variables</key>
<true/>
<key>com.apple.security.device.camera</key>
<true/>
</dict>
</plist>

0 comments on commit bb2db92

Please sign in to comment.