feat: embed dist

This commit is contained in:
naiba 2024-11-29 21:31:39 +08:00
parent fb99e88487
commit 970c0d0430
7 changed files with 83 additions and 50 deletions

View File

@ -26,8 +26,35 @@ jobs:
image: goreleaser/goreleaser-cross:v1.23 image: goreleaser/goreleaser-cross:v1.23
steps: steps:
- run: git config --global --add safe.directory /__w/nezha/nezha - run: git config --global --add safe.directory /__w/nezha/nezha
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: robinraju/release-downloader@v1
with:
repository: nezhahq/admin-frontend
tag: v1.0.4
fileName: dist.zip
latest: true
extract: true
- name: prepare admin-frontend dists
run: |
rm -rf cmd/dashboard/admin-dist
mv dist cmd/dashboard/admin-dist
- uses: robinraju/release-downloader@v1
with:
repository: nezhahq/user-frontend
tag: v1.0.3
fileName: dist.zip
latest: true
extract: true
- name: prepare admin-frontend dists
run: |
rm -rf cmd/dashboard/user-dist
mv dist cmd/dashboard/user-dist
- name: Fetch IPInfo GeoIP Database - name: Fetch IPInfo GeoIP Database
env: env:
IPINFO_TOKEN: ${{ secrets.IPINFO_TOKEN }} IPINFO_TOKEN: ${{ secrets.IPINFO_TOKEN }}
@ -130,30 +157,6 @@ jobs:
steps: steps:
- uses: actions/checkout@v4 - uses: actions/checkout@v4
- uses: robinraju/release-downloader@v1
with:
repository: nezhahq/admin-frontend
tag: v1.0.3
fileName: dist.zip
latest: true
extract: true
- name: prepare admin-frontend dists
run: |
mv dist admin-dist
- uses: robinraju/release-downloader@v1
with:
repository: nezhahq/user-frontend
tag: v1.0.2
fileName: dist.zip
latest: true
extract: true
- name: prepare admin-frontend dists
run: |
mv dist user-dist
- name: Download artifacts - name: Download artifacts
uses: actions/download-artifact@v4 uses: actions/download-artifact@v4
with: with:

6
.gitignore vendored
View File

