diff --git a/.github/workflows/build-cli.yml b/.github/workflows/build-cli.yml index 5349b27e44..17c9d27abd 100644 --- a/.github/workflows/build-cli.yml +++ b/.github/workflows/build-cli.yml @@ -31,36 +31,44 @@ jobs: fail-fast: false matrix: include: - # Linux builds - os: ubuntu-latest architecture: x86_64 target-suffix: unknown-linux-gnu build-on: ubuntu-latest use-cross: true cc: gcc-10 + variant: standard - os: ubuntu-latest architecture: aarch64 target-suffix: unknown-linux-gnu build-on: ubuntu-latest use-cross: true cc: gcc-10 - # macOS builds + variant: standard - os: macos-latest architecture: x86_64 target-suffix: apple-darwin build-on: macos-latest use-cross: true + variant: standard - os: macos-latest architecture: aarch64 target-suffix: apple-darwin build-on: macos-latest use-cross: true - # Windows builds (only x86_64 supported) + variant: standard - os: windows architecture: x86_64 target-suffix: pc-windows-msvc build-on: windows-latest use-cross: false + variant: standard + - os: windows + architecture: x86_64 + target-suffix: pc-windows-msvc + build-on: windows-latest + use-cross: false + variant: cuda steps: - name: Checkout code @@ -89,7 +97,7 @@ jobs: if: matrix.os == 'windows' uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2.8.2 with: - key: windows-msvc-cli + key: windows-msvc-cli-${{ matrix.variant }} - name: Build CLI (Linux/macOS) if: matrix.use-cross @@ -118,21 +126,54 @@ jobs: rustup show rustup target add x86_64-pc-windows-msvc + - name: Install CUDA toolkit (Windows CUDA) + if: ${{ matrix.os == 'windows' && matrix.variant == 'cuda' }} + uses: Jimver/cuda-toolkit@v0.2.35 + with: + cuda: '12.9.1' + method: 'local' + log-file-suffix: 'build-cli-windows-cuda.txt' + + - name: Set up MSVC developer environment (Windows CUDA) + if: ${{ matrix.os == 'windows' && matrix.variant == 'cuda' }} + uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0 + with: + arch: amd64 + + - name: Verify CUDA toolchain (Windows CUDA) + if: ${{ matrix.os == 'windows' && matrix.variant == 'cuda' }} + shell: pwsh + env: + CUDA_COMPUTE_CAP: "80" + run: | + Write-Output "CUDA_PATH=$env:CUDA_PATH" + Write-Output "CUDA_COMPUTE_CAP=$env:CUDA_COMPUTE_CAP" + where.exe cl + where.exe nvcc + nvcc -V + - name: Build CLI (Windows) if: matrix.os == 'windows' - shell: bash + shell: pwsh + env: + CUDA_COMPUTE_CAP: ${{ matrix.variant == 'cuda' && '80' || '' }} run: | - echo "🚀 Building Windows CLI executable..." - cargo build --release --target x86_64-pc-windows-msvc -p goose-cli + Write-Output "Building Windows CLI executable..." + if ("${{ matrix.variant }}" -eq "cuda") { + $cudaRustflagsConfig = 'target.x86_64-pc-windows-msvc.rustflags=["-C","target-feature=+crt-static"]' + cargo build --config $cudaRustflagsConfig --release --target x86_64-pc-windows-msvc -p goose-cli --features cuda + } else { + cargo build --release --target x86_64-pc-windows-msvc -p goose-cli + } - if [ ! -f "./target/x86_64-pc-windows-msvc/release/goose.exe" ]; then - echo "❌ Windows CLI binary not found." - ls -la ./target/x86_64-pc-windows-msvc/release/ || echo "Release directory doesn't exist" + if (-not (Test-Path "./target/x86_64-pc-windows-msvc/release/goose.exe")) { + Write-Error "Windows CLI binary not found." + Get-ChildItem ./target/x86_64-pc-windows-msvc/release/ -ErrorAction SilentlyContinue exit 1 - fi + } - echo "✅ Windows CLI binary found!" - ls -la ./target/x86_64-pc-windows-msvc/release/goose.exe + Write-Output "Windows CLI binary found." + Get-Item ./target/x86_64-pc-windows-msvc/release/goose.exe - name: Package CLI (Linux/macOS) if: matrix.use-cross @@ -157,21 +198,24 @@ jobs: shell: bash run: | export TARGET="${{ matrix.architecture }}-${{ matrix.target-suffix }}" + export VARIANT_SUFFIX="" + if [ "${{ matrix.variant }}" = "cuda" ]; then + VARIANT_SUFFIX="-cuda" + fi mkdir -p "target/${TARGET}/release/goose-package" cp "target/${TARGET}/release/goose.exe" "target/${TARGET}/release/goose-package/" cd "target/${TARGET}/release" - 7z a -tzip "goose-${TARGET}.zip" goose-package/ - echo "ARTIFACT_ZIP=target/${TARGET}/release/goose-${TARGET}.zip" >> $GITHUB_ENV + 7z a -tzip "goose-${TARGET}${VARIANT_SUFFIX}.zip" goose-package/ + echo "ARTIFACT_ZIP=target/${TARGET}/release/goose-${TARGET}${VARIANT_SUFFIX}.zip" >> $GITHUB_ENV - name: Upload CLI artifact uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: - name: goose-${{ matrix.architecture }}-${{ matrix.target-suffix }} + name: goose-${{ matrix.architecture }}-${{ matrix.target-suffix }}${{ matrix.variant == 'cuda' && '-cuda' || '' }} path: | ${{ env.ARTIFACT_BZ2 }} ${{ env.ARTIFACT_GZ }} ${{ env.ARTIFACT_ZIP }} - diff --git a/.github/workflows/bundle-desktop-windows.yml b/.github/workflows/bundle-desktop-windows.yml index f1777a8b9d..c9db1ba7de 100644 --- a/.github/workflows/bundle-desktop-windows.yml +++ b/.github/workflows/bundle-desktop-windows.yml @@ -8,6 +8,11 @@ on: required: false type: boolean default: false + windows_variant: + description: 'Windows artifact variant to build' + required: false + type: string + default: 'standard' workflow_call: inputs: version: @@ -24,6 +29,11 @@ on: required: false type: string default: '' + windows_variant: + description: 'Windows artifact variant to build' + required: false + type: string + default: 'standard' # Permissions required for OIDC authentication with Azure Trusted Signing permissions: @@ -64,7 +74,7 @@ jobs: - name: Cache Rust dependencies uses: Swatinem/rust-cache@v2 with: - key: windows-msvc-desktop + key: windows-msvc-desktop-${{ inputs.windows_variant }} - name: Setup Rust shell: bash @@ -72,21 +82,54 @@ jobs: rustup show rustup target add x86_64-pc-windows-msvc - - name: Build Windows executable - shell: bash + - name: Install CUDA toolkit (Windows CUDA) + if: ${{ inputs.windows_variant == 'cuda' }} + uses: Jimver/cuda-toolkit@v0.2.35 + with: + cuda: '12.9.1' + method: 'local' + log-file-suffix: 'bundle-desktop-windows-cuda.txt' + + - name: Set up MSVC developer environment (Windows CUDA) + if: ${{ inputs.windows_variant == 'cuda' }} + uses: ilammy/msvc-dev-cmd@0b201ec74fa43914dc39ae48a89fd1d8cb592756 # v1.13.0 + with: + arch: amd64 + + - name: Verify CUDA toolchain (Windows CUDA) + if: ${{ inputs.windows_variant == 'cuda' }} + shell: pwsh + env: + CUDA_COMPUTE_CAP: "80" run: | - echo "🚀 Building Windows executable..." - cargo build --release --target x86_64-pc-windows-msvc + Write-Output "CUDA_PATH=$env:CUDA_PATH" + Write-Output "CUDA_COMPUTE_CAP=$env:CUDA_COMPUTE_CAP" + where.exe cl + where.exe nvcc + nvcc -V + + - name: Build Windows executable + shell: pwsh + env: + CUDA_COMPUTE_CAP: ${{ inputs.windows_variant == 'cuda' && '80' || '' }} + run: | + Write-Output "Building Windows executable..." + if ("${{ inputs.windows_variant }}" -eq "cuda") { + $cudaRustflagsConfig = 'target.x86_64-pc-windows-msvc.rustflags=["-C","target-feature=+crt-static"]' + cargo build --config $cudaRustflagsConfig --release --target x86_64-pc-windows-msvc -p goose-server --features cuda + } else { + cargo build --release --target x86_64-pc-windows-msvc -p goose-server + } # Verify build succeeded - if [ ! -f "./target/x86_64-pc-windows-msvc/release/goosed.exe" ]; then - echo "❌ Windows binary not found." - ls -la ./target/x86_64-pc-windows-msvc/release/ || echo "Release directory doesn't exist" + if (-not (Test-Path "./target/x86_64-pc-windows-msvc/release/goosed.exe")) { + Write-Error "Windows binary not found." + Get-ChildItem ./target/x86_64-pc-windows-msvc/release/ -ErrorAction SilentlyContinue exit 1 - fi + } - echo "✅ Windows binary found!" - ls -la ./target/x86_64-pc-windows-msvc/release/goosed.exe + Write-Output "Windows binary found." + Get-Item ./target/x86_64-pc-windows-msvc/release/goosed.exe - name: Prepare Windows binary shell: bash @@ -155,7 +198,7 @@ jobs: - name: Upload unsigned distribution uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: - name: windows-unsigned + name: windows-unsigned${{ inputs.windows_variant == 'cuda' && '-cuda' || '' }} path: ui/desktop/dist-windows/ sign-desktop-windows: @@ -169,7 +212,7 @@ jobs: - name: Download unsigned distribution uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: windows-unsigned + name: windows-unsigned${{ inputs.windows_variant == 'cuda' && '-cuda' || '' }} path: dist-windows - name: Azure login @@ -206,13 +249,17 @@ jobs: - name: Create Windows zip package shell: bash run: | - 7z a -tzip "Goose-win32-x64.zip" dist-windows/ + ZIP_NAME="Goose-win32-x64" + if [ "${{ inputs.windows_variant }}" = "cuda" ]; then + ZIP_NAME="${ZIP_NAME}-cuda" + fi + 7z a -tzip "${ZIP_NAME}.zip" dist-windows/ - name: Upload signed Windows build uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: - name: Goose-win32-x64 - path: Goose-win32-x64.zip + name: Goose-win32-x64${{ inputs.windows_variant == 'cuda' && '-cuda' || '' }} + path: Goose-win32-x64${{ inputs.windows_variant == 'cuda' && '-cuda' || '' }}.zip # When signing is disabled, package the unsigned build directly package-desktop-windows: @@ -225,16 +272,20 @@ jobs: - name: Download unsigned distribution uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: windows-unsigned + name: windows-unsigned${{ inputs.windows_variant == 'cuda' && '-cuda' || '' }} path: dist-windows - name: Create Windows zip package shell: bash run: | - 7z a -tzip "Goose-win32-x64.zip" dist-windows/ + ZIP_NAME="Goose-win32-x64" + if [ "${{ inputs.windows_variant }}" = "cuda" ]; then + ZIP_NAME="${ZIP_NAME}-cuda" + fi + 7z a -tzip "${ZIP_NAME}.zip" dist-windows/ - name: Upload Windows build uses: actions/upload-artifact@b7c566a772e6b6bfb58ed0dc250532a479d7789f # v6.0.0 with: - name: Goose-win32-x64 - path: Goose-win32-x64.zip + name: Goose-win32-x64${{ inputs.windows_variant == 'cuda' && '-cuda' || '' }} + path: Goose-win32-x64${{ inputs.windows_variant == 'cuda' && '-cuda' || '' }}.zip diff --git a/.github/workflows/canary.yml b/.github/workflows/canary.yml index acb0d4512d..a4c38a9621 100644 --- a/.github/workflows/canary.yml +++ b/.github/workflows/canary.yml @@ -111,13 +111,21 @@ jobs: version: ${{ needs.prepare-version.outputs.version }} signing: false + bundle-desktop-windows-cuda: + needs: [prepare-version] + uses: ./.github/workflows/bundle-desktop-windows.yml + with: + version: ${{ needs.prepare-version.outputs.version }} + signing: false + windows_variant: cuda + # ------------------------------------ # 7) Create/Update GitHub Release # ------------------------------------ release: name: Release runs-on: ubuntu-latest - needs: [build-cli, install-script, bundle-desktop, bundle-desktop-intel, bundle-desktop-linux, bundle-desktop-windows] + needs: [build-cli, install-script, bundle-desktop, bundle-desktop-intel, bundle-desktop-linux, bundle-desktop-windows, bundle-desktop-windows-cuda] permissions: contents: write id-token: write # Required for Sigstore OIDC signing @@ -135,6 +143,7 @@ jobs: subject-path: | goose-*.tar.bz2 goose-*.tar.gz + goose-*.zip Goose*.zip *.deb *.rpm @@ -151,6 +160,7 @@ jobs: artifacts: | goose-*.tar.bz2 goose-*.tar.gz + goose-*.zip Goose*.zip *.deb *.rpm diff --git a/.github/workflows/pr-comment-build-cli.yml b/.github/workflows/pr-comment-build-cli.yml index abff0544ec..570cab9c0c 100644 --- a/.github/workflows/pr-comment-build-cli.yml +++ b/.github/workflows/pr-comment-build-cli.yml @@ -140,7 +140,8 @@ jobs: - [📦 Linux (aarch64)](https://nightly.link/${{ github.repository }}/actions/runs/${{ github.run_id }}/goose-aarch64-unknown-linux-gnu.zip) - [📦 macOS (x86_64)](https://nightly.link/${{ github.repository }}/actions/runs/${{ github.run_id }}/goose-x86_64-apple-darwin.zip) - [📦 macOS (aarch64)](https://nightly.link/${{ github.repository }}/actions/runs/${{ github.run_id }}/goose-aarch64-apple-darwin.zip) - - [📦 Windows (x86_64)](https://nightly.link/${{ github.repository }}/actions/runs/${{ github.run_id }}/goose-x86_64-pc-windows-gnu.zip) + - [📦 Windows (x86_64)](https://nightly.link/${{ github.repository }}/actions/runs/${{ github.run_id }}/goose-x86_64-pc-windows-msvc.zip) + - [📦 Windows CUDA (x86_64)](https://nightly.link/${{ github.repository }}/actions/runs/${{ github.run_id }}/goose-x86_64-pc-windows-msvc-cuda.zip) These links are provided by nightly.link and will work even if you're not logged into GitHub. diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index dfb5c6b916..fb3186aa19 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -85,13 +85,24 @@ jobs: signing: true secrets: inherit + bundle-desktop-windows-cuda: + uses: ./.github/workflows/bundle-desktop-windows.yml + permissions: + id-token: write + contents: read + actions: read + with: + signing: true + windows_variant: cuda + secrets: inherit + # ------------------------------------ # 7) Create/Update GitHub Release # ------------------------------------ release: name: Release runs-on: ubuntu-latest - needs: [build-cli, install-script, bundle-desktop, bundle-desktop-intel, bundle-desktop-linux, bundle-desktop-windows] + needs: [build-cli, install-script, bundle-desktop, bundle-desktop-intel, bundle-desktop-linux, bundle-desktop-windows, bundle-desktop-windows-cuda] permissions: contents: write id-token: write # Required for Sigstore OIDC signing diff --git a/crates/goose-cli/src/commands/update.rs b/crates/goose-cli/src/commands/update.rs index 1310d76f3d..6cf2ba9371 100644 --- a/crates/goose-cli/src/commands/update.rs +++ b/crates/goose-cli/src/commands/update.rs @@ -26,7 +26,11 @@ fn asset_name() -> &'static str { { "goose-aarch64-unknown-linux-gnu.tar.bz2" } - #[cfg(all(target_os = "windows", target_arch = "x86_64"))] + #[cfg(all(target_os = "windows", target_arch = "x86_64", feature = "cuda"))] + { + "goose-x86_64-pc-windows-msvc-cuda.zip" + } + #[cfg(all(target_os = "windows", target_arch = "x86_64", not(feature = "cuda")))] { "goose-x86_64-pc-windows-msvc.zip" } diff --git a/documentation/docs/getting-started/installation.md b/documentation/docs/getting-started/installation.md index f9e61b3007..da18589b68 100644 --- a/documentation/docs/getting-started/installation.md +++ b/documentation/docs/getting-started/installation.md @@ -141,6 +141,10 @@ import { PanelLeft } from 'lucide-react'; 1. Unzip the downloaded zip file. 2. Run the executable file to launch the goose Desktop application. + :::info Windows variants + `Windows` is the standard general-purpose build. `Windows CUDA` is for NVIDIA GPUs with a compatible CUDA driver/runtime. + ::: + :::tip Updating goose It's best to periodically [update goose](/docs/guides/updating-goose). ::: @@ -152,19 +156,33 @@ import { PanelLeft } from 'lucide-react'; - **MSYS2**: Available from [msys2.org](https://www.msys2.org/) - **PowerShell**: Available on Windows 10/11 by default - Run the installation command in your chosen environment: + Use the standard build for the general-purpose Windows install. Use the CUDA variant if you have an NVIDIA GPU with a compatible CUDA driver/runtime. + + **Git Bash / MSYS2: Standard** ```bash curl -fsSL https://github.com/aaif-goose/goose/releases/download/stable/download_cli.sh | bash ``` + **Git Bash / MSYS2: Windows CUDA** + + ```bash + curl -fsSL https://github.com/aaif-goose/goose/releases/download/stable/download_cli.sh | GOOSE_WINDOWS_VARIANT=cuda bash + ``` + To install without interactive configuration, disable `CONFIGURE`: ```bash curl -fsSL https://github.com/aaif-goose/goose/releases/download/stable/download_cli.sh | CONFIGURE=false bash ``` - **PowerShell Installation:** + To install the CUDA variant without interactive configuration: + + ```bash + curl -fsSL https://github.com/aaif-goose/goose/releases/download/stable/download_cli.sh | GOOSE_WINDOWS_VARIANT=cuda CONFIGURE=false bash + ``` + + **PowerShell Installation: Standard** Download the PowerShell installation script to your current directory. ```powershell @@ -175,6 +193,14 @@ import { PanelLeft } from 'lucide-react'; .\download_cli.ps1 ``` + **PowerShell Installation: Windows CUDA** + + ```powershell + Invoke-WebRequest -Uri "https://raw.githubusercontent.com/aaif-goose/goose/main/download_cli.ps1" -OutFile "download_cli.ps1"; + $env:GOOSE_WINDOWS_VARIANT="cuda" + .\download_cli.ps1 + ``` + :::info Windows PATH Setup If you see a warning that goose is not in your PATH, you need to add goose to your PATH: diff --git a/documentation/src/components/WindowsDesktopInstallButtons.js b/documentation/src/components/WindowsDesktopInstallButtons.js index c705569194..21b4534a84 100644 --- a/documentation/src/components/WindowsDesktopInstallButtons.js +++ b/documentation/src/components/WindowsDesktopInstallButtons.js @@ -5,13 +5,19 @@ const WindowsDesktopInstallButtons = () => { return (

