diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5f2d964..a5043d9 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,6 +27,13 @@ jobs: go-version-file: go.mod cache: true + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + cache-dependency-path: webui/package-lock.json + - name: Install packaging tools run: | sudo apt-get update @@ -47,72 +54,11 @@ jobs: echo "version=$version" >> "$GITHUB_OUTPUT" echo "Build version: $version (from $raw)" - - name: Build release binaries (Linux minimal, others default) + - name: Build and package release artifacts run: | set -euo pipefail - mkdir -p build - make sync-embed-workspace - trap 'make cleanup-embed-workspace' EXIT - - # Build non-Linux targets with default flags. - for target in darwin/amd64 darwin/arm64 windows/amd64 windows/arm64; do - goos="${target%/*}" - goarch="${target#*/}" - out="build/clawgo-${goos}-${goarch}" - if [ "${goos}" = "windows" ]; then out="${out}.exe"; fi - CGO_ENABLED=0 GOOS="${goos}" GOARCH="${goarch}" go build \ - -trimpath -buildvcs=false \ - -ldflags "-X main.version=${{ steps.ver.outputs.version }} -X main.buildTime=$(date +%FT%T%z) -s -w" \ - -o "${out}" ./cmd/clawgo - done - - # Linux targets use slimmer flags without disabling channel capabilities. - for arch in amd64 arm64 riscv64; do - out="build/clawgo-linux-${arch}" - CGO_ENABLED=0 GOOS=linux GOARCH="${arch}" go build \ - -trimpath -buildvcs=false -tags "purego,netgo,osusergo" \ - -ldflags "-X main.version=${{ steps.ver.outputs.version }} -X main.buildTime=$(date +%FT%T%z) -s -w -buildid=" \ - -o "${out}" ./cmd/clawgo - done - - - name: Package artifacts - run: | - set -euo pipefail - rm -f build/checksums.txt - for target in linux/amd64 linux/arm64 linux/riscv64 darwin/amd64 darwin/arm64 windows/amd64 windows/arm64; do - goos="${target%/*}" - goarch="${target#*/}" - bin="clawgo-${goos}-${goarch}" - if [ "${goos}" = "windows" ]; then - bin="${bin}.exe" - zip -q -j "build/clawgo-${goos}-${goarch}.zip" "build/${bin}" - else - tar -czf "build/clawgo-${goos}-${goarch}.tar.gz" -C build "${bin}" - fi - done - - if command -v sha256sum >/dev/null 2>&1; then - (cd build && sha256sum *.tar.gz *.zip | tee checksums.txt) - else - (cd build && shasum -a 256 *.tar.gz *.zip | tee checksums.txt) - fi - - - name: Setup Node.js - uses: actions/setup-node@v4 - with: - node-version: '20' - cache: 'npm' - cache-dependency-path: webui/package-lock.json - - - name: Build WebUI - run: | - if [ -f webui/package-lock.json ]; then - npm ci --prefix webui - else - npm install --prefix webui - fi - npm run build --prefix webui - tar -czf build/webui.tar.gz -C webui dist + make clean + make package-all VERSION="${{ steps.ver.outputs.version }}" - name: Upload artifacts uses: actions/upload-artifact@v4 diff --git a/Makefile b/Makefile index 6dfface..2743eff 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,4 @@ -.PHONY: all build build-linux-slim build-all package-all install install-win uninstall clean help test install-bootstrap-docs sync-embed-workspace cleanup-embed-workspace test-only clean-test-artifacts dev +.PHONY: all build build-linux-slim build-all build-webui package-all install install-win uninstall clean help test install-bootstrap-docs sync-embed-workspace sync-embed-workspace-base sync-embed-webui cleanup-embed-workspace test-only clean-test-artifacts dev # Build variables BINARY_NAME=clawgo @@ -47,11 +47,14 @@ WORKSPACE_SKILLS_DIR=$(WORKSPACE_DIR)/skills BUILTIN_SKILLS_DIR=$(CURDIR)/skills WORKSPACE_SOURCE_DIR=$(CURDIR)/workspace EMBED_WORKSPACE_DIR=$(CURDIR)/cmd/$(BINARY_NAME)/workspace +EMBED_WEBUI_DIR=$(EMBED_WORKSPACE_DIR)/webui DEV_CONFIG?=$(if $(wildcard $(CURDIR)/config.json),$(CURDIR)/config.json,$(CLAWGO_HOME)/config.json) DEV_ARGS?=--debug gateway run DEV_WORKSPACE?=$(WORKSPACE_DIR) DEV_WEBUI_DIR?=$(CURDIR)/webui -DEV_WEBUI_BUILD?=1 +WEBUI_DIST_DIR=$(DEV_WEBUI_DIR)/dist +WEBUI_PACKAGE_LOCK=$(DEV_WEBUI_DIR)/package-lock.json +NPM?=npm # OS detection UNAME_S:=$(shell uname -s) @@ -139,6 +142,28 @@ build-all: sync-embed-workspace done @echo "All builds complete" +## build-webui: Install WebUI dependencies when needed and build dist assets +build-webui: + @echo "Building WebUI..." + @if [ ! -d "$(DEV_WEBUI_DIR)" ]; then \ + echo "✗ Missing WebUI directory: $(DEV_WEBUI_DIR)"; \ + exit 1; \ + fi + @if ! command -v "$(NPM)" >/dev/null 2>&1; then \ + echo "✗ npm is required to build the WebUI"; \ + exit 1; \ + fi + @set -e; \ + if [ ! -d "$(DEV_WEBUI_DIR)/node_modules" ]; then \ + echo "Installing WebUI dependencies..."; \ + if [ -f "$(WEBUI_PACKAGE_LOCK)" ]; then \ + (cd "$(DEV_WEBUI_DIR)" && "$(NPM)" ci); \ + else \ + (cd "$(DEV_WEBUI_DIR)" && "$(NPM)" install); \ + fi; \ + fi; \ + (cd "$(DEV_WEBUI_DIR)" && "$(NPM)" run build) + ## package-all: Create compressed archives and checksums for all build targets package-all: build-all @echo "Packaging build artifacts..." @@ -155,7 +180,9 @@ package-all: build-all archive="$(BINARY_NAME)-$$goos-$$goarch.tar.gz"; \ tar -czf "$$archive" "$$bin"; \ fi; \ - done; \ + done + @tar -czf "$(BUILD_DIR)/webui.tar.gz" -C "$(DEV_WEBUI_DIR)" dist + @set -e; cd $(BUILD_DIR); \ if command -v sha256sum >/dev/null 2>&1; then \ sha256sum *.tar.gz *.zip 2>/dev/null | tee checksums.txt || true; \ elif command -v shasum >/dev/null 2>&1; then \ @@ -163,8 +190,12 @@ package-all: build-all fi @echo "Package complete: $(BUILD_DIR)" -## sync-embed-workspace: Sync root workspace files into cmd/clawgo/workspace for go:embed -sync-embed-workspace: +## sync-embed-workspace: Sync workspace seed files and built WebUI into cmd/clawgo/workspace for go:embed +sync-embed-workspace: sync-embed-workspace-base sync-embed-webui + @echo "✓ Embed assets ready in $(EMBED_WORKSPACE_DIR)" + +## sync-embed-workspace-base: Sync root workspace files into cmd/clawgo/workspace for go:embed +sync-embed-workspace-base: @echo "Syncing workspace seed files for embedding..." @if [ ! -d "$(WORKSPACE_SOURCE_DIR)" ]; then \ echo "✗ Missing source workspace directory: $(WORKSPACE_SOURCE_DIR)"; \ @@ -172,7 +203,17 @@ sync-embed-workspace: fi @mkdir -p "$(EMBED_WORKSPACE_DIR)" @rsync -a --delete "$(WORKSPACE_SOURCE_DIR)/" "$(EMBED_WORKSPACE_DIR)/" - @echo "✓ Synced to $(EMBED_WORKSPACE_DIR)" + @echo "✓ Synced workspace to $(EMBED_WORKSPACE_DIR)" + +## sync-embed-webui: Build and sync WebUI dist into embedded workspace assets +sync-embed-webui: build-webui + @if [ ! -d "$(WEBUI_DIST_DIR)" ]; then \ + echo "✗ Missing WebUI dist directory: $(WEBUI_DIST_DIR)"; \ + exit 1; \ + fi + @mkdir -p "$(EMBED_WEBUI_DIR)" + @rsync -a --delete "$(WEBUI_DIST_DIR)/" "$(EMBED_WEBUI_DIR)/" + @echo "✓ Synced WebUI dist to $(EMBED_WEBUI_DIR)" ## cleanup-embed-workspace: Remove synced embed workspace artifacts cleanup-embed-workspace: @@ -315,10 +356,6 @@ dev: sync-embed-workspace exit 1; \ fi @set -e; trap '$(MAKE) -C $(CURDIR) cleanup-embed-workspace' EXIT; \ - if [ "$(DEV_WEBUI_BUILD)" = "1" ]; then \ - echo "Building WebUI..."; \ - (cd "$(DEV_WEBUI_DIR)" && npm run build); \ - fi; \ echo "Syncing WebUI dist to $(DEV_WORKSPACE)/webui ..."; \ mkdir -p "$(DEV_WORKSPACE)/webui"; \ rsync -a --delete "$(DEV_WEBUI_DIR)/dist/" "$(DEV_WORKSPACE)/webui/"; \ @@ -360,7 +397,7 @@ help: @echo " DEV_ARGS # CLI args for make dev (default: --debug gateway run)" @echo " DEV_WORKSPACE # Workspace path for WebUI sync in make dev" @echo " DEV_WEBUI_DIR # WebUI source dir for make dev (default: ./webui)" - @echo " DEV_WEBUI_BUILD # 1=build WebUI before make dev (default: 1)" + @echo " NPM # npm executable for WebUI build (default: npm)" @echo " VERSION # Version string (default: git describe)" @echo " STRIP_SYMBOLS # 1=strip debug/symbol info (default: 1)" @echo ""