@ -17,8 +17,10 @@
.DS_Store .DS_Store
/cmd/dashboard/data /cmd/dashboard/data
/cmd/dashboard/main /cmd/dashboard/main
/cmd/dashboard/admin-dist /cmd/dashboard/admin-dist/*
/cmd/dashboard/user-dist /cmd/dashboard/user-dist/*
!/cmd/dashboard/admin-dist/.gitkeep
!/cmd/dashboard/user-dist/.gitkeep
/config.yml /config.yml
/resource/template/theme-custom /resource/template/theme-custom
/resource/static/custom /resource/static/custom

View File

@ -7,8 +7,6 @@ ARG TARGETOS
ARG TARGETARCH ARG TARGETARCH
COPY --from=certs /etc/ssl/certs /etc/ssl/certs COPY --from=certs /etc/ssl/certs /etc/ssl/certs
COPY ./admin-dist /dashboard/admin-dist
COPY ./user-dist /dashboard/user-dist
COPY ./script/entrypoint.sh /entrypoint.sh COPY ./script/entrypoint.sh /entrypoint.sh
RUN chmod +x /entrypoint.sh RUN chmod +x /entrypoint.sh

View File

View File

@ -3,6 +3,8 @@ package controller
import ( import (
"errors" "errors"
"fmt" "fmt"
"io"
"io/fs"
"log" "log"
"net/http" "net/http"
"os" "os"
@ -21,7 +23,7 @@ import (
"github.com/nezhahq/nezha/service/singleton" "github.com/nezhahq/nezha/service/singleton"
) )
func ServeWeb() http.Handler { func ServeWeb(adminFrontend, userFrontend fs.FS) http.Handler {
gin.SetMode(gin.ReleaseMode) gin.SetMode(gin.ReleaseMode)
r := gin.Default() r := gin.Default()
@ -37,12 +39,13 @@ func ServeWeb() http.Handler {
r.Use(waf.RealIp) r.Use(waf.RealIp)
r.Use(waf.Waf) r.Use(waf.Waf)
r.Use(recordPath) r.Use(recordPath)
routers(r)
routers(r, adminFrontend, userFrontend)
return r return r
} }
func routers(r *gin.Engine) { func routers(r *gin.Engine, adminFrontend, userFrontend fs.FS) {
authMiddleware, err := jwt.New(initParams()) authMiddleware, err := jwt.New(initParams())
if err != nil { if err != nil {
log.Fatal("JWT Error:" + err.Error()) log.Fatal("JWT Error:" + err.Error())
@ -129,7 +132,7 @@ func routers(r *gin.Engine) {
auth.PATCH("/setting", commonHandler(updateConfig)) auth.PATCH("/setting", commonHandler(updateConfig))
r.NoRoute(fallbackToFrontend) r.NoRoute(fallbackToFrontend(adminFrontend, userFrontend))
} }
func recordPath(c *gin.Context) { func recordPath(c *gin.Context) {
@ -208,25 +211,46 @@ func commonHandler[T any](handler handlerFunc[T]) func(*gin.Context) {
} }
} }
func fallbackToFrontend(c *gin.Context) { func fallbackToFrontend(adminFrontend, userFrontend fs.FS) func(*gin.Context) {
if strings.HasPrefix(c.Request.URL.Path, "/api") { checkLocalFileOrFs := func(c *gin.Context, fs fs.FS, path string) bool {
c.JSON(http.StatusOK, newErrorResponse(errors.New("404 Not Found"))) if _, err := os.Stat(path); err == nil {
return c.File(path)
return true
}
f, err := fs.Open(path)
if err != nil {
return false
}
defer f.Close()
fileStat, err := f.Stat()
if err != nil {
return false
}
http.ServeContent(c.Writer, c.Request, path, fileStat.ModTime(), f.(io.ReadSeeker))
return true
} }
if strings.HasPrefix(c.Request.URL.Path, "/dashboard") { return func(c *gin.Context) {
stripPath := strings.TrimPrefix(c.Request.URL.Path, "/dashboard") if strings.HasPrefix(c.Request.URL.Path, "/api") {
localFilePath := filepath.Join("./admin-dist", stripPath) c.JSON(http.StatusOK, newErrorResponse(errors.New("404 Not Found")))
if _, err := os.Stat(localFilePath); err == nil {
c.File(localFilePath)
return return
} }
c.File("admin-dist/index.html") if strings.HasPrefix(c.Request.URL.Path, "/dashboard") {
return stripPath := strings.TrimPrefix(c.Request.URL.Path, "/dashboard")
localFilePath := filepath.Join("admin-dist", stripPath)
if checkLocalFileOrFs(c, adminFrontend, localFilePath) {
return
}
if !checkLocalFileOrFs(c, adminFrontend, "admin-dist/index.html") {
c.JSON(http.StatusOK, newErrorResponse(errors.New("404 Not Found")))
}
return
}
localFilePath := filepath.Join("user-dist", c.Request.URL.Path)
if checkLocalFileOrFs(c, userFrontend, localFilePath) {
return
}
if !checkLocalFileOrFs(c, userFrontend, "user-dist/index.html") {
c.JSON(http.StatusOK, newErrorResponse(errors.New("404 Not Found")))
}
} }
localFilePath := filepath.Join("user-dist", c.Request.URL.Path)
if _, err := os.Stat(localFilePath); err == nil {
c.File(localFilePath)
return
}
c.File("user-dist/index.html")
} }

View File

@ -2,6 +2,8 @@ package main
import ( import (
"context" "context"
"embed"
_ "embed"
"flag" "flag"
"fmt" "fmt"
"log" "log"
@ -32,6 +34,10 @@ type DashboardCliParam struct {
var ( var (
dashboardCliParam DashboardCliParam dashboardCliParam DashboardCliParam
//go:embed admin-dist
adminFrontend embed.FS
//go:embed user-dist
userFrontend embed.FS
) )
func initSystem() { func initSystem() {
@ -119,7 +125,7 @@ func main() {
singleton.NewServiceSentinel(serviceSentinelDispatchBus) singleton.NewServiceSentinel(serviceSentinelDispatchBus)
grpcHandler := rpc.ServeRPC() grpcHandler := rpc.ServeRPC()
httpHandler := controller.ServeWeb() httpHandler := controller.ServeWeb(adminFrontend, userFrontend)
controller.InitUpgrader() controller.InitUpgrader()
muxHandler := newHTTPandGRPCMux(httpHandler, grpcHandler) muxHandler := newHTTPandGRPCMux(httpHandler, grpcHandler)

View File