Skip to content

Conversation

@PythonTilk
Copy link

Summary

This PR adds comprehensive Linux support to HyprNote, including platform-specific features and multi-architecture packaging workflows for major Linux distributions.

Major Features Added

1. Linux Packaging Workflows (.github/workflows/)

  • .deb packages for Ubuntu/Debian (x86_64 & ARM64)
  • AppImage universal packages (x86_64 & ARM64)
  • RPM packages for Fedora/RHEL (x86_64 & ARM64)
  • Arch Linux packages (x86_64 & ARM64)
  • Cross-compilation support for ARM64 on x86_64 runners
  • Automated testing and validation for all package formats
  • Comprehensive documentation in README_linux_packages.md

2. Audio System Support

  • ALSA microphone capture with automatic calibration
  • PulseAudio speaker capture for system audio recording
  • Configurable microphone sensitivity with persistent storage
  • Device enumeration and friendly names
  • Microphone testing UI with real-time gain adjustment

3. Calendar Integration

  • CalDAV support for iCloud calendar sync on Linux
  • CardDAV contact synchronization for Apple platforms
  • Contact sync UI controls with database integration

4. System Integration

  • D-Bus notification system implementation
  • Autostart configuration with UI toggle
  • Wayland window display improvements
  • Linux-specific app and browser detection
  • Speaker device handling and configuration

5. Platform Detection

  • Linux application detection
  • Browser detection for Linux
  • Microphone source detection

Technical Details

Packaging Architecture

Each workflow produces 2 packages per format (x86_64 & ARM64):

  • Total of 8 packages per release across 4 formats
  • Cross-compilation using aarch64-unknown-linux-gnu toolchain
  • Native testing on x86_64, package verification on ARM64

Dependencies

  • Build features: stt-openblas,llm-vulkan for optimized Linux builds
  • PulseAudio/ALSA support with proper feature gating
  • Removed heavy ML deps from default features for faster builds

Code Quality

  • Comprehensive error handling across audio and detection crates
  • Fixed doctests and imports
  • Applied code formatting with dprint
  • Deduplicated configuration validation logic

Files Changed

  • 95 files changed: 8629 insertions(+), 624 deletions(-)
  • New workflows: 3 Linux packaging workflows (~1250 lines)
  • Documentation: Added/updated Linux-specific docs
  • Core crates: Enhanced audio, calendar, notification, detection

Testing

  • Workflows include automated package installation tests (x86_64)
  • Package structure validation for ARM64
  • Test binaries for audio functionality
  • Example programs for verification

Distribution Support

  • Debian/Ubuntu: 20.04, 22.04, 24.04, and derivatives
  • Fedora/RHEL: Fedora 38+, RHEL 9+, Rocky Linux 9+
  • Arch Linux: Latest rolling release
  • Universal: AppImage works on most distributions

Breaking Changes

None - all Linux features are additive and properly feature-gated.

Related Issues

Addresses Linux platform support and distribution packaging needs.

BenediktBurger and others added 30 commits August 8, 2025 10:11
This commit introduces two new files:

- LINUX_AUDIO.md: Documents the current state of audio support on Linux.
- LINUX_SUPPORT.md: Provides a comprehensive overview of missing features for full Linux support.
Docstrings generation was requested by @PythonTilk.

* #1 (comment)

The following files were modified:

* `crates/audio/src/bin/test_mic.rs`
* `crates/audio/src/bin/test_speaker.rs`
* `crates/audio/src/lib.rs`
* `crates/audio/src/mic.rs`
* `crates/audio/src/speaker/linux.rs`
* `crates/audio/src/speaker/mod.rs`
* `crates/detect/src/app/linux.rs`
* `crates/detect/src/browser/linux.rs`
* `crates/detect/src/mic/linux.rs`
* `crates/file/examples/checksum.rs`
* `crates/transcribe-whisper-local/examples/show_data_dir.rs`
* `crates/whisper-local/examples/list_backends.rs`
* `crates/whisper-local/examples/test_model.rs`
* `crates/whisper-local/src/model.rs`
* `owhisper/owhisper-server/src/commands/run.rs`
* `plugins/listener/src/error.rs`
* `plugins/listener/src/ext.rs`
* `plugins/listener/src/fsm.rs`
📝 Add docstrings to `linux-development`
…ures; clean speaker cfg gating and linux impl typo; doc trims
…serialize, clean mic builder docs, silence unused variable, ignore local wav artifact
…ements

- Replace unwrap/expect with proper Result types throughout audio crates
- Add mutex poison error handling in speaker/windows.rs
- Extract helper functions in mic.rs to eliminate code duplication:
  * create_standard_config() for unified configuration
  * validate_device_with_fallback() for device validation
  * try_build_test_stream() for sample format testing
- Improve browser detection error handling in detect/browser/linux.rs
- Add graceful regex compilation fallbacks in detect/browser/mod.rs
- Expand error types in audio/errors.rs for better error reporting
- Update plugin systems (listener, connector) for consistency
- Clean up documentation and remove verbose comments

Resolves 100+ potential panic points and significantly improves system robustness.
Maintains existing functionality while adding comprehensive error handling.
- Remove local-llm and local-stt from default features in connector plugin
- Makes heavy ML dependencies opt-in only to avoid forcing consumers to pull large deps
- Follows AGENTS.md guidelines for optional feature management

Addresses CodeRabbit feedback on feature configuration.
- Add section about comprehensive error handling improvements in LINUX_AUDIO.md
- Document audio system robustness and detection system improvements in LINUX_SUPPORT.md
- Update LinuxInstallNotes.md with information about recent updates and optional ML features
- Reflect elimination of 100+ panic points and improved device management
- Document graceful error handling in browser detection and system integration

Updates documentation to reflect the comprehensive CodeRabbit fixes completed.
BREAKING: Resolves the most critical missing Linux feature

• Add PulseAudio-based system audio capture in speaker/linux.rs
• Replace mock implementation with real audio capture from monitor sources
• Add libpulse-binding and libpulse-simple-binding dependencies
• Implement automatic audio backend detection (PulseAudio -> ALSA -> Mock)
• Add comprehensive error handling for audio system failures
• Include monitor source discovery using pactl commands
• Support 48kHz stereo capture with stereo-to-mono downmixing
• Add AudioSystem error variant for better error reporting
• Include extended test binary for real audio capture validation

Key improvements:
- Eliminates the primary Linux support gap (speaker audio capture)
- Provides foundation for full audio processing pipeline on Linux
- Maintains fallback compatibility with existing ALSA/mock implementations
- Uses feature flags to make PulseAudio optional ('pulseaudio' feature)

Tested successfully: Captures audio samples from PulseAudio monitor sources,
enabling Echo Cancellation and full transcription pipeline on Linux.
…plementation

🎉 Major milestone: Speaker audio capture fully implemented!

• Update LINUX_AUDIO.md to show PulseAudio implementation details
• Mark speaker capture as IMPLEMENTED in LINUX_SUPPORT.md
• Update priorities to reflect resolved critical blocker
• Add PulseAudio development library requirements to LinuxInstallNotes.md
• Highlight that core audio functionality is now complete on Linux
• Update Linux support status from 'missing critical feature' to 'production ready'

The primary blocker for Linux support has been eliminated. Full audio pipeline
including microphone capture, speaker capture, and Echo Cancellation is now
functional on Linux systems with PulseAudio.
…tegration

- Add comprehensive Linux notification support via org.freedesktop.Notifications D-Bus interface
- Implement permission checking and multi-desktop environment support (GNOME, KDE, XFCE, MATE, Cinnamon)
- Add thread-safe callback mechanism with proper Send bounds
- Update documentation to reflect notification system implementation status
- Tested and verified on Hyprland with notification daemon
…ugin

