From eb2b6ee870d5b44ad120239e7eb7998b21dbdf96 Mon Sep 17 00:00:00 2001 From: Salad Dais Date: Mon, 3 May 2021 19:17:57 +0000 Subject: [PATCH] Package a zip for Windows when a release is made --- .github/workflows/bundle_windows.yml | 43 +++++++++ .github/workflows/pypi_publish.yml | 2 + hippolyzer/apps/proxy_gui.py | 12 +-- hippolyzer/lib/base/helpers.py | 5 + hippolyzer/lib/base/message/data/__init__.py | 6 +- hippolyzer/lib/proxy/http_proxy.py | 4 +- hippolyzer/lib/proxy/vfs.py | 5 +- setup_cxfreeze.py | 97 +++++++++++++++++++- tests/base/test_mesh.py | 6 +- 9 files changed, 162 insertions(+), 18 deletions(-) create mode 100644 .github/workflows/bundle_windows.yml diff --git a/.github/workflows/bundle_windows.yml b/.github/workflows/bundle_windows.yml new file mode 100644 index 0000000..e0bd0ac --- /dev/null +++ b/.github/workflows/bundle_windows.yml @@ -0,0 +1,43 @@ +# Have to manually unzip this (it gets double zipped) and add it +# onto the release after it gets created. Don't want actions with repo write. +name: Bundle Windows EXE + +on: + # Only trigger on release creation + release: + types: + - created + +jobs: + build: + + runs-on: windows-latest + strategy: + matrix: + python-version: [3.9] + + steps: + - uses: actions/checkout@v2 + + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v2 + with: + python-version: ${{ matrix.python-version }} + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -e . + pip install cx_freeze + + - name: Bundle with cx_Freeze + run: | + python setup_cxfreeze.py build_exe + python setup_cxfreeze.py cleanse_cxfreeze + python setup_cxfreeze.py build_zip + + - name: Upload the artifact + uses: actions/upload-artifact@v2 + with: + name: hippolyzer-gui-windows-${{ github.sha }} + path: ./dist/** diff --git a/.github/workflows/pypi_publish.yml b/.github/workflows/pypi_publish.yml index e0814a1..8f8d16b 100644 --- a/.github/workflows/pypi_publish.yml +++ b/.github/workflows/pypi_publish.yml @@ -6,6 +6,8 @@ on: release: types: - created + workflow_dispatch: + # based on https://github.com/pypa/gh-action-pypi-publish diff --git a/hippolyzer/apps/proxy_gui.py b/hippolyzer/apps/proxy_gui.py index 7fd1248..d105ec4 100644 --- a/hippolyzer/apps/proxy_gui.py +++ b/hippolyzer/apps/proxy_gui.py @@ -8,7 +8,6 @@ import json import logging import pathlib import multiprocessing -import os import re import signal import socket @@ -24,7 +23,7 @@ from hippolyzer.apps.model import MessageLogModel, MessageLogHeader, RegionListM from hippolyzer.apps.proxy import start_proxy from hippolyzer.lib.base import llsd from hippolyzer.lib.base.datatypes import UUID -from hippolyzer.lib.base.helpers import bytes_unescape, bytes_escape +from hippolyzer.lib.base.helpers import bytes_unescape, bytes_escape, get_resource_filename from hippolyzer.lib.base.message.llsd_msg_serializer import LLSDMessageSerializer from hippolyzer.lib.base.message.message import Block from hippolyzer.lib.base.message.msgtypes import MsgType @@ -44,11 +43,10 @@ from hippolyzer.lib.proxy.templates import CAP_TEMPLATES LOG = logging.getLogger(__name__) -BASE_PATH = os.path.dirname(os.path.abspath(__file__)) -MAIN_WINDOW_UI_PATH = os.path.join(BASE_PATH, "proxy_mainwindow.ui") -MESSAGE_BUILDER_UI_PATH = os.path.join(BASE_PATH, "message_builder.ui") -ADDON_DIALOG_UI_PATH = os.path.join(BASE_PATH, "addon_dialog.ui") -FILTER_DIALOG_UI_PATH = os.path.join(BASE_PATH, "filter_dialog.ui") +MAIN_WINDOW_UI_PATH = get_resource_filename("apps/proxy_mainwindow.ui") +MESSAGE_BUILDER_UI_PATH = get_resource_filename("apps/message_builder.ui") +ADDON_DIALOG_UI_PATH = get_resource_filename("apps/addon_dialog.ui") +FILTER_DIALOG_UI_PATH = get_resource_filename("apps/filter_dialog.ui") def show_error_message(error_msg, parent=None): diff --git a/hippolyzer/lib/base/helpers.py b/hippolyzer/lib/base/helpers.py index b829219..a34def0 100644 --- a/hippolyzer/lib/base/helpers.py +++ b/hippolyzer/lib/base/helpers.py @@ -1,6 +1,7 @@ from __future__ import annotations import functools +import pkg_resources import re import weakref from pprint import PrettyPrinter @@ -133,3 +134,7 @@ def bytes_unescape(val: bytes) -> bytes: def bytes_escape(val: bytes) -> bytes: # Try to keep newlines as-is return re.sub(rb"(? None: + pass + + def finalize_options(self) -> None: + pass + + def run(self): + for path in (BASE_DIR / "build").iterdir(): + if path.name.startswith("exe.") and path.is_dir(): + for cleanse_suffix in TO_DELETE: + cleanse_path = path / cleanse_suffix + shutil.rmtree(cleanse_path, ignore_errors=True) + try: + os.unlink(cleanse_path) + except: + pass + + +class BuildZipArchiveCommand(Command): + description = "Make a distributable zip from an EXE build" + user_options = [] + + def initialize_options(self) -> None: + pass + + def finalize_options(self) -> None: + pass + + def run(self): + (BASE_DIR / "dist").mkdir(exist_ok=True) + for path in (BASE_DIR / "build").iterdir(): + if path.name.startswith("exe.") and path.is_dir(): + zip_path = BASE_DIR / "dist" / (path.name + ".zip") + shutil.make_archive(zip_path, "zip", path) + + options = { "build_exe": { "packages": [ @@ -12,7 +100,8 @@ options = { # exclude packages that are not really needed "excludes": [ "tkinter", - ] + ], + "include_msvcr": True, } } @@ -30,4 +119,8 @@ setup( description="Hippolyzer GUI", options=options, executables=executables, + cmdclass={ + "cleanse_cxfreeze": CleanseCXFreezeCommand, + "build_zip": BuildZipArchiveCommand, + } ) diff --git a/tests/base/test_mesh.py b/tests/base/test_mesh.py index bd5232a..d112761 100644 --- a/tests/base/test_mesh.py +++ b/tests/base/test_mesh.py @@ -1,16 +1,18 @@ -import pkg_resources +import os import unittest from hippolyzer.lib.base.mesh import LLMeshSerializer, MeshAsset import hippolyzer.lib.base.serialization as se +BASE_PATH = os.path.dirname(os.path.abspath(__file__)) + class TestMesh(unittest.TestCase): @classmethod def setUpClass(cls) -> None: # Use a rigged cube SLM from the upload process as a test file - slm_file = pkg_resources.resource_filename(__name__, "test_resources/testslm.slm") + slm_file = os.path.join(BASE_PATH, "test_resources", "testslm.slm") with open(slm_file, "rb") as f: cls.slm_bytes = f.read()