From dd136858f1ea40ad3c94191d647487fa4f31926c Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 18 Oct 2024 20:33:49 +0200 Subject: Adding upstream version 9.0.0. Signed-off-by: Daniel Baumann --- models/migrations/v1_12/v117.go | 16 +++++ models/migrations/v1_12/v118.go | 25 ++++++++ models/migrations/v1_12/v119.go | 15 +++++ models/migrations/v1_12/v120.go | 19 ++++++ models/migrations/v1_12/v121.go | 16 +++++ models/migrations/v1_12/v122.go | 16 +++++ models/migrations/v1_12/v123.go | 17 ++++++ models/migrations/v1_12/v124.go | 23 ++++++++ models/migrations/v1_12/v125.go | 22 +++++++ models/migrations/v1_12/v126.go | 24 ++++++++ models/migrations/v1_12/v127.go | 44 ++++++++++++++ models/migrations/v1_12/v128.go | 127 ++++++++++++++++++++++++++++++++++++++++ models/migrations/v1_12/v129.go | 16 +++++ models/migrations/v1_12/v130.go | 111 +++++++++++++++++++++++++++++++++++ models/migrations/v1_12/v131.go | 21 +++++++ models/migrations/v1_12/v132.go | 21 +++++++ models/migrations/v1_12/v133.go | 15 +++++ models/migrations/v1_12/v134.go | 115 ++++++++++++++++++++++++++++++++++++ models/migrations/v1_12/v135.go | 21 +++++++ models/migrations/v1_12/v136.go | 125 +++++++++++++++++++++++++++++++++++++++ models/migrations/v1_12/v137.go | 15 +++++ models/migrations/v1_12/v138.go | 21 +++++++ models/migrations/v1_12/v139.go | 23 ++++++++ 23 files changed, 868 insertions(+) create mode 100644 models/migrations/v1_12/v117.go create mode 100644 models/migrations/v1_12/v118.go create mode 100644 models/migrations/v1_12/v119.go create mode 100644 models/migrations/v1_12/v120.go create mode 100644 models/migrations/v1_12/v121.go create mode 100644 models/migrations/v1_12/v122.go create mode 100644 models/migrations/v1_12/v123.go create mode 100644 models/migrations/v1_12/v124.go create mode 100644 models/migrations/v1_12/v125.go create mode 100644 models/migrations/v1_12/v126.go create mode 100644 models/migrations/v1_12/v127.go create mode 100644 models/migrations/v1_12/v128.go create mode 100644 models/migrations/v1_12/v129.go create mode 100644 models/migrations/v1_12/v130.go create mode 100644 models/migrations/v1_12/v131.go create mode 100644 models/migrations/v1_12/v132.go create mode 100644 models/migrations/v1_12/v133.go create mode 100644 models/migrations/v1_12/v134.go create mode 100644 models/migrations/v1_12/v135.go create mode 100644 models/migrations/v1_12/v136.go create mode 100644 models/migrations/v1_12/v137.go create mode 100644 models/migrations/v1_12/v138.go create mode 100644 models/migrations/v1_12/v139.go (limited to 'models/migrations/v1_12') diff --git a/models/migrations/v1_12/v117.go b/models/migrations/v1_12/v117.go new file mode 100644 index 0000000..8eadcde --- /dev/null +++ b/models/migrations/v1_12/v117.go @@ -0,0 +1,16 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_12 //nolint + +import ( + "xorm.io/xorm" +) + +func AddBlockOnRejectedReviews(x *xorm.Engine) error { + type ProtectedBranch struct { + BlockOnRejectedReviews bool `xorm:"NOT NULL DEFAULT false"` + } + + return x.Sync(new(ProtectedBranch)) +} diff --git a/models/migrations/v1_12/v118.go b/models/migrations/v1_12/v118.go new file mode 100644 index 0000000..eb022dc --- /dev/null +++ b/models/migrations/v1_12/v118.go @@ -0,0 +1,25 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_12 //nolint + +import ( + "xorm.io/xorm" +) + +func AddReviewCommitAndStale(x *xorm.Engine) 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)) +} diff --git a/models/migrations/v1_12/v119.go b/models/migrations/v1_12/v119.go new file mode 100644 index 0000000..60bfe6a --- /dev/null +++ b/models/migrations/v1_12/v119.go @@ -0,0 +1,15 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_12 //nolint + +import ( + "xorm.io/xorm" +) + +func FixMigratedRepositoryServiceType(x *xorm.Engine) error { + // structs.GithubService: + // GithubService = 2 + _, err := x.Exec("UPDATE repository SET original_service_type = ? WHERE original_url LIKE 'https://github.com/%'", 2) + return err +} diff --git a/models/migrations/v1_12/v120.go b/models/migrations/v1_12/v120.go new file mode 100644 index 0000000..3f7ed8d --- /dev/null +++ b/models/migrations/v1_12/v120.go @@ -0,0 +1,19 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_12 //nolint + +import ( + "xorm.io/xorm" +) + +func AddOwnerNameOnRepository(x *xorm.Engine) 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 +} diff --git a/models/migrations/v1_12/v121.go b/models/migrations/v1_12/v121.go new file mode 100644 index 0000000..175ec91 --- /dev/null +++ b/models/migrations/v1_12/v121.go @@ -0,0 +1,16 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_12 //nolint + +import "xorm.io/xorm" + +func AddIsRestricted(x *xorm.Engine) 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)) +} diff --git a/models/migrations/v1_12/v122.go b/models/migrations/v1_12/v122.go new file mode 100644 index 0000000..6e31d86 --- /dev/null +++ b/models/migrations/v1_12/v122.go @@ -0,0 +1,16 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_12 //nolint + +import ( + "xorm.io/xorm" +) + +func AddRequireSignedCommits(x *xorm.Engine) error { + type ProtectedBranch struct { + RequireSignedCommits bool `xorm:"NOT NULL DEFAULT false"` + } + + return x.Sync(new(ProtectedBranch)) +} diff --git a/models/migrations/v1_12/v123.go b/models/migrations/v1_12/v123.go new file mode 100644 index 0000000..b0c3af0 --- /dev/null +++ b/models/migrations/v1_12/v123.go @@ -0,0 +1,17 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_12 //nolint + +import ( + "xorm.io/xorm" +) + +func AddReactionOriginals(x *xorm.Engine) error { + type Reaction struct { + OriginalAuthorID int64 `xorm:"INDEX NOT NULL DEFAULT(0)"` + OriginalAuthor string + } + + return x.Sync(new(Reaction)) +} diff --git a/models/migrations/v1_12/v124.go b/models/migrations/v1_12/v124.go new file mode 100644 index 0000000..d2ba03f --- /dev/null +++ b/models/migrations/v1_12/v124.go @@ -0,0 +1,23 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_12 //nolint + +import ( + "xorm.io/xorm" +) + +func AddUserRepoMissingColumns(x *xorm.Engine) 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)) +} diff --git a/models/migrations/v1_12/v125.go b/models/migrations/v1_12/v125.go new file mode 100644 index 0000000..ec4ffaa --- /dev/null +++ b/models/migrations/v1_12/v125.go @@ -0,0 +1,22 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_12 //nolint + +import ( + "fmt" + + "xorm.io/xorm" +) + +func AddReviewMigrateInfo(x *xorm.Engine) error { + type Review struct { + OriginalAuthor string + OriginalAuthorID int64 + } + + if err := x.Sync(new(Review)); err != nil { + return fmt.Errorf("Sync: %w", err) + } + return nil +} diff --git a/models/migrations/v1_12/v126.go b/models/migrations/v1_12/v126.go new file mode 100644 index 0000000..ca9ec3a --- /dev/null +++ b/models/migrations/v1_12/v126.go @@ -0,0 +1,24 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_12 //nolint + +import ( + "xorm.io/builder" + "xorm.io/xorm" +) + +func FixTopicRepositoryCount(x *xorm.Engine) 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 +} diff --git a/models/migrations/v1_12/v127.go b/models/migrations/v1_12/v127.go new file mode 100644 index 0000000..00e391d --- /dev/null +++ b/models/migrations/v1_12/v127.go @@ -0,0 +1,44 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_12 //nolint + +import ( + "fmt" + + "code.gitea.io/gitea/modules/timeutil" + + "xorm.io/xorm" +) + +func AddLanguageStats(x *xorm.Engine) 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 +} diff --git a/models/migrations/v1_12/v128.go b/models/migrations/v1_12/v128.go new file mode 100644 index 0000000..6eea133 --- /dev/null +++ b/models/migrations/v1_12/v128.go @@ -0,0 +1,127 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_12 //nolint + +import ( + "fmt" + "math" + "path/filepath" + "strings" + "time" + + "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" + + "xorm.io/xorm" +) + +func FixMergeBase(x *xorm.Engine) 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 = git.NewCommand(git.DefaultContext, "merge-base").AddDashesAndList(pr.BaseBranch, gitRefName).RunStdString(&git.RunOpts{Dir: repoPath}) + if err != nil { + var err2 error + pr.MergeBase, _, err2 = git.NewCommand(git.DefaultContext, "rev-parse").AddDynamicArguments(git.BranchPrefix + pr.BaseBranch).RunStdString(&git.RunOpts{Dir: repoPath}) + 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 := git.NewCommand(git.DefaultContext, "rev-list", "--parents", "-n", "1").AddDynamicArguments(pr.MergedCommitID).RunStdString(&git.RunOpts{Dir: repoPath}) + if err != nil { + log.Warn("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 := git.NewCommand(git.DefaultContext, "merge-base").AddDashesAndList(refs...) + + pr.MergeBase, _, err = cmd.RunStdString(&git.RunOpts{Dir: repoPath}) + 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 +} diff --git a/models/migrations/v1_12/v129.go b/models/migrations/v1_12/v129.go new file mode 100644 index 0000000..cf22824 --- /dev/null +++ b/models/migrations/v1_12/v129.go @@ -0,0 +1,16 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_12 //nolint + +import ( + "xorm.io/xorm" +) + +func PurgeUnusedDependencies(x *xorm.Engine) 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 +} diff --git a/models/migrations/v1_12/v130.go b/models/migrations/v1_12/v130.go new file mode 100644 index 0000000..391810c --- /dev/null +++ b/models/migrations/v1_12/v130.go @@ -0,0 +1,111 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_12 //nolint + +import ( + "code.gitea.io/gitea/modules/json" + "code.gitea.io/gitea/modules/setting" + + "xorm.io/xorm" +) + +func ExpandWebhooks(x *xorm.Engine) 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 +} diff --git a/models/migrations/v1_12/v131.go b/models/migrations/v1_12/v131.go new file mode 100644 index 0000000..5184bc3 --- /dev/null +++ b/models/migrations/v1_12/v131.go @@ -0,0 +1,21 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_12 //nolint + +import ( + "fmt" + + "xorm.io/xorm" +) + +func AddSystemWebhookColumn(x *xorm.Engine) 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 +} diff --git a/models/migrations/v1_12/v132.go b/models/migrations/v1_12/v132.go new file mode 100644 index 0000000..3b2b28f --- /dev/null +++ b/models/migrations/v1_12/v132.go @@ -0,0 +1,21 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_12 //nolint + +import ( + "fmt" + + "xorm.io/xorm" +) + +func AddBranchProtectionProtectedFilesColumn(x *xorm.Engine) error { + type ProtectedBranch struct { + ProtectedFilePatterns string `xorm:"TEXT"` + } + + if err := x.Sync(new(ProtectedBranch)); err != nil { + return fmt.Errorf("Sync: %w", err) + } + return nil +} diff --git a/models/migrations/v1_12/v133.go b/models/migrations/v1_12/v133.go new file mode 100644 index 0000000..c9087fc --- /dev/null +++ b/models/migrations/v1_12/v133.go @@ -0,0 +1,15 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_12 //nolint + +import "xorm.io/xorm" + +func AddEmailHashTable(x *xorm.Engine) 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)) +} diff --git a/models/migrations/v1_12/v134.go b/models/migrations/v1_12/v134.go new file mode 100644 index 0000000..23c2916 --- /dev/null +++ b/models/migrations/v1_12/v134.go @@ -0,0 +1,115 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_12 //nolint + +import ( + "fmt" + "math" + "path/filepath" + "strings" + "time" + + "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" + + "xorm.io/xorm" +) + +func RefixMergeBase(x *xorm.Engine) 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 := git.NewCommand(git.DefaultContext, "rev-list", "--parents", "-n", "1").AddDynamicArguments(pr.MergedCommitID).RunStdString(&git.RunOpts{Dir: repoPath}) + if err != nil { + log.Warn("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 := git.NewCommand(git.DefaultContext, "merge-base").AddDashesAndList(refs...) + + pr.MergeBase, _, err = cmd.RunStdString(&git.RunOpts{Dir: repoPath}) + 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 +} diff --git a/models/migrations/v1_12/v135.go b/models/migrations/v1_12/v135.go new file mode 100644 index 0000000..8898011 --- /dev/null +++ b/models/migrations/v1_12/v135.go @@ -0,0 +1,21 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_12 //nolint + +import ( + "fmt" + + "xorm.io/xorm" +) + +func AddOrgIDLabelColumn(x *xorm.Engine) error { + type Label struct { + OrgID int64 `xorm:"INDEX"` + } + + if err := x.Sync(new(Label)); err != nil { + return fmt.Errorf("Sync: %w", err) + } + return nil +} diff --git a/models/migrations/v1_12/v136.go b/models/migrations/v1_12/v136.go new file mode 100644 index 0000000..d91ff92 --- /dev/null +++ b/models/migrations/v1_12/v136.go @@ -0,0 +1,125 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_12 //nolint + +import ( + "fmt" + "math" + "path/filepath" + "strings" + "time" + + "code.gitea.io/gitea/modules/git" + "code.gitea.io/gitea/modules/graceful" + "code.gitea.io/gitea/modules/log" + "code.gitea.io/gitea/modules/setting" + + "xorm.io/xorm" +) + +func AddCommitDivergenceToPulls(x *xorm.Engine) 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 + } + 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) + + divergence, err := git.GetDivergingCommits(graceful.GetManager().HammerContext(), repoPath, 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 +} diff --git a/models/migrations/v1_12/v137.go b/models/migrations/v1_12/v137.go new file mode 100644 index 0000000..0d86b72 --- /dev/null +++ b/models/migrations/v1_12/v137.go @@ -0,0 +1,15 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_12 //nolint + +import ( + "xorm.io/xorm" +) + +func AddBlockOnOutdatedBranch(x *xorm.Engine) error { + type ProtectedBranch struct { + BlockOnOutdatedBranch bool `xorm:"NOT NULL DEFAULT false"` + } + return x.Sync(new(ProtectedBranch)) +} diff --git a/models/migrations/v1_12/v138.go b/models/migrations/v1_12/v138.go new file mode 100644 index 0000000..8c8d353 --- /dev/null +++ b/models/migrations/v1_12/v138.go @@ -0,0 +1,21 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_12 //nolint + +import ( + "fmt" + + "xorm.io/xorm" +) + +func AddResolveDoerIDCommentColumn(x *xorm.Engine) error { + type Comment struct { + ResolveDoerID int64 + } + + if err := x.Sync(new(Comment)); err != nil { + return fmt.Errorf("Sync: %w", err) + } + return nil +} diff --git a/models/migrations/v1_12/v139.go b/models/migrations/v1_12/v139.go new file mode 100644 index 0000000..5b65769 --- /dev/null +++ b/models/migrations/v1_12/v139.go @@ -0,0 +1,23 @@ +// Copyright 2019 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_12 //nolint + +import ( + "code.gitea.io/gitea/modules/setting" + + "xorm.io/xorm" +) + +func PrependRefsHeadsToIssueRefs(x *xorm.Engine) error { + var query string + + if 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/%';" + } else { + 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 +} -- cgit v1.2.3