- Resolve runtime error where listener plugin couldn't start sessions due to missing local-stt feature
- Enable local-llm and local-stt features on tauri-plugin-connector dependency
- Ensures connector can properly access local STT/LLM servers
- Remove LINUX_AUDIO.md and LINUX_SUPPORT.md (information was duplicated and outdated)
- Create comprehensive linuxtodo.md consolidating all Linux issues, missing features, and TODOs
- Document critical issues: recording session failures, system tray D-Bus issues, audio pipeline testing needs
- Organize by priority: Critical Issues, Missing Features, Build/Packaging, Testing, Documentation
- Include implementation roadmap with 5 phases
- Add status summary showing 85% core functionality complete
- Add environment variable initialization for XDG_RUNTIME_DIR and DBUS_SESSION_BUS_ADDRESS
- Implement monitor detection fallback for Wayland compositors (Hyprland)
- Clean up audio backend detection and logging
- Fix duplicate function declaration in owhisper run command
- Update Linux todo documentation with resolved issues

These changes fix the core functionality issues preventing the app from starting
properly on Wayland-based systems with PipeWire/PulseAudio.
- Add Linux-specific speaker device parameter handling (always use default)
- Format code with cargo fmt for consistency
- Improve error messages and logging formatting
- Fix whitespace issues in listener FSM
- Add target-specific dependency configuration in listener plugin
- Enable PulseAudio feature only on Linux builds
- Fix trailing whitespace in browser detection code
…storage

Enable users to adjust microphone gain via Settings UI with values persisted to database, improving audio capture quality for different recording environments
Implement comprehensive CardDAV contact synchronization infrastructure:

Core Infrastructure:
- Add ContactSource trait to calendar-interface for contact operations
- Implement CardDavHandle with vcard_parser for parsing vCard data from CardDAV servers
- Create contact database schema, types, and CRUD operations in db-user
- Add sync_contacts function following same pattern as calendar/event sync

Technical Changes:
- Replace incorrect vcard crate (for generation) with vcard_parser (for parsing)
- Parse FN, EMAIL, TEL, ORG, NOTE fields from vCard 3.0/4.0 format
- Store emails and phone_numbers as JSON arrays in database
- Support given_name, family_name, organization, emails, phone_numbers, note fields
- Add contacts_access_status() for permission checking

Platform Support:
- Linux/CalDAV: Fully implemented with CardDAV client integration
- macOS: Permission handling implemented, fetching TODO (requires CNContactFetchRequest bindings)

Changes:
- crates/calendar-apple: Add carddav_client.rs, update Cargo.toml with vcard_parser dependency
- crates/calendar-interface: Add ContactSource trait and Contact struct
- crates/db-user: Add contacts migration, types, and operations with full CRUD support
- plugins/apple-calendar: Add sync_contacts command, ext method, and sync logic

Tests:
- All tests pass: cargo test -p calendar-apple, db-user, tauri-plugin-apple-calendar
- Contact CRUD operations verified in db-user::contacts_ops::tests::test_contacts
- Add sync button in ContactView for manual contact synchronization
- Add sync button with expandable section in calendar settings
- Fix database error handling in upsert_contact (use libsql::de::from_row)
- Add index comment for contacts table user_id column
- Both sync buttons show loading state with spinning icon
- Invalidate contact queries after successful sync
- Remove forced autostart disable in lib.rs to restore functionality
- Add 'Start automatically at login' toggle in Settings → General
- Implement XDG Autostart standard via tauri-plugin-autostart
- Update documentation with autostart setup and compatibility notes
- Mark autostart implementation as complete in linuxtodo.md

Compatible with 95%+ of Linux desktop environments (GNOME, KDE, XFCE, etc.)
- Add ALSA loopback device detection and testing
- Implement alsa_capture_thread for speaker audio capture
- Support multiple device names (hw:Loopback,1,0, plughw:Loopback,1, etc.)
- Configure 48kHz stereo float32 format matching PulseAudio
- Add automatic device testing and error recovery
- Provide fallback chain: PulseAudio → ALSA → Mock

Users can enable ALSA loopback with: sudo modprobe snd-aloop
Tauri config files are located in apps/desktop/src-tauri/, not ./src-tauri/.
Updated all three workflows to use correct path.
When using 'pnpm -F desktop', the command runs in the apps/desktop
directory context, so config paths must be relative to that directory.
Changed from './apps/desktop/src-tauri/tauri.conf.*.json' to
'./src-tauri/tauri.conf.*.json' in all three Linux packaging workflows.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (7)
.github/workflows/linux_packages_arch.yaml (2)

24-25: Release channel logic does not differentiate pre-releases from stable releases.

The environment variables only check workflow_dispatch events and do not handle release events. Additionally, the proposed fix in past reviews treats all release events as 'stable', which incorrectly handles pre-releases. The logic should distinguish between normal releases (use stable config) and pre-releases (use nightly config) using github.event.release.prerelease.

Apply this corrected diff:

 env:
-  RELEASE_CHANNEL: ${{ github.event_name == 'workflow_dispatch' && inputs.channel || 'nightly' }}
-  TAURI_CONF_PATH: ${{ github.event_name == 'workflow_dispatch' && inputs.channel == 'stable' && './apps/desktop/src-tauri/tauri.conf.stable.json' || './apps/desktop/src-tauri/tauri.conf.nightly.json' }}
+  RELEASE_CHANNEL: ${{ (github.event_name == 'release' && !github.event.release.prerelease && 'stable') || (github.event_name == 'workflow_dispatch' && inputs.channel) || 'nightly' }}
+  TAURI_CONF_PATH: ${{ ((github.event_name == 'release' && !github.event.release.prerelease) || (github.event_name == 'workflow_dispatch' && inputs.channel == 'stable')) && './apps/desktop/src-tauri/tauri.conf.stable.json' || './apps/desktop/src-tauri/tauri.conf.nightly.json' }}

This ensures stable releases use the stable config, pre-releases fall back to nightly, and workflow_dispatch respects the user's channel input.


374-374: Upgrade deprecated action to Node 20–compatible version.

softprops/action-gh-release@v1 targets the obsolete Node 12 runtime and fails on current GitHub-hosted runners. Upgrade to @v2.

-        uses: softprops/action-gh-release@v1
+        uses: softprops/action-gh-release@v2
.github/workflows/linux_packages_rpm.yaml (2)

24-25: Release channel logic does not differentiate pre-releases from stable releases.

The environment variables only check workflow_dispatch events and do not handle release events. The logic should distinguish between normal releases (use stable config) and pre-releases (use nightly config) using github.event.release.prerelease.

Apply this corrected diff:

 env:
-  RELEASE_CHANNEL: ${{ github.event_name == 'workflow_dispatch' && inputs.channel || 'nightly' }}
-  TAURI_CONF_PATH: ${{ (github.event_name == 'workflow_dispatch' && inputs.channel == 'stable') && './apps/desktop/src-tauri/tauri.conf.stable.json' || './apps/desktop/src-tauri/tauri.conf.nightly.json' }}
+  RELEASE_CHANNEL: ${{ (github.event_name == 'release' && !github.event.release.prerelease && 'stable') || (github.event_name == 'workflow_dispatch' && inputs.channel) || 'nightly' }}
+  TAURI_CONF_PATH: ${{ ((github.event_name == 'release' && !github.event.release.prerelease) || (github.event_name == 'workflow_dispatch' && inputs.channel == 'stable')) && './apps/desktop/src-tauri/tauri.conf.stable.json' || './apps/desktop/src-tauri/tauri.conf.nightly.json' }}

This ensures stable releases use the stable config, pre-releases fall back to nightly, and workflow_dispatch respects the user's channel input.


296-296: Upgrade deprecated action to Node 20–compatible version.

