Skip to content
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

feat: goose windows #880

Merged
merged 38 commits into from
Feb 10, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
cd00d1c
release rust executables for windows
Kvadratni Jan 29, 2025
b1cc50e
add windows support in computer controller
Kvadratni Jan 29, 2025
86e4ebc
possible UI app for Windows
Kvadratni Jan 29, 2025
70d9bc0
add powershell support for just
Kvadratni Jan 29, 2025
616339d
added just run-ui-windows
Kvadratni Jan 29, 2025
9ae426b
Update Justfile
Kvadratni Jan 30, 2025
c43e798
modified process spawning for electron
Kvadratni Jan 30, 2025
48ab7d5
fixed credential management for windows
Kvadratni Jan 30, 2025
c195a2c
Add Windows build support and extensive logging for cross-compilation
Kvadratni Jan 30, 2025
f6abb82
fix no window frame on windows
Kvadratni Jan 30, 2025
0ec676a
fmt
Kvadratni Jan 30, 2025
0ec75a2
build fixes
Kvadratni Jan 31, 2025
c905882
build fixes + kill fixes
Kvadratni Jan 31, 2025
6a1bd43
build fixes + kill fixes
Kvadratni Jan 31, 2025
49473b3
revert credential changes for base
Kvadratni Jan 31, 2025
3e6b916
fix just file for powershell
Kvadratni Jan 31, 2025
8c5af0d
persistent cache for windows builds
Kvadratni Feb 1, 2025
3867f2c
fix ` Error storing extension config: TypeError: window.electron.send…
Kvadratni Feb 1, 2025
febb30a
hide terminal on windows
Kvadratni Feb 1, 2025
edb6444
fix env var for windows
Kvadratni Feb 2, 2025
2797fd7
shell platform developer extension
Kvadratni Feb 3, 2025
7c1fd3a
attempt to fix windows ui
Kvadratni Feb 4, 2025
9e6bcda
ditch router to fix the UI
Kvadratni Feb 4, 2025
f59bc6d
fix github
Kvadratni Feb 4, 2025
30eacc6
add windows build comment to PR
Kvadratni Feb 5, 2025
3710290
update tool use preference for windows
Kvadratni Feb 5, 2025
2dcb3f2
address comments
Kvadratni Feb 5, 2025
bb918e4
separate windows and macos prompts
Kvadratni Feb 5, 2025
cb229f2
fix rebase errors
Kvadratni Feb 6, 2025
e618662
fix issue with listing dir
Kvadratni Feb 6, 2025
f73aa4b
hide extension windows on windows
Kvadratni Feb 6, 2025
1a47b5a
fix deeplinks
Kvadratni Feb 6, 2025
1c8da79
some mandatory resources
Kvadratni Feb 7, 2025
6f7b338
fix uvx (requires manual install)
Kvadratni Feb 8, 2025
04d4d0a
added windows specific uvx npx
Kvadratni Feb 8, 2025
fc9d771
added windows specific uvx npx
Kvadratni Feb 8, 2025
8fff517
fix uvx shim
Kvadratni Feb 8, 2025
8877d1d
comment windows release out
Kvadratni Feb 10, 2025
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
14 changes: 12 additions & 2 deletions .github/workflows/build-cli.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand All @@ -60,12 +62,20 @@ jobs:
- name: Build CLI
env:
CROSS_NO_WARNINGS: 0
RUST_LOG: debug
Copy link
Collaborator

Choose a reason for hiding this comment

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

were these left for testing? or do we want them here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

helps to find issues

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
Copy link
Collaborator

Choose a reason for hiding this comment

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

same question as above - probably wanna remove these?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I don't think this is revealing anything bad but helps debug


# '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
Expand Down
157 changes: 157 additions & 0 deletions .github/workflows/bundle-desktop-windows.yml
Original file line number Diff line number Diff line change
@@ -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"
Copy link
Collaborator

Choose a reason for hiding this comment

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

Can this be done without the hard coded version? Will this change underneath the CI process when that updates?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

WDYM? This is for CI only

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

oh you mean the version of the signtool. yeah it's a good question. I'm not great at github actions

& $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/
18 changes: 1 addition & 17 deletions .github/workflows/bundle-desktop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Copy link
Collaborator

Choose a reason for hiding this comment

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

why was this removed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

because once I removed react router - this log is not generated anymore, so no way to test this reliably

# 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"
22 changes: 19 additions & 3 deletions .github/workflows/pr-comment-bundle-desktop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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.
15 changes: 14 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
# ------------------------------------
Expand Down
7 changes: 6 additions & 1 deletion Cross.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ pre-build = [
libxcb1-dev:arm64
"""
]
env = { PKG_CONFIG_PATH = "/usr/lib/aarch64-linux-gnu/pkgconfig" }
Copy link
Collaborator

Choose a reason for hiding this comment

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

why was this removed? is it actually not needed?

Copy link
Collaborator

Choose a reason for hiding this comment

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


[target.x86_64-unknown-linux-gnu]
xargo = false
Expand All @@ -27,3 +26,9 @@ pre-build = [
libxcb1-dev \
"""
]

[target.x86_64-pc-windows-gnu]
image = "dockcross/windows-static-x64:latest"
# Enable verbose output for Windows builds
build-std = true
env = { "RUST_LOG" = "debug", "RUST_BACKTRACE" = "1", "CROSS_VERBOSE" = "1" }
63 changes: 63 additions & 0 deletions Justfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,31 @@ release-binary:
cargo build --release
@just copy-binary

# Build Windows executable
release-windows:
#!/usr/bin/env sh
if [ "$(uname)" = "Darwin" ] || [ "$(uname)" = "Linux" ]; then
echo "Building Windows executable using Docker..."
docker volume create goose-windows-cache || true
docker run --rm \
-v "$(pwd)":/usr/src/myapp \
-v goose-windows-cache:/usr/local/cargo/registry \
-w /usr/src/myapp \
rust:latest \
sh -c "rustup target add x86_64-pc-windows-gnu && \
apt-get update && \
apt-get install -y mingw-w64 && \
cargo build --release --target x86_64-pc-windows-gnu && \
GCC_DIR=\$(ls -d /usr/lib/gcc/x86_64-w64-mingw32/*/ | head -n 1) && \
cp \$GCC_DIR/libstdc++-6.dll /usr/src/myapp/target/x86_64-pc-windows-gnu/release/ && \
cp \$GCC_DIR/libgcc_s_seh-1.dll /usr/src/myapp/target/x86_64-pc-windows-gnu/release/ && \
cp /usr/x86_64-w64-mingw32/lib/libwinpthread-1.dll /usr/src/myapp/target/x86_64-pc-windows-gnu/release/"
else
echo "Building Windows executable using Docker through PowerShell..."
powershell.exe -Command "docker volume create goose-windows-cache; docker run --rm -v ${PWD}:/usr/src/myapp -v goose-windows-cache:/usr/local/cargo/registry -w /usr/src/myapp rust:latest sh -c 'rustup target add x86_64-pc-windows-gnu && apt-get update && apt-get install -y mingw-w64 && cargo build --release --target x86_64-pc-windows-gnu && GCC_DIR=\$(ls -d /usr/lib/gcc/x86_64-w64-mingw32/*/ | head -n 1) && cp \$GCC_DIR/libstdc++-6.dll /usr/src/myapp/target/x86_64-pc-windows-gnu/release/ && cp \$GCC_DIR/libgcc_s_seh-1.dll /usr/src/myapp/target/x86_64-pc-windows-gnu/release/ && cp /usr/x86_64-w64-mingw32/lib/libwinpthread-1.dll /usr/src/myapp/target/x86_64-pc-windows-gnu/release/'"
Copy link
Collaborator

Choose a reason for hiding this comment

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

What's happening here? 😃 Please help me understand lol. Might be easier to make a script and call that

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

essentially I added this to build it on docker as I could not compile windows executable on my mac.
This does the windows specific build + copy of required dll's
I tried extracting to a separate script, but it broke so many times I gave up for now.

fi
echo "Windows executable and required DLLs created at ./target/x86_64-pc-windows-gnu/release/"

# Copy binary command
copy-binary:
@if [ -f ./target/release/goosed ]; then \
Expand All @@ -20,12 +45,30 @@ copy-binary:
exit 1; \
fi

# Copy Windows binary command
copy-binary-windows:
@powershell.exe -Command "if (Test-Path ./target/x86_64-pc-windows-gnu/release/goosed.exe) { \
Write-Host 'Copying Windows binary and DLLs to ui/desktop/src/bin...'; \
Copy-Item -Path './target/x86_64-pc-windows-gnu/release/goosed.exe' -Destination './ui/desktop/src/bin/' -Force; \
Copy-Item -Path './target/x86_64-pc-windows-gnu/release/*.dll' -Destination './ui/desktop/src/bin/' -Force; \
} else { \
Write-Host 'Windows binary not found.' -ForegroundColor Red; \
exit 1; \
}"

# Run UI with latest
run-ui:
@just release-binary
@echo "Running UI..."
cd ui/desktop && npm install && npm run start-gui

# Run UI with latest (Windows version)
run-ui-windows:
@just release-windows
@powershell.exe -Command "Write-Host 'Copying Windows binary...'"
@just copy-binary-windows
@powershell.exe -Command "Write-Host 'Running UI...'; Set-Location ui/desktop; npm install; npm run start-gui"

# Run Docusaurus server for documentation
run-docs:
@echo "Running docs server..."
Expand All @@ -41,6 +84,26 @@ make-ui:
@just release-binary
cd ui/desktop && npm run bundle:default

# make GUI with latest Windows binary
make-ui-windows:
@just release-windows
#!/usr/bin/env sh
if [ -f "./target/x86_64-pc-windows-gnu/release/goosed.exe" ]; then \
echo "Copying Windows binary and DLLs to ui/desktop/src/bin..."; \
mkdir -p ./ui/desktop/src/bin; \
cp -f ./target/x86_64-pc-windows-gnu/release/goosed.exe ./ui/desktop/src/bin/; \
cp -f ./target/x86_64-pc-windows-gnu/release/*.dll ./ui/desktop/src/bin/; \
echo "Building Windows package..."; \
cd ui/desktop && \
npm run bundle:windows && \
mkdir -p out/Goose-win32-x64/resources/bin && \
cp -f src/bin/goosed.exe out/Goose-win32-x64/resources/bin/ && \
cp -f src/bin/*.dll out/Goose-win32-x64/resources/bin/; \
else \
echo "Windows binary not found."; \
exit 1; \
fi

# Setup langfuse server
langfuse-server:
#!/usr/bin/env bash
Expand Down
Loading
Loading