Skip to content
Merged
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
212 changes: 194 additions & 18 deletions .github/workflows/build-cli.yml
Original file line number Diff line number Diff line change
@@ -1,25 +1,19 @@
# This is a **reuseable** workflow that bundles the Desktop App for macOS.
# This is a **reuseable** workflow that builds the CLI for multiple platforms.
# It doesn't get triggered on its own. It gets used in multiple workflows:
# - release.yml
# - canary.yml
#
# Platform Build Strategy:
# - Linux: Uses Ubuntu runner with cross-compilation
# - macOS: Uses macOS runner with cross-compilation
# - Windows: Uses Ubuntu runner with Docker cross-compilation (same as desktop build)
on:
workflow_call:
inputs:
version:
required: false
default: ""
type: string
# Let's allow overriding the OSes and architectures in JSON array form:
# e.g. '["ubuntu-latest","macos-latest"]'
# If no input is provided, these defaults apply.
operating-systems:
type: string
required: false
default: '["ubuntu-latest","macos-latest"]'
architectures:
type: string
required: false
default: '["x86_64","aarch64"]'
ref:
type: string
required: false
Expand All @@ -30,17 +24,40 @@ name: "Reusable workflow to build CLI"
jobs:
build-cli:
name: Build CLI
runs-on: ${{ matrix.os }}
runs-on: ${{ matrix.build-on }}
strategy:
fail-fast: false
matrix:
os: ${{ fromJson(inputs.operating-systems) }}
architecture: ${{ fromJson(inputs.architectures) }}
include:
# Linux builds
- os: ubuntu-latest
architecture: x86_64
target-suffix: unknown-linux-gnu
build-on: ubuntu-latest
use-cross: true
- os: ubuntu-latest
architecture: aarch64
target-suffix: unknown-linux-gnu
build-on: ubuntu-latest
use-cross: true
# macOS builds
- os: macos-latest
architecture: x86_64
target-suffix: apple-darwin
build-on: macos-latest
use-cross: true
- os: macos-latest
architecture: aarch64
target-suffix: apple-darwin
build-on: macos-latest
use-cross: true
# Windows builds (only x86_64 supported)
- os: windows
architecture: x86_64
target-suffix: pc-windows-gnu
build-on: ubuntu-latest
use-cross: false
use-docker: true

steps:
- name: Checkout code
Expand All @@ -56,6 +73,7 @@ jobs:
rm -f Cargo.toml.bak

- name: Install cross
if: matrix.use-cross
run: source ./bin/activate-hermit && cargo install cross --git https://github.com/cross-rs/cross

# Install Go for building temporal-service
Expand All @@ -64,7 +82,32 @@ jobs:
with:
go-version: '1.21'

- name: Build CLI
# Cache Cargo registry and git dependencies for Windows builds
- name: Cache Cargo registry (Windows)
if: matrix.use-docker
uses: actions/cache@2f8e54208210a422b2efd51efaa6bd6d7ca8920f
with:
path: |
~/.cargo/registry/index
~/.cargo/registry/cache
~/.cargo/git/db
key: ${{ runner.os }}-cargo-registry-${{ hashFiles('Cargo.lock') }}
restore-keys: |
${{ runner.os }}-cargo-registry-

# Cache compiled dependencies (target/release/deps) for Windows builds
- name: Cache Cargo build (Windows)
if: matrix.use-docker
uses: actions/cache@2f8e54208210a422b2efd51efaa6bd6d7ca8920f
with:
path: target
key: ${{ runner.os }}-cargo-build-${{ hashFiles('Cargo.lock') }}-${{ hashFiles('rust-toolchain.toml') }}
restore-keys: |
${{ runner.os }}-cargo-build-${{ hashFiles('Cargo.lock') }}-
${{ runner.os }}-cargo-build-

- name: Build CLI (Linux/macOS)
if: matrix.use-cross
env:
CROSS_NO_WARNINGS: 0
RUST_LOG: debug
Expand All @@ -83,7 +126,102 @@ jobs:
echo "Building with explicit PROTOC path..."
cross build --release --target ${TARGET} -p goose-cli -vv

- name: Build temporal-service for target platform using build.sh script
- name: Build CLI (Windows)
if: matrix.use-docker
run: |
echo "🚀 Building Windows CLI executable with enhanced GitHub Actions caching..."

# Create cache directories
mkdir -p ~/.cargo/registry ~/.cargo/git

# Use enhanced caching with GitHub Actions cache mounts
docker run --rm \
-v "$(pwd)":/usr/src/myapp \
-v "$HOME/.cargo/registry":/usr/local/cargo/registry \
-v "$HOME/.cargo/git":/usr/local/cargo/git \
-w /usr/src/myapp \
rust:latest \
bash -c "
set -e
echo '=== Setting up Rust environment with caching ==='
export CARGO_HOME=/usr/local/cargo
export PATH=/usr/local/cargo/bin:\$PATH

