Stable minor since v0.15.0. Bumps version to 0.16.0 across app, web, AUR, and Flatpak AppStream, and refreshes docs, changelog, and SECURITY. Tag v0.16.0 after this lands on main.
370 lines
12 KiB
YAML
370 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 \
|
|
spirv-headers \
|
|
spirv-tools
|
|
|
|
- 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 \
|
|
spirv-headers \
|
|
spirv-tools
|
|
|
|
- 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
|