softprops/action-gh-release@v1 targets the obsolete Node 12 runtime and fails on current GitHub-hosted runners. Upgrade to @v2.

-        uses: softprops/action-gh-release@v1
+        uses: softprops/action-gh-release@v2
.github/workflows/linux_packages.yaml (3)

24-25: Release channel logic does not differentiate pre-releases from stable releases.

The environment variables only check workflow_dispatch events and do not handle release events. The logic should distinguish between normal releases (use stable config) and pre-releases (use nightly config) using github.event.release.prerelease.

Apply this corrected diff:

 env:
-  RELEASE_CHANNEL: ${{ github.event_name == 'workflow_dispatch' && inputs.channel || 'nightly' }}
-  TAURI_CONF_PATH: ${{ (github.event_name == 'workflow_dispatch' && inputs.channel == 'stable') && './apps/desktop/src-tauri/tauri.conf.stable.json' || './apps/desktop/src-tauri/tauri.conf.nightly.json' }}
+  RELEASE_CHANNEL: ${{ (github.event_name == 'release' && !github.event.release.prerelease && 'stable') || (github.event_name == 'workflow_dispatch' && inputs.channel) || 'nightly' }}
+  TAURI_CONF_PATH: ${{ ((github.event_name == 'release' && !github.event.release.prerelease) || (github.event_name == 'workflow_dispatch' && inputs.channel == 'stable')) && './apps/desktop/src-tauri/tauri.conf.stable.json' || './apps/desktop/src-tauri/tauri.conf.nightly.json' }}

This ensures stable releases use the stable config, pre-releases fall back to nightly, and workflow_dispatch respects the user's channel input.


285-285: Upgrade deprecated action to Node 20–compatible version.

softprops/action-gh-release@v1 targets the obsolete Node 12 runtime and fails on current GitHub-hosted runners. Upgrade to @v2.

       - name: Upload .deb to release
         if: github.event_name == 'release'
-        uses: softprops/action-gh-release@v1
+        uses: softprops/action-gh-release@v2
         with:
           files: ${{ steps.find-deb.outputs.deb_path }}

570-570: Upgrade deprecated action to Node 20–compatible version.

softprops/action-gh-release@v1 targets the obsolete Node 12 runtime and fails on current GitHub-hosted runners. Upgrade to @v2.

       - name: Upload AppImage to release
         if: github.event_name == 'release'
-        uses: softprops/action-gh-release@v1
+        uses: softprops/action-gh-release@v2
         with:
           files: ${{ steps.find-appimage.outputs.appimage_path }}
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bf171ce and e6ec36e.

📒 Files selected for processing (3)
  • .github/workflows/linux_packages.yaml (1 hunks)
  • .github/workflows/linux_packages_arch.yaml (1 hunks)
  • .github/workflows/linux_packages_rpm.yaml (1 hunks)
🧰 Additional context used
🪛 actionlint (1.7.8)
.github/workflows/linux_packages.yaml

131-131: name is required in action metadata "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)


131-131: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)


144-144: name is required in action metadata "/home/jailuser/git/.github/actions/pnpm_install/action.yaml"

(action)


144-144: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/pnpm_install/action.yaml"

(action)


147-147: name is required in action metadata "/home/jailuser/git/.github/actions/poetry_install/action.yaml"

(action)


147-147: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/poetry_install/action.yaml"

(action)


285-285: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


303-303: label "ubuntu-20.04" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2025", "windows-2022", "windows-11-arm", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-24.04-arm", "ubuntu-22.04", "ubuntu-22.04-arm", "macos-latest", "macos-latest-xl", "macos-latest-xlarge", "macos-latest-large", "macos-26-xlarge", "macos-26", "macos-15-intel", "macos-15-xlarge", "macos-15-large", "macos-15", "macos-14-xl", "macos-14-xlarge", "macos-14-large", "macos-14", "macos-13-xl", "macos-13-xlarge", "macos-13-large", "macos-13", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file

(runner-label)


307-307: label "ubuntu-20.04" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2025", "windows-2022", "windows-11-arm", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-24.04-arm", "ubuntu-22.04", "ubuntu-22.04-arm", "macos-latest", "macos-latest-xl", "macos-latest-xlarge", "macos-latest-large", "macos-26-xlarge", "macos-26", "macos-15-intel", "macos-15-xlarge", "macos-15-large", "macos-15", "macos-14-xl", "macos-14-xlarge", "macos-14-large", "macos-14", "macos-13-xl", "macos-13-xlarge", "macos-13-large", "macos-13", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file

(runner-label)


570-570: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

.github/workflows/linux_packages_arch.yaml

374-374: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

.github/workflows/linux_packages_rpm.yaml

117-117: name is required in action metadata "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)


117-117: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)


296-296: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

The Arch workflow only needs the binary to create the .pkg.tar.zst package.
AppImage bundling fails due to old strip utility not recognizing modern
.relr.dyn sections in Arch libraries, but this doesn't affect the Arch
package creation.
- Fix RPM test script to correctly detect package name (hyprnote-nightly vs hyprnote)
- Fix Debian test script to correctly detect package name
- Update binary path detection to use '/usr/bin/' instead of 'bin/.*' pattern
- Add package contents debugging output on binary detection failure
- Disable ARM64 builds temporarily in all workflows due to cross-compilation dependency issues
- This ensures all x86_64 builds and tests complete successfully
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (3)
.github/workflows/linux_packages.yaml (1)

23-29: Release event logic is missing from environment variables — same issue as linux_packages_rpm.yaml.

Lines 24–25 only evaluate workflow_dispatch and always fall back to 'nightly' when triggered by a release. Both the DEB and AppImage jobs depend on these environment variables but will receive nightly configuration for release-triggered builds.

Apply this diff:

 env:
-  RELEASE_CHANNEL: ${{ github.event_name == 'workflow_dispatch' && inputs.channel || 'nightly' }}
-  TAURI_CONF_PATH: ${{ (github.event_name == 'workflow_dispatch' && inputs.channel == 'stable') && './apps/desktop/src-tauri/tauri.conf.stable.json' || './apps/desktop/src-tauri/tauri.conf.nightly.json' }}
+  RELEASE_CHANNEL: ${{ github.event_name == 'release' && 'stable' || (github.event_name == 'workflow_dispatch' && inputs.channel) || 'nightly' }}
+  TAURI_CONF_PATH: ${{ (github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.channel == 'stable')) && './apps/desktop/src-tauri/tauri.conf.stable.json' || './apps/desktop/src-tauri/tauri.conf.nightly.json' }}
.github/workflows/linux_packages_rpm.yaml (2)

303-303: Upgrade softprops/action-gh-release to a supported version.

Line 303 uses softprops/action-gh-release@v1, which targets the obsolete Node.js 12 runtime and is no longer compatible with current GitHub-hosted runners. This step will fail when attempting to publish release artifacts. Update to @v2.

-        uses: softprops/action-gh-release@v1
+        uses: softprops/action-gh-release@v2

23-29: Release event logic is missing from environment variables — builds will use nightly config.

Lines 24–25 only evaluate workflow_dispatch inputs and will always fall back to 'nightly' when triggered by a release event. This causes release builds to incorrectly use the nightly Tauri configuration. The job condition on line 29 already properly guards against null access to github.event.release, so the environment expressions should handle it too.

Apply this diff:

 env:
-  RELEASE_CHANNEL: ${{ github.event_name == 'workflow_dispatch' && inputs.channel || 'nightly' }}
-  TAURI_CONF_PATH: ${{ (github.event_name == 'workflow_dispatch' && inputs.channel == 'stable') && './apps/desktop/src-tauri/tauri.conf.stable.json' || './apps/desktop/src-tauri/tauri.conf.nightly.json' }}
+  RELEASE_CHANNEL: ${{ github.event_name == 'release' && 'stable' || (github.event_name == 'workflow_dispatch' && inputs.channel) || 'nightly' }}
+  TAURI_CONF_PATH: ${{ (github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.channel == 'stable')) && './apps/desktop/src-tauri/tauri.conf.stable.json' || './apps/desktop/src-tauri/tauri.conf.nightly.json' }}
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f7e2a87 and 67f3661.

