Skip to content

Add backport migration support #23511

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 73 additions & 7 deletions models/migrations/migrations.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"code.gitea.io/gitea/models/migrations/v1_7"
"code.gitea.io/gitea/models/migrations/v1_8"
"code.gitea.io/gitea/models/migrations/v1_9"
"code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
Expand All @@ -38,16 +39,23 @@ const minDBVersion = 70 // Gitea 1.5.3
type Migration interface {
Description() string
Migrate(*xorm.Engine) error
BackportVersion() int64
}

type migration struct {
description string
migrate func(*xorm.Engine) error
description string
migrate func(*xorm.Engine) error
backportVersion int64
}

// NewMigration creates a new migration
func NewMigration(desc string, fn func(*xorm.Engine) error) Migration {
return &migration{desc, fn}
return &migration{desc, fn, 0}
}

// NewBackportMigration creates a new backport migration
func NewBackportMigration(desc string, fn func(*xorm.Engine) error, version int64) Migration {
return &migration{desc, fn, version}
}

// Description returns the migration's description
Expand All @@ -60,12 +68,23 @@ func (m *migration) Migrate(x *xorm.Engine) error {
return m.migrate(x)
}

// IsBackport returns whether the migration is a backport migration
func (m *migration) BackportVersion() int64 {
return m.backportVersion
}

// Version describes the version table. Should have only one row with id==1
type Version struct {
ID int64 `xorm:"pk autoincr"`
Version int64
}

// BackportVersion describes the backport version table.
type BackportVersion struct {
ID int64 `xorm:"pk autoincr"`
Version int64
}

// Use noopMigration when there is a migration that has been no-oped
var noopMigration = func(_ *xorm.Engine) error { return nil }

Expand Down Expand Up @@ -471,8 +490,14 @@ var migrations = []Migration{
NewMigration("Rename Webhook org_id to owner_id", v1_20.RenameWebhookOrgToOwner),
// v246 -> v247
NewMigration("Add missed column owner_id for project table", v1_20.AddNewColumnForProject),
// v247 -> v248
NewMigration("Add BackportVersion table", v1_20.AddBackportVersion),
}

// This is a sequence of backport migrations. Add new backport migrations to the bottom of the list.
// Only in old version branch can insert backport migrations.
var backportMigrations = []Migration{}

// GetCurrentDBVersion returns the current db version
func GetCurrentDBVersion(x *xorm.Engine) (int64, error) {
if err := x.Sync(new(Version)); err != nil {
Expand Down Expand Up @@ -526,6 +551,9 @@ func Migrate(x *xorm.Engine) error {
if err := x.Sync(new(Version)); err != nil {
return fmt.Errorf("sync: %w", err)
}
if err := x.Sync(new(BackportVersion)); err != nil {
return fmt.Errorf("sync: %w", err)
}

currentVersion := &Version{ID: 1}
has, err := x.Get(currentVersion)
Expand Down Expand Up @@ -568,16 +596,54 @@ Please try upgrading to a lower version first (suggested v1.6.4), then upgrade t
}
}

// Get Migrated Backport Versions
var bvs []*BackportVersion
if err = x.Find(&bvs); err != nil {
return err
}
migratedBackportVersions := make(container.Set[int64], len(bvs))
for _, bv := range bvs {
if bv.Version >= minDBVersion {
migratedBackportVersions.Add(bv.Version)
}
}

// Migrate
for i, m := range migrations[v-minDBVersion:] {
log.Info("Migration[%d]: %s", v+int64(i), m.Description())
if migratedBackportVersions.Contains(v + int64(i)) {
log.Info("Skip Migration[%d]: %s, as it is migrated in backport.", v+int64(i), m.Description())
// remove db record
if _, err = x.Delete(&BackportVersion{Version: v + int64(i)}); err != nil {
return err
}
} else {
log.Info("Migration[%d]: %s", v+int64(i), m.Description())
// Reset the mapper between each migration - migrations are not supposed to depend on each other
x.SetMapper(names.GonicMapper{})
if err = m.Migrate(x); err != nil {
return fmt.Errorf("migration[%d]: %s failed: %w", v+int64(i), m.Description(), err)
}
}
currentVersion.Version = v + int64(i) + 1
if _, err = x.ID(1).Update(currentVersion); err != nil {
return err
}
}

// Migrate Backport
for _, m := range backportMigrations {
// Skip migrated backport migration
if migratedBackportVersions.Contains(m.BackportVersion()) {
log.Info("Skip Backport Migration[%d]: %s, as it is migrated.", m.BackportVersion(), m.Description())
continue
}
log.Info("Backport Migration[%d]: %s", m.BackportVersion(), m.Description())
// Reset the mapper between each migration - migrations are not supposed to depend on each other
x.SetMapper(names.GonicMapper{})
if err = m.Migrate(x); err != nil {
return fmt.Errorf("migration[%d]: %s failed: %w", v+int64(i), m.Description(), err)
return fmt.Errorf("backport migration[%d]: %s failed: %w", m.BackportVersion(), m.Description(), err)
}
currentVersion.Version = v + int64(i) + 1
if _, err = x.ID(1).Update(currentVersion); err != nil {
if _, err := x.Insert(&BackportVersion{Version: m.BackportVersion()}); err != nil {
return err
}
}
Expand Down
17 changes: 17 additions & 0 deletions models/migrations/v1_20/v247.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT

package v1_20 //nolint

import (
"xorm.io/xorm"
)

func AddBackportVersion(x *xorm.Engine) error {
type BackportVersion struct {
ID int64 `xorm:"pk autoincr"`
Version int64
}

return x.Sync(new(BackportVersion))
}