# Check if Windows target is already installed in cache
if rustup target list --installed | grep -q x86_64-pc-windows-gnu; then
echo '✅ Windows cross-compilation target already installed'
else
echo '📦 Installing Windows cross-compilation target...'
rustup target add x86_64-pc-windows-gnu
fi

echo '=== Setting up build dependencies ==='
apt-get update
apt-get install -y mingw-w64 protobuf-compiler cmake time

echo '=== Setting up cross-compilation environment ==='
export CC_x86_64_pc_windows_gnu=x86_64-w64-mingw32-gcc
export CXX_x86_64_pc_windows_gnu=x86_64-w64-mingw32-g++
export AR_x86_64_pc_windows_gnu=x86_64-w64-mingw32-ar
export CARGO_TARGET_X86_64_PC_WINDOWS_GNU_LINKER=x86_64-w64-mingw32-gcc
export PKG_CONFIG_ALLOW_CROSS=1
export PROTOC=/usr/bin/protoc

echo '=== Optimized Cargo configuration ==='
mkdir -p .cargo
echo '[build]' > .cargo/config.toml
echo 'jobs = 4' >> .cargo/config.toml
echo '' >> .cargo/config.toml
echo '[target.x86_64-pc-windows-gnu]' >> .cargo/config.toml
echo 'linker = \"x86_64-w64-mingw32-gcc\"' >> .cargo/config.toml
echo '' >> .cargo/config.toml
echo '[net]' >> .cargo/config.toml
echo 'git-fetch-with-cli = true' >> .cargo/config.toml
echo 'retry = 3' >> .cargo/config.toml
echo '' >> .cargo/config.toml
echo '[profile.release]' >> .cargo/config.toml
echo 'codegen-units = 1' >> .cargo/config.toml
echo 'lto = false' >> .cargo/config.toml
echo 'panic = \"abort\"' >> .cargo/config.toml
echo 'debug = false' >> .cargo/config.toml
echo 'opt-level = 2' >> .cargo/config.toml
echo '' >> .cargo/config.toml
echo '[registries.crates-io]' >> .cargo/config.toml
echo 'protocol = \"sparse\"' >> .cargo/config.toml

echo '=== Building with cached dependencies ==='
# Check if we have cached build artifacts
if [ -d target/x86_64-pc-windows-gnu/release/deps ] && [ \"\$(ls -A target/x86_64-pc-windows-gnu/release/deps)\" ]; then
echo '✅ Found cached build artifacts, performing incremental build...'
CARGO_INCREMENTAL=1
else
echo '🔨 No cached artifacts found, performing full build...'
CARGO_INCREMENTAL=0
fi

echo '🔨 Building Windows CLI executable...'
CARGO_INCREMENTAL=\$CARGO_INCREMENTAL \
CARGO_NET_RETRY=3 \
CARGO_HTTP_TIMEOUT=60 \
RUST_BACKTRACE=1 \
cargo build --release --target x86_64-pc-windows-gnu -p goose-cli --jobs 4

echo '✅ Build completed successfully!'
ls -la target/x86_64-pc-windows-gnu/release/
"

# Verify build succeeded
if [ ! -f "./target/x86_64-pc-windows-gnu/release/goose.exe" ]; then
echo "❌ Windows CLI binary not found."
ls -la ./target/x86_64-pc-windows-gnu/release/ || echo "Release directory doesn't exist"
exit 1
fi

echo "✅ Windows CLI binary found!"
ls -la ./target/x86_64-pc-windows-gnu/release/goose.exe

- name: Build temporal-service for target platform using build.sh script (Linux/macOS)
if: matrix.use-cross
run: |
source ./bin/activate-hermit
export TARGET="${{ matrix.architecture }}-${{ matrix.target-suffix }}"
Expand Down Expand Up @@ -124,7 +262,28 @@ jobs:
mv "${BINARY_NAME}" "../target/${TARGET}/release/${BINARY_NAME}"
echo "temporal-service built successfully for ${TARGET}"

- name: Package CLI with temporal-service
- name: Build temporal-service for Windows
if: matrix.use-docker
run: |
echo "Building temporal-service for Windows using build.sh script..."
docker run --rm \
-v "$(pwd)":/usr/src/myapp \
-w /usr/src/myapp/temporal-service \
golang:latest \
sh -c "
# Make build.sh executable
chmod +x build.sh
# Set Windows build environment and run build script
GOOS=windows GOARCH=amd64 ./build.sh
"

# Move the built binary to the expected location
mkdir -p target/x86_64-pc-windows-gnu/release
mv temporal-service/temporal-service.exe target/x86_64-pc-windows-gnu/release/temporal-service.exe
echo "temporal-service.exe built successfully for Windows"

- name: Package CLI with temporal-service (Linux/macOS)
if: matrix.use-cross
run: |
source ./bin/activate-hermit
export TARGET="${{ matrix.architecture }}-${{ matrix.target-suffix }}"
Expand All @@ -141,6 +300,23 @@ jobs:
tar -cjf "goose-${TARGET}.tar.bz2" -C goose-package .
echo "ARTIFACT=target/${TARGET}/release/goose-${TARGET}.tar.bz2" >> $GITHUB_ENV

- name: Package CLI with temporal-service (Windows)
if: matrix.use-docker
run: |
export TARGET="${{ matrix.architecture }}-${{ matrix.target-suffix }}"

# Create a directory for the package contents
mkdir -p "target/${TARGET}/release/goose-package"

# Copy binaries
cp "target/${TARGET}/release/goose.exe" "target/${TARGET}/release/goose-package/"
cp "target/${TARGET}/release/temporal-service.exe" "target/${TARGET}/release/goose-package/"

# Create the zip archive with both binaries (Windows uses zip instead of tar.bz2)
cd "target/${TARGET}/release"
zip -r "goose-${TARGET}.zip" goose-package/
echo "ARTIFACT=target/${TARGET}/release/goose-${TARGET}.zip" >> $GITHUB_ENV

- name: Upload CLI artifact
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # pin@v4
with:
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/pr-comment-build-cli.yml
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ 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)

