diff --git a/.github/workflows/build-binaries.yml b/.github/workflows/build-binaries.yml new file mode 100644 index 0000000..6d939df --- /dev/null +++ b/.github/workflows/build-binaries.yml @@ -0,0 +1,142 @@ +# .github/workflows/build.yml +name: Build CX_Freeze Binaries + +on: + release: + types: [created] + workflow_dispatch: +env: + FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: true # ← opt into Node 24 now + +permissions: + contents: write + +jobs: + build: + strategy: + matrix: + include: + - os: ubuntu-latest + artifact-name: OpenVRCScaler + output-ext: ".AppImage" + - os: windows-latest + artifact-name: OpenVRCScaler + output-ext: ".msi" + + runs-on: ${{ matrix.os }} + + steps: + - name: Checkout main repo + uses: actions/checkout@v4 + + # --- Python + CX_Freeze --- + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: "3.13" + + - name: Install dependencies (Windows) + if: runner.os == 'Windows' + shell: pwsh + run: | + pip install -r requirements.txt + pip install cx_Freeze freeze-core Nuitka pyinstaller + + - name: Install dependencies (Linux) + if: runner.os == 'Linux' + run: | + sudo apt-get update + pip install -r requirements.txt + pip install cx_Freeze freeze-core + ##needed if adding a systemtray icon + #- name: Set up virtual display (Linux) + #if: runner.os == 'Linux' + #run: | + # sudo apt-get install -y xvfb + # Xvfb :99 -screen 0 1024x768x24 & + # echo "DISPLAY=:99" >> $GITHUB_ENV + + # --- Build CX_Freeze --- + - name: Build with CX_Freeze (Linux) + if: runner.os == 'Linux' + ##needed if systray icon is added + #env: + #DISPLAY: ':99' + run: | + python setup.py bdist_appimage + + - name: Build with CX_Freeze (Windows) + if: runner.os == 'Windows' + shell: cmd + run: | + python setup.py bdist_msi + + # --- Build pyinstaller --- + + - name: Build with pyinstaller (Windows) + if: runner.os == 'Windows' + shell: cmd + run: | + pyinstaller ^ + --noconfirm ^ + --onefile ^ + --windowed ^ + --name OpenVRCScaler-pyinstaller.exe ^ + --icon "open_vrc_scaler_icon.ico" ^ + "open_vrc_scaler.py" + + # --- Build Nuitka --- + - name: Build with Nuitka (Windows) + if: runner.os == 'Windows' + shell: cmd + run: | + nuitka ^ + --assume-yes-for-downloads ^ + --windows-console-mode=disable ^ + --windows-icon-from-ico=open_vrc_scaler_icon.ico ^ + --output-filename=OpenVRCScaler-nuitka.exe ^ + --enable-plugin=tk-inter ^ + --output-dir=dist ^ + --mode=onefile ^ + open_vrc_scaler.py + + # --- Upload --- + - name: Upload binary + uses: actions/upload-artifact@v6 + with: + name: ${{ matrix.artifact-name }} + path: dist/OpenVRCScaler${{ matrix.output-ext }} + retention-days: 30 + + - name: Upload PyInstaller artifact (Windows) + if: runner.os == 'Windows' + uses: actions/upload-artifact@v6 + with: + name: ${{ matrix.artifact-name }}-pyinstaller + path: dist/OpenVRCScaler-pyinstaller.exe + retention-days: 30 + + - name: Upload Nuitka artifact (Windows) + if: runner.os == 'Windows' + uses: actions/upload-artifact@v6 + with: + name: ${{ matrix.artifact-name }}-nuitka + path: dist/OpenVRCScaler-nuitka.exe + retention-days: 30 + + - name: Upload to Release + uses: softprops/action-gh-release@v2 + with: + files: dist/OpenVRCScaler${{ matrix.output-ext }} + + - name: Upload PyInstaller build to Release (Windows) + if: runner.os == 'Windows' + uses: softprops/action-gh-release@v2 + with: + files: dist/OpenVRCScaler-pyinstaller.exe + + - name: Upload Nuitka build to Release (Windows) + if: runner.os == 'Windows' + uses: softprops/action-gh-release@v2 + with: + files: dist/OpenVRCScaler-nuitka.exe diff --git a/open_vrc_scaler_icon.svg b/open_vrc_scaler_icon.svg new file mode 100644 index 0000000..767706d --- /dev/null +++ b/open_vrc_scaler_icon.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/setup.py b/setup.py new file mode 100644 index 0000000..ba46cae --- /dev/null +++ b/setup.py @@ -0,0 +1,81 @@ +import sys +import subprocess +from cx_Freeze import setup, Executable +#stuff if using pystray +#force pysystray without a desktop +#pystray_path = subprocess.check_output( +# [sys.executable, '-c', +# 'import importlib.util; import os; ' +# 'spec = importlib.util.find_spec("pystray"); ' +# 'print(os.path.dirname(spec.origin))'], +# text=True +#).strip() + +# Dependencies are automatically detected, but it might need +# fine tuning. +build_options = { + 'packages': [], + 'include_files': [], + 'zip_exclude_packages': [], + 'excludes': [], +} + +base = 'gui' + +directory_table = [ + ("ProgramMenuFolder", "TARGETDIR", "."), + ("MyProgramMenu", "ProgramMenuFolder", "MYPROG~1|My Program"), +] + +msi_data = { + "Directory": directory_table, + "ProgId": [ + ("Prog.Id", "2026.05.26.1", None, "Scale your avatar over OSC", "IconId", None), + ], + "Icon": [ + ("IconId", "open_vrc_scaler_icon.ico"), + ], + "Shortcut": [ + ("DesktopShortcut", "DesktopFolder", "OpenVRCScaler", + "TARGETDIR", "[TARGETDIR]open_vrc_scaler.exe", + None, None, None, None, None, None, "TARGETDIR"), + ("StartMenuShortcut", "MyProgramMenu", "OpenVRCScaler", + "TARGETDIR", "[TARGETDIR]open_vrc_scaler.exe", + None, None, None, None, None, None, "TARGETDIR"), + ], +} + +bdist_msi_options = { + "add_to_path": True, + "data": msi_data, + "upgrade_code": "{ae44905e-0759-43b3-813c-a31f3483d407}", + "output_name": "OpenVRCScaler.msi", +} +bdist_appimage_options = { + "target_name": "OpenVRCScaler.AppImage", +} + +# Pick the right icon per platform +if sys.platform == "win32": + icon = 'open_vrc_scaler_icon.ico' +else: + icon = 'open_vrc_scaler_icon.svg' + +executables = [ + Executable( + 'open_vrc_scaler.py', + base=base, + icon=icon, + ), +] + +setup(name='OpenVRCScaler', + version = '2026.05.26.1', + description = "Change your avatar's scale over osc", + license = "MIT License", + options = { + 'build_exe': build_options, + 'bdist_msi': bdist_msi_options, + 'bdist_appimage': bdist_appimage_options, + }, + executables = executables)