18 Commits

Author SHA1 Message Date
eb2ce5360f upd examples 2026-03-10 19:46:26 +00:00
45dbcae804 upd examples 2026-03-10 19:45:26 +00:00
4fab6d9ad9 add examples 2026-03-10 19:38:08 +00:00
fee3fa199b add 1.10.0 to CHANGELOG 2026-03-10 04:17:36 +00:00
cf3205a86f add required release step 2026-03-10 04:02:10 +00:00
c0416d5b7c rename gui entry points 2026-03-10 03:51:34 +00:00
a952f64bab minor bump 2026-03-10 03:47:17 +00:00
3f6172c4bf add publish+ruff actions 2026-03-10 03:46:28 +00:00
96f3fbbee1 fix artifact name patterns 2026-03-10 03:32:19 +00:00
0bc566fa00 access poetry from POETRY_BIN 2026-03-10 03:20:50 +00:00
c9b7f89453 PATH fix attempt 2026-03-10 03:13:48 +00:00
bdba07694b PATH fix attempt 2026-03-10 03:05:12 +00:00
462301cd4e PATH fix attempt 2026-03-10 03:01:04 +00:00
768fed217b remove then readd deps 2026-03-10 02:56:17 +00:00
34299ad84e avoid using local path deps in workflow 2026-03-10 02:49:50 +00:00
7a78d7233e use poetry self add to avoid Windows path issue, see: https://github.com/python-poetry/poetry/issues/10028 2026-03-10 02:42:01 +00:00
971b4a4601 upd shell, see https://github.com/snok/install-poetry?tab=readme-ov-file#running-on-windows 2026-03-10 02:36:34 +00:00
b219511ef8 replace Install Task step with go-task action. 2026-03-10 02:31:05 +00:00
7 changed files with 169 additions and 46 deletions

53
.github/workflows/publish.yml vendored Normal file
View File

@@ -0,0 +1,53 @@
name: Publish to PyPI
on:
release:
types: [published]
push:
tags:
- 'v*.*.*'
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.12'
- name: Install Poetry
run: |
pip install poetry==2.3.1
poetry --version
- name: Build package
run: |
poetry install --only-root
poetry build
- uses: actions/upload-artifact@v4
with:
name: dist
path: ./dist
pypi-publish:
needs: build
name: Upload release to PyPI
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/project/voicemeeter-compact/
permissions:
id-token: write
steps:
- uses: actions/download-artifact@v4
with:
name: dist
path: ./dist
- name: Publish package distributions to PyPI
uses: pypa/gh-action-pypi-publish@release/v1
with:
packages-dir: ./dist

View File

