* 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++.
339 lines
12 KiB
YAML
339 lines
12 KiB
YAML
name: Nightly Build
|
|
|
|
on:
|
|
schedule:
|
|
- cron: '0 2 * * *'
|
|
workflow_dispatch: # Allow manual triggering for testing
|
|
|
|
permissions:
|
|
contents: write # Required to create/update releases
|
|
|
|
jobs:
|
|
nightly:
|
|
name: Build and Publish Nightly
|
|
runs-on: ubuntu-latest
|
|
outputs:
|
|
version: ${{ steps.version.outputs.version }}
|
|
release_tag: ${{ steps.create_release.outputs.tag }}
|
|
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v5
|
|
with:
|
|
ref: main
|
|
fetch-depth: 0
|
|
|
|
- name: Set up Python
|
|
uses: actions/setup-python@v5
|
|
with:
|
|
python-version: '3.10'
|
|
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 setuptools wheel build twine
|
|
|
|
- name: Build package
|
|
run: |
|
|
python -m build
|
|
ls -la dist/
|
|
|
|
- name: Generate nightly version
|
|
id: version
|
|
run: |
|
|
BASE_VERSION=$(grep -oP '__version__\s*=\s*"\K[^"]+' src/vocalinux/version.py)
|
|
DATE=$(date +%Y%m%d)
|
|
SHORT_SHA=$(git rev-parse --short HEAD)
|
|
NIGHTLY_VERSION="${BASE_VERSION}.dev${DATE}+${SHORT_SHA}"
|
|
echo "version=${NIGHTLY_VERSION}" >> $GITHUB_OUTPUT
|
|
echo "base_version=${BASE_VERSION}" >> $GITHUB_OUTPUT
|
|
echo "date=${DATE}" >> $GITHUB_OUTPUT
|
|
echo "sha=${SHORT_SHA}" >> $GITHUB_OUTPUT
|
|
echo "Built version: ${NIGHTLY_VERSION}"
|
|
|
|
- name: Rename artifacts for nightly
|
|
run: |
|
|
for file in dist/*; do
|
|
base=$(basename "$file")
|
|
if [[ "$base" == vocalinux-* ]]; then
|
|
# Extract the file extension
|
|
if [[ "$base" == *.whl ]]; then
|
|
# vocalinux-0.5.0b0-py3-none-any.whl -> vocalinux-0.5.0b0.dev20250211+g1234567-py3-none-any.whl
|
|
newname="vocalinux-${{ steps.version.outputs.version }}-py3-none-any.whl"
|
|
elif [[ "$base" == *.tar.gz ]]; then
|
|
# vocalinux-0.5.0b0.tar.gz -> vocalinux-0.5.0b0.dev20250211+g1234567.tar.gz
|
|
newname="vocalinux-${{ steps.version.outputs.version }}.tar.gz"
|
|
else
|
|
# Fallback: replace version in filename
|
|
newname=$(echo "$base" | sed 's/vocalinux-[^[:space:]]*/vocalinux-${{ steps.version.outputs.version }}/')
|
|
fi
|
|
if [[ "$base" != "$newname" ]]; then
|
|
mv "$file" "dist/$newname"
|
|
fi
|
|
fi
|
|
done
|
|
ls -la dist/
|
|
|
|
- name: Build AppImage (x86_64)
|
|
env:
|
|
VOCALINUX_APPIMAGE_REQUIRE_VULKAN: "1"
|
|
run: |
|
|
bash packaging/appimage/build.sh dist/*.whl "${{ steps.version.outputs.version }}" dist
|
|
ls -la dist/*.AppImage
|
|
|
|
- name: Cleanup old nightly releases
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
run: |
|
|
# Calculate the cutoff date (3 days ago) in seconds since epoch
|
|
CUTOFF_DATE=$(date -d '3 days ago' +%s)
|
|
echo "Cutoff date: $(date -d @$CUTOFF_DATE -u +"%Y-%m-%d %H:%M:%S UTC") (3 days ago)"
|
|
|
|
# Get nightly releases with their actual creation timestamps using JSON output
|
|
# Filter for releases older than 3 days and delete them
|
|
gh release list --repo ${{ github.repository }} --json tagName,createdAt --limit 100 | \
|
|
jq -r '.[] | select(.tagName | startswith("nightly-")) | [.tagName, .createdAt] | @tsv' | \
|
|
while IFS=$'\t' read -r tag created_at; do
|
|
# Parse the ISO 8601 date to seconds since epoch
|
|
RELEASE_DATE=$(date -d "$created_at" +%s 2>/dev/null || echo "0")
|
|
|
|
if [ "$RELEASE_DATE" != "0" ] && [ "$RELEASE_DATE" -lt "$CUTOFF_DATE" ]; then
|
|
echo "Deleting old nightly release: $tag (created: $(date -d @$RELEASE_DATE -u +"%Y-%m-%d %H:%M:%S UTC"))"
|
|
gh release delete "$tag" --yes --repo ${{ github.repository }} 2>/dev/null || true
|
|
git push origin :refs/tags/"$tag" 2>/dev/null || true
|
|
git tag -d "$tag" 2>/dev/null || true
|
|
else
|
|
echo "Keeping nightly release: $tag (created: $(date -d @$RELEASE_DATE -u +"%Y-%m-%d %H:%M:%S UTC"))"
|
|
fi
|
|
done
|
|
|
|
- name: Generate release notes
|
|
id: release_notes
|
|
run: |
|
|
COMMIT_MSG=$(git log -1 --pretty=format:"%s" HEAD)
|
|
COMMIT_AUTHOR=$(git log -1 --pretty=format:"%an" HEAD)
|
|
COMMIT_DATE=$(git log -1 --pretty=format:"%ci" HEAD)
|
|
COMMIT_BODY=$(git log -1 --pretty=format:"%b" HEAD)
|
|
|
|
# Get recent commits (last 10) for changelog
|
|
RECENT_COMMITS=$(git log --oneline -10 --no-decorate | sed 's/^/- /')
|
|
|
|
# Get changes since last tag (if exists)
|
|
LAST_TAG=$(git describe --tags --abbrev=0 --match "nightly-*" 2>/dev/null || echo "")
|
|
if [ -n "$LAST_TAG" ]; then
|
|
CHANGES_SINCE=$(git log --oneline "$LAST_TAG"..HEAD --no-decorate | sed 's/^/- /')
|
|
CHANGES_SECTION="### Changes Since Last Nightly
|
|
${CHANGES_SINCE:-"*No new commits since last nightly*"}"
|
|
else
|
|
CHANGES_SECTION="### Recent Commits
|
|
${RECENT_COMMITS}"
|
|
fi
|
|
|
|
cat > /tmp/release_notes.md << EOF
|
|
## Nightly Build ${{ steps.version.outputs.version }}
|
|
|
|
**This is a nightly development build. It may contain bugs or incomplete features. Use at your own risk.**
|
|
|
|
---
|
|
|
|
### What's in This Build
|
|
|
|
**Commit Details:**
|
|
- **SHA:** \`${{ steps.version.outputs.sha }}\`
|
|
- **Message:** ${COMMIT_MSG}
|
|
- **Author:** ${COMMIT_AUTHOR}
|
|
- **Date:** ${COMMIT_DATE}
|
|
|
|
${CHANGES_SECTION}
|
|
|
|
---
|
|
|
|
### Installation
|
|
|
|
#### Quick Install (Recommended)
|
|
Download the wheel file below and install:
|
|
\`\`\`bash
|
|
pip install vocalinux-${{ steps.version.outputs.version }}-py3-none-any.whl
|
|
\`\`\`
|
|
|
|
#### From PyPI (Stable)
|
|
For the latest stable release:
|
|
\`\`\`bash
|
|
pip install vocalinux
|
|
\`\`\`
|
|
|
|
#### Using Install Script
|
|
\`\`\`bash
|
|
curl -fsSL https://raw.githubusercontent.com/VocaHQ/vocalinux/main/install.sh | bash
|
|
\`\`\`
|
|
|
|
#### AppImage (no install, no root)
|
|
Download the \`.AppImage\` matching your CPU (\`x86_64\` or \`aarch64\`) below:
|
|
\`\`\`bash
|
|
chmod +x Vocalinux-${{ steps.version.outputs.version }}-x86_64.AppImage
|
|
./Vocalinux-${{ steps.version.outputs.version }}-x86_64.AppImage
|
|
\`\`\`
|
|
Requires \`xdotool\`/\`wtype\`/\`ydotool\` on the host for text injection, same as the PyPI install path.
|
|
|
|
---
|
|
|
|
### Build Information
|
|
|
|
| Property | Value |
|
|
|----------|-------|
|
|
| **Version** | ${{ steps.version.outputs.version }} |
|
|
| **Base Version** | ${{ steps.version.outputs.base_version }} |
|
|
| **Build Date** | ${{ steps.version.outputs.date }} |
|
|
| **Python** | 3.9+ |
|
|
| **OS** | Linux (X11 & Wayland) |
|
|
|
|
---
|
|
|
|
### Files
|
|
|
|
- **\`vocalinux-${{ steps.version.outputs.version }}-py3-none-any.whl\`** - Python wheel (recommended)
|
|
- **\`vocalinux-${{ steps.version.outputs.version }}.tar.gz\`** - Source distribution
|
|
- **\`Vocalinux-${{ steps.version.outputs.version }}-x86_64.AppImage\`** - Self-contained, no install (Intel/AMD)
|
|
- **\`Vocalinux-${{ steps.version.outputs.version }}-aarch64.AppImage\`** - Self-contained, no install (ARM64, added shortly after this release is published)
|
|
|
|
---
|
|
|
|
### Links
|
|
|
|
- [Documentation](https://vocalinux.com)
|
|
- [Report Issues](https://github.com/VocaHQ/vocalinux/issues)
|
|
- [Other Releases](https://github.com/VocaHQ/vocalinux/releases)
|
|
|
|
---
|
|
|
|
*Only the 3 most recent nightly builds are kept. This build will be automatically deleted when newer nightlies are created.*
|
|
|
|
*Generated on $(date -u +"%Y-%m-%d %H:%M:%S UTC")*
|
|
EOF
|
|
echo "notes_file=/tmp/release_notes.md" >> $GITHUB_OUTPUT
|
|
|
|
- name: Create nightly release
|
|
id: create_release
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
run: |
|
|
# Create release with dated tag: nightly-2025-02-11
|
|
RELEASE_TAG="nightly-$(date +%Y-%m-%d)"
|
|
|
|
# If a release for today already exists, delete it first
|
|
gh release delete "$RELEASE_TAG" --yes --repo ${{ github.repository }} 2>/dev/null || true
|
|
git push origin :refs/tags/"$RELEASE_TAG" 2>/dev/null || true
|
|
git tag -d "$RELEASE_TAG" 2>/dev/null || true
|
|
|
|
gh release create "$RELEASE_TAG" \
|
|
--title "Nightly Build - ${{ steps.version.outputs.version }}" \
|
|
--notes-file ${{ steps.release_notes.outputs.notes_file }} \
|
|
--prerelease \
|
|
dist/*
|
|
|
|
echo "tag=${RELEASE_TAG}" >> "$GITHUB_OUTPUT"
|
|
|
|
- name: Upload artifacts (backup)
|
|
uses: actions/upload-artifact@v4
|
|
with:
|
|
name: vocalinux-nightly-${{ steps.version.outputs.version }}
|
|
path: dist/
|
|
retention-days: 7
|
|
|
|
nightly-appimage-arm64:
|
|
name: Build and Attach Nightly AppImage (aarch64)
|
|
runs-on: ubuntu-24.04-arm
|
|
needs: nightly
|
|
if: needs.nightly.result == 'success'
|
|
|
|
steps:
|
|
- name: Checkout code
|
|
uses: actions/checkout@v5
|
|
with:
|
|
ref: main
|
|
|
|
- name: Set up Python
|
|
uses: actions/setup-python@v5
|
|
with:
|
|
python-version: '3.10'
|
|
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 setuptools wheel build
|
|
|
|
- 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 "${{ needs.nightly.outputs.version }}" dist
|
|
ls -la dist/*.AppImage
|
|
|
|
- name: Attach to nightly release
|
|
env:
|
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
run: |
|
|
gh release upload "${{ needs.nightly.outputs.release_tag }}" \
|
|
dist/*.AppImage \
|
|
--repo ${{ github.repository }} \
|
|
--clobber
|