📒 Files selected for processing (2)
  • .github/workflows/linux_packages.yaml (1 hunks)
  • .github/workflows/linux_packages_rpm.yaml (1 hunks)
🧰 Additional context used
🪛 actionlint (1.7.8)
.github/workflows/linux_packages_rpm.yaml

118-118: name is required in action metadata "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)


118-118: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)


303-303: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

.github/workflows/linux_packages.yaml

132-132: name is required in action metadata "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)


132-132: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)


145-145: name is required in action metadata "/home/jailuser/git/.github/actions/pnpm_install/action.yaml"

(action)


145-145: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/pnpm_install/action.yaml"

(action)


148-148: name is required in action metadata "/home/jailuser/git/.github/actions/poetry_install/action.yaml"

(action)


148-148: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/poetry_install/action.yaml"

(action)


292-292: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


310-310: label "ubuntu-20.04" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2025", "windows-2022", "windows-11-arm", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-24.04-arm", "ubuntu-22.04", "ubuntu-22.04-arm", "macos-latest", "macos-latest-xl", "macos-latest-xlarge", "macos-latest-large", "macos-26-xlarge", "macos-26", "macos-15-intel", "macos-15-xlarge", "macos-15-large", "macos-15", "macos-14-xl", "macos-14-xlarge", "macos-14-large", "macos-14", "macos-13-xl", "macos-13-xlarge", "macos-13-large", "macos-13", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file

(runner-label)


578-578: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🔇 Additional comments (3)
.github/workflows/linux_packages_rpm.yaml (1)

118-121: ARM64 OpenBLAS dependency handling is graceful.

The conditional block correctly attempts to install libopenblas-dev:arm64 but continues with a warning if unavailable, preventing the entire build from failing on systems where the package is not present. This aligns with the cross-compilation scaffolding.

.github/workflows/linux_packages.yaml (2)

456-508: AppImage extraction and testing logic is defensive and well-structured.

The test step uses timeout guards, fallback error handling, and graceful degradation for cross-compiled ARM64 verification where extraction may fail. The headless CI acknowledgment (line 506) is appropriate.


510-567: ARM64 AppImage verification handles extraction gracefully.

The verification step appropriately relaxes assertions for cross-compiled ARM64 binaries on x86_64 runners, where extraction/verification may not be possible. The conditional logic (lines 531–565) lets the step complete without hard failure, which is pragmatic for CI environments.

The previous attempt used '|| echo' but this didn't work because the
script runs with 'set -e' which exits immediately on any error.

This fix:
- Temporarily disables 'set -e' during the Tauri build
- Captures the exit code
- Re-enables 'set -e'
- Checks if the build failed, and if so, verifies the binary was still
  built (which is all we need for the Arch package)
- Provides clear messaging about expected AppImage bundling failures
- Only exits with error if the binary itself wasn't built

The AppImage bundling fails on modern Arch due to incompatible strip
utility, but we only need the binary for creating the .pkg.tar.zst
package.
The previous approach tried to handle AppImage bundling failures, but
the failure occurs during the Tauri build process before the binary
compilation completes.

This fix uses --bundles none to skip all bundling (AppImage, deb, rpm)
and only build the binary. This is perfect for Arch since we create our
own .pkg.tar.zst package from the binary.

This avoids the strip incompatibility issue with modern Arch libraries
that have .relr.dyn sections.
The --bundles flag doesn't accept 'none' as a value. Instead of using
Tauri CLI (which always tries to create bundles), we now build with
cargo directly. This gives us just the binary, which is all we need
for creating the .pkg.tar.zst Arch package.

Changes:
- Build with cargo instead of Tauri CLI
- Pass FEATURES environment variable to Docker container
- Verify binary is built at expected location
- Skip all bundling steps (AppImage/deb/rpm)
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (2)
.github/workflows/linux_packages_arch.yaml (2)

379-379: Update deprecated softprops/action-gh-release@v1 to v2.

The maintained version is v2, which targets Node 20. Version 1 targets Node 16, which reached end-of-life on November 12, 2024, and will fail on current GitHub Actions runners.

-        uses: softprops/action-gh-release@v1
+        uses: softprops/action-gh-release@v2

24-25: Handle release events in environment variable logic.

The RELEASE_CHANNEL and TAURI_CONF_PATH expressions only check for workflow_dispatch events. When a release event triggers, these variables incorrectly default to 'nightly' configuration since github.event_name == 'release' fails the condition. This causes stable releases to use nightly settings instead of stable configuration.

 env:
-  RELEASE_CHANNEL: ${{ github.event_name == 'workflow_dispatch' && inputs.channel || 'nightly' }}
-  TAURI_CONF_PATH: ${{ github.event_name == 'workflow_dispatch' && inputs.channel == 'stable' && './apps/desktop/src-tauri/tauri.conf.stable.json' || './apps/desktop/src-tauri/tauri.conf.nightly.json' }}
+  RELEASE_CHANNEL: ${{ (github.event_name == 'release' && !github.event.release.prerelease && 'stable') || (github.event_name == 'workflow_dispatch' && inputs.channel) || 'nightly' }}
+  TAURI_CONF_PATH: ${{ ((github.event_name == 'release' && !github.event.release.prerelease) || (github.event_name == 'workflow_dispatch' && inputs.channel == 'stable')) && './apps/desktop/src-tauri/tauri.conf.stable.json' || './apps/desktop/src-tauri/tauri.conf.nightly.json' }}

Same issue exists in linux_packages_rpm.yaml, linux_packages.yaml, and desktop_cd.yaml.

🧹 Nitpick comments (2)
CLAUDE.md (1)

67-70: Reduce repetitive sentence structure in the "Do Not" section.

Three consecutive lines start with "Do not", creating redundant sentence patterns. Consider varying the structure while preserving clarity and emphasis.

 ## Do Not
-
-Do not commit large model binaries.
-Do not add new formatters or global toolchains without discussion.
-Do not enable heavy features for simple type export or CI smoke tests.
+
+- Commit large model binaries
+- Add new formatters or global toolchains without discussion
+- Enable heavy features for simple type export or CI smoke tests
.github/workflows/linux_packages_arch.yaml (1)

332-368: ARM64 verification step is well-guarded but incomplete.

The step conditionally runs only for ARM64 builds (currently disabled) and properly extracts/validates package structure. However, since ARM64 builds are disabled in the matrix (lines 41-46), this step will never execute.

Consider adding a comment clarifying when this becomes active, or restructure the condition to prevent confusing dead code.

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8bf8d8c and c0d0e35.

📒 Files selected for processing (2)
  • .github/workflows/linux_packages_arch.yaml (1 hunks)
  • CLAUDE.md (1 hunks)
🧰 Additional context used
🪛 actionlint (1.7.8)
.github/workflows/linux_packages_arch.yaml

379-379: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🪛 LanguageTool
CLAUDE.md

[style] ~70-~70: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...global toolchains without discussion. - Do not enable heavy features for simple ty...

(ENGLISH_WORD_REPEAT_BEGINNING_RULE)

🔇 Additional comments (4)
.github/workflows/linux_packages_arch.yaml (4)

29-29: Job condition properly guards release-triggered builds.

The if guard correctly uses null-safe checks (github.event.release &&) to validate release events before proceeding, preventing null reference errors.


63-78: Version validation logic is sound.

The step correctly extracts version from config using jq and validates it matches the release tag for release events, with proper error handling and GITHUB_ENV export.


