Files
goose/.github/workflows/bundle-desktop-windows.yml
2025-06-10 08:17:45 -07:00

183 lines
7.1 KiB
YAML

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
ref:
type: string
required: false
default: 'refs/heads/main'
jobs:
build-desktop-windows:
name: Build Desktop (Windows)
runs-on: ubuntu-latest # Use Ubuntu for cross-compilation
steps:
# 1) Check out source
- name: Checkout repository
uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744
with:
ref: ${{ inputs.ref }}
fetch-depth: 0
# 2) Set up Node.js
- name: Set up Node.js
uses: actions/setup-node@1a4442cacd436585916779262731d5b162bc6ec7 # pin@v3
with:
node-version: 18
# 3) Cache dependencies
- name: Cache node_modules
uses: actions/cache@2f8e54208210a422b2efd51efaa6bd6d7ca8920f # pin@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-
# 4) Build Rust for Windows using Docker (cross-compilation)
- name: Build Windows executable using Docker
run: |
echo "Building Windows executable using Docker cross-compilation..."
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 protobuf-compiler cmake && \
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 && \
export PATH=/usr/bin:\$PATH && \
protoc --version && \
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/"
# 4.5) Build temporal-service for Windows
- name: Build temporal-service for Windows
run: |
echo "Building temporal-service for Windows..."
docker run --rm \
-v "$(pwd)":/usr/src/myapp \
-w /usr/src/myapp/temporal-service \
golang:latest \
sh -c "GOOS=windows GOARCH=amd64 go build -o temporal-service.exe main.go"
echo "temporal-service.exe built successfully"
# 4.6) Download temporal CLI for Windows
- name: Download temporal CLI for Windows
run: |
echo "Downloading temporal CLI for Windows..."
TEMPORAL_VERSION="1.3.0"
curl -L "https://github.com/temporalio/cli/releases/download/v${TEMPORAL_VERSION}/temporal_cli_${TEMPORAL_VERSION}_windows_amd64.zip" -o temporal-cli-windows.zip
unzip temporal-cli-windows.zip
chmod +x temporal.exe
echo "temporal CLI downloaded successfully"
# 5) Prepare Windows binary and DLLs
- name: Prepare Windows binary and DLLs
run: |
if [ ! -f "./target/x86_64-pc-windows-gnu/release/goosed.exe" ]; then
echo "Windows binary not found."
exit 1
fi
if [ ! -f "./temporal-service/temporal-service.exe" ]; then
echo "temporal-service.exe not found."
exit 1
fi
if [ ! -f "./temporal.exe" ]; then
echo "temporal.exe not found."
exit 1
fi
echo "Cleaning destination directory..."
rm -rf ./ui/desktop/src/bin
mkdir -p ./ui/desktop/src/bin
echo "Copying Windows binary and DLLs..."
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 "Copying temporal-service.exe..."
cp -f ./temporal-service/temporal-service.exe ./ui/desktop/src/bin/
echo "Copying temporal.exe..."
cp -f ./temporal.exe ./ui/desktop/src/bin/
# Copy Windows platform files (tools, scripts, etc.)
if [ -d "./ui/desktop/src/platform/windows/bin" ]; then
echo "Copying Windows platform files..."
for file in ./ui/desktop/src/platform/windows/bin/*.{exe,dll,cmd}; do
if [ -f "$file" ] && [ "$(basename "$file")" != "goosed.exe" ]; then
cp -f "$file" ./ui/desktop/src/bin/
fi
done
if [ -d "./ui/desktop/src/platform/windows/bin/goose-npm" ]; then
echo "Setting up npm environment..."
rsync -a --delete ./ui/desktop/src/platform/windows/bin/goose-npm/ ./ui/desktop/src/bin/goose-npm/
fi
echo "Windows-specific files copied successfully"
fi
# 6) Install & build UI desktop
- name: Build desktop UI with npm
run: |
cd ui/desktop
npm install
npm run bundle:windows
# 7) Copy exe/dll to final out/Goose-win32-x64/resources/bin
- name: Copy exe/dll to out folder
run: |
cd ui/desktop
mkdir -p ./out/Goose-win32-x64/resources/bin
rsync -av src/bin/ out/Goose-win32-x64/resources/bin/
# 8) Code signing (if enabled)
- name: Sign Windows executable
if: inputs.signing && inputs.signing == true
env:
WINDOWS_CERTIFICATE: ${{ secrets.WINDOWS_CERTIFICATE }}
WINDOWS_CERTIFICATE_PASSWORD: ${{ secrets.WINDOWS_CERTIFICATE_PASSWORD }}
run: |
# Note: This would need to be adapted for Linux-based signing
# or moved to a Windows runner for the signing step only
echo "Code signing would be implemented here"
echo "Currently skipped as we're running on Ubuntu"
# 9) Upload the final Windows build
- name: Upload Windows build artifacts
uses: actions/upload-artifact@4cec3d8aa04e39d1a68397de0c4cd6fb9dce8ec1 # pin@v4
with:
name: desktop-windows-dist
path: ui/desktop/out/Goose-win32-x64/