attempt to build CLI native for Windows (#3058)
This commit is contained in:
+194
-18
@@ -1,7 +1,12 @@
|
||||
# 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:
|
||||
@@ -9,17 +14,6 @@ on:
|
||||
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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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 }}"
|
||||
@@ -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 }}"
|
||||
@@ -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:
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user