79-277: Docker build process structure is robust.

The build script:

  • Installs all required system dependencies
  • Properly sources Rust environment after installation
  • Sets correct environment variables for Tauri and libclang
  • Uses non-root builder user with proper sudoers setup
  • Correctly handles PKGBUILD variable substitution with bash escaping
  • Properly exports output artifacts

The containerized approach with environment variable passing isolates the build cleanly.


291-330: Test coverage for x86_64 is comprehensive.

The test step validates:

  • Package installation via pacman
  • Binary existence, executability, and architecture
  • Runtime library dependencies (ldd output)
  • .desktop file presence and content
  • Proper error handling for missing components

The package filename contains spaces (e.g., 'Hyprnote Nightly_0.0.63_amd64.deb')
which causes dpkg to fail when the path is not quoted.

This fix adds quotes around the deb_path output variable in the
installation command.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

♻️ Duplicate comments (3)
.github/workflows/linux_packages_arch.yaml (2)

405-405: Upgrade deprecated action to Node 20-compatible version.

softprops/action-gh-release@v1 targets Node 12 (EOL) and will fail on current GitHub-hosted runners. Update to v2 to ensure release uploads succeed.

-        uses: softprops/action-gh-release@v1
+        uses: softprops/action-gh-release@v2

24-25: Fix environment logic to handle release events and differentiate stable from pre-releases.

The RELEASE_CHANNEL and TAURI_CONF_PATH expressions only match workflow_dispatch events, causing release-triggered workflows to incorrectly fall back to 'nightly' config. Additionally, the workflow triggers on both published and prereleased release types, requiring differentiation.

Stable releases (published without prerelease flag) should use stable config; pre-releases should use nightly. Apply this corrected logic:

 env:
-  RELEASE_CHANNEL: ${{ github.event_name == 'workflow_dispatch' && inputs.channel || 'nightly' }}
-  TAURI_CONF_PATH: ${{ github.event_name == 'workflow_dispatch' && inputs.channel == 'stable' && './apps/desktop/src-tauri/tauri.conf.stable.json' || './apps/desktop/src-tauri/tauri.conf.nightly.json' }}
+  RELEASE_CHANNEL: ${{ (github.event_name == 'release' && !github.event.release.prerelease && 'stable') || (github.event_name == 'workflow_dispatch' && inputs.channel) || 'nightly' }}
+  TAURI_CONF_PATH: ${{ ((github.event_name == 'release' && !github.event.release.prerelease) || (github.event_name == 'workflow_dispatch' && inputs.channel == 'stable')) && './apps/desktop/src-tauri/tauri.conf.stable.json' || './apps/desktop/src-tauri/tauri.conf.nightly.json' }}
.github/workflows/linux_packages.yaml (1)

24-25: Fix environment logic to handle release events and differentiate stable from pre-releases.

The RELEASE_CHANNEL and TAURI_CONF_PATH expressions only match workflow_dispatch events, causing release-triggered workflows to incorrectly fall back to 'nightly' config. Additionally, the workflow triggers on both published and prereleased release types, requiring differentiation.

Stable releases (published without prerelease flag) should use stable config; pre-releases should use nightly. Apply this corrected logic:

 env:
-  RELEASE_CHANNEL: ${{ github.event_name == 'workflow_dispatch' && inputs.channel || 'nightly' }}
-  TAURI_CONF_PATH: ${{ (github.event_name == 'workflow_dispatch' && inputs.channel == 'stable') && './apps/desktop/src-tauri/tauri.conf.stable.json' || './apps/desktop/src-tauri/tauri.conf.nightly.json' }}
+  RELEASE_CHANNEL: ${{ (github.event_name == 'release' && !github.event.release.prerelease && 'stable') || (github.event_name == 'workflow_dispatch' && inputs.channel) || 'nightly' }}
+  TAURI_CONF_PATH: ${{ ((github.event_name == 'release' && !github.event.release.prerelease) || (github.event_name == 'workflow_dispatch' && inputs.channel == 'stable')) && './apps/desktop/src-tauri/tauri.conf.stable.json' || './apps/desktop/src-tauri/tauri.conf.nightly.json' }}
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between c0d0e35 and 10c678e.

📒 Files selected for processing (2)
  • .github/workflows/linux_packages.yaml (1 hunks)
  • .github/workflows/linux_packages_arch.yaml (1 hunks)
🧰 Additional context used
🪛 actionlint (1.7.8)
.github/workflows/linux_packages.yaml

132-132: name is required in action metadata "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)


132-132: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)


145-145: name is required in action metadata "/home/jailuser/git/.github/actions/pnpm_install/action.yaml"

(action)


145-145: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/pnpm_install/action.yaml"

(action)


148-148: name is required in action metadata "/home/jailuser/git/.github/actions/poetry_install/action.yaml"

(action)


148-148: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/poetry_install/action.yaml"

(action)


292-292: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


310-310: label "ubuntu-20.04" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2025", "windows-2022", "windows-11-arm", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-24.04-arm", "ubuntu-22.04", "ubuntu-22.04-arm", "macos-latest", "macos-latest-xl", "macos-latest-xlarge", "macos-latest-large", "macos-26-xlarge", "macos-26", "macos-15-intel", "macos-15-xlarge", "macos-15-large", "macos-15", "macos-14-xl", "macos-14-xlarge", "macos-14-large", "macos-14", "macos-13-xl", "macos-13-xlarge", "macos-13-large", "macos-13", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file

(runner-label)


578-578: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

.github/workflows/linux_packages_arch.yaml

405-405: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

- target: "x86_64-unknown-linux-gnu"
arch: "x86_64"
features: "stt-openblas,llm-vulkan"
runner: "ubuntu-20.04"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Replace retired runner labels with a supported version.

The build-appimage matrix uses the retired ubuntu-20.04 label, which GitHub no longer provides. Jobs using this label will remain queued indefinitely. Update both matrix entries to ubuntu-24.04 (consistent with the build-linux-packages job on line 40).

           - target: "x86_64-unknown-linux-gnu"
             arch: "x86_64"
             features: "stt-openblas,llm-vulkan"
-            runner: "ubuntu-20.04"
+            runner: "ubuntu-24.04"
           # ARM64 builds disabled temporarily due to cross-compilation dependency issues
           # - target: "aarch64-unknown-linux-gnu"
           #   arch: "aarch64"
           #   features: "stt-openblas,llm-vulkan"
-          #   runner: "ubuntu-20.04"
+          #   runner: "ubuntu-24.04"

Also applies to: 315-315

🧰 Tools
🪛 actionlint (1.7.8)

310-310: label "ubuntu-20.04" is unknown. available labels are "windows-latest", "windows-latest-8-cores", "windows-2025", "windows-2022", "windows-11-arm", "ubuntu-latest", "ubuntu-latest-4-cores", "ubuntu-latest-8-cores", "ubuntu-latest-16-cores", "ubuntu-24.04", "ubuntu-24.04-arm", "ubuntu-22.04", "ubuntu-22.04-arm", "macos-latest", "macos-latest-xl", "macos-latest-xlarge", "macos-latest-large", "macos-26-xlarge", "macos-26", "macos-15-intel", "macos-15-xlarge", "macos-15-large", "macos-15", "macos-14-xl", "macos-14-xlarge", "macos-14-large", "macos-14", "macos-13-xl", "macos-13-xlarge", "macos-13-large", "macos-13", "self-hosted", "x64", "arm", "arm64", "linux", "macos", "windows". if it is a custom label for self-hosted runner, set list of labels in actionlint.yaml config file

(runner-label)

