feat: goose windows (#880)

Co-authored-by: Ryan Versaw <ryan@versaw.com>
This commit is contained in:
Max Novich
2025-02-10 15:05:13 -08:00
committed by GitHub
parent 98aecbef23
commit cfd3ee8fd9
43 changed files with 1327 additions and 456 deletions

View File

@@ -15,7 +15,7 @@ on:
operating-systems:
type: string
required: false
default: '["ubuntu-latest","macos-latest"]'
default: '["ubuntu-latest","macos-latest","windows-latest"]'
architectures:
type: string
required: false
@@ -37,6 +37,8 @@ jobs:
target-suffix: unknown-linux-gnu
- os: macos-latest
target-suffix: apple-darwin
- os: windows-latest
target-suffix: pc-windows-gnu
steps:
- name: Checkout code
@@ -60,12 +62,20 @@ jobs:
- name: Build CLI
env:
CROSS_NO_WARNINGS: 0
RUST_LOG: debug
RUST_BACKTRACE: 1
CROSS_VERBOSE: 1
run: |
export TARGET="${{ matrix.architecture }}-${{ matrix.target-suffix }}"
rustup target add "${TARGET}"
echo "Building for target: ${TARGET}"
echo "Rust toolchain info:"
rustup show
echo "Cross version:"
cross --version
# 'cross' is used to cross-compile for different architectures (see Cross.toml)
cross build --release --target ${TARGET} -p goose-cli
cross build --release --target ${TARGET} -p goose-cli -vv
# tar the goose binary as goose-<TARGET>.tar.bz2
cd target/${TARGET}/release

View File

@@ -0,0 +1,157 @@
name: "Bundle Desktop (Windows)"
on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
workflow_call:
inputs:
signing:
description: 'Whether to sign the Windows executable'
required: false
type: boolean
default: false
secrets:
WINDOWS_CERTIFICATE:
required: false
WINDOWS_CERTIFICATE_PASSWORD:
required: false
jobs:
build-desktop-windows:
name: Build Desktop (Windows)
runs-on: windows-latest
steps:
# 1) Check out source
- name: Checkout repository
uses: actions/checkout@v3
# 2) Set up Rust
- name: Set up Rust
uses: dtolnay/rust-toolchain@stable
# If you need a specific version, you could do:
# or uses: actions/setup-rust@v1
# with:
# rust-version: 1.73.0
# 3) Set up Node.js
- name: Set up Node.js
uses: actions/setup-node@v3
with:
node-version: 16
# 4) Cache dependencies (optional, can add more paths if needed)
- name: Cache node_modules
uses: actions/cache@v3
with:
path: |
node_modules
ui/desktop/node_modules
key: ${{ runner.os }}-build-desktop-windows-${{ hashFiles('**/package-lock.json') }}
restore-keys: |
${{ runner.os }}-build-desktop-windows-
# 5) Install top-level dependencies if a package.json is in root
- name: Install top-level deps
run: |
if (Test-Path package.json) {
npm install
}
# 6) Build rust for x86_64-pc-windows-gnu
- name: Install MinGW dependencies
run: |
choco install mingw --version=8.1.0
# Debug - check installation paths
Write-Host "Checking MinGW installation..."
Get-ChildItem -Path "C:\ProgramData\chocolatey\lib\mingw" -Recurse -Filter "*.dll" | ForEach-Object {
Write-Host $_.FullName
}
Get-ChildItem -Path "C:\tools" -Recurse -Filter "*.dll" | ForEach-Object {
Write-Host $_.FullName
}
- name: Cargo build for Windows
run: |
cargo build --release --target x86_64-pc-windows-gnu
# 7) Check that the compiled goosed.exe exists and copy exe/dll to ui/desktop/src/bin
- name: Prepare Windows binary and DLLs
run: |
if (!(Test-Path .\target\x86_64-pc-windows-gnu\release\goosed.exe)) {
Write-Error "Windows binary not found."; exit 1;
}
Write-Host "Copying Windows binary and DLLs to ui/desktop/src/bin..."
if (!(Test-Path ui\desktop\src\bin)) {
New-Item -ItemType Directory -Path ui\desktop\src\bin | Out-Null
}
Copy-Item .\target\x86_64-pc-windows-gnu\release\goosed.exe ui\desktop\src\bin\
# Copy MinGW DLLs - try both possible locations
$mingwPaths = @(
"C:\ProgramData\chocolatey\lib\mingw\tools\install\mingw64\bin",
"C:\tools\mingw64\bin"
)
foreach ($path in $mingwPaths) {
if (Test-Path "$path\libstdc++-6.dll") {
Write-Host "Found MinGW DLLs in $path"
Copy-Item "$path\libstdc++-6.dll" ui\desktop\src\bin\
Copy-Item "$path\libgcc_s_seh-1.dll" ui\desktop\src\bin\
Copy-Item "$path\libwinpthread-1.dll" ui\desktop\src\bin\
break
}
}
# Copy any other DLLs from the release directory
ls .\target\x86_64-pc-windows-gnu\release\*.dll | ForEach-Object {
Copy-Item $_ ui\desktop\src\bin\
}
# 8) Install & build UI desktop
- name: Build desktop UI with npm
run: |
cd ui\desktop
npm install
npm run bundle:windows
# 9) Copy exe/dll to final out/Goose-win32-x64/resources/bin
- name: Copy exe/dll to out folder
run: |
cd ui\desktop
if (!(Test-Path .\out\Goose-win32-x64\resources\bin)) {
New-Item -ItemType Directory -Path .\out\Goose-win32-x64\resources\bin | Out-Null
}
Copy-Item .\src\bin\goosed.exe .\out\Goose-win32-x64\resources\bin\
ls .\src\bin\*.dll | ForEach-Object {
Copy-Item $_ .\out\Goose-win32-x64\resources\bin\
}
# 10) Code signing (if enabled)
- name: Sign Windows executable
# Skip this step by default - enable when we have a certificate
if: inputs.signing && inputs.signing == true
env:
WINDOWS_CERTIFICATE: ${{ secrets.WINDOWS_CERTIFICATE }}
WINDOWS_CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }}
run: |
# Create a temporary certificate file
$certBytes = [Convert]::FromBase64String($env:WINDOWS_CERTIFICATE)
$certPath = Join-Path -Path $env:RUNNER_TEMP -ChildPath "certificate.pfx"
[IO.File]::WriteAllBytes($certPath, $certBytes)
# Sign the main executable
$signtool = "C:\Program Files (x86)\Windows Kits\10\bin\10.0.17763.0\x64\signtool.exe"
& $signtool sign /f $certPath /p $env:WINDOWS_CERTIFICATE_PASSWORD /tr http://timestamp.digicert.com /td sha256 /fd sha256 "ui\desktop\out\Goose-win32-x64\Goose.exe"
# Clean up the certificate
Remove-Item -Path $certPath
# 11) Upload the final Windows build
- name: Upload Windows build artifacts
uses: actions/upload-artifact@v4
with:
name: desktop-windows-dist
path: ui/desktop/out/Goose-win32-x64/

