Refactor: Load UserTemplates from embedded yaml file (#575)

* Refactor: Load UserTemplates from embedded yaml file

* feat: add version field to UserTemplates

* refactor: use shell script to fetch frontends

* chore: add *-dist to .gitignore

* refactor: rename to FrontendTemplates

BREAKING CHANGE: This commit changes the `user_templates` filed
in the communication json between backend and the admin-frontend.

Keep user config.yml `user_template` filed.
This commit is contained in:
Moraxyc 2024-12-10 21:57:20 +08:00 committed by GitHub
parent 96cbec9dd3
commit 8f8a30c02c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 98 additions and 70 deletions

View File

@ -25,49 +25,18 @@ jobs:
container:
image: goreleaser/goreleaser-cross:v1.23
steps:
- run: |
apt update && apt install unzip curl -y
wget https://github.com/mikefarah/yq/releases/latest/download/yq_linux_amd64 -O /usr/bin/yq
chmod +x /usr/bin/yq
- run: git config --global --add safe.directory /__w/nezha/nezha
- uses: actions/checkout@v4
- name: clean cache
- name: Prepare frontends' dists
run: |
rm -rf cmd/dashboard/*-dist
- uses: robinraju/release-downloader@v1
with:
repository: nezhahq/admin-frontend
tag: v1.1.1
fileName: dist.zip
latest: true
extract: true
- name: prepare admin-frontend dists
run: |
mv dist cmd/dashboard/admin-dist
- uses: robinraju/release-downloader@v1
with:
repository: nezhahq/user-frontend
tag: v1.1.1
fileName: dist.zip
latest: true
extract: true
- name: prepare admin-frontend dists
run: |
mv dist cmd/dashboard/user-dist
- uses: robinraju/release-downloader@v1
with:
repository: hi2shark/nazhua
tag: v0.4.9
fileName: dist.zip
latest: true
extract: true
- name: prepare nazhua-frontend dists
run: |
mv dist cmd/dashboard/nazhua-dist
chmod +x ./script/fetch-frontends.sh && ./script/fetch-frontends.sh
- name: Fetch IPInfo GeoIP Database
env:

3
.gitignore vendored
View File

@ -17,8 +17,7 @@
.DS_Store
/cmd/dashboard/data
/cmd/dashboard/main
/cmd/dashboard/admin-dist/*
/cmd/dashboard/user-dist/*
/cmd/dashboard/*-dist
!/cmd/dashboard/admin-dist/.gitkeep
!/cmd/dashboard/user-dist/.gitkeep
/config.yml

View File

@ -23,9 +23,9 @@ func listConfig(c *gin.Context) (model.SettingResponse, error) {
authorized := isMember // TODO || isViewPasswordVerfied
conf := model.SettingResponse{
Config: *singleton.Conf,
Version: singleton.Version,
UserTemplates: singleton.UserTemplates,
Config: *singleton.Conf,
Version: singleton.Version,
FrontendTemplates: singleton.FrontendTemplates,
}
if !authorized {
@ -59,8 +59,8 @@ func updateConfig(c *gin.Context) (any, error) {
return nil, err
}
var userTemplateValid bool
for _, v := range singleton.UserTemplates {
if v.Path == sf.UserTemplate {
for _, v := range singleton.FrontendTemplates {
if v.Path == sf.UserTemplate && sf.UserTemplate != "admin-dist" {
userTemplateValid = true
break
}

View File

@ -104,6 +104,7 @@ func main() {
}
// 初始化 dao 包
singleton.InitFrontendTemplates()
singleton.InitConfigFromPath(dashboardCliParam.ConfigFile)
singleton.InitTimezoneAndCache()
singleton.InitDBFromPath(dashboardCliParam.DatebaseLocation)

View File

@ -56,7 +56,7 @@ type Config struct {
}
// Read 读取配置文件并应用
func (c *Config) Read(path string, userTemplates []UserTemplate) error {
func (c *Config) Read(path string, frontendTemplates []FrontendTemplate) error {
c.k = koanf.New(".")
c.filePath = path
@ -89,8 +89,8 @@ func (c *Config) Read(path string, userTemplates []UserTemplate) error {
c.Location = "Asia/Shanghai"
}
var userTemplateValid bool
for _, v := range userTemplates {
if v.Path == c.UserTemplate {
for _, v := range frontendTemplates {
if v.Path == c.UserTemplate && c.UserTemplate != "admin-dist" {
userTemplateValid = true
break
}

View File

@ -18,17 +18,19 @@ type SettingForm struct {
EnablePlainIPInNotification bool `json:"enable_plain_ip_in_notification,omitempty" validate:"optional"`
}
type UserTemplate struct {
type FrontendTemplate struct {
Path string `json:"path,omitempty"`
Name string `json:"name,omitempty"`
Repository string `json:"repository,omitempty"`
Author string `json:"author,omitempty"`
Community bool `json:"community,omitempty"`
Version string `json:"version,omitempty"`
IsAdmin string `json:"is_admin,omitempty"`
}
type SettingResponse struct {
Config
Version string `json:"version,omitempty"`
UserTemplates []UserTemplate `json:"user_templates,omitempty"`
Version string `json:"version,omitempty"`
FrontendTemplates []FrontendTemplate `json:"frontend_templates,omitempty"`
}

40
script/fetch-frontends.sh Executable file
View File

@ -0,0 +1,40 @@
#!/bin/bash
set -euo pipefail
ROOT_DIR="$(realpath "$(dirname "${BASH_SOURCE[0]}")/..")"
TEMPLATES_FILE="$ROOT_DIR/service/singleton/frontend-templates.yaml"
download_and_extract() {
local repository="$1"
local version="$2"
local targetDir="$3"
local TMP_DIR
TMP_DIR="$(mktemp -d)"
echo "Downloading from repository: $repository, version: $version"
pushd "$TMP_DIR" || exit
curl -L -o "dist.zip" "$repository/releases/download/$version/dist.zip"
[ -e "$targetDir" ] && rm -r "$targetDir"
unzip -q dist.zip
mv dist "$targetDir"
rm "dist.zip"
popd || exit
}
count=$(yq eval '. | length' "$TEMPLATES_FILE")
for i in $(seq 0 $(("$count"-1))); do
path=$(yq -r ".[$i].path" "$TEMPLATES_FILE")
repository=$(yq -r ".[$i].repository" "$TEMPLATES_FILE")
version=$(yq -r ".[$i].version" "$TEMPLATES_FILE")
if [[ -n $path && -n $repository && -n $version ]]; then
download_and_extract "$repository" "$version" "$ROOT_DIR/cmd/dashboard/$path"
fi
done

View File

@ -0,0 +1,17 @@
- path: "admin-dist"
name: "OfficialAdmin"
repository: "https://github.com/nezhahq/admin-frontend"
author: "nezhahq"
version: "v1.1.1"
isadmin: true
- path: "user-dist"
name: "Official"
repository: "https://github.com/hamster1963/nezha-dash-v1"
author: "hamster1963"
version: "v1.2.5"
- path: "nazhua-dist"
name: "Nazhua"
repository: "https://github.com/hi2shark/nazhua"
author: "hi2hi"
version: "v0.4.10"
community: true

View File

@ -1,10 +1,12 @@
package singleton
import (
_ "embed"
"log"
"time"
"github.com/patrickmn/go-cache"
"gopkg.in/yaml.v3"
"gorm.io/driver/sqlite"
"gorm.io/gorm"
@ -15,27 +17,17 @@ import (
var Version = "debug"
var (
Conf *model.Config
Cache *cache.Cache
DB *gorm.DB
Loc *time.Location
UserTemplates = []model.UserTemplate{
{
Path: "user-dist",
Name: "Official",
Repository: "https://github.com/hamster1963/nezha-dash",
Author: "hamster1963",
}, {
Path: "nazhua-dist",
Name: "Nazhua",
Repository: "https://github.com/hi2shark/nazhua",
Author: "hi2hi",
Community: true,
},
}
Conf *model.Config
Cache *cache.Cache
DB *gorm.DB
Loc *time.Location
FrontendTemplates []model.FrontendTemplate
DashboardBootTime = uint64(time.Now().Unix())
)
//go:embed frontend-templates.yaml
var frontendTemplatesYAML []byte
func InitTimezoneAndCache() {
var err error
Loc, err = time.LoadLocation(Conf.Location)
@ -56,10 +48,18 @@ func LoadSingleton() {
initDDNS()
}
// InitFrontendTemplates 从内置文件中加载FrontendTemplates
func InitFrontendTemplates() {
err := yaml.Unmarshal(frontendTemplatesYAML, &FrontendTemplates)
if err != nil {
panic(err)
}
}
// InitConfigFromPath 从给出的文件路径中加载配置
func InitConfigFromPath(path string) {
Conf = &model.Config{}
err := Conf.Read(path, UserTemplates)
err := Conf.Read(path, FrontendTemplates)
if err != nil {
panic(err)
}