refactor: prepare to decouple the "model migration" package and "models" package (#38533)

Migrations should never use model structs directly, because the model
structs can be different in different releases. e.g. if one migration uses
"User" model, it works in the early releases, then one day, when the
User model changes, the migration breaks because it will use the
new (incorrect) User model, it should only use the old User model.

The same to "modules/structs".

---------

Signed-off-by: wxiaoguang <wxiaoguang@gmail.com>
Co-authored-by: delvh <dev.lh@web.de>
This commit is contained in:
wxiaoguang
2026-07-20 03:42:02 +00:00
committed by GitHub
co-authored by delvh
parent 775e3bdb34
commit fff32e9469
378 changed files with 708 additions and 721 deletions
+14
View File
@@ -0,0 +1,14 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package v1_12
import "gitea.dev/modelmigration/base"
func AddBlockOnRejectedReviews(x base.EngineMigration) error {
type ProtectedBranch struct {
BlockOnRejectedReviews bool `xorm:"NOT NULL DEFAULT false"`
}
return x.Sync(new(ProtectedBranch))
}
+23
View File
@@ -0,0 +1,23 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package v1_12
import "gitea.dev/modelmigration/base"
func AddReviewCommitAndStale(x base.EngineMigration) error {
type Review struct {
CommitID string `xorm:"VARCHAR(40)"`
Stale bool `xorm:"NOT NULL DEFAULT false"`
}
type ProtectedBranch struct {
DismissStaleApprovals bool `xorm:"NOT NULL DEFAULT false"`
}
// Old reviews will have commit ID set to "" and not stale
if err := x.Sync(new(Review)); err != nil {
return err
}
return x.Sync(new(ProtectedBranch))
}
+13
View File
@@ -0,0 +1,13 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package v1_12
import "gitea.dev/modelmigration/base"
func FixMigratedRepositoryServiceType(x base.EngineMigration) error {
// structs.GithubService:
// GithubService = 2
_, err := x.Exec("UPDATE repository SET original_service_type = ? WHERE original_url LIKE 'https://github.com/%'", 2)
return err
}
+17
View File
@@ -0,0 +1,17 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package v1_12
import "gitea.dev/modelmigration/base"
func AddOwnerNameOnRepository(x base.EngineMigration) error {
type Repository struct {
OwnerName string
}
if err := x.Sync(new(Repository)); err != nil {
return err
}
_, err := x.Exec("UPDATE repository SET owner_name = (SELECT name FROM `user` WHERE `user`.id = repository.owner_id)")
return err
}
+16
View File
@@ -0,0 +1,16 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package v1_12
import "gitea.dev/modelmigration/base"
func AddIsRestricted(x base.EngineMigration) error {
// User see models/user.go
type User struct {
ID int64 `xorm:"pk autoincr"`
IsRestricted bool `xorm:"NOT NULL DEFAULT false"`
}
return x.Sync(new(User))
}
+14
View File
@@ -0,0 +1,14 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package v1_12
import "gitea.dev/modelmigration/base"
func AddRequireSignedCommits(x base.EngineMigration) error {
type ProtectedBranch struct {
RequireSignedCommits bool `xorm:"NOT NULL DEFAULT false"`
}
return x.Sync(new(ProtectedBranch))
}
+15
View File
@@ -0,0 +1,15 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package v1_12
import "gitea.dev/modelmigration/base"
func AddReactionOriginals(x base.EngineMigration) error {
type Reaction struct {
OriginalAuthorID int64 `xorm:"INDEX NOT NULL DEFAULT(0)"`
OriginalAuthor string
}
return x.Sync(new(Reaction))
}
+21
View File
@@ -0,0 +1,21 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package v1_12
import "gitea.dev/modelmigration/base"
func AddUserRepoMissingColumns(x base.EngineMigration) error {
type VisibleType int
type User struct {
PasswdHashAlgo string `xorm:"NOT NULL DEFAULT 'pbkdf2'"`
Visibility VisibleType `xorm:"NOT NULL DEFAULT 0"`
}
type Repository struct {
IsArchived bool `xorm:"INDEX"`
Topics []string `xorm:"TEXT JSON"`
}
return x.Sync(new(User), new(Repository))
}
+22
View File
@@ -0,0 +1,22 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package v1_12
import (
"fmt"
"gitea.dev/modelmigration/base"
)
func AddReviewMigrateInfo(x base.EngineMigration) error {
type Review struct {
OriginalAuthor string
OriginalAuthorID int64
}
if err := x.Sync(new(Review)); err != nil {
return fmt.Errorf("Sync: %w", err)
}
return nil
}
+25
View File
@@ -0,0 +1,25 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package v1_12
import (
"gitea.dev/modelmigration/base"
"xorm.io/builder"
)
func FixTopicRepositoryCount(x base.EngineMigration) error {
_, err := x.Exec(builder.Delete(builder.NotIn("`repo_id`", builder.Select("`id`").From("`repository`"))).From("`repo_topic`"))
if err != nil {
return err
}
_, err = x.Exec(builder.Update(
builder.Eq{
"`repo_count`": builder.Select("count(*)").From("`repo_topic`").Where(builder.Eq{
"`repo_topic`.`topic_id`": builder.Expr("`topic`.`id`"),
}),
}).From("`topic`").Where(builder.Eq{"'1'": "1"}))
return err
}
+43
View File
@@ -0,0 +1,43 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package v1_12
import (
"fmt"
"gitea.dev/modelmigration/base"
"gitea.dev/modules/timeutil"
)
func AddLanguageStats(x base.EngineMigration) error {
// LanguageStat see models/repo_language_stats.go
type LanguageStat struct {
ID int64 `xorm:"pk autoincr"`
RepoID int64 `xorm:"UNIQUE(s) INDEX NOT NULL"`
CommitID string
IsPrimary bool
Language string `xorm:"VARCHAR(30) UNIQUE(s) INDEX NOT NULL"`
Percentage float32 `xorm:"NUMERIC(5,2) NOT NULL DEFAULT 0"`
Color string `xorm:"-"`
CreatedUnix timeutil.TimeStamp `xorm:"INDEX CREATED"`
}
type RepoIndexerType int
// RepoIndexerStatus see models/repo_stats_indexer.go
type RepoIndexerStatus struct {
ID int64 `xorm:"pk autoincr"`
RepoID int64 `xorm:"INDEX(s)"`
CommitSha string `xorm:"VARCHAR(40)"`
IndexerType RepoIndexerType `xorm:"INDEX(s) NOT NULL DEFAULT 0"`
}
if err := x.Sync(new(LanguageStat)); err != nil {
return fmt.Errorf("Sync: %w", err)
}
if err := x.Sync(new(RepoIndexerStatus)); err != nil {
return fmt.Errorf("Sync: %w", err)
}
return nil
}
+128
View File
@@ -0,0 +1,128 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package v1_12
import (
"context"
"fmt"
"math"
"path/filepath"
"strings"
"time"
"gitea.dev/modelmigration/base"
"gitea.dev/modules/git"
"gitea.dev/modules/git/gitcmd"
"gitea.dev/modules/log"
"gitea.dev/modules/setting"
)
func FixMergeBase(ctx context.Context, x base.EngineMigration) error {
type Repository struct {
ID int64 `xorm:"pk autoincr"`
OwnerID int64 `xorm:"UNIQUE(s) index"`
OwnerName string
LowerName string `xorm:"UNIQUE(s) INDEX NOT NULL"`
Name string `xorm:"INDEX NOT NULL"`
}
type PullRequest struct {
ID int64 `xorm:"pk autoincr"`
Index int64
HeadRepoID int64 `xorm:"INDEX"`
BaseRepoID int64 `xorm:"INDEX"`
HeadBranch string
BaseBranch string
MergeBase string `xorm:"VARCHAR(40)"`
HasMerged bool `xorm:"INDEX"`
MergedCommitID string `xorm:"VARCHAR(40)"`
}
limit := setting.Database.IterateBufferSize
if limit <= 0 {
limit = 50
}
ticker := time.NewTicker(5 * time.Second)
defer ticker.Stop()
count, err := x.Count(new(PullRequest))
if err != nil {
return err
}
log.Info("%d Pull Request(s) to migrate ...", count)
i := 0
start := 0
for {
prs := make([]PullRequest, 0, 50)
if err := x.Limit(limit, start).Asc("id").Find(&prs); err != nil {
return fmt.Errorf("Find: %w", err)
}
if len(prs) == 0 {
break
}
start += 50
for _, pr := range prs {
baseRepo := &Repository{ID: pr.BaseRepoID}
has, err := x.Table("repository").Get(baseRepo)
if err != nil {
return fmt.Errorf("Unable to get base repo %d %w", pr.BaseRepoID, err)
}
if !has {
log.Error("Missing base repo with id %d for PR ID %d", pr.BaseRepoID, pr.ID)
continue
}
userPath := filepath.Join(setting.RepoRootPath, strings.ToLower(baseRepo.OwnerName))
repoPath := filepath.Join(userPath, strings.ToLower(baseRepo.Name)+".git")
gitRefName := fmt.Sprintf("refs/pull/%d/head", pr.Index)
if !pr.HasMerged {
var err error
pr.MergeBase, _, err = gitcmd.NewCommand("merge-base").AddDashesAndList(pr.BaseBranch, gitRefName).WithDir(repoPath).RunStdString(ctx)
if err != nil {
var err2 error
pr.MergeBase, _, err2 = gitcmd.NewCommand("rev-parse").AddDynamicArguments(git.BranchPrefix + pr.BaseBranch).WithDir(repoPath).RunStdString(ctx)
if err2 != nil {
log.Error("Unable to get merge base for PR ID %d, Index %d in %s/%s. Error: %v & %v", pr.ID, pr.Index, baseRepo.OwnerName, baseRepo.Name, err, err2)
continue
}
}
} else {
parentsString, _, err := gitcmd.NewCommand("rev-list", "--parents", "-n", "1").AddDynamicArguments(pr.MergedCommitID).WithDir(repoPath).RunStdString(ctx)
if err != nil {
log.Error("Unable to get parents for merged PR ID %d, Index %d in %s/%s. Error: %v", pr.ID, pr.Index, baseRepo.OwnerName, baseRepo.Name, err)
continue
}
parents := strings.Split(strings.TrimSpace(parentsString), " ")
if len(parents) < 2 {
continue
}
refs := append([]string{}, parents[1:]...)
refs = append(refs, gitRefName)
cmd := gitcmd.NewCommand("merge-base").AddDashesAndList(refs...)
pr.MergeBase, _, err = cmd.WithDir(repoPath).RunStdString(ctx)
if err != nil {
log.Error("Unable to get merge base for merged PR ID %d, Index %d in %s/%s. Error: %v", pr.ID, pr.Index, baseRepo.OwnerName, baseRepo.Name, err)
continue
}
}
pr.MergeBase = strings.TrimSpace(pr.MergeBase)
_, _ = x.ID(pr.ID).Cols("merge_base").Update(pr)
i++
select {
case <-ticker.C:
log.Info("%d/%d (%2.0f%%) Pull Request(s) migrated in %d batches. %d PRs Remaining ...", i, count, float64(i)/float64(count)*100, int(math.Ceil(float64(i)/float64(limit))), count-int64(i))
default:
}
}
}
log.Info("Completed migrating %d Pull Request(s) in: %d batches", count, int(math.Ceil(float64(i)/float64(limit))))
return nil
}
+14
View File
@@ -0,0 +1,14 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package v1_12
import "gitea.dev/modelmigration/base"
func PurgeUnusedDependencies(x base.EngineMigration) error {
if _, err := x.Exec("DELETE FROM issue_dependency WHERE issue_id NOT IN (SELECT id FROM issue)"); err != nil {
return err
}
_, err := x.Exec("DELETE FROM issue_dependency WHERE dependency_id NOT IN (SELECT id FROM issue)")
return err
}
+110
View File
@@ -0,0 +1,110 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package v1_12
import (
"gitea.dev/modelmigration/base"
"gitea.dev/modules/json"
"gitea.dev/modules/setting"
)
func ExpandWebhooks(x base.EngineMigration) error {
type HookEvents struct {
Create bool `json:"create"`
Delete bool `json:"delete"`
Fork bool `json:"fork"`
Issues bool `json:"issues"`
IssueAssign bool `json:"issue_assign"`
IssueLabel bool `json:"issue_label"`
IssueMilestone bool `json:"issue_milestone"`
IssueComment bool `json:"issue_comment"`
Push bool `json:"push"`
PullRequest bool `json:"pull_request"`
PullRequestAssign bool `json:"pull_request_assign"`
PullRequestLabel bool `json:"pull_request_label"`
PullRequestMilestone bool `json:"pull_request_milestone"`
PullRequestComment bool `json:"pull_request_comment"`
PullRequestReview bool `json:"pull_request_review"`
PullRequestSync bool `json:"pull_request_sync"`
Repository bool `json:"repository"`
Release bool `json:"release"`
}
type HookEvent struct {
PushOnly bool `json:"push_only"`
SendEverything bool `json:"send_everything"`
ChooseEvents bool `json:"choose_events"`
BranchFilter string `json:"branch_filter"`
HookEvents `json:"events"`
}
type Webhook struct {
ID int64
Events string
}
var bytes []byte
var last int
batchSize := setting.Database.IterateBufferSize
sess := x.NewSession()
defer sess.Close()
for {
if err := sess.Begin(); err != nil {
return err
}
results := make([]Webhook, 0, batchSize)
err := x.OrderBy("id").
Limit(batchSize, last).
Find(&results)
if err != nil {
return err
}
if len(results) == 0 {
break
}
last += len(results)
for _, res := range results {
var events HookEvent
if err = json.Unmarshal([]byte(res.Events), &events); err != nil {
return err
}
if !events.ChooseEvents {
continue
}
if events.Issues {
events.IssueAssign = true
events.IssueLabel = true
events.IssueMilestone = true
events.IssueComment = true
}
if events.PullRequest {
events.PullRequestAssign = true
events.PullRequestLabel = true
events.PullRequestMilestone = true
events.PullRequestComment = true
events.PullRequestReview = true
events.PullRequestSync = true
}
if bytes, err = json.Marshal(&events); err != nil {
return err
}
_, err = sess.Exec("UPDATE webhook SET events = ? WHERE id = ?", string(bytes), res.ID)
if err != nil {
return err
}
}
if err := sess.Commit(); err != nil {
return err
}
}
return nil
}
+21
View File
@@ -0,0 +1,21 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package v1_12
import (
"fmt"
"gitea.dev/modelmigration/base"
)
func AddSystemWebhookColumn(x base.EngineMigration) error {
type Webhook struct {
IsSystemWebhook bool `xorm:"NOT NULL DEFAULT false"`
}
if err := x.Sync(new(Webhook)); err != nil {
return fmt.Errorf("Sync: %w", err)
}
return nil
}
+21
View File
@@ -0,0 +1,21 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package v1_12
import (
"fmt"
"gitea.dev/modelmigration/base"
)
func AddBranchProtectionProtectedFilesColumn(x base.EngineMigration) error {
type ProtectedBranch struct {
ProtectedFilePatterns string `xorm:"TEXT"`
}
if err := x.Sync(new(ProtectedBranch)); err != nil {
return fmt.Errorf("Sync: %w", err)
}
return nil
}
+15
View File
@@ -0,0 +1,15 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package v1_12
import "gitea.dev/modelmigration/base"
func AddEmailHashTable(x base.EngineMigration) error {
// EmailHash represents a pre-generated hash map
type EmailHash struct {
Hash string `xorm:"pk varchar(32)"`
Email string `xorm:"UNIQUE NOT NULL"`
}
return x.Sync(new(EmailHash))
}
+115
View File
@@ -0,0 +1,115 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package v1_12
import (
"context"
"fmt"
"math"
"path/filepath"
"strings"
"time"
"gitea.dev/modelmigration/base"
"gitea.dev/modules/git/gitcmd"
"gitea.dev/modules/log"
"gitea.dev/modules/setting"
)
func RefixMergeBase(ctx context.Context, x base.EngineMigration) error {
type Repository struct {
ID int64 `xorm:"pk autoincr"`
OwnerID int64 `xorm:"UNIQUE(s) index"`
OwnerName string
LowerName string `xorm:"UNIQUE(s) INDEX NOT NULL"`
Name string `xorm:"INDEX NOT NULL"`
}
type PullRequest struct {
ID int64 `xorm:"pk autoincr"`
Index int64
HeadRepoID int64 `xorm:"INDEX"`
BaseRepoID int64 `xorm:"INDEX"`
HeadBranch string
BaseBranch string
MergeBase string `xorm:"VARCHAR(40)"`
HasMerged bool `xorm:"INDEX"`
MergedCommitID string `xorm:"VARCHAR(40)"`
}
limit := setting.Database.IterateBufferSize
if limit <= 0 {
limit = 50
}
ticker := time.NewTicker(5 * time.Second)
defer ticker.Stop()
count, err := x.Where("has_merged = ?", true).Count(new(PullRequest))
if err != nil {
return err
}
log.Info("%d Merged Pull Request(s) to migrate ...", count)
i := 0
start := 0
for {
prs := make([]PullRequest, 0, 50)
if err := x.Limit(limit, start).Asc("id").Where("has_merged = ?", true).Find(&prs); err != nil {
return fmt.Errorf("Find: %w", err)
}
if len(prs) == 0 {
break
}
start += 50
for _, pr := range prs {
baseRepo := &Repository{ID: pr.BaseRepoID}
has, err := x.Table("repository").Get(baseRepo)
if err != nil {
return fmt.Errorf("Unable to get base repo %d %w", pr.BaseRepoID, err)
}
if !has {
log.Error("Missing base repo with id %d for PR ID %d", pr.BaseRepoID, pr.ID)
continue
}
userPath := filepath.Join(setting.RepoRootPath, strings.ToLower(baseRepo.OwnerName))
repoPath := filepath.Join(userPath, strings.ToLower(baseRepo.Name)+".git")
gitRefName := fmt.Sprintf("refs/pull/%d/head", pr.Index)
parentsString, _, err := gitcmd.NewCommand("rev-list", "--parents", "-n", "1").AddDynamicArguments(pr.MergedCommitID).WithDir(repoPath).RunStdString(ctx)
if err != nil {
log.Error("Unable to get parents for merged PR ID %d, Index %d in %s/%s. Error: %v", pr.ID, pr.Index, baseRepo.OwnerName, baseRepo.Name, err)
continue
}
parents := strings.Split(strings.TrimSpace(parentsString), " ")
if len(parents) < 3 {
continue
}
// we should recalculate
refs := append([]string{}, parents[1:]...)
refs = append(refs, gitRefName)
cmd := gitcmd.NewCommand("merge-base").AddDashesAndList(refs...)
pr.MergeBase, _, err = cmd.WithDir(repoPath).RunStdString(ctx)
if err != nil {
log.Error("Unable to get merge base for merged PR ID %d, Index %d in %s/%s. Error: %v", pr.ID, pr.Index, baseRepo.OwnerName, baseRepo.Name, err)
continue
}
pr.MergeBase = strings.TrimSpace(pr.MergeBase)
_, _ = x.ID(pr.ID).Cols("merge_base").Update(pr)
i++
select {
case <-ticker.C:
log.Info("%d/%d (%2.0f%%) Pull Request(s) migrated in %d batches. %d PRs Remaining ...", i, count, float64(i)/float64(count)*100, int(math.Ceil(float64(i)/float64(limit))), count-int64(i))
default:
}
}
}
log.Info("Completed migrating %d Pull Request(s) in: %d batches", count, int(math.Ceil(float64(i)/float64(limit))))
return nil
}
+21
View File
@@ -0,0 +1,21 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package v1_12
import (
"fmt"
"gitea.dev/modelmigration/base"
)
func AddOrgIDLabelColumn(x base.EngineMigration) error {
type Label struct {
OrgID int64 `xorm:"INDEX"`
}
if err := x.Sync(new(Label)); err != nil {
return fmt.Errorf("Sync: %w", err)
}
return nil
}
+120
View File
@@ -0,0 +1,120 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package v1_12
import (
"fmt"
"math"
"time"
"gitea.dev/modelmigration/base"
repo_model "gitea.dev/models/repo"
"gitea.dev/modules/gitrepo"
"gitea.dev/modules/graceful"
"gitea.dev/modules/log"
"gitea.dev/modules/setting"
)
func AddCommitDivergenceToPulls(x base.EngineMigration) error {
type Repository struct {
ID int64 `xorm:"pk autoincr"`
OwnerID int64 `xorm:"UNIQUE(s) index"`
OwnerName string
LowerName string `xorm:"UNIQUE(s) INDEX NOT NULL"`
Name string `xorm:"INDEX NOT NULL"`
}
type PullRequest struct {
ID int64 `xorm:"pk autoincr"`
IssueID int64 `xorm:"INDEX"`
Index int64
CommitsAhead int
CommitsBehind int
BaseRepoID int64 `xorm:"INDEX"`
BaseBranch string
HasMerged bool `xorm:"INDEX"`
MergedCommitID string `xorm:"VARCHAR(40)"`
}
if err := x.Sync(new(PullRequest)); err != nil {
return fmt.Errorf("Sync: %w", err)
}
last := 0
migrated := 0
batchSize := setting.Database.IterateBufferSize
sess := x.NewSession()
defer sess.Close()
ticker := time.NewTicker(5 * time.Second)
defer ticker.Stop()
count, err := sess.Where("has_merged = ?", false).Count(new(PullRequest))
if err != nil {
return err
}
log.Info("%d Unmerged Pull Request(s) to migrate ...", count)
for {
if err := sess.Begin(); err != nil {
return err
}
results := make([]*PullRequest, 0, batchSize)
err := sess.Where("has_merged = ?", false).OrderBy("id").Limit(batchSize, last).Find(&results)
if err != nil {
return err
}
if len(results) == 0 {
break
}
last += batchSize
for _, pr := range results {
baseRepo := &Repository{ID: pr.BaseRepoID}
has, err := x.Table("repository").Get(baseRepo)
if err != nil {
return fmt.Errorf("Unable to get base repo %d %w", pr.BaseRepoID, err)
}
if !has {
log.Error("Missing base repo with id %d for PR ID %d", pr.BaseRepoID, pr.ID)
continue
}
repoStore := repo_model.CodeRepoByName(baseRepo.OwnerName, baseRepo.Name)
gitRefName := fmt.Sprintf("refs/pull/%d/head", pr.Index)
divergence, err := gitrepo.GetDivergingCommits(graceful.GetManager().HammerContext(), repoStore, pr.BaseBranch, gitRefName)
if err != nil {
log.Warn("Could not recalculate Divergence for pull: %d", pr.ID)
pr.CommitsAhead = 0
pr.CommitsBehind = 0
}
pr.CommitsAhead = divergence.Ahead
pr.CommitsBehind = divergence.Behind
if _, err = sess.ID(pr.ID).Cols("commits_ahead", "commits_behind").Update(pr); err != nil {
return fmt.Errorf("Update Cols: %w", err)
}
migrated++
}
if err := sess.Commit(); err != nil {
return err
}
select {
case <-ticker.C:
log.Info(
"%d/%d (%2.0f%%) Pull Request(s) migrated in %d batches. %d PRs Remaining ...",
migrated,
count,
float64(migrated)/float64(count)*100,
int(math.Ceil(float64(migrated)/float64(batchSize))),
count-int64(migrated))
default:
}
}
log.Info("Completed migrating %d Pull Request(s) in: %d batches", count, int(math.Ceil(float64(migrated)/float64(batchSize))))
return nil
}
+13
View File
@@ -0,0 +1,13 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package v1_12
import "gitea.dev/modelmigration/base"
func AddBlockOnOutdatedBranch(x base.EngineMigration) error {
type ProtectedBranch struct {
BlockOnOutdatedBranch bool `xorm:"NOT NULL DEFAULT false"`
}
return x.Sync(new(ProtectedBranch))
}
+21
View File
@@ -0,0 +1,21 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package v1_12
import (
"fmt"
"gitea.dev/modelmigration/base"
)
func AddResolveDoerIDCommentColumn(x base.EngineMigration) error {
type Comment struct {
ResolveDoerID int64
}
if err := x.Sync(new(Comment)); err != nil {
return fmt.Errorf("Sync: %w", err)
}
return nil
}
+25
View File
@@ -0,0 +1,25 @@
// Copyright 2019 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package v1_12
import (
"gitea.dev/modelmigration/base"
"gitea.dev/modules/setting"
)
func PrependRefsHeadsToIssueRefs(x base.EngineMigration) error {
var query string
switch {
case setting.Database.Type.IsMSSQL():
query = "UPDATE `issue` SET `ref` = 'refs/heads/' + `ref` WHERE `ref` IS NOT NULL AND `ref` <> '' AND `ref` NOT LIKE 'refs/%'"
case setting.Database.Type.IsMySQL():
query = "UPDATE `issue` SET `ref` = CONCAT('refs/heads/', `ref`) WHERE `ref` IS NOT NULL AND `ref` <> '' AND `ref` NOT LIKE 'refs/%';"
default:
query = "UPDATE `issue` SET `ref` = 'refs/heads/' || `ref` WHERE `ref` IS NOT NULL AND `ref` <> '' AND `ref` NOT LIKE 'refs/%'"
}
_, err := x.Exec(query)
return err
}