From b7fe7cf401f4bddd6455efc651f7ac054f3fe1cf Mon Sep 17 00:00:00 2001 From: Earl Warren Date: Tue, 8 Aug 2023 23:55:25 +0200 Subject: [PATCH] [SEMVER] store SemVer in ForgejoSemVer after a database upgrade --- Makefile | 2 +- main.go | 3 ++ models/db/engine.go | 1 + models/db/engine_test.go | 1 + models/forgejo/semver/main_test.go | 18 +++++++ models/forgejo/semver/semver.go | 77 ++++++++++++++++++++++++++++ models/forgejo/semver/semver_test.go | 46 +++++++++++++++++ models/forgejo_migrations/migrate.go | 8 ++- modules/setting/setting.go | 2 + 9 files changed, 156 insertions(+), 2 deletions(-) create mode 100644 models/forgejo/semver/main_test.go create mode 100644 models/forgejo/semver/semver.go create mode 100644 models/forgejo/semver/semver_test.go diff --git a/Makefile b/Makefile index 7a9ebbf2fa..ab6077d705 100644 --- a/Makefile +++ b/Makefile @@ -91,7 +91,7 @@ VERSION = ${GITEA_VERSION} # SemVer FORGEJO_VERSION := 6.0.0+0-gitea-1.21.0 -LDFLAGS := $(LDFLAGS) -X "main.MakeVersion=$(MAKE_VERSION)" -X "main.Version=$(GITEA_VERSION)" -X "main.Tags=$(TAGS)" -X "code.gitea.io/gitea/routers/api/forgejo/v1.ForgejoVersion=$(FORGEJO_VERSION)" +LDFLAGS := $(LDFLAGS) -X "main.MakeVersion=$(MAKE_VERSION)" -X "main.Version=$(GITEA_VERSION)" -X "main.Tags=$(TAGS)" -X "code.gitea.io/gitea/routers/api/forgejo/v1.ForgejoVersion=$(FORGEJO_VERSION)" -X "main.ForgejoVersion=$(FORGEJO_VERSION)" LINUX_ARCHS ?= linux/amd64,linux/386,linux/arm-5,linux/arm-6,linux/arm64 diff --git a/main.go b/main.go index 775c729c56..700b75d748 100644 --- a/main.go +++ b/main.go @@ -31,8 +31,11 @@ var ( MakeVersion = "" // "make" program version if built with make ) +var ForgejoVersion = "1.0.0" + func init() { setting.AppVer = Version + setting.ForgejoVersion = ForgejoVersion setting.AppBuiltWith = formatBuiltWith() setting.AppStartTime = time.Now().UTC() } diff --git a/models/db/engine.go b/models/db/engine.go index 07e4d00270..6d1c10e55b 100755 --- a/models/db/engine.go +++ b/models/db/engine.go @@ -47,6 +47,7 @@ type Engine interface { Incr(column string, arg ...any) *xorm.Session Insert(...any) (int64, error) Iterate(any, xorm.IterFunc) error + IsTableExist(any) (bool, error) Join(joinOperator string, tablename, condition any, args ...any) *xorm.Session SQL(any, ...any) *xorm.Session Where(any, ...any) *xorm.Session diff --git a/models/db/engine_test.go b/models/db/engine_test.go index 5514366777..fb5c73e44f 100644 --- a/models/db/engine_test.go +++ b/models/db/engine_test.go @@ -68,6 +68,7 @@ func TestPrimaryKeys(t *testing.T) { whitelist := map[string]string{ "the_table_name_to_skip_checking": "Write a note here to explain why", + "forgejo_sem_ver": "seriously dude", } for _, bean := range beans { diff --git a/models/forgejo/semver/main_test.go b/models/forgejo/semver/main_test.go new file mode 100644 index 0000000000..46aebd9475 --- /dev/null +++ b/models/forgejo/semver/main_test.go @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: MIT + +package semver + +import ( + "path/filepath" + "testing" + + "code.gitea.io/gitea/models/unittest" + + _ "code.gitea.io/gitea/models" +) + +func TestMain(m *testing.M) { + unittest.MainTest(m, &unittest.TestOptions{ + GiteaRootPath: filepath.Join("..", "..", ".."), + }) +} diff --git a/models/forgejo/semver/semver.go b/models/forgejo/semver/semver.go new file mode 100644 index 0000000000..50923d0a09 --- /dev/null +++ b/models/forgejo/semver/semver.go @@ -0,0 +1,77 @@ +// SPDX-License-Identifier: MIT + +package semver + +import ( + "context" + + "code.gitea.io/gitea/models/db" + + "github.com/hashicorp/go-version" +) + +func init() { + db.RegisterModel(new(ForgejoSemVer)) +} + +type ForgejoSemVer struct { + Version string +} + +func GetVersion(ctx context.Context) (*version.Version, error) { + return GetVersionWithEngine(db.GetEngine(ctx)) +} + +func GetVersionWithEngine(e db.Engine) (*version.Version, error) { + versionString := "v1.0.0" + exists, err := e.IsTableExist("forgejo_sem_ver") + if err != nil { + return nil, err + } + if exists { + var semver ForgejoSemVer + has, err := e.Get(&semver) + if err != nil { + return nil, err + } else if has { + versionString = semver.Version + } + } + + v, err := version.NewVersion(versionString) + if err != nil { + return nil, err + } + return v, nil +} + +func SetVersionString(ctx context.Context, versionString string) error { + return SetVersionStringWithEngine(db.GetEngine(ctx), versionString) +} + +func SetVersionStringWithEngine(e db.Engine, versionString string) error { + v, err := version.NewVersion(versionString) + if err != nil { + return err + } + return SetVersionWithEngine(e, v) +} + +func SetVersion(ctx context.Context, v *version.Version) error { + return SetVersionWithEngine(db.GetEngine(ctx), v) +} + +func SetVersionWithEngine(e db.Engine, v *version.Version) error { + var semver ForgejoSemVer + has, err := e.Get(&semver) + if err != nil { + return err + } + + if !has { + _, err = e.Exec("insert into forgejo_sem_ver values (?)", v.String()) + } else { + _, err = e.Exec("update forgejo_sem_ver set version = ?", v.String()) + } + return err +} diff --git a/models/forgejo/semver/semver_test.go b/models/forgejo/semver/semver_test.go new file mode 100644 index 0000000000..8aca7bee57 --- /dev/null +++ b/models/forgejo/semver/semver_test.go @@ -0,0 +1,46 @@ +// SPDX-License-Identifier: MIT + +package semver + +import ( + "testing" + + "code.gitea.io/gitea/models/db" + "code.gitea.io/gitea/models/unittest" + + "github.com/hashicorp/go-version" + "github.com/stretchr/testify/assert" +) + +func TestForgejoSemVerSetGet(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + ctx := db.DefaultContext + + newVersion, err := version.NewVersion("v1.2.3") + assert.NoError(t, err) + assert.NoError(t, SetVersionString(ctx, newVersion.String())) + databaseVersion, err := GetVersion(ctx) + assert.NoError(t, err) + assert.EqualValues(t, newVersion.String(), databaseVersion.String()) + assert.True(t, newVersion.Equal(databaseVersion)) +} + +func TestForgejoSemVerMissing(t *testing.T) { + assert.NoError(t, unittest.PrepareTestDatabase()) + ctx := db.DefaultContext + e := db.GetEngine(ctx) + + _, err := e.Exec("delete from forgejo_sem_ver") + assert.NoError(t, err) + + v, err := GetVersion(ctx) + assert.NoError(t, err) + assert.EqualValues(t, "1.0.0", v.String()) + + _, err = e.Exec("drop table forgejo_sem_ver") + assert.NoError(t, err) + + v, err = GetVersion(ctx) + assert.NoError(t, err) + assert.EqualValues(t, "1.0.0", v.String()) +} diff --git a/models/forgejo_migrations/migrate.go b/models/forgejo_migrations/migrate.go index 805ffc4b3b..5f7f63587c 100644 --- a/models/forgejo_migrations/migrate.go +++ b/models/forgejo_migrations/migrate.go @@ -8,6 +8,7 @@ import ( "fmt" "os" + "code.gitea.io/gitea/models/forgejo/semver" forgejo_v1_20 "code.gitea.io/gitea/models/forgejo_migrations/v1_20" "code.gitea.io/gitea/modules/git" "code.gitea.io/gitea/modules/log" @@ -139,5 +140,10 @@ func Migrate(x *xorm.Engine) error { return err } } - return nil + + if err := x.Sync(new(semver.ForgejoSemVer)); err != nil { + return fmt.Errorf("sync: %w", err) + } + + return semver.SetVersionStringWithEngine(x, setting.ForgejoVersion) } diff --git a/modules/setting/setting.go b/modules/setting/setting.go index d444d9a017..ebfd3b27be 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -15,6 +15,8 @@ import ( "code.gitea.io/gitea/modules/user" ) +var ForgejoVersion = "1.0.0" + // settings var ( // AppVer is the version of the current build of Gitea. It is set in main.go from main.Version.