Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
97 changes: 86 additions & 11 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,38 @@ on:
- Main

jobs:
# ── 1. Run test suite ──────────────────────────────────────────────────────
# ── 1. Lint ──────────────────────────────────────────────────────────────
lint:
name: Lint
runs-on: ubuntu-latest
permissions:
contents: read

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Install uv
uses: astral-sh/setup-uv@v5
with:
enable-cache: true

- name: Set up Python 3.13
run: uv python install 3.13

- name: Install dependencies (incl. dev)
run: uv sync --all-groups

- name: Ruff — lint
run: uv run ruff check .

- name: Ruff — format check
run: uv run ruff format --check .

# ── 2. Run test suite ──────────────────────────────────────────────────────
test:
name: Run Tests
needs: lint
runs-on: macos-latest
permissions:
checks: write
Expand Down Expand Up @@ -41,11 +70,28 @@ jobs:
reporter: java-junit
fail-on-error: false

# ── 2. Build macOS app (only when tests pass) ──────────────────────────────
# ── 2. Build per platform (only when tests pass) ──────────────────────────
build:
name: Build macOS App
name: Build — ${{ matrix.os-label }}
needs: test
runs-on: macos-latest
runs-on: ${{ matrix.runner }}
permissions:
contents: read
strategy:
fail-fast: false
matrix:
include:
- runner: macos-14
os-label: macOS ARM (Apple Silicon)
artifact: MultiChannelWavMixer-macOS-arm64.zip

- runner: macos-15-intel
os-label: macOS x64 (Intel)
artifact: MultiChannelWavMixer-macOS-x64.zip

- runner: windows-latest
os-label: Windows x64
artifact: MultiChannelWavMixer-Windows-x64.zip

steps:
- name: Checkout code
Expand All @@ -62,17 +108,46 @@ jobs:
- name: Install dependencies (incl. dev)
run: uv sync --all-groups

- name: Build app with PyInstaller
run: bash build.sh
- name: Build with PyInstaller (macOS)
if: runner.os == 'macOS'
run: |
uv run pyinstaller MultiChannelWavMixer.spec --noconfirm --log-level WARN
cd dist && zip -r ${{ matrix.artifact }} MultiChannelWavMixer.app

- name: Build with PyInstaller (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
uv run pyinstaller MultiChannelWavMixer.spec --noconfirm --log-level WARN
Compress-Archive -Path dist\MultiChannelWavMixer -DestinationPath dist\${{ matrix.artifact }}

- name: Zip app bundle
- name: Smoke test — macOS
if: runner.os == 'macOS'
run: |
dist/MultiChannelWavMixer.app/Contents/MacOS/MultiChannelWavMixer &
APP_PID=$!
sleep 10
if kill -0 "$APP_PID" 2>/dev/null; then
kill "$APP_PID"
echo "Smoke test passed: app still running after 10s"
else
wait "$APP_PID"
EXIT=$?
[ $EXIT -eq 0 ] || (echo "App crashed with exit $EXIT"; exit 1)
fi

- name: Smoke test — Windows
if: runner.os == 'Windows'
shell: pwsh
run: |
cd dist
zip -r MultiChannelWavMixer.zip MultiChannelWavMixer.app
$proc = Start-Process -FilePath 'dist\MultiChannelWavMixer\MultiChannelWavMixer.exe' -PassThru
Start-Sleep 10
if (!$proc.HasExited) { $proc.Kill(); exit 0 }
if ($proc.ExitCode -ne 0) { Write-Error "App crashed with exit $($proc.ExitCode)"; exit 1 }

- name: Upload build artifact
uses: actions/upload-artifact@v4
with:
name: MultiChannelWavMixer-macOS
path: dist/MultiChannelWavMixer.zip
name: ${{ matrix.artifact }}
path: dist/${{ matrix.artifact }}
retention-days: 30
53 changes: 44 additions & 9 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,16 @@ jobs:
id: cz_manual
if: github.event_name == 'workflow_dispatch'
run: |
uv run cz bump --yes --exact-version ${{ inputs.version }}
echo "bumped=true" >> "$GITHUB_OUTPUT"
echo "new_version=${{ inputs.version }}" >> "$GITHUB_OUTPUT"
VERSION="${{ inputs.version }}"
# Update version in pyproject.toml if it differs
sed -i "s/^version = \".*\"/version = \"${VERSION}\"/" pyproject.toml
if ! git diff --quiet pyproject.toml; then
git add pyproject.toml
git commit -m "bump: release v${VERSION}"
fi
git tag -a "v${VERSION}" -m "Release v${VERSION}"
echo "bumped=true" >> "$GITHUB_OUTPUT"
echo "new_version=${VERSION}" >> "$GITHUB_OUTPUT"

# ── Auto: derive version from conventional commits ────────────────────
# Exit code 21 = "nothing to release" — treated as success (no-op).
Expand Down Expand Up @@ -102,13 +109,17 @@ jobs:
fail-fast: false
matrix:
include:
- runner: macos-latest
os-label: macOS
artifact: MultiChannelWavMixer-macOS.zip
- runner: macos-14
os-label: macOS ARM (Apple Silicon)
artifact: MultiChannelWavMixer-macOS-arm64.zip

- runner: macos-15-intel
os-label: macOS x64 (Intel)
artifact: MultiChannelWavMixer-macOS-x64.zip

- runner: windows-latest
os-label: Windows
artifact: MultiChannelWavMixer-Windows.zip
- runner: windows-latest
os-label: Windows x64
artifact: MultiChannelWavMixer-Windows-x64.zip

steps:
- name: Checkout code at new tag
Expand Down Expand Up @@ -140,6 +151,30 @@ jobs:
uv run pyinstaller MultiChannelWavMixer.spec --noconfirm --log-level WARN
Compress-Archive -Path dist\MultiChannelWavMixer -DestinationPath dist\${{ matrix.artifact }}

- name: Smoke test — macOS
if: runner.os == 'macOS'
run: |
dist/MultiChannelWavMixer.app/Contents/MacOS/MultiChannelWavMixer &
APP_PID=$!
sleep 10
if kill -0 "$APP_PID" 2>/dev/null; then
kill "$APP_PID"
echo "Smoke test passed: app still running after 10s"
else
wait "$APP_PID"
EXIT=$?
[ $EXIT -eq 0 ] || (echo "App crashed with exit $EXIT"; exit 1)
fi

- name: Smoke test — Windows
if: runner.os == 'Windows'
shell: pwsh
run: |
$proc = Start-Process -FilePath 'dist\MultiChannelWavMixer\MultiChannelWavMixer.exe' -PassThru
Start-Sleep 10
if (!$proc.HasExited) { $proc.Kill(); exit 0 }
if ($proc.ExitCode -ne 0) { Write-Error "App crashed with exit $($proc.ExitCode)"; exit 1 }

- name: Upload artifact
uses: actions/upload-artifact@v4
with:
Expand Down
Loading