Click one of the buttons below to download goose Desktop for Windows:

-
+
Windows + + Windows CUDA +
); diff --git a/download_cli.ps1 b/download_cli.ps1 index 2d2ddc2116..e40993475c 100644 --- a/download_cli.ps1 +++ b/download_cli.ps1 @@ -16,6 +16,7 @@ # $env:GOOSE_VERSION - Optional: specific version to install (e.g., "v1.0.25"). Can be in the format vX.Y.Z, vX.Y.Z-suffix, or X.Y.Z # $env:GOOSE_PROVIDER - Optional: provider for goose # $env:GOOSE_MODEL - Optional: model for goose +# $env:GOOSE_WINDOWS_VARIANT - Optional: Windows package variant to install ("standard" or "cuda") # $env:CANARY - Optional: if set to "true", downloads from canary release instead of stable # $env:CONFIGURE - Optional: if set to "false", disables running goose configure interactively ############################################################################## @@ -35,6 +36,7 @@ if (-not $env:GOOSE_BIN_DIR) { # Determine release type $RELEASE = if ($env:CANARY -eq "true") { "true" } else { "false" } $CONFIGURE = if ($env:CONFIGURE -eq "false") { "false" } else { "true" } +$WINDOWS_VARIANT = if ($env:GOOSE_WINDOWS_VARIANT) { $env:GOOSE_WINDOWS_VARIANT.ToLowerInvariant() } else { "standard" } # Determine release tag if ($env:GOOSE_VERSION) { @@ -62,8 +64,13 @@ if ($ARCH -eq "AMD64") { exit 1 } +if ($WINDOWS_VARIANT -ne "standard" -and $WINDOWS_VARIANT -ne "cuda") { + Write-Error "Unsupported GOOSE_WINDOWS_VARIANT '$WINDOWS_VARIANT'. Expected 'standard' or 'cuda'." + exit 1 +} + # --- 3) Build download URL --- -$FILE = "goose-$ARCH-pc-windows-msvc.zip" +$FILE = if ($WINDOWS_VARIANT -eq "cuda") { "goose-$ARCH-pc-windows-msvc-cuda.zip" } else { "goose-$ARCH-pc-windows-msvc.zip" } $DOWNLOAD_URL = "https://github.com/$REPO/releases/download/$RELEASE_TAG/$FILE" Write-Host "Downloading $RELEASE_TAG release: $FILE..." -ForegroundColor Green diff --git a/download_cli.sh b/download_cli.sh index 84be009a0c..c34afe8ad2 100755 --- a/download_cli.sh +++ b/download_cli.sh @@ -18,6 +18,7 @@ set -eu # GOOSE_VERSION - Optional: specific version to install (e.g., "v1.0.25"). Overrides CANARY. Can be in the format vX.Y.Z, vX.Y.Z-suffix, or X.Y.Z # GOOSE_PROVIDER - Optional: provider for goose # GOOSE_MODEL - Optional: model for goose +# GOOSE_WINDOWS_VARIANT - Optional: Windows package variant to install (`standard` or `cuda`) # CANARY - Optional: if set to "true", downloads from canary release instead of stable # CONFIGURE - Optional: if set to "false", disables running goose configure interactively # ** other provider specific environment variables (eg. DATABRICKS_HOST) @@ -73,6 +74,7 @@ fi GOOSE_BIN_DIR="${GOOSE_BIN_DIR:-$DEFAULT_BIN_DIR}" RELEASE="${CANARY:-false}" CONFIGURE="${CONFIGURE:-true}" +GOOSE_WINDOWS_VARIANT="${GOOSE_WINDOWS_VARIANT:-standard}" if [ -n "${GOOSE_VERSION:-}" ]; then # Validate the version format if [[ ! "$GOOSE_VERSION" =~ ^v?[0-9]+\.[0-9]+\.[0-9]+(-.*)?$ ]]; then @@ -179,12 +181,22 @@ if [ "$OS" = "darwin" ]; then FILE="goose-$ARCH-apple-darwin.tar.bz2" EXTRACT_CMD="tar" elif [ "$OS" = "windows" ]; then + case "$GOOSE_WINDOWS_VARIANT" in + standard|cuda) ;; + *) + echo "Error: Unsupported GOOSE_WINDOWS_VARIANT '$GOOSE_WINDOWS_VARIANT'. Expected 'standard' or 'cuda'." + exit 1 + ;; + esac # Windows only supports x86_64 currently if [ "$ARCH" != "x86_64" ]; then echo "Error: Windows currently only supports x86_64 architecture." exit 1 fi FILE="goose-$ARCH-pc-windows-msvc.zip" + if [ "$GOOSE_WINDOWS_VARIANT" = "cuda" ]; then + FILE="goose-$ARCH-pc-windows-msvc-cuda.zip" + fi EXTRACT_CMD="unzip" OUT_FILE="goose.exe" else