Skip to content

fix: resolve Windows build issues with macOS permissions #26

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
150 changes: 150 additions & 0 deletions .github/workflows/build-windows.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
name: Build Windows App

on:
push:
branches:
- main
- 'feature/**'
paths-ignore:
- '.github/**'
- '!.github/workflows/build-windows.yml'
pull_request:
branches:
- main
workflow_dispatch:

permissions:
contents: write

jobs:
build:
name: Build Windows App
runs-on: windows-latest
strategy:
matrix:
arch: [x64]

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.3'
extensions: mbstring, xml, ctype, iconv, intl, pdo_sqlite, dom, filter, gd, json, mbstring, pdo
tools: composer:v2
coverage: none

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: '22'

- name: Get version
id: version
shell: bash
run: |
VERSION=$(grep "'version' =>" config/nativephp.php | sed -E "s/.*'([0-9]+\.[0-9]+\.[0-9]+)'.*/\1/")
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT
echo "Building version: $VERSION"

- name: Cache Composer dependencies
uses: actions/cache@v4
with:
path: vendor
key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: |
${{ runner.os }}-composer-

- name: Install Composer dependencies
run: composer install --no-interaction --no-dev --prefer-dist --optimize-autoloader

- name: Clean npm cache and node_modules
shell: cmd
run: |
if exist node_modules rmdir /s /q node_modules
if exist package-lock.json del package-lock.json
npm cache clean --force

- name: Install NPM dependencies (Windows-specific)
shell: cmd
run: |
echo Installing npm dependencies for Windows...
npm install --omit=dev --no-optional
echo Dependencies installed successfully

- name: Copy .env file
run: cp .env.example .env

- name: Generate application key
run: php artisan key:generate

- name: Build frontend assets
run: npm run build

- name: Generate Ziggy routes
run: php artisan ziggy:generate

- name: Install Electron dependencies
working-directory: vendor/nativephp/electron/resources/js
shell: cmd
run: |
if exist node_modules rmdir /s /q node_modules
npm install --no-optional

- name: Rebuild Electron native modules
working-directory: vendor/nativephp/electron/resources/js
run: npx electron-rebuild

- name: Build NativePHP application
env:
NATIVEPHP_APP_VERSION: ${{ steps.version.outputs.VERSION }}
run: |
php artisan native:build win ${{ matrix.arch }}

- name: Upload artifacts
uses: actions/upload-artifact@v4
with:
name: Clueless-${{ steps.version.outputs.VERSION }}-win-${{ matrix.arch }}
path: dist/*.exe
retention-days: 5

release:
name: Create Windows Release
needs: build
runs-on: ubuntu-latest
if: github.event_name == 'push' && github.ref == 'refs/heads/main'

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Get version
id: version
run: |
VERSION=$(grep "'version' =>" config/nativephp.php | sed -E "s/.*'([0-9]+\.[0-9]+\.[0-9]+)'.*/\1/")
echo "VERSION=$VERSION" >> $GITHUB_OUTPUT

- name: Download x64 artifact
uses: actions/download-artifact@v4
with:
name: Clueless-${{ steps.version.outputs.VERSION }}-win-x64
path: ./artifacts/win-x64

- name: Upload Windows Release Assets
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
# Find the existing release for v${{ steps.version.outputs.VERSION }}
RELEASE_ID=$(gh api repos/${{ github.repository }}/releases/tags/v${{ steps.version.outputs.VERSION }} --jq '.id' || echo "")

if [ -z "$RELEASE_ID" ]; then
echo "No release found for v${{ steps.version.outputs.VERSION }}. Windows build will be added when release is created."
exit 0
fi

# Upload the Windows executables
gh release upload v${{ steps.version.outputs.VERSION }} \
./artifacts/win-x64/Clueless-${{ steps.version.outputs.VERSION }}-win-x64.exe \
--clobber
40 changes: 40 additions & 0 deletions app/Http/Controllers/ConversationController.php
Original file line number Diff line number Diff line change
Expand Up @@ -282,4 +282,44 @@ public function destroy(ConversationSession $session)
return redirect()->route('conversations.index')
->with('message', 'Conversation deleted successfully');
}

/**
* Update recording information for a conversation session.
*/
public function updateRecording(ConversationSession $session, Request $request)
{
// No auth check needed for single-user desktop app

$validated = $request->validate([
'has_recording' => 'required|boolean',
'recording_path' => 'required|string',
'recording_duration' => 'required|integer|min:0',
'recording_size' => 'required|integer|min:0',
]);

// Validate that the recording file actually exists
if ($validated['has_recording'] && $validated['recording_path']) {
if (!file_exists($validated['recording_path'])) {
return response()->json([
'message' => 'Recording file not found at specified path',
], 422);
}

// Verify file size matches
$actualSize = filesize($validated['recording_path']);
if ($actualSize !== $validated['recording_size']) {
\Log::warning('Recording file size mismatch', [
'session_id' => $session->id,
'expected_size' => $validated['recording_size'],
'actual_size' => $actualSize,
]);
}
}

$session->update($validated);

return response()->json([
'message' => 'Recording information updated successfully',
]);
}
}
7 changes: 7 additions & 0 deletions app/Models/ConversationSession.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ class ConversationSession extends Model
'total_action_items',
'ai_summary',
'user_notes',
'has_recording',
'recording_path',
'recording_duration',
'recording_size',
];

protected $casts = [
Expand All @@ -42,6 +46,9 @@ class ConversationSession extends Model
'total_topics' => 'integer',
'total_commitments' => 'integer',
'total_action_items' => 'integer',
'has_recording' => 'boolean',
'recording_duration' => 'integer',
'recording_size' => 'integer',
];

public function user(): BelongsTo
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::table('conversation_sessions', function (Blueprint $table) {
$table->boolean('has_recording')->default(false)->after('ended_at');
$table->string('recording_path')->nullable()->after('has_recording');
$table->integer('recording_duration')->nullable()->comment('Duration in seconds')->after('recording_path');
$table->bigInteger('recording_size')->nullable()->comment('Size in bytes')->after('recording_duration');
});
}

/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::table('conversation_sessions', function (Blueprint $table) {
$table->dropColumn(['has_recording', 'recording_path', 'recording_duration', 'recording_size']);
});
}
};
Loading
Loading