Files
voculinux/.github/workflows/release.yml
T
Jatin K MalikandGitHub 279d99fea0 fix(whisper): honor bundled GPU libs and skip software Vulkan devices (#674)
* fix(whisper): use bundled GPU libs and skip software Vulkan devices

AppImage 0.15.0 shipped a CPU-only pywhispercpp wheel, so the Settings
GPU picker and host vulkaninfo never moved inference off the CPU. Rebuild
pywhispercpp with Vulkan in the AppImage, log the libraries that actually
load, skip llvmpipe in auto-select, and document how to verify.

Fixes #604

* fix(appimage): pin gcc/g++ for Vulkan pywhispercpp rebuild

Hosts that default cc/c++ to clang fail CMAKE's C++ test because clang
does not search gcc's libstdc++ path. Default the rebuild to gcc/g++.
2026-08-16 18:29:07 -07:00

366 lines
12 KiB
YAML

name: Release
on:
push:
tags:
- 'v*'
permissions:
contents: write
packages: write
id-token: write # Required for PyPI trusted publishing
env:
PYTHON_VERSION: '3.10'
jobs:
build-and-release:
name: Build and Create Release
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
cache: 'pip'
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
portaudio19-dev \
python3-dev \
libgirepository1.0-dev \
libgirepository-2.0-dev \
pkg-config \
libcairo2-dev \
gobject-introspection \
gir1.2-gtk-3.0 \
gir1.2-appindicator3-0.1 \
gir1.2-ayatanaappindicator3-0.1 \
gir1.2-notify-0.7 \
gir1.2-dbusmenu-glib-0.4 \
gir1.2-ibus-1.0 \
gir1.2-rsvg-2.0 \
librsvg2-common \
libdbusmenu-gtk3-4 \
libnotify4 \
cmake \
ninja-build \
build-essential \
libvulkan-dev \
glslc
- name: Install build dependencies
run: |
python -m pip install --upgrade pip
pip install build twine wheel setuptools
- name: Extract version from tag
id: get_version
run: |
VERSION=${GITHUB_REF#refs/tags/v}
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
echo "Building version: $VERSION"
- name: Verify version consistency
run: |
# Get version from version.py file directly (avoid importing full package which needs gi)
PACKAGE_VERSION=$(grep -oP '__version__\s*=\s*"\K[^"]+' src/vocalinux/version.py)
TAG_VERSION=${{ steps.get_version.outputs.VERSION }}
echo "Package version: $PACKAGE_VERSION"
echo "Tag version: $TAG_VERSION"
# Allow alpha/beta suffixes in package version
if [[ ! "$PACKAGE_VERSION" == *"$TAG_VERSION"* ]] && [[ ! "$TAG_VERSION" == *"$PACKAGE_VERSION"* ]]; then
echo "Warning: Version mismatch between tag ($TAG_VERSION) and package ($PACKAGE_VERSION)"
fi
- name: Build package
run: |
python -m build
echo "Built packages:"
ls -la dist/
- name: Build AppImage (x86_64)
env:
VOCALINUX_APPIMAGE_REQUIRE_VULKAN: "1"
run: |
bash packaging/appimage/build.sh dist/*.whl "${{ steps.get_version.outputs.VERSION }}" dist
ls -la dist/*.AppImage
- name: Create Release
id: create_release
uses: softprops/action-gh-release@v2
with:
files: |
dist/*.whl
dist/*.tar.gz
dist/*.AppImage
generate_release_notes: true
draft: false
prerelease: ${{ contains(github.ref, 'alpha') || contains(github.ref, 'beta') || contains(github.ref, 'rc') }}
body: |
## Installation
### Quick Install (Recommended)
```bash
curl -fsSL https://raw.githubusercontent.com/VocaHQ/vocalinux/${{ github.ref_name }}/install.sh | bash
```
### From Source
```bash
git clone https://github.com/VocaHQ/vocalinux.git
cd vocalinux
./install.sh
```
### From PyPI
```bash
# Install the Linux system packages first:
# GTK/AppIndicator, PortAudio, and xdotool/wtype are required.
python3 -m venv ~/.local/share/vocalinux-pypi/venv --system-site-packages
source ~/.local/share/vocalinux-pypi/venv/bin/activate
pip install vocalinux
vocalinux
```
PyPI installs the Python package only. For automatic system dependency,
desktop integration, and model setup, use the Quick Install command above.
See docs/INSTALL.md for distro-specific PyPI prerequisites.
### Arch Linux (AUR)
```bash
yay -S vocalinux
```
### AppImage (no install, no root)
Download the `.AppImage` matching your CPU (`x86_64` or `aarch64`, the latter attached
shortly after this release is published) below:
```bash
chmod +x Vocalinux-${{ steps.get_version.outputs.VERSION }}-x86_64.AppImage
./Vocalinux-${{ steps.get_version.outputs.VERSION }}-x86_64.AppImage
```
Still requires `xdotool`/`wtype`/`ydotool` on the host for text injection, same as the PyPI path.
---
See [CHANGELOG](https://github.com/VocaHQ/vocalinux/releases) for detailed changes.
build-appimage-arm64:
name: Build and Attach AppImage (aarch64)
needs: build-and-release
runs-on: ubuntu-24.04-arm
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
cache: 'pip'
- name: Install system dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
portaudio19-dev \
python3-dev \
libgirepository1.0-dev \
libgirepository-2.0-dev \
pkg-config \
libcairo2-dev \
gobject-introspection \
gir1.2-gtk-3.0 \
gir1.2-appindicator3-0.1 \
gir1.2-ayatanaappindicator3-0.1 \
gir1.2-notify-0.7 \
gir1.2-dbusmenu-glib-0.4 \
gir1.2-ibus-1.0 \
gir1.2-rsvg-2.0 \
librsvg2-common \
libdbusmenu-gtk3-4 \
libnotify4 \
cmake \
ninja-build \
build-essential \
libvulkan-dev \
glslc
- name: Install build dependencies
run: |
python -m pip install --upgrade pip
pip install build wheel setuptools
- name: Extract version from tag
id: get_version
run: |
VERSION=${GITHUB_REF#refs/tags/v}
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
- name: Build package
run: |
python -m build
ls -la dist/
- name: Build AppImage (aarch64)
env:
VOCALINUX_APPIMAGE_REQUIRE_VULKAN: "1"
run: |
bash packaging/appimage/build.sh dist/*.whl "${{ steps.get_version.outputs.VERSION }}" dist
ls -la dist/*.AppImage
- name: Attach to release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
gh release upload "${{ github.ref_name }}" \
dist/*.AppImage \
--repo ${{ github.repository }} \
--clobber
publish-pypi:
name: Publish to PyPI
needs: build-and-release
runs-on: ubuntu-latest
environment:
name: pypi
url: https://pypi.org/project/vocalinux/
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: ${{ env.PYTHON_VERSION }}
cache: 'pip'
- name: Install build dependencies
run: |
python -m pip install --upgrade pip
pip install build twine
- name: Build package
run: |
python -m build
echo "Built packages:"
ls -la dist/
- name: Verify package
run: |
twine check dist/*
- name: Publish to PyPI
env:
TWINE_USERNAME: __token__
TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }}
run: |
twine upload dist/* --skip-existing
publish-aur:
name: Publish to AUR
needs: build-and-release
runs-on: ubuntu-latest
# Secrets: AUR_SSH_PRIVATE_KEY, AUR_USERNAME, AUR_EMAIL — see docs/AUR.md
steps:
- name: Check for AUR credentials
id: aur
env:
AUR_SSH_PRIVATE_KEY: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
run: |
if [ -z "$AUR_SSH_PRIVATE_KEY" ]; then
echo "configured=false" >> "$GITHUB_OUTPUT"
echo "AUR_SSH_PRIVATE_KEY not set; skipping (docs/AUR.md)"
else
echo "configured=true" >> "$GITHUB_OUTPUT"
fi
- name: Checkout code
if: steps.aur.outputs.configured == 'true'
uses: actions/checkout@v5
- name: Bump PKGBUILD version
if: steps.aur.outputs.configured == 'true'
run: |
set -euo pipefail
TAG="${GITHUB_REF#refs/tags/v}"
PKGBUILD=packaging/aur/vocalinux/PKGBUILD
sed -i "s/^pkgver=.*/pkgver=${TAG//-/}/; s/^_tag=.*/_tag=${TAG}/; s/^pkgrel=.*/pkgrel=1/" "$PKGBUILD"
grep -E '^(pkgver|_tag|pkgrel)=' "$PKGBUILD"
- name: Publish AUR package
if: steps.aur.outputs.configured == 'true'
uses: KSXGitHub/github-actions-deploy-aur@v4.2.0
with:
pkgname: vocalinux
pkgbuild: packaging/aur/vocalinux/PKGBUILD
updpkgsums: 'true'
commit_username: ${{ secrets.AUR_USERNAME }}
commit_email: ${{ secrets.AUR_EMAIL }}
ssh_private_key: ${{ secrets.AUR_SSH_PRIVATE_KEY }}
commit_message: 'Release ${{ github.ref_name }}'
deploy-website:
name: Deploy Website
runs-on: ubuntu-latest
needs: [build-and-release, publish-pypi]
steps:
- name: Checkout code
uses: actions/checkout@v5
- name: Setup Node.js
uses: actions/setup-node@v5
with:
node-version: '24'
cache: 'npm'
cache-dependency-path: './web/package-lock.json'
- name: Install dependencies
working-directory: ./web
run: npm ci || npm install
- name: Sync version from source code
run: |
VERSION=$(grep -oP '__version__\s*=\s*"\K[^"]+' src/vocalinux/version.py)
echo "Syncing version: $VERSION"
# JSON-LD uses unquoted JS keys: softwareVersion: "x.y.z"
if grep -qE 'softwareVersion:\s*"' web/src/app/page.tsx; then
sed -i 's/softwareVersion: "[^"]*"/softwareVersion: "'"$VERSION"'"/' web/src/app/page.tsx
echo "Updated page.tsx version:"
grep -oP 'softwareVersion:\s*"\K[^"]+' web/src/app/page.tsx
elif grep -qE 'softwareVersion:\s*"' web/src/app/layout.tsx; then
sed -i 's/softwareVersion: "[^"]*"/softwareVersion: "'"$VERSION"'"/' web/src/app/layout.tsx
echo "Updated layout.tsx version:"
grep -oP 'softwareVersion:\s*"\K[^"]+' web/src/app/layout.tsx
else
echo "::warning::No softwareVersion field found in page.tsx or layout.tsx; skipping sync"
fi
# Update package.json version (remove -alpha/beta/rc suffix for npm)
NPM_VERSION=${VERSION%-*}
NPM_VERSION=${NPM_VERSION%-beta*}
NPM_VERSION=${NPM_VERSION%-rc*}
sed -i 's/"version": "[^"]*"/"version": "'"$NPM_VERSION"'"/' web/package.json
# Verify the changes
echo "Updated package.json version:"
grep -oP '"version":\s*"\K[^"]+' web/package.json
- name: Build and deploy website
working-directory: ./web
run: |
npm ci || npm install
npm run deploy
- name: Deploy to gh-pages
uses: peaceiris/actions-gh-pages@v4
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
publish_dir: ./web/out
publish_branch: gh-pages
cname: vocalinux.com
force_orphan: true