diff --git a/Dockerfile b/Dockerfile index 59591ee..3e368c4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -108,7 +108,11 @@ RUN --mount=type=cache,id=pulse-go-mod,target=/go/pkg/mod \ CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build \ -ldflags="-s -w -X github.com/rcourtman/pulse-go-rewrite/internal/hostagent.Version=${VERSION}" \ -trimpath \ - -o pulse-host-agent-windows-amd64.exe ./cmd/pulse-host-agent + -o pulse-host-agent-windows-amd64.exe ./cmd/pulse-host-agent && \ + CGO_ENABLED=0 GOOS=windows GOARCH=arm64 go build \ + -ldflags="-s -w -X github.com/rcourtman/pulse-go-rewrite/internal/hostagent.Version=${VERSION}" \ + -trimpath \ + -o pulse-host-agent-windows-arm64.exe ./cmd/pulse-host-agent # Build pulse-sensor-proxy for all Linux architectures (for download endpoint) RUN --mount=type=cache,id=pulse-go-mod,target=/go/pkg/mod \ @@ -206,8 +210,10 @@ COPY --from=backend-builder /app/pulse-host-agent-linux-armv7 /opt/pulse/bin/ COPY --from=backend-builder /app/pulse-host-agent-darwin-amd64 /opt/pulse/bin/ COPY --from=backend-builder /app/pulse-host-agent-darwin-arm64 /opt/pulse/bin/ COPY --from=backend-builder /app/pulse-host-agent-windows-amd64.exe /opt/pulse/bin/ -# Create symlink for Windows without .exe extension -RUN ln -s pulse-host-agent-windows-amd64.exe /opt/pulse/bin/pulse-host-agent-windows-amd64 +COPY --from=backend-builder /app/pulse-host-agent-windows-arm64.exe /opt/pulse/bin/ +# Create symlinks for Windows without .exe extension +RUN ln -s pulse-host-agent-windows-amd64.exe /opt/pulse/bin/pulse-host-agent-windows-amd64 && \ + ln -s pulse-host-agent-windows-arm64.exe /opt/pulse/bin/pulse-host-agent-windows-arm64 # Copy multi-arch pulse-sensor-proxy binaries for download endpoint COPY --from=backend-builder /app/pulse-sensor-proxy-linux-amd64 /opt/pulse/bin/ diff --git a/frontend-modern/public/install-host-agent.ps1 b/frontend-modern/public/install-host-agent.ps1 index 6c3b85e..634e99c 100644 --- a/frontend-modern/public/install-host-agent.ps1 +++ b/frontend-modern/public/install-host-agent.ps1 @@ -131,7 +131,16 @@ Write-Host " Install Path: $InstallPath" Write-Host "" # Determine architecture -$arch = if ([Environment]::Is64BitOperatingSystem) { "amd64" } else { "386" } +$osArch = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture +switch ($osArch) { + 'Arm64' { $arch = 'arm64' } + 'X64' { $arch = 'amd64' } + 'X86' { $arch = '386' } + default { + Write-Error "Unsupported architecture: $osArch" + exit 1 + } +} $downloadUrl = "$PulseUrl/download/pulse-host-agent?platform=windows&arch=$arch" Write-Info "Downloading agent binary from $downloadUrl..." diff --git a/scripts/build-release.sh b/scripts/build-release.sh index b0182da..fd81c63 100755 --- a/scripts/build-release.sh +++ b/scripts/build-release.sh @@ -235,7 +235,14 @@ chmod +x "$universal_dir/bin/pulse-host-agent" # Add VERSION file echo "$VERSION" > "$universal_dir/VERSION" -# Build host agent for macOS arm64 +# Build host agent for macOS +echo "Building host agent for macOS amd64..." +env GOOS=darwin GOARCH=amd64 go build \ + -ldflags="-s -w -X github.com/rcourtman/pulse-go-rewrite/internal/hostagent.Version=v${VERSION}" \ + -trimpath \ + -o "$BUILD_DIR/pulse-host-agent-darwin-amd64" \ + ./cmd/pulse-host-agent + echo "Building host agent for macOS arm64..." env GOOS=darwin GOARCH=arm64 go build \ -ldflags="-s -w -X github.com/rcourtman/pulse-go-rewrite/internal/hostagent.Version=v${VERSION}" \ @@ -243,8 +250,26 @@ env GOOS=darwin GOARCH=arm64 go build \ -o "$BUILD_DIR/pulse-host-agent-darwin-arm64" \ ./cmd/pulse-host-agent -# Package macOS host agent +# Build host agent for Windows +echo "Building host agent for Windows amd64..." +env GOOS=windows GOARCH=amd64 go build \ + -ldflags="-s -w -X github.com/rcourtman/pulse-go-rewrite/internal/hostagent.Version=v${VERSION}" \ + -trimpath \ + -o "$BUILD_DIR/pulse-host-agent-windows-amd64.exe" \ + ./cmd/pulse-host-agent + +echo "Building host agent for Windows arm64..." +env GOOS=windows GOARCH=arm64 go build \ + -ldflags="-s -w -X github.com/rcourtman/pulse-go-rewrite/internal/hostagent.Version=v${VERSION}" \ + -trimpath \ + -o "$BUILD_DIR/pulse-host-agent-windows-arm64.exe" \ + ./cmd/pulse-host-agent + +# Package standalone host agent binaries +tar -czf "$RELEASE_DIR/pulse-host-agent-v${VERSION}-darwin-amd64.tar.gz" -C "$BUILD_DIR" pulse-host-agent-darwin-amd64 tar -czf "$RELEASE_DIR/pulse-host-agent-v${VERSION}-darwin-arm64.tar.gz" -C "$BUILD_DIR" pulse-host-agent-darwin-arm64 +zip -j "$RELEASE_DIR/pulse-host-agent-v${VERSION}-windows-amd64.zip" "$BUILD_DIR/pulse-host-agent-windows-amd64.exe" +zip -j "$RELEASE_DIR/pulse-host-agent-v${VERSION}-windows-arm64.zip" "$BUILD_DIR/pulse-host-agent-windows-arm64.exe" # Create universal tarball cd "$universal_dir" @@ -268,8 +293,11 @@ for build_name in "${!builds[@]}"; do cp "$BUILD_DIR/pulse-host-agent-$build_name" "$RELEASE_DIR/" done -# Also copy standalone macOS host-agent (not tarballed version) +# Also copy standalone macOS and Windows host-agent binaries +cp "$BUILD_DIR/pulse-host-agent-darwin-amd64" "$RELEASE_DIR/" cp "$BUILD_DIR/pulse-host-agent-darwin-arm64" "$RELEASE_DIR/" +cp "$BUILD_DIR/pulse-host-agent-windows-amd64.exe" "$RELEASE_DIR/" +cp "$BUILD_DIR/pulse-host-agent-windows-arm64.exe" "$RELEASE_DIR/" # Optionally package Helm chart if [ "${SKIP_HELM_PACKAGE:-0}" != "1" ]; then diff --git a/scripts/install-host-agent.ps1 b/scripts/install-host-agent.ps1 index 6c3b85e..634e99c 100644 --- a/scripts/install-host-agent.ps1 +++ b/scripts/install-host-agent.ps1 @@ -131,7 +131,16 @@ Write-Host " Install Path: $InstallPath" Write-Host "" # Determine architecture -$arch = if ([Environment]::Is64BitOperatingSystem) { "amd64" } else { "386" } +$osArch = [System.Runtime.InteropServices.RuntimeInformation]::OSArchitecture +switch ($osArch) { + 'Arm64' { $arch = 'arm64' } + 'X64' { $arch = 'amd64' } + 'X86' { $arch = '386' } + default { + Write-Error "Unsupported architecture: $osArch" + exit 1 + } +} $downloadUrl = "$PulseUrl/download/pulse-host-agent?platform=windows&arch=$arch" Write-Info "Downloading agent binary from $downloadUrl..." diff --git a/scripts/validate-release.sh b/scripts/validate-release.sh index 00da300..d4e8357 100755 --- a/scripts/validate-release.sh +++ b/scripts/validate-release.sh @@ -72,8 +72,8 @@ success "All installer/uninstaller scripts present and executable" # Validate all required binaries exist and are non-empty info "Checking downloadable binaries in /opt/pulse/bin/..." -docker run --rm --entrypoint /bin/sh "$IMAGE" -c 'set -euo pipefail; cd /opt/pulse/bin; required="pulse pulse-docker-agent pulse-docker-agent-linux-amd64 pulse-docker-agent-linux-arm64 pulse-docker-agent-linux-armv7 pulse-host-agent-linux-amd64 pulse-host-agent-linux-arm64 pulse-host-agent-linux-armv7 pulse-host-agent-darwin-amd64 pulse-host-agent-darwin-arm64 pulse-host-agent-windows-amd64.exe pulse-host-agent-windows-amd64 pulse-sensor-proxy pulse-sensor-proxy-linux-amd64 pulse-sensor-proxy-linux-arm64 pulse-sensor-proxy-linux-armv7"; for f in $required; do [ -e "$f" ] || { echo "missing binary $f" >&2; exit 1; }; [ -s "$f" ] || { echo "empty binary $f" >&2; exit 1; }; done; [ "$(readlink pulse-host-agent-windows-amd64)" = "pulse-host-agent-windows-amd64.exe" ] || { echo "windows symlink broken" >&2; exit 1; }; echo "All binaries present"' || { error "Binary validation failed"; exit 1; } -success "All downloadable binaries present (16 binaries + Windows symlink)" +docker run --rm --entrypoint /bin/sh "$IMAGE" -c 'set -euo pipefail; cd /opt/pulse/bin; required="pulse pulse-docker-agent pulse-docker-agent-linux-amd64 pulse-docker-agent-linux-arm64 pulse-docker-agent-linux-armv7 pulse-host-agent-linux-amd64 pulse-host-agent-linux-arm64 pulse-host-agent-linux-armv7 pulse-host-agent-darwin-amd64 pulse-host-agent-darwin-arm64 pulse-host-agent-windows-amd64.exe pulse-host-agent-windows-amd64 pulse-host-agent-windows-arm64.exe pulse-host-agent-windows-arm64 pulse-sensor-proxy pulse-sensor-proxy-linux-amd64 pulse-sensor-proxy-linux-arm64 pulse-sensor-proxy-linux-armv7"; for f in $required; do [ -e "$f" ] || { echo "missing binary $f" >&2; exit 1; }; [ -s "$f" ] || { echo "empty binary $f" >&2; exit 1; }; done; [ "$(readlink pulse-host-agent-windows-amd64)" = "pulse-host-agent-windows-amd64.exe" ] || { echo "windows amd64 symlink broken" >&2; exit 1; }; [ "$(readlink pulse-host-agent-windows-arm64)" = "pulse-host-agent-windows-arm64.exe" ] || { echo "windows arm64 symlink broken" >&2; exit 1; }; echo "All binaries present"' || { error "Binary validation failed"; exit 1; } +success "All downloadable binaries present (18 binaries + 2 Windows symlinks)" # Validate version embedding in Docker image binaries info "Validating version embedding in Docker image binaries..." @@ -191,8 +191,10 @@ if command -v file >/dev/null 2>&1; then file pulse-host-agent-linux-amd64 | grep -qF 'ELF 64-bit' | grep -qF 'x86-64' || warn "pulse-host-agent-linux-amd64 architecture check failed" file pulse-host-agent-linux-arm64 | grep -qF 'ELF 64-bit' | grep -qF 'aarch64' || warn "pulse-host-agent-linux-arm64 architecture check failed" file pulse-host-agent-linux-armv7 | grep -qF 'ELF 32-bit' | grep -qF 'ARM' || warn "pulse-host-agent-linux-armv7 architecture check failed" + file pulse-host-agent-darwin-amd64 | grep -qF 'Mach-O' | grep -qF 'x86_64' || warn "pulse-host-agent-darwin-amd64 architecture check failed" file pulse-host-agent-darwin-arm64 | grep -qF 'Mach-O' | grep -qF 'arm64' || warn "pulse-host-agent-darwin-arm64 architecture check failed" - file pulse-host-agent-windows-amd64.exe | grep -qF 'PE32+' || warn "pulse-host-agent-windows-amd64.exe architecture check failed" + file pulse-host-agent-windows-amd64.exe | grep -qF 'PE32+' | grep -qF 'x86-64' || warn "pulse-host-agent-windows-amd64.exe architecture check failed" + file pulse-host-agent-windows-arm64.exe | grep -qF 'PE32+' | grep -qF 'Aarch64' || warn "pulse-host-agent-windows-arm64.exe architecture check failed" success "Binary architectures validated" fi