diff --git a/.github/workflows/docker.yml b/.github/workflows/docker.yml index b61edc96..47e3c15d 100644 --- a/.github/workflows/docker.yml +++ b/.github/workflows/docker.yml @@ -22,7 +22,7 @@ jobs: - name: Get Version run: | - echo VERSION=$(cat share/const.go |grep 'const VERSION' | awk '{print $4}' | sed "s/\"//g") >> $GITHUB_ENV + echo VERSION=$(cat share/const.go |grep 'const VERSION' | awk '{print $4}' | sed "s/\"//g")-dev >> $GITHUB_ENV - name: Check Version run: echo $VERSION diff --git a/.github/workflows/release-linux.yml b/.github/workflows/release-linux.yml index cc0a6543..acfdc1ee 100644 --- a/.github/workflows/release-linux.yml +++ b/.github/workflows/release-linux.yml @@ -6,7 +6,7 @@ on: tags: description: "Version tags" push: - branches: [main] + branches: [v0.10.3-dev] paths: - "share/const.go" @@ -108,6 +108,8 @@ jobs: - name: Checkout Code uses: actions/checkout@v2 + with: + ref: v0.10.3-dev - name: Setup Go ${{ matrix.go }} uses: actions/setup-go@v3 diff --git a/.github/workflows/release-macos.yml b/.github/workflows/release-macos.yml index d6bdda4c..c1e39ae4 100644 --- a/.github/workflows/release-macos.yml +++ b/.github/workflows/release-macos.yml @@ -6,7 +6,7 @@ on: tags: description: "Version tags" push: - branches: [main] + branches: [v0.10.3-dev] paths: - "share/const.go" @@ -105,6 +105,8 @@ jobs: - name: Checkout Code uses: actions/checkout@v2 + with: + ref: v0.10.3-dev - name: Setup Go ${{ matrix.go }} uses: actions/setup-go@v3 diff --git a/.github/workflows/unit-test.yml b/.github/workflows/unit-test.yml index bb9ad54f..50dba61a 100644 --- a/.github/workflows/unit-test.yml +++ b/.github/workflows/unit-test.yml @@ -4,9 +4,9 @@ on: workflow_dispatch: inputs: tags: - description: "Comment" + description: "Version" push: - branches: [main] + branches: [v0.10.3-dev] env: YAO_DEV: ${{ github.WORKSPACE }} @@ -133,6 +133,8 @@ jobs: - name: Checkout Code uses: actions/checkout@v3 + with: + ref: v0.10.3-dev - name: Start Redis uses: supercharge/redis-github-action@1.4.0 diff --git a/Makefile b/Makefile index deaf9264..7e368c12 100644 --- a/Makefile +++ b/Makefile @@ -174,7 +174,7 @@ artifacts-linux: clean mv dist/yao-*-* dist/release/ chmod +x dist/release/yao-*-* ls -l dist/release/ - dist/release/yao-${VERSION}-linux-amd64 version + dist/release/yao-${VERSION}-dev-linux-amd64 version # Reset const # cp -f share/const.goe share/const.go @@ -224,7 +224,7 @@ artifacts-macos: clean mv dist/yao-*-* dist/release/ chmod +x dist/release/yao-*-* ls -l dist/release/ - dist/release/yao-${VERSION}-darwin-amd64 version + dist/release/yao-${VERSION}-dev-darwin-amd64 version # Reset const # cp -f share/const.goe share/const.go diff --git a/README.md b/README.md index 7228c30a..6f5903c4 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@

-

YAO App Engine

+

YAO App Engine ( v0.10.3 - dev )