🤖 Prompt for AI Agents
.github/workflows/linux_packages.yaml lines 310 and 315: the build-appimage
matrix uses the retired runner label "ubuntu-20.04" which will cause jobs to
queue indefinitely; update both matrix entries to "ubuntu-24.04" to match the
build-linux-packages job (line 40) and supported runners, ensuring the workflow
uses the new label in both places.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (2)
.github/workflows/linux_packages_arch.yaml (2)

24-25: Fix environment variable logic to handle release events correctly.

The RELEASE_CHANNEL and TAURI_CONF_PATH expressions only check for workflow_dispatch events. When the workflow is triggered by a release event, these variables incorrectly default to 'nightly', causing stable releases to use the nightly configuration. Since the workflow triggers on both published and prereleased release types, you must differentiate between stable releases (non-prerelease) and pre-releases.

Apply this diff to handle all trigger scenarios:

 env:
-  RELEASE_CHANNEL: ${{ github.event_name == 'workflow_dispatch' && inputs.channel || 'nightly' }}
-  TAURI_CONF_PATH: ${{ github.event_name == 'workflow_dispatch' && inputs.channel == 'stable' && './apps/desktop/src-tauri/tauri.conf.stable.json' || './apps/desktop/src-tauri/tauri.conf.nightly.json' }}
+  RELEASE_CHANNEL: ${{ (github.event_name == 'release' && !github.event.release.prerelease && 'stable') || (github.event_name == 'workflow_dispatch' && inputs.channel) || 'nightly' }}
+  TAURI_CONF_PATH: ${{ ((github.event_name == 'release' && !github.event.release.prerelease) || (github.event_name == 'workflow_dispatch' && inputs.channel == 'stable')) && './apps/desktop/src-tauri/tauri.conf.stable.json' || './apps/desktop/src-tauri/tauri.conf.nightly.json' }}

This ensures:

  • Normal releases (published without prerelease flag) → 'stable'
  • Pre-releases (published with prerelease flag) → 'nightly'
  • workflow_dispatch with manual input → respects the selected channel
  • Fallback to 'nightly' for other cases

406-406: Upgrade deprecated action to Node 20–compatible version.

softprops/action-gh-release@v1 targets a deprecated Node runtime and is incompatible with current GitHub Actions runners. Update to v2 or another maintained version that supports Node 20.

-        uses: softprops/action-gh-release@v1
+        uses: softprops/action-gh-release@v2

Verify that the inputs and outputs remain compatible with the new version.

🧹 Nitpick comments (1)
.github/workflows/linux_packages_arch.yaml (1)

68-77: Verify null-safety for release event access.

Line 69 accesses github.event.release.tag_name without checking if github.event.release exists. While the job condition at line 29 guards against completely missing releases, it's safer to add explicit null-checks before accessing release properties, especially since release event data may be absent or incomplete under edge cases.

Consider adding a safety check:

  if [[ "${{ github.event_name }}" == "release" ]]; then
+   if [[ -z "${{ github.event.release.tag_name }}" ]]; then
+     echo "Error: Release tag_name is empty"
+     exit 1
+   fi
    TAG_NAME="${{ github.event.release.tag_name }}"
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 10c678e and a0720c7.

📒 Files selected for processing (1)
  • .github/workflows/linux_packages_arch.yaml (1 hunks)
🧰 Additional context used
🪛 actionlint (1.7.8)
.github/workflows/linux_packages_arch.yaml

406-406: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

The Cargo package is named 'desktop', not 'hyprnote', so the compiled
binary is named 'desktop'. Updated the workflow to:
- Look for the 'desktop' binary after cargo build
- Rename it to 'hyprnote' during package installation

This fixes the binary not found error in the Arch Linux packaging.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (2)
.github/workflows/linux_packages_arch.yaml (2)

24-25: Environment variables don't handle release events; stable releases will use nightly configuration.

The RELEASE_CHANNEL and TAURI_CONF_PATH expressions only evaluate workflow_dispatch events. When triggered by a release event (lines 14–17), both variables incorrectly fall back to 'nightly', causing stable releases to use the nightly Tauri configuration instead of the stable one.

Additionally, the workflow declares both published and prereleased release types (lines 16–17), which need different handling: normal releases should use 'stable' while pre-releases should use 'nightly'.

Apply this diff to handle release events and differentiate stable from pre-release builds:

 env:
-  RELEASE_CHANNEL: ${{ github.event_name == 'workflow_dispatch' && inputs.channel || 'nightly' }}
-  TAURI_CONF_PATH: ${{ github.event_name == 'workflow_dispatch' && inputs.channel == 'stable' && './apps/desktop/src-tauri/tauri.conf.stable.json' || './apps/desktop/src-tauri/tauri.conf.nightly.json' }}
+  RELEASE_CHANNEL: ${{ (github.event_name == 'release' && !github.event.release.prerelease && 'stable') || (github.event_name == 'workflow_dispatch' && inputs.channel) || 'nightly' }}
+  TAURI_CONF_PATH: ${{ ((github.event_name == 'release' && !github.event.release.prerelease) || (github.event_name == 'workflow_dispatch' && inputs.channel == 'stable')) && './apps/desktop/src-tauri/tauri.conf.stable.json' || './apps/desktop/src-tauri/tauri.conf.nightly.json' }}

418-418: Upgrade deprecated release action to Node 20–compatible version.

The softprops/action-gh-release@v1 action targets the deprecated Node 16 runtime and will fail on current GitHub Actions runners. Upgrade to v2 (or another maintained Node 20–compatible version) to ensure release uploads succeed.

Apply this diff:

-        uses: softprops/action-gh-release@v1
+        uses: softprops/action-gh-release@v2
🧹 Nitpick comments (1)
.github/workflows/linux_packages_arch.yaml (1)

305-305: Unused environment variable passed to Docker container.

Line 305 exports TAURI_CONF to the container, but the build script does not use this variable. The version extraction at line 66 uses ${{ env.TAURI_CONF_PATH }}, which is expanded by GitHub Actions before the script runs. If TAURI_CONF is not intended for future use, remove it to reduce clutter.

-            -e TAURI_CONF="${{ env.TAURI_CONF_PATH }}" \
             -e PROTOC_ARCH_NAME="$PROTOC_ARCH_NAME" \
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 1e06672 and 5c7791c.

📒 Files selected for processing (1)
  • .github/workflows/linux_packages_arch.yaml (1 hunks)
🧰 Additional context used
🪛 actionlint (1.7.8)
.github/workflows/linux_packages_arch.yaml

418-418: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

Changed from ubuntu-20.04 to ubuntu-22.04 for the AppImage build job.
While ubuntu-20.04 offers better compatibility, ubuntu-22.04 runners
have better availability on GitHub Actions, reducing queue times.
Ubuntu 22.04 needs libsoup-3.0-dev explicitly installed for Tauri v2.
While libwebkit2gtk-4.0-dev provides libsoup-2.4, Tauri requires the
newer libsoup-3.0 API.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ad4735e and da37532.

📒 Files selected for processing (1)
  • .github/workflows/linux_packages.yaml (1 hunks)
🧰 Additional context used
🪛 actionlint (1.7.8)
.github/workflows/linux_packages.yaml

292-292: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


399-399: name is required in action metadata "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)


399-399: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)


412-412: name is required in action metadata "/home/jailuser/git/.github/actions/pnpm_install/action.yaml"

(action)


412-412: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/pnpm_install/action.yaml"

(action)


415-415: name is required in action metadata "/home/jailuser/git/.github/actions/poetry_install/action.yaml"

(action)


415-415: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/poetry_install/action.yaml"

(action)


581-581: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

Comment on lines +23 to +25
env:
RELEASE_CHANNEL: ${{ github.event_name == 'workflow_dispatch' && inputs.channel || 'nightly' }}
TAURI_CONF_PATH: ${{ (github.event_name == 'workflow_dispatch' && inputs.channel == 'stable') && './apps/desktop/src-tauri/tauri.conf.stable.json' || './apps/desktop/src-tauri/tauri.conf.nightly.json' }}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Fix release channel env logic to handle release events.