@@ -28,11 +28,9 @@ jobs:
virtualenvs-in-project: true virtualenvs-in-project: true
- name: Install Task - name: Install Task
run: | uses: go-task/setup-task@v1
Invoke-WebRequest -OutFile go-task.zip -Uri "https://github.com/go-task/task/releases/latest/download/task_windows_amd64.zip" with:
Expand-Archive -Path go-task.zip -DestinationPath . version: 3.x
Move-Item task.exe C:\Windows\System32\
shell: pwsh
- name: Download Forest TTK Theme - name: Download Forest TTK Theme
run: | run: |
@@ -68,14 +66,31 @@ jobs:
path: .venv path: .venv
key: venv-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }} key: venv-${{ runner.os }}-${{ hashFiles('**/poetry.lock') }}
- name: Install Poetry plugins
run: poetry self add poethepoet
shell: bash
- name: Replace path dependencies with PyPI versions
run: |
poetry remove voicemeeter-api vban-cmd || true
poetry add voicemeeter-api vban-cmd
shell: bash
- name: Install dependencies - name: Install dependencies
run: poetry install --with build run: poetry install --with build
shell: bash
- name: Build artifacts with dynamic taskfile - name: Build artifacts with dynamic taskfile
run: task --taskfile Taskfile.dynamic.yml build-all run: task --taskfile Taskfile.dynamic.yml build-all
shell: bash
env:
POETRY_BIN: /c/Users/runneradmin/.local/bin/poetry
- name: Create release archives - name: Create release archives
run: task --taskfile Taskfile.dynamic.yml compress-all run: task --taskfile Taskfile.dynamic.yml compress-all
shell: bash
env:
POETRY_BIN: /c/Users/runneradmin/.local/bin/poetry
# Sunvalley theme variants # Sunvalley theme variants
- name: Upload build artifacts - Sunvalley Basic - name: Upload build artifacts - Sunvalley Basic
@@ -100,77 +115,77 @@ jobs:
- name: Upload build artifacts - Forest Basic Dark - name: Upload build artifacts - Forest Basic Dark
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: forest-basic-dark name: forest-dark-basic
path: dist/forest-basic-dark.zip path: dist/forest-dark-basic.zip
- name: Upload build artifacts - Forest Banana Dark - name: Upload build artifacts - Forest Banana Dark
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: forest-banana-dark name: forest-dark-banana
path: dist/forest-banana-dark.zip path: dist/forest-dark-banana.zip
- name: Upload build artifacts - Forest Potato Dark - name: Upload build artifacts - Forest Potato Dark
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: forest-potato-dark name: forest-dark-potato
path: dist/forest-potato-dark.zip path: dist/forest-dark-potato.zip
# Forest theme variants (light) # Forest theme variants (light)
- name: Upload build artifacts - Forest Basic Light - name: Upload build artifacts - Forest Basic Light
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: forest-basic-light name: forest-light-basic
path: dist/forest-basic-light.zip path: dist/forest-light-basic.zip
- name: Upload build artifacts - Forest Banana Light - name: Upload build artifacts - Forest Banana Light
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: forest-banana-light name: forest-light-banana
path: dist/forest-banana-light.zip path: dist/forest-light-banana.zip
- name: Upload build artifacts - Forest Potato Light - name: Upload build artifacts - Forest Potato Light
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: forest-potato-light name: forest-light-potato
path: dist/forest-potato-light.zip path: dist/forest-light-potato.zip
# Azure theme variants (dark) # Azure theme variants (dark)
- name: Upload build artifacts - Azure Basic Dark - name: Upload build artifacts - Azure Basic Dark
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: azure-basic-dark name: azure-dark-basic
path: dist/azure-basic-dark.zip path: dist/azure-dark-basic.zip
- name: Upload build artifacts - Azure Banana Dark - name: Upload build artifacts - Azure Banana Dark
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: azure-banana-dark name: azure-dark-banana
path: dist/azure-banana-dark.zip path: dist/azure-dark-banana.zip
- name: Upload build artifacts - Azure Potato Dark - name: Upload build artifacts - Azure Potato Dark
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: azure-potato-dark name: azure-dark-potato
path: dist/azure-potato-dark.zip path: dist/azure-dark-potato.zip
# Azure theme variants (light) # Azure theme variants (light)
- name: Upload build artifacts - Azure Basic Light - name: Upload build artifacts - Azure Basic Light
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: azure-basic-light name: azure-light-basic
path: dist/azure-basic-light.zip path: dist/azure-light-basic.zip
- name: Upload build artifacts - Azure Banana Light - name: Upload build artifacts - Azure Banana Light
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: azure-banana-light name: azure-light-banana
path: dist/azure-banana-light.zip path: dist/azure-light-banana.zip
- name: Upload build artifacts - Azure Potato Light - name: Upload build artifacts - Azure Potato Light
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
name: azure-potato-light name: azure-light-potato
path: dist/azure-potato-light.zip path: dist/azure-light-potato.zip
release: release:
if: startsWith(github.ref, 'refs/tags/v') if: startsWith(github.ref, 'refs/tags/v')
@@ -180,6 +195,9 @@ jobs:
contents: write contents: write
steps: steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Download all artifacts - name: Download all artifacts
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4

19
.github/workflows/ruff.yml vendored Normal file
View File