View File

@@ -201,21 +201,5 @@ jobs:
echo "App did not stay open. Possible crash or startup error."
exit 1
fi
LOGFILE="$HOME/Library/Application Support/Goose/logs/main.log"
# Print the log and verify "ChatWindow loaded" is in the logs
if [ -f "$LOGFILE" ]; then
echo "===== Log file contents ====="
cat "$LOGFILE"
echo "============================="
if grep -F "ChatWindow loaded" "$LOGFILE"; then
echo "Confirmed: 'ChatWindow loaded' found in logs!"
else
echo "Did not find 'ChatWindow loaded' in logs. Failing..."
exit 1
fi
else
echo "No log file found at $LOGFILE. Exiting with failure."
exit 1
fi
# Kill the app to clean up
pkill -f "Goose.app/Contents/MacOS/Goose"
pkill -f "Goose.app/Contents/MacOS/Goose"

View File

@@ -51,10 +51,21 @@ jobs:
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
bundle-desktop-windows:
# Only run this if ".bundle" command is detected.
needs: [trigger-on-command]
if: ${{ needs.trigger-on-command.outputs.continue == 'true' }}
uses: ./.github/workflows/bundle-desktop-windows.yml
with:
signing: true
secrets:
WINDOWS_CERTIFICATE: ${{ secrets.WINDOWS_CERTIFICATE }}
WINDOWS_CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }}
pr-comment:
name: PR Comment with Desktop App
runs-on: ubuntu-latest
needs: [trigger-on-command, bundle-desktop]
needs: [trigger-on-command, bundle-desktop, bundle-desktop-windows]
permissions:
pull-requests: write
@@ -71,10 +82,15 @@ jobs:
body: |
### Desktop App for this PR
The following build is available for testing:
The following builds are available for testing:
- [📱 macOS Desktop App (arm64, signed)](https://nightly.link/${{ github.repository }}/actions/runs/${{ github.run_id }}/Goose-darwin-arm64.zip)
- [🪟 Windows Desktop App (x64, signed)](https://nightly.link/${{ github.repository }}/actions/runs/${{ github.run_id }}/desktop-windows-dist.zip)
**macOS Instructions:**
After downloading, unzip the file and drag the Goose.app to your Applications folder. The app is signed and notarized for macOS.
This link is provided by nightly.link and will work even if you're not logged into GitHub.
**Windows Instructions:**
After downloading, unzip the file and run Goose.exe. The app is signed for Windows.
These links are provided by nightly.link and will work even if you're not logged into GitHub.

View File

@@ -33,7 +33,7 @@ jobs:
path: download_cli.sh
# ------------------------------------------------------------
# 3) Bundle Desktop App (macOS only)
# 3) Bundle Desktop App (macOS)
# ------------------------------------------------------------
bundle-desktop:
uses: ./.github/workflows/bundle-desktop.yml
@@ -46,6 +46,19 @@ jobs:
APPLE_ID_PASSWORD: ${{ secrets.APPLE_ID_PASSWORD }}
APPLE_TEAM_ID: ${{ secrets.APPLE_TEAM_ID }}
# # ------------------------------------------------------------
# # 4) Bundle Desktop App (Windows)
# # ------------------------------------------------------------
# bundle-desktop-windows:
# uses: ./.github/workflows/bundle-desktop-windows.yml
# # Signing is disabled by default until we have a certificate
# with:
# signing: false
# # Uncomment and configure these when we have a certificate:
# # secrets:
# # WINDOWS_CERTIFICATE: ${{ secrets.WINDOWS_CERTIFICATE }}
# # WINDOWS_CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }}
# ------------------------------------
# 4) Create/Update GitHub Release
# ------------------------------------