Release events never match the workflow_dispatch condition, so both RELEASE_CHANNEL and TAURI_CONF_PATH stay on nightly settings. This means actual release builds ship with nightly config instead of stable. Update both expressions to include the release event trigger.

 env:
-  RELEASE_CHANNEL: ${{ github.event_name == 'workflow_dispatch' && inputs.channel || 'nightly' }}
-  TAURI_CONF_PATH: ${{ (github.event_name == 'workflow_dispatch' && inputs.channel == 'stable') && './apps/desktop/src-tauri/tauri.conf.stable.json' || './apps/desktop/src-tauri/tauri.conf.nightly.json' }}
+  RELEASE_CHANNEL: ${{ github.event_name == 'release' && 'stable' || (github.event_name == 'workflow_dispatch' && inputs.channel) || 'nightly' }}
+  TAURI_CONF_PATH: ${{ (github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.channel == 'stable')) && './apps/desktop/src-tauri/tauri.conf.stable.json' || './apps/desktop/src-tauri/tauri.conf.nightly.json' }}
🤖 Prompt for AI Agents
In .github/workflows/linux_packages.yaml around lines 23 to 25, the env
expressions only check for github.event_name == 'workflow_dispatch' so release
events fall back to nightly; update both expressions to also handle the
'release' event by treating a release as stable: set RELEASE_CHANNEL to use
inputs.channel when workflow_dispatch, or to 'stable' when github.event_name ==
'release', otherwise default to 'nightly'; similarly set TAURI_CONF_PATH to use
the stable tauri.conf when inputs.channel == 'stable' or when github.event_name
== 'release', otherwise use the nightly tauri.conf.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (2)
.github/workflows/linux_packages.yaml (2)

23-25: Release events are not handled in env expressions—stable config won't be used on release.

Both RELEASE_CHANNEL and TAURI_CONF_PATH only check workflow_dispatch, so release-triggered workflows fall back to nightly settings. This means actual releases ship with nightly config instead of stable.

Apply this diff to include release event handling:

 env:
-  RELEASE_CHANNEL: ${{ github.event_name == 'workflow_dispatch' && inputs.channel || 'nightly' }}
-  TAURI_CONF_PATH: ${{ (github.event_name == 'workflow_dispatch' && inputs.channel == 'stable') && './apps/desktop/src-tauri/tauri.conf.stable.json' || './apps/desktop/src-tauri/tauri.conf.nightly.json' }}
+  RELEASE_CHANNEL: ${{ github.event_name == 'release' && 'stable' || (github.event_name == 'workflow_dispatch' && inputs.channel) || 'nightly' }}
+  TAURI_CONF_PATH: ${{ (github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.channel == 'stable')) && './apps/desktop/src-tauri/tauri.conf.stable.json' || './apps/desktop/src-tauri/tauri.conf.nightly.json' }}

292-292: Upgrade softprops/action-gh-release from v1 to v2 for Node 20 compatibility.

Both release upload steps use the deprecated softprops/action-gh-release@v1 which targets Node 12 (EOL). This action will fail on current GitHub-hosted runners. Update both to @v2 to ensure .deb and AppImage release uploads succeed.

Apply this diff:

       - name: Upload .deb to release
         if: github.event_name == 'release'
-        uses: softprops/action-gh-release@v1
+        uses: softprops/action-gh-release@v2
         with:
           files: ${{ steps.find-deb.outputs.deb_path }}

And similarly at line 582:

       - name: Upload AppImage to release
         if: github.event_name == 'release'
-        uses: softprops/action-gh-release@v1
+        uses: softprops/action-gh-release@v2
         with:
           files: ${{ steps.find-appimage.outputs.appimage_path }}

Also applies to: 582-582

🧹 Nitpick comments (1)
.github/workflows/linux_packages.yaml (1)

315-315: Commented ARM64 runner uses retired label; fix before re-enabling.

The commented ARM64 entry uses ubuntu-20.04, which GitHub retired and no longer provides. If this ARM64 build is re-enabled in the future, update the runner to ubuntu-24.04 (consistent with build-linux-packages at line 40).

-          #   runner: "ubuntu-20.04"
+          #   runner: "ubuntu-24.04"
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between da37532 and a5461d1.

📒 Files selected for processing (1)
  • .github/workflows/linux_packages.yaml (1 hunks)
🧰 Additional context used
🪛 actionlint (1.7.8)
.github/workflows/linux_packages.yaml

132-132: name is required in action metadata "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)


132-132: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)


145-145: name is required in action metadata "/home/jailuser/git/.github/actions/pnpm_install/action.yaml"

(action)


145-145: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/pnpm_install/action.yaml"

(action)


148-148: name is required in action metadata "/home/jailuser/git/.github/actions/poetry_install/action.yaml"

(action)


148-148: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/poetry_install/action.yaml"

(action)


292-292: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


582-582: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

♻️ Duplicate comments (2)
.github/workflows/linux_packages.yaml (2)

23-25: Fix release event handling in RELEASE_CHANNEL and TAURI_CONF_PATH.

The current expressions only check github.event_name == 'workflow_dispatch', so release-triggered builds incorrectly default to nightly config. This means actual releases ship with nightly settings instead of stable. Both environment variables must also handle the release event to use the stable configuration.

Apply this diff:

 env:
-  RELEASE_CHANNEL: ${{ github.event_name == 'workflow_dispatch' && inputs.channel || 'nightly' }}
-  TAURI_CONF_PATH: ${{ (github.event_name == 'workflow_dispatch' && inputs.channel == 'stable') && './apps/desktop/src-tauri/tauri.conf.stable.json' || './apps/desktop/src-tauri/tauri.conf.nightly.json' }}
+  RELEASE_CHANNEL: ${{ github.event_name == 'release' && 'stable' || (github.event_name == 'workflow_dispatch' && inputs.channel) || 'nightly' }}
+  TAURI_CONF_PATH: ${{ (github.event_name == 'release' || (github.event_name == 'workflow_dispatch' && inputs.channel == 'stable')) && './apps/desktop/src-tauri/tauri.conf.stable.json' || './apps/desktop/src-tauri/tauri.conf.nightly.json' }}

315-315: Update commented ubuntu-20.04 to ubuntu-24.04 for future ARM64 enablement.

The commented-out ARM64 matrix entry on line 315 still references the retired ubuntu-20.04 runner label. When ARM64 cross-compilation is re-enabled, this will cause jobs to queue indefinitely. Update the label to match the active x86_64 entry and the build-linux-packages job.

Apply this diff:

           # ARM64 builds disabled temporarily due to cross-compilation dependency issues
           # - target: "aarch64-unknown-linux-gnu"
           #   arch: "aarch64"
           #   features: "stt-openblas,llm-vulkan"
-          #   runner: "ubuntu-20.04"
+          #   runner: "ubuntu-24.04"
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between a5461d1 and 033b919.

📒 Files selected for processing (1)
  • .github/workflows/linux_packages.yaml (1 hunks)
🧰 Additional context used
🪛 actionlint (1.7.8)
.github/workflows/linux_packages.yaml

132-132: name is required in action metadata "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)


132-132: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/setup_protoc/action.yaml"

(action)


145-145: name is required in action metadata "/home/jailuser/git/.github/actions/pnpm_install/action.yaml"

(action)


145-145: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/pnpm_install/action.yaml"

(action)


148-148: name is required in action metadata "/home/jailuser/git/.github/actions/poetry_install/action.yaml"

(action)


148-148: description is required in metadata of "" action at "/home/jailuser/git/.github/actions/poetry_install/action.yaml"

(action)


292-292: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


579-579: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)