diff --git a/cmd/start.go b/cmd/start.go index 9cfb2b17..0aecbed3 100644 --- a/cmd/start.go +++ b/cmd/start.go @@ -129,13 +129,15 @@ var startCmd = &cobra.Command{ } - // start watching - if mode == "development" && !startDisableWatching { - // Watching - fmt.Println(color.WhiteString("\n---------------------------------")) - fmt.Println(color.WhiteString(L("Watching"))) - fmt.Println(color.WhiteString("---------------------------------")) - // service.Watch(config.Conf) + srv, err := service.Start(config.Conf) + defer func() { + service.Stop(srv) + fmt.Println(color.GreenString(L("✨EXITED✨"))) + }() + + if err != nil { + fmt.Println(color.RedString(L("Fatal: %s"), err.Error())) + os.Exit(1) } // print the messages under the production mode @@ -147,11 +149,15 @@ var startCmd = &cobra.Command{ printStores(true) } - srv, err := service.Start(config.Conf) - defer func() { - service.Stop(srv) - fmt.Println(color.GreenString(L("✨EXITED✨"))) - }() + // start watching + watchDone := make(chan uint8, 1) + if mode == "development" && !startDisableWatching { + // Watching + fmt.Println(color.WhiteString("\n---------------------------------")) + fmt.Println(color.WhiteString(L("Watching"))) + fmt.Println(color.WhiteString("---------------------------------")) + go service.Watch(srv, watchDone) + } for { select { @@ -170,6 +176,7 @@ var startCmd = &cobra.Command{ } case <-interrupt: + watchDone <- 1 return } } diff --git a/docker/development/Dockerfile b/docker/development/Dockerfile index 37498434..18f85cb8 100644 --- a/docker/development/Dockerfile +++ b/docker/development/Dockerfile @@ -20,7 +20,7 @@ ARG ARCH RUN groupadd -r yao && useradd -r -g yao yao && \ apt-get update && \ apt-get install -y curl sudo procps net-tools -RUN curl -fsSL "https://release-sv-1252011659.cos.na-siliconvalley.myqcloud.com/archives/yao-${VERSION}-linux-${ARCH}" > /usr/local/bin/yao && \ +RUN curl -fsSL "https://release-sv-1252011659.cos.na-siliconvalley.myqcloud.com/archives/yao-${VERSION}-dev-linux-${ARCH}" > /usr/local/bin/yao && \ chmod +x /usr/local/bin/yao && \ mkdir -p /data/app diff --git a/docker/production/Dockerfile b/docker/production/Dockerfile index 5339f235..17cb1176 100644 --- a/docker/production/Dockerfile +++ b/docker/production/Dockerfile @@ -18,7 +18,7 @@ FROM alpine:latest ARG VERSION ARG ARCH RUN apk --no-cache add curl -RUN curl -fsSL "https://release-sv-1252011659.cos.na-siliconvalley.myqcloud.com/archives/yao-${VERSION}-linux-${ARCH}" > /usr/local/bin/yao && \ +RUN curl -fsSL "https://release-sv-1252011659.cos.na-siliconvalley.myqcloud.com/archives/yao-${VERSION}-dev-linux-${ARCH}" > /usr/local/bin/yao && \ chmod +x /usr/local/bin/yao RUN mkdir -p /data/app VOLUME /data/app diff --git a/service/watch.go b/service/watch.go index 48a2f755..ac636a18 100644 --- a/service/watch.go +++ b/service/watch.go @@ -13,6 +13,8 @@ import ( "github.com/fatih/color" "github.com/fsnotify/fsnotify" + "github.com/yaoapp/gou/application" + "github.com/yaoapp/gou/server/http" "github.com/yaoapp/kun/log" "github.com/yaoapp/yao/config" "github.com/yaoapp/yao/engine" @@ -27,12 +29,41 @@ var handlers = map[string]func(root string, file string, event string, cfg confi } // Watch the application code change for hot update -func Watch(cfg config.Config) (err error) { - go func() { err = watchStart(cfg) }() - select { - case <-watchReady: - return nil +func Watch(srv *http.Server, interrupt chan uint8) (err error) { + + if application.App == nil { + return fmt.Errorf("Application is not initialized") } + + return application.App.Watch(func(event, name string) { + if strings.Contains(event, "CHMOD") { + return + } + + // Reload + err = engine.Reload(config.Conf) + if err != nil { + fmt.Println(color.RedString("[Watch] Reload: %s", err.Error())) + return + } + fmt.Println(color.GreenString("[Watch] Reload Completed")) + + // Model + if strings.HasPrefix(name, "/models") { + fmt.Println(color.GreenString("[Watch] Model: %s changed (Please run yao migrate manually)", name)) + } + + // Restart + if strings.HasPrefix(name, "/apis") { + err = srv.Restart() + if err != nil { + fmt.Println(color.RedString("[Watch] Restart: %s", err.Error())) + return + } + fmt.Println(color.GreenString("[Watch] Restart Completed")) + } + + }, interrupt) } // StopWatch stop watching the code change diff --git a/service/watch_test.go b/service/watch_test.go index aad54ec9..d62b7380 100644 --- a/service/watch_test.go +++ b/service/watch_test.go @@ -1,153 +1,31 @@ package service import ( - "fmt" - "io/ioutil" - "os" - "path/filepath" "testing" "time" "github.com/yaoapp/yao/config" - "github.com/yaoapp/yao/share" + "github.com/yaoapp/yao/engine" ) func TestWatch(t *testing.T) { - - share.DBConnect(config.Conf.DB) - err := Watch(config.Conf) + err := engine.Load(config.Conf) if err != nil { t.Fatal(err) } - defer StopWatch() - createDir(t) - renameDir(t) - - createModel(t) - changeModel(t) - renameModel(t) - removeModel(t) - - createModel(t) - removeDir(t) -} - -func TestWatchReload(t *testing.T) { - go Start(config.Conf) - // defer Stop(func() {}) - share.DBConnect(config.Conf.DB) - watchReload("", "", "", config.Conf) -} - -func createDir(t *testing.T) { - root := config.Conf.Root - file := filepath.Join(root, "models", "watch", "test") - fmt.Println("CREATE-DIR", file) - err := os.MkdirAll(file, os.ModePerm) + srv, err := Start(config.Conf) if err != nil { t.Fatal(err) } - time.Sleep(1 * time.Second) -} + defer Stop(srv) -func renameDir(t *testing.T) { - root := config.Conf.Root - file := filepath.Join(root, "models", "watch", "test") - new := filepath.Join(root, "models", "watch", "test_new") - fmt.Println("RENAME-DIR", file) - err := os.Rename(file, new) - if err != nil { - t.Fatal(err) - } - time.Sleep(1 * time.Second) -} + done := make(chan uint8, 1) + go Watch(srv, done) -func removeDir(t *testing.T) { - root := config.Conf.Root - file := filepath.Join(root, "models", "watch") - fmt.Println("REMOVE-DIR", file) - err := os.RemoveAll(file) - if err != nil { - t.Fatal(err) + select { + case <-time.After(200 * time.Millisecond): + done <- 1 + return } - time.Sleep(1 * time.Second) -} - -func createModel(t *testing.T) { - dsl := ` - { - "name": "watch-test", - "table": { - "name": "watch_test", - "comment": "WatchTest", - "engine": "InnoDB" - }, - "columns": [ - { "name": "id", "type": "ID" }, - { "label": "Name", "name": "name", "type": "string", "index": true } - ], - "relations": {}, - "option": { "timestamps": true, "soft_deletes": true } - } - ` - root := config.Conf.Root - file := filepath.Join(root, "models", "watch", "test_new", "watch.mod.json") - fmt.Println("CREATE", file) - err := ioutil.WriteFile(file, []byte(dsl), 0644) - if err != nil { - t.Fatal(err) - } - time.Sleep(1 * time.Second) -} - -func changeModel(t *testing.T) { - dsl := ` - { - "name": "watch-test", - "table": { - "name": "watch_test", - "comment": "WatchTest", - "engine": "InnoDB" - }, - "columns": [ - { "name": "id", "type": "ID" }, - { "label": "Name", "name": "name", "type": "string", "index": true }, - { "label": "Data", "name": "data", "type": "json", "nullable": true } - ], - "relations": {}, - "option": { "timestamps": true, "soft_deletes": true } - } - ` - root := config.Conf.Root - file := filepath.Join(root, "models", "watch", "test_new", "watch.mod.json") - fmt.Println("CHANGE", file) - err := ioutil.WriteFile(file, []byte(dsl), 0644) - if err != nil { - t.Fatal(err) - } - time.Sleep(1 * time.Second) -} - -func renameModel(t *testing.T) { - root := config.Conf.Root - file := filepath.Join(root, "models", "watch", "test_new", "watch.mod.json") - new := filepath.Join(root, "models", "watch", "test_new", "watch_new.mod.json") - fmt.Println("RENAME", new) - err := os.Rename(file, new) - if err != nil { - t.Fatal(err) - } - time.Sleep(1 * time.Second) -} - -func removeModel(t *testing.T) { - root := config.Conf.Root - file := filepath.Join(root, "models", "watch", "test_new", "watch_new.mod.json") - fmt.Println("REMOVE", file) - err := os.Remove(file) - if err != nil { - t.Fatal(err) - } - time.Sleep(1 * time.Second) }