Files
voculinux/.github/workflows/nightly.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

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