- name: Upload .deb to release
if: github.event_name == 'release'
uses: softprops/action-gh-release@v1
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Upgrade softprops/action-gh-release from v1 to v2.

Both release upload steps use softprops/action-gh-release@v1, which targets the deprecated Node 12 runtime and fails on current GitHub-hosted runners. Update both to @v2 for Node 20 compatibility so release artifact uploads succeed.

Apply this diff:

       - name: Upload .deb to release
         if: github.event_name == 'release'
-        uses: softprops/action-gh-release@v1
+        uses: softprops/action-gh-release@v2
         with:
           files: ${{ steps.find-deb.outputs.deb_path }}
         env:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
 
       ...
 
       - name: Upload AppImage to release
         if: github.event_name == 'release'
-        uses: softprops/action-gh-release@v1
+        uses: softprops/action-gh-release@v2
         with:
           files: ${{ steps.find-appimage.outputs.appimage_path }}
         env:
           GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}

Also applies to: 579-579

🧰 Tools
🪛 actionlint (1.7.8)

292-292: the runner of "softprops/action-gh-release@v1" action is too old to run on GitHub Actions. update the action's version to fix this issue

(action)

🤖 Prompt for AI Agents
.github/workflows/linux_packages.yaml around lines 292 and 579: both steps use
softprops/action-gh-release@v1 which targets deprecated Node 12 and fails on
current runners; update each occurrence to softprops/action-gh-release@v2
(replace @v1 with @v2) so the action runs on Node 20-compatible runtime and
artifact uploads succeed.

PythonTilk and others added 2 commits November 14, 2025 23:21
…ation

- Add foreign key constraint to contacts table with CASCADE delete
- Improve error handling in whisper-local example (remove unwrap, use expect)
- Enhance LinuxInstallNotes.md with pnpm prerequisites, xhost security warnings, and professional tone
- Fix misleading comment in audio test binary
- Correct count mismatch (two -> three systems)
fix: address CodeRabbit review findings for code quality and document…
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
LinuxInstallNotes.md (1)

70-76: Consider moving xhost configuration to a troubleshooting section.

The xhost command is only needed for specific scenarios (container environments, privileged execution) and not for typical Linux desktop development. Placing it in the main setup flow may cause unnecessary configuration and confuse users about whether it's required.

Consider moving this section to a "Troubleshooting" or "Advanced Setup" section with clearer context about when it's needed:

-# access the X Window System display without authentication
-# WARNING: This relaxes X server access control for the current local user
-# Only use when running GUI apps that require X11 access (e.g., from containers/sudo)
-# Security: Grants local user processes GUI access; avoid on multi-user systems
-# Revoke after use with: xhost -SI:localuser:$USER
-# Alternative: Use Xauthority forwarding or run without privilege escalation
-xhost +SI:localuser:$USER

 # add virtual echo-cancel source to allow shared access
 pactl load-module module-echo-cancel

Then add a new "Troubleshooting" section with:

## Troubleshooting

### X11 Access Issues (Container/Sudo)
If running the application in a container or with privilege escalation and GUI windows fail to appear:
\`\`\`bash
xhost +SI:localuser:$USER
\`\`\`
⚠️ Warning: This relaxes X server access control. Revoke after use with: `xhost -SI:localuser:$USER`
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 033b919 and ad51002.

📒 Files selected for processing (4)
  • LinuxInstallNotes.md (1 hunks)
  • crates/audio/src/bin/test_friendly_names.rs (1 hunks)
  • crates/db-user/src/contacts_migration.sql (1 hunks)
  • crates/whisper-local/examples/test_model.rs (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • crates/whisper-local/examples/test_model.rs
  • crates/audio/src/bin/test_friendly_names.rs
  • crates/db-user/src/contacts_migration.sql
🔇 Additional comments (3)
LinuxInstallNotes.md (3)

87-88: Verify turbo syntax for passing feature flags to underlying build tasks.

The syntax turbo -F @hypr/desktop tauri:dev --features local-llm,local-stt may not correctly pass the --features flag to the Cargo build. Turbo typically requires -- to forward flags to underlying commands.

Please confirm the correct syntax for your monorepo setup. The command likely should be:

-turbo -F @hypr/desktop tauri:dev --features local-llm,local-stt
+turbo -F @hypr/desktop tauri:dev -- --features local-llm,local-stt

If the current syntax works with your turbo configuration, no change is needed. Otherwise, verify and update accordingly.


5-32: Feature claims align well with PR scope and implementation status.

The production-ready feature descriptions (Speaker Audio Capture, Notification System, Autostart Support) are consistent with the PR objectives and author's testing reports. No concerns with the accuracy or specificity of claims in this section.


34-89: Installation guide is well-structured and comprehensive.

The documentation provides clear progressive disclosure from toolchain setup through system dependencies, optional features, and build commands. Good separation between required (audio, notifications) and optional (ML features) components.

curl https://sh.rustup.rs -sSf | sh

# system dependencies for tauri
sudo apt install libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev patchel libclang-dev libxss-dev
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

Fix package name typo that will break installation.

Line 45 contains patchel which is not a valid Debian/Ubuntu package name. This will cause apt install to fail. The intended package is likely patchelf (if ELF patching is needed for Tauri) or patch (if needed for build system).

Assuming patchelf is the intended package:

-sudo apt install libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev patchel libclang-dev libxss-dev
+sudo apt install libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev patchelf libclang-dev libxss-dev

If this dependency is not needed for the build, it can be removed entirely.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
sudo apt install libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev patchel libclang-dev libxss-dev
sudo apt install libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev patchelf libclang-dev libxss-dev
🤖 Prompt for AI Agents
In LinuxInstallNotes.md around line 45, the package list contains a typo
"patchel" which is not a valid Debian package; replace "patchel" with the
correct package name (likely "patchelf" for ELF patching or "patch" if only
patch utility is needed), or remove it entirely if that dependency is
unnecessary for the build; update the apt install line accordingly and verify
installation works.

Comment on lines +78 to +79
# add virtual echo-cancel source to allow shared access
pactl load-module module-echo-cancel
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Clarify that PulseAudio module loading is temporary and session-based.

The pactl load-module module-echo-cancel command only persists for the current PulseAudio session and will need to be rerun after logout/reboot or daemon restart. Users following this setup guide may expect it to be permanent after running once, leading to confusion when echo cancellation doesn't work later.

Revise the comment to clarify the temporary nature:

 # add virtual echo-cancel source to allow shared access
-pactl load-module module-echo-cancel
+# Note: This command loads the module only for the current session and must be re-run after logout/reboot
+# For persistent configuration, add to ~/.config/pulse/default.pa or system-wide /etc/pulse/default.pa
+pactl load-module module-echo-cancel

Alternatively, if this should be a persistent setup step, provide instructions for adding it to PulseAudio's configuration files.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
# add virtual echo-cancel source to allow shared access
pactl load-module module-echo-cancel
# add virtual echo-cancel source to allow shared access
# Note: This command loads the module only for the current session and must be re-run after logout/reboot
# For persistent configuration, add to ~/.config/pulse/default.pa or system-wide /etc/pulse/default.pa
pactl load-module module-echo-cancel
🤖 Prompt for AI Agents
In LinuxInstallNotes.md around lines 78-79, clarify that `pactl load-module
module-echo-cancel` is temporary and only lasts for the current PulseAudio
session, so users must rerun it after logout/reboot or a PulseAudio restart;
update the text to state this explicitly and offer the persistent alternative by
instructing users to add `load-module module-echo-cancel` to their PulseAudio
config (e.g., ~/.config/pulse/default.pa for a per-user persistent change or
/etc/pulse/default.pa for a system-wide change) and to restart PulseAudio (or
the user session) after editing the config.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants