fix: build system — findWebDir order, auto-copy web static to bin

* findWebDir: CWD and project root checked before binary-adjacent path,
  so dev always serves fresh web/build/ over stale bin/web/build/
* build-go: auto-copies web/build/ to bin/web/ before Go compile
* build-prod: same auto-copy for production builds
* Proper refresh of frontend static on every make build
This commit is contained in:
Maksim Totmin 2026-06-25 19:30:49 +07:00
parent 78e53f42bf
commit 0d8a56e73f
2 changed files with 13 additions and 19 deletions

View File

@ -22,13 +22,17 @@ build-web:
@echo "→ Сборка SvelteKit..."
cd $(WEB_DIR) && npm run build
# Сборка Go бинарника
# Сборка Go бинарника (с авто-копированием статики)
build-go:
@mkdir -p $(BINDIR)
@echo "→ Сборка Go backend..."
@if [ -d $(WEB_DIR)/build ]; then \
rm -rf $(BINDIR)/web && cp -r $(WEB_DIR)/build $(BINDIR)/web; \
echo " статика скопирована в $(BINDIR)/web/"; \
fi
go build -o $(BINDIR)/$(APP) ./cmd/$(APP)
# Быстрая сборка только Go (без фронта)
# Быстрая сборка только Go (без фронта, без статики)
build-go-only:
@mkdir -p $(BINDIR)
go build -o $(BINDIR)/$(APP) ./cmd/$(APP)
@ -43,6 +47,7 @@ run:
build-prod:
@mkdir -p $(BINDIR)
cd $(WEB_DIR) && npm run build
rm -rf $(BINDIR)/web && cp -r $(WEB_DIR)/build $(BINDIR)/web
CGO_ENABLED=0 go build -ldflags="-s -w" -o $(BINDIR)/$(APP) ./cmd/$(APP)
# Установка: копирует бинарник и статику в /usr/local

View File

@ -5,8 +5,6 @@ package main
import (
"context"
"crypto/rand"
"encoding/hex"
"fmt"
"log"
"net/http"
@ -24,6 +22,7 @@ import (
filelog "github.com/pulse-lets-go/internal/log"
"github.com/pulse-lets-go/internal/models"
"github.com/pulse-lets-go/internal/nats"
"github.com/pulse-lets-go/internal/util"
)
func main() {
@ -91,7 +90,7 @@ func main() {
}
// Создаём новый balance-транк
now := time.Now().UTC()
trunkID := "trk-" + randomHex(6)
trunkID := "trk-" + util.RandomHex(6)
trunk := models.Trunk{
ID: trunkID,
Name: fmt.Sprintf("%s баланс", nodeID),
@ -113,7 +112,7 @@ func main() {
})
// 6. HTTP API
apiHandler := api.NewAPI(eng, cfgMgr, cfg.JWTSecret, cfg.MonitoringAPIKey, sub.IsConnected, cfg)
apiHandler := api.NewAPI(eng, cfgMgr, cfg.GetJWTSecret(), cfg.MonitoringAPIKey, sub.IsConnected, cfg)
handler := apiHandler.Handler()
// 6.1 ESL-клиент (опционально — если сконфигурирован)
@ -230,7 +229,6 @@ func main() {
log.Printf("[main] ошибка остановки HTTP сервера: %v", err)
}
sub.Close()
metricsLogger.Close()
log.Println("[main] pulse-lets-go остановлен")
@ -241,9 +239,9 @@ func main() {
func findWebDir(exeDir string) string {
candidates := []string{
os.Getenv("PULSE_WEB_DIR"),
filepath.Join(exeDir, "web", "build"), // bin/web/build
filepath.Join(filepath.Dir(exeDir), "web", "build"), // ../web/build (корень проекта)
"web/build", // ./web/build (CWD)
"web/build", // ./web/build (CWD — dev, systemd working dir)
filepath.Join(filepath.Dir(exeDir), "web", "build"), // ../web/build (корень проекта, dev с bin/)
filepath.Join(exeDir, "web", "build"), // рядом с бинарником (production install)
}
for _, d := range candidates {
if d == "" {
@ -294,15 +292,6 @@ func withSPA(webDir string, apiHandler http.Handler) http.Handler {
})
}
// randomHex генерирует случайную hex-строку заданной длины.
func randomHex(n int) string {
b := make([]byte, n)
if _, err := rand.Read(b); err != nil {
return fmt.Sprintf("%x", time.Now().UnixNano())[:n]
}
return hex.EncodeToString(b)[:n]
}
// extractHostFromGateway извлекает хост из SIP URI.
// "sip:mts-gw.lan:5060" → "mts-gw.lan"
func extractHostFromGateway(gateway string) string {