These links are provided by nightly.link and will work even if you're not logged into GitHub.

46 changes: 43 additions & 3 deletions documentation/docs/getting-started/installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,32 @@ import LinuxDesktopInstallButtons from '@site/src/components/LinuxDesktopInstall
</div>
</TabItem>
<TabItem value="cli" label="Goose CLI">
There isn't native installation support for Windows CLI, however you can run Goose using WSL (Windows Subsystem for Linux).
Install the Goose CLI directly from the browser using our download script, or use WSL for a Linux-like experience.

<h3 style={{ marginTop: '1rem' }}>Option 1: Native Windows CLI (Recommended)</h3>
Run the following command in **Git Bash**, **MSYS2**, or **PowerShell** to install the latest version of Goose natively on Windows:

```bash
curl -fsSL https://github.com/block/goose/releases/download/stable/download_cli.sh | bash
```
This script will fetch the latest version of Goose and set it up on your system.

If you'd like to install without interactive configuration, disable `CONFIGURE`:

```bash
curl -fsSL https://github.com/block/goose/releases/download/stable/download_cli.sh | CONFIGURE=false bash
```

:::note Prerequisites
- **Git Bash** (recommended): Comes with [Git for Windows](https://git-scm.com/download/win)
- **MSYS2**: Available from [msys2.org](https://www.msys2.org/)
- **PowerShell**: Available on Windows 10/11 by default

The script requires `curl` and `unzip` to be available in your environment.
:::

<h3>Option 2: Windows Subsystem for Linux (WSL)</h3>
If you prefer a Linux-like environment, you can run Goose using WSL:

1. Open [PowerShell](https://learn.microsoft.com/en-us/powershell/scripting/install/installing-powershell-on-windows) as Administrator and install WSL and the default Ubuntu distribution:

Expand Down Expand Up @@ -193,7 +218,7 @@ Goose works with a set of [supported LLM providers][providers], and you'll need
Upon installing, Goose will automatically enter its configuration screen. Here is where you can set up your LLM provider.

:::tip Windows Users
Choose to not store to keyring when prompted.
When using the native Windows CLI, choose to not store to keyring when prompted during initial configuration.
:::

Example:
Expand Down Expand Up @@ -221,6 +246,12 @@ Goose works with a set of [supported LLM providers][providers], and you'll need
:::info Windows Users
On initial run, you may encounter errors about keyrings when setting your API Keys. Set the needed environment variables manually, e.g.:

**For Native Windows CLI (Git Bash/MSYS2):**
```bash
export OPENAI_API_KEY={your_api_key}
```

**For WSL:**
```bash
export OPENAI_API_KEY={your_api_key}
```
Expand All @@ -231,8 +262,17 @@ Goose works with a set of [supported LLM providers][providers], and you'll need
● OPENAI_API_KEY is set via environment variable
```

To make the changes persist in WSL across sessions, add the goose path and export commands to your `.bashrc` or `.bash_profile` file so you can load it later.
**To make the changes persist across sessions:**

**For Native Windows CLI (Git Bash):**
Add the goose path and export commands to your `~/.bashrc` or `~/.bash_profile` file:
```bash
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
echo 'export OPENAI_API_KEY=your_api_key' >> ~/.bashrc
source ~/.bashrc
```

**For WSL:**
```bash
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.bashrc
echo 'export OPENAI_API_KEY=your_api_key' >> ~/.bashrc
Expand Down
Loading
Loading