2ee2aaaffb
Add deepseek to resume commands Rename app to spaceshell Add SurfacePicker component for preset panel configuration Extract agent selection logic to shared agents.ts Update landing
182 lines
8.1 KiB
Makefile
182 lines
8.1 KiB
Makefile
# spacesh — local build helpers (macOS).
|
|
# `make` or `make help` lists targets.
|
|
|
|
APP_DIR := app
|
|
TAURI_TARGET := universal-apple-darwin
|
|
DMG_DIR := $(APP_DIR)/src-tauri/target/$(TAURI_TARGET)/release/bundle/dmg
|
|
NATIVE_DMG_DIR := $(APP_DIR)/src-tauri/target/release/bundle/dmg
|
|
NATIVE_TRIPLE := $(shell rustc -vV 2>/dev/null | awk '/^host:/{print $$2}')
|
|
SIDECAR_DIR := $(APP_DIR)/src-tauri/bin
|
|
BUNDLE_CONFIG := src-tauri/tauri.bundle.conf.json
|
|
APP_BUNDLE := $(APP_DIR)/src-tauri/target/$(TAURI_TARGET)/release/bundle/macos/spaceshell.app
|
|
NATIVE_APP_BUNDLE := $(APP_DIR)/src-tauri/target/release/bundle/macos/spaceshell.app
|
|
APP_VERSION := $(shell node -p "require('./$(APP_DIR)/src-tauri/tauri.conf.json').version" 2>/dev/null || echo 0.0.0)
|
|
|
|
LANDING_IMAGE := spacesh-landing
|
|
LANDING_VERSION := $(shell cat landing/VERSION 2>/dev/null || echo 0.0.0)
|
|
REGISTRY ?= git.realmanual.ru
|
|
REPO ?= spacesh
|
|
|
|
# ---- Gitea generic package registry (versioned .dmg downloads) ----
|
|
GITEA_URL ?= https://git.realmanual.ru
|
|
GITEA_OWNER ?= pub
|
|
GITEA_PKG ?= spacesh
|
|
GITEA_TOKEN ?= # token with package:write; pass via env/CLI, never commit
|
|
|
|
# ---- Prod deploy (SSH) ----
|
|
SSH_HOST ?= 192.168.8.5
|
|
SSH_USER ?= root
|
|
SSH_REMOTE_DIR ?= /srv/spaceshell
|
|
SSH_KEY ?= $(HOME)/.ssh/id_rsa
|
|
SSH_OPTS := -i $(SSH_KEY) -o StrictHostKeyChecking=accept-new
|
|
|
|
.DEFAULT_GOAL := help
|
|
|
|
.PHONY: help
|
|
help: ## show this help
|
|
@echo "spacesh — make targets (app v$(APP_VERSION)):"
|
|
@grep -hE '^[a-zA-Z_-]+:.*?## ' $(MAKEFILE_LIST) | \
|
|
awk 'BEGIN{FS=":.*?## "}{printf " \033[36m%-16s\033[0m %s\n", $$1, $$2}'
|
|
|
|
# ---- App / DMG (macOS) ----
|
|
|
|
.PHONY: deps
|
|
deps: ## install frontend deps (npm ci)
|
|
cd $(APP_DIR) && npm ci
|
|
|
|
.PHONY: targets
|
|
targets: ## add rust targets for the universal build
|
|
rustup target add aarch64-apple-darwin x86_64-apple-darwin
|
|
|
|
.PHONY: bump
|
|
bump: ## increment the patch version for BOTH the GUI (tauri.conf.json) and the daemon (workspace Cargo.toml)
|
|
@node scripts/bump_version.mjs
|
|
|
|
.PHONY: dmg
|
|
dmg: bump targets ## bump version + build the universal (Intel + Apple Silicon) .dmg — UNSIGNED
|
|
# Tauri's universal build needs BOTH the per-arch sidecars (resolved during each
|
|
# arch sub-build) AND a fat spaceshd-universal-apple-darwin (copied into the final
|
|
# bundle — Tauri does not lipo sidecars itself). spaceshd ships inside
|
|
# spacesh.app/Contents/MacOS else the GUI is offline.
|
|
cargo build --release -p spaceshd --target aarch64-apple-darwin
|
|
cargo build --release -p spaceshd --target x86_64-apple-darwin
|
|
rm -rf $(SIDECAR_DIR) && mkdir -p $(SIDECAR_DIR) # avoid stale sidecars poisoning the bundle
|
|
cp target/aarch64-apple-darwin/release/spaceshd $(SIDECAR_DIR)/spaceshd-aarch64-apple-darwin
|
|
cp target/x86_64-apple-darwin/release/spaceshd $(SIDECAR_DIR)/spaceshd-x86_64-apple-darwin
|
|
lipo -create -output $(SIDECAR_DIR)/spaceshd-universal-apple-darwin \
|
|
target/aarch64-apple-darwin/release/spaceshd \
|
|
target/x86_64-apple-darwin/release/spaceshd
|
|
cd $(APP_DIR) && npm run tauri build -- --target $(TAURI_TARGET) --config $(BUNDLE_CONFIG)
|
|
@echo "→ $(DMG_DIR)" && ls -lh $(DMG_DIR)/*.dmg
|
|
|
|
.PHONY: dmg-native
|
|
dmg-native: bump ## bump version + build a .dmg for the current arch only (faster)
|
|
cargo build --release -p spaceshd
|
|
rm -rf $(SIDECAR_DIR) && mkdir -p $(SIDECAR_DIR) # avoid stale sidecars poisoning the bundle
|
|
cp target/release/spaceshd $(SIDECAR_DIR)/spaceshd-$(NATIVE_TRIPLE)
|
|
cd $(APP_DIR) && npm run tauri build -- --config $(BUNDLE_CONFIG)
|
|
@ls -lh $(NATIVE_DMG_DIR)/*.dmg
|
|
|
|
.PHONY: app-bundle
|
|
app-bundle: ## build just the native .app (no .dmg/hdiutil — fast, for self-install)
|
|
cargo build --release -p spaceshd
|
|
rm -rf $(SIDECAR_DIR) && mkdir -p $(SIDECAR_DIR)
|
|
cp target/release/spaceshd $(SIDECAR_DIR)/spaceshd-$(NATIVE_TRIPLE)
|
|
cd $(APP_DIR) && npm run tauri build -- --bundles app --config $(BUNDLE_CONFIG)
|
|
|
|
.PHONY: dev
|
|
dev: ## run the app in dev mode (tauri dev)
|
|
cd $(APP_DIR) && npm run tauri dev
|
|
|
|
.PHONY: daemon
|
|
daemon: ## build & run the daemon
|
|
cargo run -p spaceshd
|
|
|
|
.PHONY: kill-daemon
|
|
kill-daemon: ## stop a running spaceshd so a freshly-built one takes over
|
|
-pkill -x spaceshd
|
|
-rm -f $$HOME/.spacesh/sock
|
|
|
|
.PHONY: install
|
|
install: kill-daemon ## install the native .app to /Applications, restart daemon, clear quarantine
|
|
rm -rf /Applications/spacesh.app /Applications/spaceshell.app # drop the pre-rename app too
|
|
cp -R "$(NATIVE_APP_BUNDLE)" /Applications/
|
|
xattr -dr com.apple.quarantine /Applications/spaceshell.app
|
|
@echo "Installed (native). Quit & relaunch spaceshell; the bundled daemon restarts."
|
|
|
|
.PHONY: install-universal
|
|
install-universal: kill-daemon ## install the universal .app to /Applications
|
|
rm -rf /Applications/spacesh.app /Applications/spaceshell.app
|
|
cp -R "$(APP_BUNDLE)" /Applications/
|
|
xattr -dr com.apple.quarantine /Applications/spaceshell.app
|
|
|
|
.PHONY: reinstall
|
|
reinstall: app-bundle install ## fast self-update: build .app (no dmg), reinstall, restart daemon
|
|
|
|
# ---- Tests ----
|
|
|
|
.PHONY: test
|
|
test: ## run all tests (cargo + tsc)
|
|
cargo test
|
|
cd $(APP_DIR) && npx tsc --noEmit
|
|
|
|
# ---- Landing ----
|
|
|
|
.PHONY: landing-image
|
|
landing-image: ## build the landing nginx image
|
|
docker build -t $(LANDING_IMAGE):$(LANDING_VERSION) -t $(LANDING_IMAGE):latest landing
|
|
|
|
.PHONY: landing-run
|
|
landing-run: landing-image ## serve the landing locally on http://localhost:8088
|
|
docker run --rm -p 8088:80 $(LANDING_IMAGE):latest
|
|
|
|
.PHONY: landing-push
|
|
landing-push: landing-image ## tag & push the landing image to the registry
|
|
docker tag $(LANDING_IMAGE):latest $(REGISTRY)/$(REPO)/$(LANDING_IMAGE):$(LANDING_VERSION)
|
|
docker tag $(LANDING_IMAGE):latest $(REGISTRY)/$(REPO)/$(LANDING_IMAGE):latest
|
|
docker push $(REGISTRY)/$(REPO)/$(LANDING_IMAGE):$(LANDING_VERSION)
|
|
docker push $(REGISTRY)/$(REPO)/$(LANDING_IMAGE):latest
|
|
|
|
# ---- Prod deploy ----
|
|
|
|
.PHONY: deploy-dmg
|
|
deploy-dmg: dmg ## upload .dmg + manifest to prod, and publish the versioned .dmg to Gitea Packages
|
|
@VER=$$(node -p "require('./$(APP_DIR)/src-tauri/tauri.conf.json').version"); \
|
|
printf '{"version":"%s","url":"https://spaceshell.ru/download/spacesh.dmg"}\n' "$$VER" > /tmp/spacesh-latest.json; \
|
|
echo "manifest version → $$VER"
|
|
ssh $(SSH_OPTS) $(SSH_USER)@$(SSH_HOST) "mkdir -p $(SSH_REMOTE_DIR)/download"
|
|
scp $(SSH_OPTS) $(DMG_DIR)/*.dmg "$(SSH_USER)@$(SSH_HOST):$(SSH_REMOTE_DIR)/download/spacesh.dmg"
|
|
scp $(SSH_OPTS) /tmp/spacesh-latest.json "$(SSH_USER)@$(SSH_HOST):$(SSH_REMOTE_DIR)/download/latest.json"
|
|
@echo "Uploaded → https://spaceshell.ru/download/spacesh.dmg + latest.json"
|
|
@$(MAKE) --no-print-directory _publish-dmg
|
|
|
|
.PHONY: publish-dmg
|
|
publish-dmg: dmg _publish-dmg ## build + publish the versioned .dmg to the Gitea package registry
|
|
|
|
# Internal: upload the most recently built .dmg to Gitea's generic registry under
|
|
# the current version. No build dependency, so deploy-dmg can call it without a
|
|
# second bump/rebuild. Skips (doesn't fail) when GITEA_TOKEN is unset.
|
|
.PHONY: _publish-dmg
|
|
_publish-dmg:
|
|
@if [ -z "$(GITEA_TOKEN)" ]; then echo "GITEA_TOKEN unset — skipping Gitea Packages publish"; exit 0; fi; \
|
|
VER=$$(node -p "require('./$(APP_DIR)/src-tauri/tauri.conf.json').version"); \
|
|
DMG=$$(ls -t $(DMG_DIR)/*.dmg 2>/dev/null | head -1); \
|
|
if [ -z "$$DMG" ]; then echo "no .dmg in $(DMG_DIR) — run make dmg first"; exit 1; fi; \
|
|
URL="$(GITEA_URL)/api/packages/$(GITEA_OWNER)/generic/$(GITEA_PKG)/$$VER/spaceshell-$$VER.dmg"; \
|
|
echo "Publishing $$DMG → $$URL"; \
|
|
curl --fail-with-body -sS -H "Authorization: token $(GITEA_TOKEN)" --upload-file "$$DMG" "$$URL" && \
|
|
echo "Published spaceshell-$$VER.dmg to Gitea Packages ($(GITEA_OWNER)/$(GITEA_PKG)@$$VER)"
|
|
|
|
.PHONY: deploy-stack
|
|
deploy-stack: ## sync compose+proxy.conf to prod and pull/up (manual; CI does this on push)
|
|
ssh $(SSH_OPTS) $(SSH_USER)@$(SSH_HOST) "mkdir -p $(SSH_REMOTE_DIR)/download"
|
|
scp $(SSH_OPTS) deploy/docker-compose.yaml deploy/proxy.conf "$(SSH_USER)@$(SSH_HOST):$(SSH_REMOTE_DIR)/"
|
|
ssh $(SSH_OPTS) $(SSH_USER)@$(SSH_HOST) "cd $(SSH_REMOTE_DIR) && docker compose pull && docker compose up -d"
|
|
|
|
# ---- Clean ----
|
|
|
|
.PHONY: clean
|
|
clean: ## remove build artifacts
|
|
cargo clean
|
|
rm -rf $(APP_DIR)/dist
|