@@ -0,0 +1,19 @@
name: Ruff
on:
push:
branches: [main]
pull_request:
branches: [main]
workflow_dispatch:
jobs:
ruff:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- uses: astral-sh/ruff-action@v3
with:
args: 'format --check --diff'

View File

@@ -9,6 +9,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- [ ] - [ ]
## [1.10.0] - 2026-03-26
### Added
- Automated builds for Releases. This is much preferred over manual releases because users can be sure the files are built directly from the source code.
- Azure theme added to Releases.
- vban.toml files can now use key `host` intead of `ip`.
- `ip` is still usable for backwards compatibility.
### Changed
- Attempting a VBAN connection now uses a PING/PONG handshake to verify connection, this makes connections more reliable.
- Navigation frame is disabled by default. You can easily enable it from the menu or with an app.toml config.
### Fixed
- Comp, Gate sliders now receive feedback when changes are made on the Voicemeeter GUI.
- Bus CONFIG mode button rotates through the correct modes for Basic Kind.
- Bus CONFIG mono now rotates through *off, on, stereo reverse*.
- Bus CONFIG mode/mono buttons are now a fixed width.
## [1.9.8] - 2025-01-22 ## [1.9.8] - 2025-01-22
### Changed ### Changed

View File

@@ -1,7 +1,15 @@
version: '3' version: '3'
# Dynamic build system - no spec files needed! # Dynamic build system - no spec files needed!
# Usage: task build THEMES="azure forest" or task build-all # Examples:
# - task -t Taskfile.dynamic.yml build THEMES="azure forest"
# - task -t Taskfile.dynamic.yml build-all
# THEMES can be specified as a space-separated list or "all" to build everything.
#
# Compression tasks are also dynamic and can be used like:
# Usage examples:
# - task -t Taskfile.dynamic.yml compress THEME=azure
# - task -t Taskfile.dynamic.yml compress-all
vars: vars:
THEMES: '{{.THEMES | default "all"}}' THEMES: '{{.THEMES | default "all"}}'
@@ -11,27 +19,27 @@ tasks:
build: build:
desc: Build specified themes dynamically (no spec files needed) desc: Build specified themes dynamically (no spec files needed)
cmds: cmds:
- poetry run python tools/dynamic_builder.py {{.THEMES}} - ${POETRY_BIN:-poetry} run python tools/dynamic_builder.py {{.THEMES}}
build-all: build-all:
desc: Build all themes desc: Build all themes
cmds: cmds:
- poetry run python tools/dynamic_builder.py all - ${POETRY_BIN:-poetry} run python tools/dynamic_builder.py all
build-azure: build-azure:
desc: Build only azure theme desc: Build only azure theme
cmds: cmds:
- poetry run python tools/dynamic_builder.py azure - ${POETRY_BIN:-poetry} run python tools/dynamic_builder.py azure
build-forest: build-forest:
desc: Build only forest theme desc: Build only forest theme
cmds: cmds:
- poetry run python tools/dynamic_builder.py forest - ${POETRY_BIN:-poetry} run python tools/dynamic_builder.py forest
build-sunvalley: build-sunvalley:
desc: Build only sunvalley theme desc: Build only sunvalley theme
cmds: cmds:
- poetry run python tools/dynamic_builder.py sunvalley - ${POETRY_BIN:-poetry} run python tools/dynamic_builder.py sunvalley
compress: compress:
desc: Compress artifacts for specified theme desc: Compress artifacts for specified theme

View File

@@ -1,6 +1,6 @@
[project] [project]
name = "voicemeeter-compact" name = "voicemeeter-compact"
version = "1.9.8" version = "1.10.0"
description = "A Compact Voicemeeter Remote App" description = "A Compact Voicemeeter Remote App"
authors = [{ name = "Onyx and Iris", email = "code@onyxandiris.online" }] authors = [{ name = "Onyx and Iris", email = "code@onyxandiris.online" }]
license = { text = "MIT" } license = { text = "MIT" }
@@ -14,9 +14,9 @@ dependencies = [
] ]
[project.scripts] [project.scripts]
gui-basic-compact = "vmcompact.gui.basic:run" voicemeeter-compact-basic = "vmcompact.gui.basic:run"
gui-banana-compact = "vmcompact.gui.banana:run" voicemeeter-compact-banana = "vmcompact.gui.banana:run"
gui-potato-compact = "vmcompact.gui.potato:run" voicemeeter-compact-potato = "vmcompact.gui.potato:run"
[tool.poetry] [tool.poetry]
packages = [{ include = "vmcompact" }] packages = [{ include = "vmcompact" }]

