aur setup

This commit is contained in:
LeonardoTrapani
2025-09-07 20:51:23 +02:00
parent de20033c1a
commit 2631293d12
10 changed files with 804 additions and 83 deletions
+48
View File
@@ -0,0 +1,48 @@
name: CI
on:
push:
branches: [ main, develop ]
pull_request:
branches: [ main, develop ]
jobs:
test:
name: Test
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.21'
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
build-essential \
pkg-config \
libasound2-dev \
libpulse-dev \
libpipewire-0.3-dev
- name: Download dependencies
run: go mod download
- name: Run tests
run: go test -v ./...
- name: Build binary
env:
CGO_ENABLED: 1
run: go build -o hyprvoice ./cmd/hyprvoice
- name: Test binary help
run: ./hyprvoice --help
- name: Test configure command
run: ./hyprvoice configure --help
+112
View File
@@ -0,0 +1,112 @@
name: Release
on:
push:
tags:
- 'v*'
jobs:
build:
name: Build and Release
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.21'
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install -y \
build-essential \
pkg-config \
libasound2-dev \
libpulse-dev \
libpipewire-0.3-dev
- name: Extract version from tag
id: version
run: echo "VERSION=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT
- name: Build binary
env:
CGO_ENABLED: 1
GOOS: linux
GOARCH: amd64
run: |
go mod download
go build -ldflags="-s -w" -o hyprvoice-linux-x86_64 ./cmd/hyprvoice
chmod +x hyprvoice-linux-x86_64
- name: Run tests
run: go test ./...
- name: Create release
id: create_release
uses: actions/create-release@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
tag_name: ${{ github.ref }}
release_name: Release ${{ steps.version.outputs.VERSION }}
body: |
## Hyprvoice v${{ steps.version.outputs.VERSION }}
### Installation
**From AUR (Recommended):**
```bash
yay -S hyprvoice-bin
hyprvoice configure
systemctl --user enable --now hyprvoice.service
```
**Manual installation:**
```bash
wget https://github.com/leonardotrapani/hyprvoice/releases/download/v${{ steps.version.outputs.VERSION }}/hyprvoice-linux-x86_64
chmod +x hyprvoice-linux-x86_64
mv hyprvoice-linux-x86_64 ~/.local/bin/hyprvoice
```
### What's Changed
- See commit history for detailed changes
### Requirements
- Wayland desktop environment
- PipeWire audio system
- OpenAI API key for transcription
**Full Changelog**: https://github.com/leonardotrapani/hyprvoice/commits/v${{ steps.version.outputs.VERSION }}
draft: false
prerelease: false
- name: Upload binary
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./hyprvoice-linux-x86_64
asset_name: hyprvoice-linux-x86_64
asset_content_type: application/octet-stream
- name: Upload checksums
run: |
sha256sum hyprvoice-linux-x86_64 > hyprvoice-linux-x86_64.sha256
echo "Binary SHA256:"
cat hyprvoice-linux-x86_64.sha256
- name: Upload checksum file
uses: actions/upload-release-asset@v1
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
upload_url: ${{ steps.create_release.outputs.upload_url }}
asset_path: ./hyprvoice-linux-x86_64.sha256
asset_name: hyprvoice-linux-x86_64.sha256
asset_content_type: text/plain
+87 -83
View File
@@ -15,24 +15,23 @@ Press a toggle key, speak, and get instant text input. Built natively for Waylan
## Installation ## Installation
### From AUR (Arch Linux) ### From AUR (Arch Linux) - Recommended
```bash ```bash
# Using your preferred AUR helper # Install hyprvoice and all dependencies automatically
yay -S hyprvoice-bin yay -S hyprvoice-bin
# or # or
paru -S hyprvoice-bin paru -S hyprvoice-bin
# Enable user service
systemctl --user enable --now hyprvoice.service
``` ```
### Download Binary The AUR package automatically installs all dependencies (`pipewire`, `wl-clipboard`, `wtype`, etc.) and sets up the systemd service. Follow the post-install instructions to complete setup.
1. Download from [GitHub Releases](https://github.com/leonardotrapani/hyprvoice/releases) ### Alternative: Download Binary
2. Install:
For non-Arch users or testing:
```bash ```bash
# Download and install binary
wget https://github.com/leonardotrapani/hyprvoice/releases/latest/download/hyprvoice-linux-x86_64 wget https://github.com/leonardotrapani/hyprvoice/releases/latest/download/hyprvoice-linux-x86_64
mkdir -p ~/.local/bin mkdir -p ~/.local/bin
mv hyprvoice-linux-x86_64 ~/.local/bin/hyprvoice mv hyprvoice-linux-x86_64 ~/.local/bin/hyprvoice
@@ -40,6 +39,9 @@ chmod +x ~/.local/bin/hyprvoice
# Add to PATH (add to ~/.bashrc or ~/.zshrc) # Add to PATH (add to ~/.bashrc or ~/.zshrc)
export PATH="$HOME/.local/bin:$PATH" export PATH="$HOME/.local/bin:$PATH"
# You'll need to manually install dependencies and create systemd service
# See Requirements section above
``` ```
### Build from Source ### Build from Source
@@ -47,83 +49,67 @@ export PATH="$HOME/.local/bin:$PATH"
```bash ```bash
git clone https://github.com/leonardotrapani/hyprvoice.git git clone https://github.com/leonardotrapani/hyprvoice.git
cd hyprvoice cd hyprvoice
# Install Go dependencies
go mod download go mod download
# Build the binary
go build -o hyprvoice ./cmd/hyprvoice go build -o hyprvoice ./cmd/hyprvoice
# Install locally (optional) # Install locally
sudo cp hyprvoice /usr/local/bin/
# Or install to user directory
mkdir -p ~/.local/bin mkdir -p ~/.local/bin
cp hyprvoice ~/.local/bin/ cp hyprvoice ~/.local/bin/
export PATH="$HOME/.local/bin:$PATH" # Add to ~/.bashrc or ~/.zshrc export PATH="$HOME/.local/bin:$PATH"
``` ```
## Requirements ## Requirements
- **Wayland desktop** (Hyprland, Niri, GNOME, KDE, etc.) - **Wayland desktop** (Hyprland, Niri, GNOME, KDE, etc.)
- **PipeWire audio system** with tools - **PipeWire audio system** with tools
- **System packages**: - **OpenAI API key** (for transcription)
**System packages** (automatically installed with AUR package):
- `pipewire`, `pipewire-pulse`, `pipewire-audio` - Audio capture
- `wl-clipboard` - Clipboard integration
- `wtype` - Text typing
- `libnotify` - Desktop notifications
- `systemd` - User service management
For manual installation on other distros:
```bash ```bash
# Arch Linux
sudo pacman -S pipewire pipewire-pulse pw-record wl-clipboard
# Ubuntu/Debian # Ubuntu/Debian
sudo apt install pipewire-pulse pipewire-bin wl-clipboard sudo apt install pipewire-pulse pipewire-bin wl-clipboard wtype libnotify-bin
# Fedora # Fedora
sudo dnf install pipewire-utils wl-clipboard sudo dnf install pipewire-utils wl-clipboard wtype libnotify
``` ```
**For text injection:**
```bash
# Arch Linux
sudo pacman -S wtype
# Ubuntu/Debian
sudo apt install wtype
# Alternative: ydotool (if wtype unavailable)
# Follow ydotool setup for user permissions
```
**Optional:**
- `notify-send` (desktop notifications)
- `systemd --user` (daemon service)
## Quick Start ## Quick Start
1. **Setup daemon service:** After installing via AUR:
1. **Configure hyprvoice interactively:**
```bash ```bash
# Enable and start the user service (reccomended) hyprvoice configure
systemctl --user enable --now hyprvoice.service ```
This wizard will guide you through setting up your OpenAI API key, audio preferences, and other settings.
# Or run manually in background 2. **Enable and start the service:**
hyprvoice serve & ```bash
systemctl --user enable --now hyprvoice.service
``` ```
2. **Configure Hyprland keybind:** 3. **Add keybinding to your window manager:**
```bash ```bash
# Add to ~/.config/hypr/hyprland.conf # For Hyprland, add to ~/.config/hypr/hyprland.conf
bind = SUPER, R, exec, hyprvoice toggle bind = SUPER, R, exec, hyprvoice toggle
``` ```
3. **Test voice input:** 4. **Test voice input:**
```bash ```bash
# Check daemon status # Check daemon status
hyprvoice status hyprvoice status
# Toggle recording (or use Super+R) # Toggle recording (or use your keybind)
hyprvoice toggle hyprvoice toggle
# Speak something... # Speak something...
hyprvoice toggle # Stop and transcribe hyprvoice toggle # Stop and transcribe
@@ -134,6 +120,9 @@ hyprvoice toggle # Stop and transcribe
### Common Commands ### Common Commands
```bash ```bash
# Interactive configuration wizard
hyprvoice configure
# Start the daemon # Start the daemon
hyprvoice serve hyprvoice serve
@@ -198,7 +187,21 @@ hyprvoice status
## Configuration ## Configuration
Configuration is automatically loaded from `~/.config/hyprvoice/config.toml`. The daemon creates this file with sensible defaults and helpful comments on first run. Changes to the config file are applied immediately without restarting the daemon. Use the interactive configuration wizard:
```bash
hyprvoice configure
```
This will guide you through setting up:
- OpenAI API key for transcription
- Language preferences (auto-detect or specific language)
- Text injection method (clipboard/typing/fallback)
- Notification settings
- Recording timeout
Configuration is stored in `~/.config/hyprvoice/config.toml` and can also be edited manually. Changes are applied immediately without restarting the daemon.
### Transcription Providers ### Transcription Providers
@@ -326,33 +329,24 @@ The daemon automatically watches the config file for changes and applies them im
- **Recording/Transcription settings**: Applied to new recording sessions - **Recording/Transcription settings**: Applied to new recording sessions
- **Invalid configs**: Rejected with error notification, daemon continues with previous config - **Invalid configs**: Rejected with error notification, daemon continues with previous config
### Service Configuration ### Service Management
#### Systemd Service The systemd user service is automatically installed with the AUR package:
The daemon runs as a user service:
```bash ```bash
# Create service file # Check service status
mkdir -p ~/.config/systemd/user systemctl --user status hyprvoice.service
cat > ~/.config/systemd/user/hyprvoice.service << 'EOF'
[Unit]
Description=Hyprvoice voice-to-text daemon
After=pipewire.service
[Service] # Start/stop service
Type=simple systemctl --user start hyprvoice.service
ExecStart=/usr/local/bin/hyprvoice serve systemctl --user stop hyprvoice.service
Restart=on-failure
RestartSec=5
[Install] # Enable/disable autostart
WantedBy=default.target systemctl --user enable hyprvoice.service
EOF systemctl --user disable hyprvoice.service
# Enable and start # View logs
systemctl --user daemon-reload journalctl --user -u hyprvoice.service -f
systemctl --user enable --now hyprvoice.service
``` ```
### File Locations ### File Locations
@@ -372,8 +366,10 @@ systemctl --user enable --now hyprvoice.service
| OpenAI transcription | ✅ | HTTP API integration | | OpenAI transcription | ✅ | HTTP API integration |
| Text injection | ✅ | Clipboard + wtype with fallback | | Text injection | ✅ | Clipboard + wtype with fallback |
| Configuration system | ✅ | TOML-based user settings with hot-reload | | Configuration system | ✅ | TOML-based user settings with hot-reload |
| Interactive setup | ✅ | `hyprvoice configure` wizard for easy setup |
| Unit test coverage | ✅ | Comprehensive test suite (100% pass) | | Unit test coverage | ✅ | Comprehensive test suite (100% pass) |
| Installation (AUR etc) | | Installation via AUR and easy setup | | CI/CD Pipeline | | Automated builds and releases via GitHub Actions |
| Installation (AUR etc) | ✅ | AUR package with automated dependency installation |
| Light dictation models | ⏳ | Alternatives to whispers for light and fast dictation | | Light dictation models | ⏳ | Alternatives to whispers for light and fast dictation |
| whisper.cpp support | ⏳ | Local model inference | | whisper.cpp support | ⏳ | Local model inference |
@@ -563,18 +559,26 @@ hyprvoice status
```bash ```bash
git clone https://github.com/leonardotrapani/hyprvoice.git git clone https://github.com/leonardotrapani/hyprvoice.git
cd hyprvoice cd hyprvoice
# Install Go dependencies
go mod download go mod download
go build -o hyprvoice ./cmd/hyprvoice
# Build
CGO_ENABLED=1 go build -o hyprvoice ./cmd/hyprvoice
# Run tests
go test ./...
# Install locally # Install locally
sudo cp hyprvoice /usr/local/bin/ mkdir -p ~/.local/bin
cp hyprvoice ~/.local/bin/
export PATH="$HOME/.local/bin:$PATH"
```
## For Maintainers
### Publishing to AUR
See [`packaging/RELEASE.md`](packaging/RELEASE.md) for complete release process including AUR deployment.
Quick start for AUR:
```bash
# After creating your first GitHub release
cd packaging/
./setup-aur.sh # One-time AUR repository setup
``` ```
### Project Structure ### Project Structure
+227
View File
@@ -1,9 +1,15 @@
package main package main
import ( import (
"bufio"
"fmt" "fmt"
"os"
"strconv"
"strings"
"time"
"github.com/leonardotrapani/hyprvoice/internal/bus" "github.com/leonardotrapani/hyprvoice/internal/bus"
"github.com/leonardotrapani/hyprvoice/internal/config"
"github.com/leonardotrapani/hyprvoice/internal/daemon" "github.com/leonardotrapani/hyprvoice/internal/daemon"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
@@ -24,6 +30,7 @@ func init() {
statusCmd(), statusCmd(),
versionCmd(), versionCmd(),
stopCmd(), stopCmd(),
configureCmd(),
) )
} }
@@ -100,3 +107,223 @@ func stopCmd() *cobra.Command {
}, },
} }
} }
func configureCmd() *cobra.Command {
return &cobra.Command{
Use: "configure",
Short: "Interactive configuration setup",
Long: `Interactive configuration wizard for hyprvoice.
This will guide you through setting up:
- OpenAI API key for transcription
- Audio and text injection preferences
- Notification settings`,
RunE: func(cmd *cobra.Command, args []string) error {
return runInteractiveConfig()
},
}
}
func runInteractiveConfig() error {
fmt.Println("🎤 Hyprvoice Configuration Wizard")
fmt.Println("==================================")
fmt.Println()
// Load existing config or create default
cfg, err := config.Load()
if err != nil {
return fmt.Errorf("failed to load config: %w", err)
}
scanner := bufio.NewScanner(os.Stdin)
// Configure transcription
fmt.Println("📝 Transcription Configuration")
fmt.Println("------------------------------")
// OpenAI API Key
fmt.Printf("OpenAI API Key (current: %s): ", maskAPIKey(cfg.Transcription.APIKey))
if scanner.Scan() {
input := strings.TrimSpace(scanner.Text())
if input != "" {
cfg.Transcription.APIKey = input
}
}
// Language
fmt.Printf("Language (empty for auto-detect, current: %s): ", cfg.Transcription.Language)
if scanner.Scan() {
input := strings.TrimSpace(scanner.Text())
cfg.Transcription.Language = input
}
fmt.Println()
// Configure injection
fmt.Println("⌨️ Text Injection Configuration")
fmt.Println("--------------------------------")
fmt.Printf("Injection mode [clipboard/type/fallback] (current: %s): ", cfg.Injection.Mode)
if scanner.Scan() {
input := strings.TrimSpace(scanner.Text())
if input != "" && (input == "clipboard" || input == "type" || input == "fallback") {
cfg.Injection.Mode = input
}
}
fmt.Printf("Restore clipboard after injection [y/n] (current: %v): ", cfg.Injection.RestoreClipboard)
if scanner.Scan() {
switch strings.TrimSpace(strings.ToLower(scanner.Text())) {
case "y", "yes":
cfg.Injection.RestoreClipboard = true
case "n", "no":
cfg.Injection.RestoreClipboard = false
}
}
fmt.Println()
// Configure notifications
fmt.Println("🔔 Notification Configuration")
fmt.Println("-----------------------------")
fmt.Printf("Enable notifications [y/n] (current: %v): ", cfg.Notifications.Enabled)
if scanner.Scan() {
switch strings.TrimSpace(strings.ToLower(scanner.Text())) {
case "y", "yes":
cfg.Notifications.Enabled = true
case "n", "no":
cfg.Notifications.Enabled = false
}
}
fmt.Println()
// Configure recording timeout
fmt.Println("⏱️ Recording Configuration")
fmt.Println("---------------------------")
fmt.Printf("Recording timeout in minutes (current: %.0f): ", cfg.Recording.Timeout.Minutes())
if scanner.Scan() {
input := strings.TrimSpace(scanner.Text())
if input != "" {
if minutes, err := strconv.Atoi(input); err == nil && minutes > 0 {
cfg.Recording.Timeout = time.Duration(minutes) * time.Minute
}
}
}
fmt.Println()
// Validate configuration
if err := cfg.Validate(); err != nil {
fmt.Printf("❌ Configuration validation failed: %v\n", err)
fmt.Println("Please check your inputs and try again.")
return err
}
// Save configuration
fmt.Println("💾 Saving configuration...")
if err := saveConfig(cfg); err != nil {
return fmt.Errorf("failed to save config: %w", err)
}
fmt.Println("✅ Configuration saved successfully!")
fmt.Println()
// Show next steps
fmt.Println("🚀 Next Steps:")
fmt.Println("1. Start/restart the daemon: systemctl --user restart hyprvoice.service")
fmt.Println("2. Test voice input: hyprvoice toggle")
fmt.Println()
configPath, _ := config.GetConfigPath()
fmt.Printf("📁 Config file location: %s\n", configPath)
return nil
}
func maskAPIKey(key string) string {
if key == "" {
return "<not set>"
}
if len(key) <= 8 {
return "****"
}
return key[:4] + "****" + key[len(key)-4:]
}
func saveConfig(cfg *config.Config) error {
configPath, err := config.GetConfigPath()
if err != nil {
return err
}
file, err := os.Create(configPath)
if err != nil {
return fmt.Errorf("failed to create config file: %w", err)
}
defer file.Close()
configContent := fmt.Sprintf(`# Hyprvoice Configuration
# This file is automatically generated with defaults.
# Edit values as needed - changes are applied immediately without daemon restart.
# Audio Recording Configuration
[recording]
sample_rate = %d # Audio sample rate in Hz (16000 recommended for speech)
channels = %d # Number of audio channels (1 = mono, 2 = stereo)
format = "%s" # Audio format (s16 = 16-bit signed integers)
buffer_size = %d # Internal buffer size in bytes (larger = less CPU, more latency)
device = "%s" # PipeWire audio device (empty = use default microphone)
channel_buffer_size = %d # Audio frame buffer size (frames to buffer)
timeout = "%s" # Maximum recording duration (e.g., "30s", "2m", "5m")
# Speech Transcription Configuration
[transcription]
provider = "%s" # Transcription service ("openai" only currently supported)
api_key = "%s" # OpenAI API key (or set OPENAI_API_KEY environment variable)
language = "%s" # Language code (empty for auto-detect, "en", "it", "es", "fr", etc.)
model = "%s" # OpenAI model name ("whisper-1" recommended)
# Text Injection Configuration
[injection]
mode = "%s" # Injection method ("clipboard", "type", "fallback")
restore_clipboard = %v # Restore original clipboard after injection
wtype_timeout = "%s" # Timeout for direct typing via wtype
clipboard_timeout = "%s" # Timeout for clipboard operations
# Desktop Notification Configuration
[notifications]
enabled = %v # Enable desktop notifications
type = "%s" # Notification type ("desktop", "log", "none")
# Mode explanations:
# - "clipboard": Copy text to clipboard only
# - "type": Direct typing via wtype only
# - "fallback": Try typing first, fallback to clipboard if it fails
#
# Language codes: Use empty string ("") for automatic detection, or specific codes like:
# "en" (English), "it" (Italian), "es" (Spanish), "fr" (French), "de" (German), etc.
`,
cfg.Recording.SampleRate,
cfg.Recording.Channels,
cfg.Recording.Format,
cfg.Recording.BufferSize,
cfg.Recording.Device,
cfg.Recording.ChannelBufferSize,
cfg.Recording.Timeout,
cfg.Transcription.Provider,
cfg.Transcription.APIKey,
cfg.Transcription.Language,
cfg.Transcription.Model,
cfg.Injection.Mode,
cfg.Injection.RestoreClipboard,
cfg.Injection.WtypeTimeout,
cfg.Injection.ClipboardTimeout,
cfg.Notifications.Enabled,
cfg.Notifications.Type,
)
if _, err := file.WriteString(configContent); err != nil {
return fmt.Errorf("failed to write config content: %w", err)
}
return nil
}
+38
View File
@@ -0,0 +1,38 @@
# Maintainer: Leonardo Trapani <leo@trapani.sh>
pkgname=hyprvoice-bin
pkgver=0.1.0
pkgrel=1
pkgdesc="Voice-powered typing for Wayland/Hyprland"
arch=('x86_64')
url="https://github.com/leonardotrapani/hyprvoice"
license=('MIT')
depends=(
'pipewire'
'pipewire-pulse'
'pipewire-audio'
'wl-clipboard'
'wtype'
'libnotify'
'systemd'
)
optdepends=(
'hyprland: For Hyprland window manager integration'
'sway: For Sway window manager integration'
)
provides=('hyprvoice')
conflicts=('hyprvoice')
source=(
"hyprvoice-${pkgver}::https://github.com/leonardotrapani/hyprvoice/releases/download/v${pkgver}/hyprvoice-linux-x86_64"
"hyprvoice.service"
)
sha256sums=('SKIP' # Update this with: updpkgsums after first release
'SKIP') # Update this with: sha256sum hyprvoice.service
install=hyprvoice.install
package() {
# Install binary
install -Dm755 "hyprvoice-${pkgver}" "${pkgdir}/usr/bin/hyprvoice"
# Install systemd service file
install -Dm644 hyprvoice.service "${pkgdir}/usr/lib/systemd/user/hyprvoice.service"
}
+110
View File
@@ -0,0 +1,110 @@
# Release Process
This document describes how to create a new release of hyprvoice.
## Automated Release Process
### 1. Create a Release Tag
```bash
# Make sure you're on main branch with latest changes
git checkout main
git pull origin main
# Create and push a version tag
git tag v0.1.0
git push origin v0.1.0
```
### 2. GitHub Actions Automatically:
- ✅ Builds the binary with CGO for Linux x86_64
- ✅ Runs all tests
- ✅ Creates a GitHub release with changelog
- ✅ Uploads `hyprvoice-linux-x86_64` binary
- ✅ Generates and uploads SHA256 checksums
### 3. Update AUR Package
```bash
cd packaging/
./update-aur.sh 0.1.0
```
That's it! The script handles everything:
- Updates PKGBUILD version and checksums
- Copies files to AUR repository
- Generates .SRCINFO
- Tests the build
- Commits and pushes to AUR (with confirmation)
## Manual Release (if needed)
### Build Binary
```bash
CGO_ENABLED=1 GOOS=linux GOARCH=amd64 go build -ldflags="-s -w" -o hyprvoice-linux-x86_64 ./cmd/hyprvoice
```
### Create Release
1. Go to GitHub Releases
2. Click "Create a new release"
3. Tag: `v0.1.0`
4. Release title: `Release 0.1.0`
5. Upload `hyprvoice-linux-x86_64`
6. Publish release
## Version Scheme
- **Major.Minor.Patch** (e.g., `0.1.0`)
- **Major**: Breaking changes
- **Minor**: New features, backwards compatible
- **Patch**: Bug fixes, small improvements
## Complete Release Checklist
### Pre-release
- [ ] All tests pass: `go test ./...`
- [ ] Binary builds: `go build ./cmd/hyprvoice`
- [ ] Configure command works: `./hyprvoice configure --help`
- [ ] Version bumped in any relevant files
- [ ] Changes documented
### GitHub Release
- [ ] Create and push version tag: `git tag v0.1.0 && git push origin v0.1.0`
- [ ] Verify GitHub Actions completed successfully
- [ ] Verify binary uploaded to GitHub releases
- [ ] Verify checksums generated
### AUR Package Update (if AUR package exists)
- [ ] Run complete AUR update: `./packaging/update-aur.sh 0.1.0`
- [ ] Verify AUR package page updated
### Post-release Verification
- [ ] Test AUR installation: `yay -S hyprvoice-bin`
- [ ] Test configure command: `hyprvoice configure`
- [ ] Test service: `systemctl --user status hyprvoice.service`
- [ ] Update project README if needed
## Files Updated in Release
- `packaging/PKGBUILD` - Version and checksums
- GitHub Release - Binary and checksums
- AUR repository - Updated package
## Troubleshooting
### Build Fails
- Check that all CGO dependencies are installed
- Ensure Go version matches workflow (1.21+)
### AUR Package Issues
- Run `makepkg -si` to test locally
- Check checksums match: `updpkgsums`
- Verify binary downloads correctly
### GitHub Actions Issues
- Check workflow logs in Actions tab
- Ensure tag follows `v*` pattern
- Verify GITHUB_TOKEN has necessary permissions
+43
View File
@@ -0,0 +1,43 @@
post_install() {
echo "==> Hyprvoice installation complete!"
echo ""
echo " 📋 Next steps (in order):"
echo " 1. Configure hyprvoice: hyprvoice configure"
echo " 2. Enable the service: systemctl --user enable --now hyprvoice.service"
echo " 3. Add keybinding to your window manager config"
echo ""
echo " 🔑 For Hyprland, add to ~/.config/hypr/hyprland.conf:"
echo " bind = SUPER, R, exec, hyprvoice toggle"
echo ""
echo " 💡 The configure step will guide you through API key setup and preferences."
echo ""
}
post_upgrade() {
echo "==> Hyprvoice has been upgraded."
echo ""
echo " 📋 Next steps:"
echo " 1. Restart the service: systemctl --user restart hyprvoice.service"
echo " 2. Check for new options: hyprvoice configure"
echo ""
}
pre_remove() {
# Stop and disable service if running
if systemctl --user is-active --quiet hyprvoice.service 2>/dev/null; then
echo "==> Stopping hyprvoice service..."
systemctl --user stop hyprvoice.service 2>/dev/null || true
fi
if systemctl --user is-enabled --quiet hyprvoice.service 2>/dev/null; then
echo "==> Disabling hyprvoice service..."
systemctl --user disable hyprvoice.service 2>/dev/null || true
fi
}
post_remove() {
echo "==> Hyprvoice has been removed."
echo " Configuration files remain in ~/.config/hyprvoice/"
echo " Cache files remain in ~/.cache/hyprvoice/"
echo " Remove them manually if desired."
}
+15
View File
@@ -0,0 +1,15 @@
[Unit]
Description=Hyprvoice voice-to-text daemon
Documentation=https://github.com/leonardotrapani/hyprvoice
After=pipewire.service
Wants=pipewire.service
[Service]
Type=simple
ExecStart=/usr/bin/hyprvoice serve
Restart=on-failure
RestartSec=5
Environment=XDG_RUNTIME_DIR=/run/user/%i
[Install]
WantedBy=default.target
+97
View File
@@ -0,0 +1,97 @@
#!/bin/bash
# Complete script to update AUR package after a new release
set -e
if [ $# -ne 1 ]; then
echo "Usage: $0 <version>"
echo "Example: $0 0.1.0"
exit 1
fi
VERSION=$1
AUR_DIR="../hyprvoice-bin"
echo "🚀 Updating AUR package for version $VERSION..."
echo ""
# Check if we're in the packaging directory
if [ ! -f "PKGBUILD" ]; then
echo "❌ Error: PKGBUILD not found. Run this from the packaging/ directory."
exit 1
fi
# Check if AUR directory exists
if [ ! -d "$AUR_DIR" ]; then
echo "❌ Error: AUR directory not found at $AUR_DIR"
echo " Expected structure:"
echo " ├── hyprvoice/ # Main repo"
echo " │ └── packaging/ # You are here"
echo " └── hyprvoice-bin/ # AUR repo"
echo ""
echo " Run the initial AUR setup first."
exit 1
fi
# Update version in PKGBUILD
echo "📝 Updating version to $VERSION..."
sed -i "s/pkgver=.*/pkgver=${VERSION}/" PKGBUILD
# Update checksums
echo "🔐 Updating checksums..."
if ! updpkgsums; then
echo "❌ Error: Failed to update checksums."
echo " Make sure GitHub release v$VERSION exists and is accessible."
exit 1
fi
# Copy files to AUR repo
echo "📋 Copying files to AUR repository..."
cp PKGBUILD "$AUR_DIR/"
cp hyprvoice.service "$AUR_DIR/"
cp hyprvoice.install "$AUR_DIR/"
# Switch to AUR directory
cd "$AUR_DIR"
# Generate .SRCINFO
echo "📄 Generating .SRCINFO..."
makepkg --printsrcinfo > .SRCINFO
# Test build
echo "🔨 Testing package build..."
if ! makepkg --noextract --nodeps; then
echo "❌ Error: Package build failed."
exit 1
fi
echo "✅ Package build successful!"
echo ""
# Show git status
echo "📊 AUR repository status:"
git status --short
echo ""
echo "🚀 Ready to publish to AUR:"
echo " git add ."
echo " git commit -m \"Update to version $VERSION\""
echo " git push origin master"
echo ""
read -p "Push to AUR now? (y/N): " push_confirm
if [[ $push_confirm == [yY] ]]; then
git add .
git commit -m "Update to version $VERSION"
git push origin master
echo ""
echo "🎉 Successfully updated AUR package to v$VERSION!"
echo " AUR page: https://aur.archlinux.org/packages/hyprvoice-bin"
else
echo "📝 To push later:"
echo " cd $AUR_DIR"
echo " git add . && git commit -m \"Update to version $VERSION\" && git push"
fi
echo ""
echo "✅ AUR update complete!"
+27
View File
@@ -0,0 +1,27 @@
#!/bin/bash
# Helper script to update PKGBUILD after a new release
set -e
if [ $# -ne 1 ]; then
echo "Usage: $0 <version>"
echo "Example: $0 0.1.0"
exit 1
fi
VERSION=$1
echo "Updating PKGBUILD for version $VERSION..."
# Update version in PKGBUILD
sed -i "s/pkgver=.*/pkgver=${VERSION}/" PKGBUILD
# Update checksums
echo "Updating checksums..."
updpkgsums
echo "✅ PKGBUILD updated for version $VERSION"
echo ""
echo "Next steps:"
echo "1. Review the changes: git diff"
echo "2. Test the package: makepkg -si"
echo "3. Commit and push to AUR"