ci(backend): 调整 embed server

This commit is contained in:
Forest
2025-12-20 16:44:25 +08:00
parent 1e1f3c0c74
commit aa89777dda
5 changed files with 46 additions and 13 deletions

7
.gitignore vendored
View File

@@ -81,7 +81,12 @@ build/
release/
# 后端嵌入的前端构建产物
# Keep a placeholder file so `//go:embed all:dist` always has a match in CI/lint,
# while still ignoring generated frontend build outputs.
backend/internal/web/dist/
!backend/internal/web/dist/
backend/internal/web/dist/*
!backend/internal/web/dist/.keep
# 后端运行时缓存数据
backend/data/
@@ -92,4 +97,4 @@ backend/data/
tests
CLAUDE.md
.claude
scripts
scripts

View File

@@ -14,10 +14,11 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
go-version-file: backend/go.mod
check-latest: true
cache: true
- name: Run tests
working-directory: backend
run: go test ./...
golangci-lint:
@@ -26,11 +27,12 @@ jobs:
- uses: actions/checkout@v4
- uses: actions/setup-go@v5
with:
go-version-file: go.mod
go-version-file: backend/go.mod
check-latest: true
cache: true
- name: golangci-lint
uses: golangci/golangci-lint-action@v6
uses: golangci/golangci-lint-action@v9
with:
version: latest
version: v2.7
args: --timeout=5m
working-directory: backend

View File

@@ -1,6 +1,16 @@
.PHONY: wire
.PHONY: wire build build-embed
wire:
@echo "生成 Wire 代码..."
@cd cmd/server && go generate
@echo "Wire 代码生成完成"
@echo "Wire 代码生成完成"
build:
@echo "构建后端(不嵌入前端)..."
@go build -o bin/server ./cmd/server
@echo "构建完成: bin/server"
build-embed:
@echo "构建后端(嵌入前端)..."
@go build -tags embed -o bin/server ./cmd/server
@echo "构建完成: bin/server (with embedded frontend)"

View File

@@ -0,0 +1,20 @@
//go:build !embed
package web
import (
"net/http"
"github.com/gin-gonic/gin"
)
func ServeEmbeddedFrontend() gin.HandlerFunc {
return func(c *gin.Context) {
c.String(http.StatusNotFound, "Frontend not embedded. Build with -tags embed to include frontend.")
c.Abort()
}
}
func HasEmbeddedFrontend() bool {
return false
}

View File

@@ -1,3 +1,5 @@
//go:build embed
package web
import (
@@ -13,8 +15,6 @@ import (
//go:embed all:dist
var frontendFS embed.FS
// ServeEmbeddedFrontend returns a Gin handler that serves embedded frontend assets
// and handles SPA routing by falling back to index.html for non-API routes.
func ServeEmbeddedFrontend() gin.HandlerFunc {
distFS, err := fs.Sub(frontendFS, "dist")
if err != nil {
@@ -25,7 +25,6 @@ func ServeEmbeddedFrontend() gin.HandlerFunc {
return func(c *gin.Context) {
path := c.Request.URL.Path
// Skip API and gateway routes
if strings.HasPrefix(path, "/api/") ||
strings.HasPrefix(path, "/v1/") ||
strings.HasPrefix(path, "/setup/") ||
@@ -34,7 +33,6 @@ func ServeEmbeddedFrontend() gin.HandlerFunc {
return
}
// Try to serve static file
cleanPath := strings.TrimPrefix(path, "/")
if cleanPath == "" {
cleanPath = "index.html"
@@ -47,7 +45,6 @@ func ServeEmbeddedFrontend() gin.HandlerFunc {
return
}
// SPA fallback: serve index.html for all other routes
serveIndexHTML(c, distFS)
}
}
@@ -72,7 +69,6 @@ func serveIndexHTML(c *gin.Context, fsys fs.FS) {
c.Abort()
}
// HasEmbeddedFrontend checks if frontend assets are embedded
func HasEmbeddedFrontend() bool {
_, err := frontendFS.ReadFile("dist/index.html")
return err == nil