mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-02-18 00:17:39 +01:00
The .sha256 files generated during release builds contained only the hash, but sha256sum -c expects the format "hash filename". This caused all install.sh updates to fail with "Checksum verification failed" even when the checksum was correct. Root cause: build-release.sh line 289 was using awk to extract only field 1 (the hash), discarding the filename that sha256sum -c needs. Fix: Remove the awk filter to preserve the full sha256sum output format. This affected the demo server update workflow and user installations.
313 lines
10 KiB
Bash
Executable File
313 lines
10 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
# Build script for Pulse releases
|
|
# Creates release archives for different architectures
|
|
|
|
set -euo pipefail
|
|
|
|
# Use Go 1.24 if available
|
|
if [ -x /usr/local/go/bin/go ]; then
|
|
export PATH=/usr/local/go/bin:$PATH
|
|
fi
|
|
|
|
# Force static binaries so release artifacts run on older glibc hosts
|
|
export CGO_ENABLED=0
|
|
|
|
VERSION=${1:-$(cat VERSION)}
|
|
BUILD_DIR="build"
|
|
RELEASE_DIR="release"
|
|
|
|
echo "Building Pulse v${VERSION}..."
|
|
|
|
# Clean previous builds
|
|
rm -rf $BUILD_DIR $RELEASE_DIR
|
|
mkdir -p $BUILD_DIR $RELEASE_DIR
|
|
|
|
# Build frontend
|
|
echo "Building frontend..."
|
|
npm --prefix frontend-modern ci
|
|
npm --prefix frontend-modern run build
|
|
|
|
# Copy frontend dist for embedding (required for Go embed)
|
|
echo "Copying frontend dist for embedding..."
|
|
rm -rf internal/api/frontend-modern
|
|
mkdir -p internal/api/frontend-modern
|
|
cp -r frontend-modern/dist internal/api/frontend-modern/
|
|
|
|
# Build for different architectures
|
|
declare -A builds=(
|
|
["linux-amd64"]="GOOS=linux GOARCH=amd64"
|
|
["linux-arm64"]="GOOS=linux GOARCH=arm64"
|
|
["linux-armv7"]="GOOS=linux GOARCH=arm GOARM=7"
|
|
)
|
|
|
|
for build_name in "${!builds[@]}"; do
|
|
echo "Building for $build_name..."
|
|
|
|
# Get build environment
|
|
build_env="${builds[$build_name]}"
|
|
|
|
build_time=$(date -u '+%Y-%m-%d_%H:%M:%S')
|
|
git_commit=$(git rev-parse --short HEAD 2>/dev/null || echo 'unknown')
|
|
|
|
# Build backend binary with version info
|
|
env $build_env go build \
|
|
-ldflags="-s -w -X main.Version=v${VERSION} -X main.BuildTime=${build_time} -X main.GitCommit=${git_commit} -X github.com/rcourtman/pulse-go-rewrite/internal/dockeragent.Version=v${VERSION}" \
|
|
-trimpath \
|
|
-o "$BUILD_DIR/pulse-$build_name" \
|
|
./cmd/pulse
|
|
|
|
# Build docker agent binary
|
|
env $build_env go build \
|
|
-ldflags="-s -w -X github.com/rcourtman/pulse-go-rewrite/internal/dockeragent.Version=v${VERSION}" \
|
|
-trimpath \
|
|
-o "$BUILD_DIR/pulse-docker-agent-$build_name" \
|
|
./cmd/pulse-docker-agent
|
|
|
|
# Build host agent binary
|
|
env $build_env go build \
|
|
-ldflags="-s -w -X github.com/rcourtman/pulse-go-rewrite/internal/hostagent.Version=v${VERSION}" \
|
|
-trimpath \
|
|
-o "$BUILD_DIR/pulse-host-agent-$build_name" \
|
|
./cmd/pulse-host-agent
|
|
|
|
# Build temperature proxy binary
|
|
env $build_env go build \
|
|
-ldflags="-s -w -X main.Version=v${VERSION} -X main.BuildTime=${build_time} -X main.GitCommit=${git_commit}" \
|
|
-trimpath \
|
|
-o "$BUILD_DIR/pulse-sensor-proxy-$build_name" \
|
|
./cmd/pulse-sensor-proxy
|
|
|
|
# Create release archive with proper structure
|
|
tar_name="pulse-v${VERSION}-${build_name}.tar.gz"
|
|
|
|
# Create staging directory
|
|
staging_dir="$BUILD_DIR/staging-$build_name"
|
|
rm -rf "$staging_dir"
|
|
mkdir -p "$staging_dir/bin"
|
|
mkdir -p "$staging_dir/scripts"
|
|
|
|
# Copy binaries and VERSION file
|
|
cp "$BUILD_DIR/pulse-$build_name" "$staging_dir/bin/pulse"
|
|
cp "$BUILD_DIR/pulse-docker-agent-$build_name" "$staging_dir/bin/pulse-docker-agent"
|
|
cp "$BUILD_DIR/pulse-host-agent-$build_name" "$staging_dir/bin/pulse-host-agent"
|
|
cp "$BUILD_DIR/pulse-sensor-proxy-$build_name" "$staging_dir/bin/pulse-sensor-proxy"
|
|
cp "scripts/install-docker-agent.sh" "$staging_dir/scripts/install-docker-agent.sh"
|
|
chmod 755 "$staging_dir/scripts/install-docker-agent.sh"
|
|
echo "$VERSION" > "$staging_dir/VERSION"
|
|
|
|
# Create tarball from staging directory
|
|
cd "$staging_dir"
|
|
tar -czf "../../$RELEASE_DIR/$tar_name" .
|
|
cd ../..
|
|
|
|
# Cleanup staging
|
|
rm -rf "$staging_dir"
|
|
|
|
echo "Created $RELEASE_DIR/$tar_name"
|
|
done
|
|
|
|
# Create universal tarball with all binaries
|
|
echo "Creating universal tarball..."
|
|
universal_dir="$BUILD_DIR/universal"
|
|
rm -rf "$universal_dir"
|
|
mkdir -p "$universal_dir/bin"
|
|
mkdir -p "$universal_dir/scripts"
|
|
|
|
# Copy all binaries to bin/ directory to maintain consistent structure
|
|
for build_name in "${!builds[@]}"; do
|
|
cp "$BUILD_DIR/pulse-$build_name" "$universal_dir/bin/pulse-${build_name}"
|
|
cp "$BUILD_DIR/pulse-docker-agent-$build_name" "$universal_dir/bin/pulse-docker-agent-${build_name}"
|
|
cp "$BUILD_DIR/pulse-host-agent-$build_name" "$universal_dir/bin/pulse-host-agent-${build_name}"
|
|
cp "$BUILD_DIR/pulse-sensor-proxy-$build_name" "$universal_dir/bin/pulse-sensor-proxy-${build_name}"
|
|
done
|
|
|
|
cp "scripts/install-docker-agent.sh" "$universal_dir/scripts/install-docker-agent.sh"
|
|
chmod 755 "$universal_dir/scripts/install-docker-agent.sh"
|
|
|
|
# Create a detection script that creates the pulse symlink based on architecture
|
|
cat > "$universal_dir/bin/pulse" << 'EOF'
|
|
#!/bin/sh
|
|
# Auto-detect architecture and run appropriate binary
|
|
|
|
ARCH=$(uname -m)
|
|
case "$ARCH" in
|
|
x86_64|amd64)
|
|
exec "$(dirname "$0")/pulse-linux-amd64" "$@"
|
|
;;
|
|
aarch64|arm64)
|
|
exec "$(dirname "$0")/pulse-linux-arm64" "$@"
|
|
;;
|
|
armv7l|armhf)
|
|
exec "$(dirname "$0")/pulse-linux-armv7" "$@"
|
|
;;
|
|
*)
|
|
echo "Unsupported architecture: $ARCH" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
EOF
|
|
chmod +x "$universal_dir/bin/pulse"
|
|
|
|
cat > "$universal_dir/bin/pulse-docker-agent" << 'EOF'
|
|
#!/bin/sh
|
|
# Auto-detect architecture and run appropriate pulse-docker-agent binary
|
|
|
|
ARCH=$(uname -m)
|
|
case "$ARCH" in
|
|
x86_64|amd64)
|
|
exec "$(dirname "$0")/pulse-docker-agent-linux-amd64" "$@"
|
|
;;
|
|
aarch64|arm64)
|
|
exec "$(dirname "$0")/pulse-docker-agent-linux-arm64" "$@"
|
|
;;
|
|
armv7l|armhf)
|
|
exec "$(dirname "$0")/pulse-docker-agent-linux-armv7" "$@"
|
|
;;
|
|
*)
|
|
echo "Unsupported architecture: $ARCH" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
EOF
|
|
chmod +x "$universal_dir/bin/pulse-docker-agent"
|
|
|
|
cat > "$universal_dir/bin/pulse-sensor-proxy" << 'EOF'
|
|
#!/bin/sh
|
|
# Auto-detect architecture and run appropriate pulse-sensor-proxy binary
|
|
|
|
ARCH=$(uname -m)
|
|
case "$ARCH" in
|
|
x86_64|amd64)
|
|
exec "$(dirname "$0")/pulse-sensor-proxy-linux-amd64" "$@"
|
|
;;
|
|
aarch64|arm64)
|
|
exec "$(dirname "$0")/pulse-sensor-proxy-linux-arm64" "$@"
|
|
;;
|
|
armv7l|armhf)
|
|
exec "$(dirname "$0")/pulse-sensor-proxy-linux-armv7" "$@"
|
|
;;
|
|
*)
|
|
echo "Unsupported architecture: $ARCH" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
EOF
|
|
chmod +x "$universal_dir/bin/pulse-sensor-proxy"
|
|
|
|
cat > "$universal_dir/bin/pulse-host-agent" << 'EOF'
|
|
#!/bin/sh
|
|
# Auto-detect architecture and run appropriate pulse-host-agent binary
|
|
|
|
ARCH=$(uname -m)
|
|
case "$ARCH" in
|
|
x86_64|amd64)
|
|
exec "$(dirname "$0")/pulse-host-agent-linux-amd64" "$@"
|
|
;;
|
|
aarch64|arm64)
|
|
exec "$(dirname "$0")/pulse-host-agent-linux-arm64" "$@"
|
|
;;
|
|
armv7l|armhf)
|
|
exec "$(dirname "$0")/pulse-host-agent-linux-armv7" "$@"
|
|
;;
|
|
*)
|
|
echo "Unsupported architecture: $ARCH" >&2
|
|
exit 1
|
|
;;
|
|
esac
|
|
EOF
|
|
chmod +x "$universal_dir/bin/pulse-host-agent"
|
|
|
|
# Add VERSION file
|
|
echo "$VERSION" > "$universal_dir/VERSION"
|
|
|
|
# Build host agent for macOS arm64
|
|
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}" \
|
|
-trimpath \
|
|
-o "$BUILD_DIR/pulse-host-agent-darwin-arm64" \
|
|
./cmd/pulse-host-agent
|
|
|
|
# Package macOS host agent
|
|
tar -czf "$RELEASE_DIR/pulse-host-agent-v${VERSION}-darwin-arm64.tar.gz" -C "$BUILD_DIR" pulse-host-agent-darwin-arm64
|
|
|
|
# Create universal tarball
|
|
cd "$universal_dir"
|
|
tar -czf "../../$RELEASE_DIR/pulse-v${VERSION}.tar.gz" .
|
|
cd ../..
|
|
|
|
# Cleanup
|
|
rm -rf "$universal_dir"
|
|
|
|
# Copy standalone pulse-sensor-proxy binaries to release directory
|
|
# These are needed by install-sensor-proxy.sh installer script
|
|
echo "Copying standalone pulse-sensor-proxy binaries..."
|
|
for build_name in "${!builds[@]}"; do
|
|
cp "$BUILD_DIR/pulse-sensor-proxy-$build_name" "$RELEASE_DIR/"
|
|
done
|
|
|
|
# Copy standalone pulse-host-agent binaries to release directory
|
|
# These are needed for manual host-agent installation without a running Pulse server
|
|
echo "Copying standalone pulse-host-agent binaries..."
|
|
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)
|
|
cp "$BUILD_DIR/pulse-host-agent-darwin-arm64" "$RELEASE_DIR/"
|
|
|
|
# Optionally package Helm chart
|
|
if [ "${SKIP_HELM_PACKAGE:-0}" != "1" ]; then
|
|
if command -v helm >/dev/null 2>&1; then
|
|
echo "Packaging Helm chart..."
|
|
./scripts/package-helm-chart.sh "$VERSION"
|
|
if [ -f "dist/pulse-$VERSION.tgz" ]; then
|
|
cp "dist/pulse-$VERSION.tgz" "$RELEASE_DIR/"
|
|
fi
|
|
else
|
|
echo "Helm not found on PATH; skipping Helm chart packaging. Install Helm 3.9+ or set SKIP_HELM_PACKAGE=1 to silence this message."
|
|
fi
|
|
fi
|
|
|
|
# Copy install.sh to release directory (required for GitHub releases)
|
|
echo "Copying install.sh to release directory..."
|
|
cp install.sh "$RELEASE_DIR/"
|
|
|
|
# Generate checksums (include tarballs, helm chart, standalone binaries, and install.sh)
|
|
cd "$RELEASE_DIR"
|
|
shopt -s nullglob
|
|
checksum_files=( *.tar.gz pulse-sensor-proxy-* pulse-host-agent-* install.sh )
|
|
if compgen -G "pulse-*.tgz" > /dev/null; then
|
|
checksum_files+=( pulse-*.tgz )
|
|
fi
|
|
if [ ${#checksum_files[@]} -eq 0 ]; then
|
|
echo "Warning: no release artifacts found to checksum."
|
|
else
|
|
# Generate individual .sha256 files for each asset (required by install.sh)
|
|
for file in "${checksum_files[@]}"; do
|
|
sha256sum "$file" > "${file}.sha256"
|
|
done
|
|
|
|
# Also generate combined checksums.txt for convenience
|
|
sha256sum "${checksum_files[@]}" > checksums.txt
|
|
if [ -n "${SIGNING_KEY_ID:-}" ]; then
|
|
if command -v gpg >/dev/null 2>&1; then
|
|
echo "Signing checksums with GPG key ${SIGNING_KEY_ID}..."
|
|
gpg --batch --yes --detach-sign --armor \
|
|
--local-user "${SIGNING_KEY_ID}" \
|
|
--output checksums.txt.asc \
|
|
checksums.txt
|
|
else
|
|
echo "SIGNING_KEY_ID is set but gpg is not installed; skipping signature."
|
|
fi
|
|
fi
|
|
fi
|
|
shopt -u nullglob
|
|
cd ..
|
|
|
|
echo
|
|
echo "Release build complete!"
|
|
echo "Archives created in $RELEASE_DIR/"
|
|
ls -lh $RELEASE_DIR/
|