View File

@@ -5,6 +5,7 @@ Generates spec files on-the-fly and builds executables without storing intermedi
""" """
import argparse import argparse
import os
import shutil import shutil
import subprocess import subprocess
import sys import sys
@@ -164,8 +165,9 @@ class DynamicBuilder:
# Build with PyInstaller # Build with PyInstaller
dist_path = self.dist_dir / f'{theme_variant}-{kind}' dist_path = self.dist_dir / f'{theme_variant}-{kind}'
poetry_bin = os.getenv('POETRY_BIN', 'poetry')
cmd = [ cmd = [
'poetry', poetry_bin,
'run', 'run',
'pyinstaller', 'pyinstaller',
'--noconfirm', '--noconfirm',
@@ -179,14 +181,14 @@ class DynamicBuilder:
cmd, cwd=self.base_dir, capture_output=True, text=True cmd, cwd=self.base_dir, capture_output=True, text=True
) )
if result.returncode == 0: if result.returncode == 0:
print(f' Built {theme_variant}-{kind}') print(f'[OK] Built {theme_variant}-{kind}')
return True return True
else: else:
print(f' Failed to build {theme_variant}-{kind}') print(f'[FAIL] Failed to build {theme_variant}-{kind}')
print(f'Error: {result.stderr}') print(f'Error: {result.stderr}')
return False return False
except Exception as e: except Exception as e:
print(f' Exception building {theme_variant}-{kind}: {e}') print(f'[ERROR] Exception building {theme_variant}-{kind}: {e}')
return False return False
def build_theme(self, theme_family: str) -> Dict[str, bool]: def build_theme(self, theme_family: str) -> Dict[str, bool]:
@@ -211,8 +213,9 @@ def run_rewriter(theme_family: str, base_dir: Path) -> bool:
"""Run the theme rewriter if needed.""" """Run the theme rewriter if needed."""
if theme_family in ['azure', 'forest']: if theme_family in ['azure', 'forest']:
print(f'Running rewriter for {theme_family} theme...') print(f'Running rewriter for {theme_family} theme...')
poetry_bin = os.getenv('POETRY_BIN', 'poetry')
cmd = [ cmd = [
'poetry', poetry_bin,
'run', 'run',
'python', 'python',
'tools/rewriter.py', 'tools/rewriter.py',
@@ -232,7 +235,8 @@ def run_rewriter(theme_family: str, base_dir: Path) -> bool:
def restore_rewriter(base_dir: Path) -> bool: def restore_rewriter(base_dir: Path) -> bool:
"""Restore files after rewriter.""" """Restore files after rewriter."""
print('Restoring rewriter changes...') print('Restoring rewriter changes...')
cmd = ['poetry', 'run', 'python', 'tools/rewriter.py', '--restore'] poetry_bin = os.getenv('POETRY_BIN', 'poetry')
cmd = [poetry_bin, 'run', 'python', 'tools/rewriter.py', '--restore']
try: try:
result = subprocess.run(cmd, cwd=base_dir) result = subprocess.run(cmd, cwd=base_dir)
return result.returncode == 0 return result.returncode == 0
@@ -298,7 +302,7 @@ def main():
total_count = 0 total_count = 0
for build_name, success in all_results.items(): for build_name, success in all_results.items():
status = '' if success else '' status = '[OK]' if success else '[FAIL]'
print(f'{status} {build_name}') print(f'{status} {build_name}')
if success: if success:
success_count += 1 success_count += 1