Merge branch 'main' into allow-force-push-protected-branches

This commit is contained in:
Henry Goodman
2024-01-31 12:06:44 +11:00
committed by GitHub
375 changed files with 5214 additions and 2316 deletions
+8 -5
View File
@@ -46,10 +46,13 @@ type ActionRun struct {
TriggerEvent string // the trigger event defined in the `on` configuration of the triggered workflow
Status Status `xorm:"index"`
Version int `xorm:"version default 0"` // Status could be updated concomitantly, so an optimistic lock is needed
Started timeutil.TimeStamp
Stopped timeutil.TimeStamp
Created timeutil.TimeStamp `xorm:"created"`
Updated timeutil.TimeStamp `xorm:"updated"`
// Started and Stopped is used for recording last run time, if rerun happened, they will be reset to 0
Started timeutil.TimeStamp
Stopped timeutil.TimeStamp
// PreviousDuration is used for recording previous duration
PreviousDuration time.Duration
Created timeutil.TimeStamp `xorm:"created"`
Updated timeutil.TimeStamp `xorm:"updated"`
}
func init() {
@@ -118,7 +121,7 @@ func (run *ActionRun) LoadAttributes(ctx context.Context) error {
}
func (run *ActionRun) Duration() time.Duration {
return calculateDuration(run.Started, run.Stopped, run.Status)
return calculateDuration(run.Started, run.Stopped, run.Status) + run.PreviousDuration
}
func (run *ActionRun) GetPushEventPayload() (*api.PushPayload, error) {
+3 -2
View File
@@ -14,6 +14,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"xorm.io/xorm"
)
@@ -65,7 +66,7 @@ func GetActivityStats(ctx context.Context, repo *repo_model.Repository, timeFrom
return nil, fmt.Errorf("FillUnresolvedIssues: %w", err)
}
if code {
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repo.RepoPath())
gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, repo)
if err != nil {
return nil, fmt.Errorf("OpenRepository: %w", err)
}
@@ -82,7 +83,7 @@ func GetActivityStats(ctx context.Context, repo *repo_model.Repository, timeFrom
// GetActivityStatsTopAuthors returns top author stats for git commits for all branches
func GetActivityStatsTopAuthors(ctx context.Context, repo *repo_model.Repository, timeFrom time.Time, count int) ([]*ActivityAuthorData, error) {
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repo.RepoPath())
gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, repo)
if err != nil {
return nil, fmt.Errorf("OpenRepository: %w", err)
}
+21 -11
View File
@@ -133,17 +133,21 @@ type FindOptionsOrder interface {
// Find represents a common find function which accept an options interface
func Find[T any](ctx context.Context, opts FindOptions) ([]*T, error) {
sess := GetEngine(ctx)
sess := GetEngine(ctx).Where(opts.ToConds())
if joinOpt, ok := opts.(FindOptionsJoin); ok && len(joinOpt.ToJoins()) > 0 {
if joinOpt, ok := opts.(FindOptionsJoin); ok {
for _, joinFunc := range joinOpt.ToJoins() {
if err := joinFunc(sess); err != nil {
return nil, err
}
}
}
if orderOpt, ok := opts.(FindOptionsOrder); ok {
if order := orderOpt.ToOrders(); order != "" {
sess.OrderBy(order)
}
}
sess = sess.Where(opts.ToConds())
page, pageSize := opts.GetPage(), opts.GetPageSize()
if !opts.IsListAll() && pageSize > 0 {
if page == 0 {
@@ -151,9 +155,6 @@ func Find[T any](ctx context.Context, opts FindOptions) ([]*T, error) {
}
sess.Limit(pageSize, (page-1)*pageSize)
}
if newOpt, ok := opts.(FindOptionsOrder); ok && newOpt.ToOrders() != "" {
sess.OrderBy(newOpt.ToOrders())
}
findPageSize := defaultFindSliceSize
if pageSize > 0 {
@@ -168,8 +169,8 @@ func Find[T any](ctx context.Context, opts FindOptions) ([]*T, error) {
// Count represents a common count function which accept an options interface
func Count[T any](ctx context.Context, opts FindOptions) (int64, error) {
sess := GetEngine(ctx)
if joinOpt, ok := opts.(FindOptionsJoin); ok && len(joinOpt.ToJoins()) > 0 {
sess := GetEngine(ctx).Where(opts.ToConds())
if joinOpt, ok := opts.(FindOptionsJoin); ok {
for _, joinFunc := range joinOpt.ToJoins() {
if err := joinFunc(sess); err != nil {
return 0, err
@@ -178,7 +179,7 @@ func Count[T any](ctx context.Context, opts FindOptions) (int64, error) {
}
var object T
return sess.Where(opts.ToConds()).Count(&object)
return sess.Count(&object)
}
// FindAndCount represents a common findandcount function which accept an options interface
@@ -188,8 +189,17 @@ func FindAndCount[T any](ctx context.Context, opts FindOptions) ([]*T, int64, er
if !opts.IsListAll() && pageSize > 0 && page >= 1 {
sess.Limit(pageSize, (page-1)*pageSize)
}
if newOpt, ok := opts.(FindOptionsOrder); ok && newOpt.ToOrders() != "" {
sess.OrderBy(newOpt.ToOrders())
if joinOpt, ok := opts.(FindOptionsJoin); ok {
for _, joinFunc := range joinOpt.ToJoins() {
if err := joinFunc(sess); err != nil {
return nil, 0, err
}
}
}
if orderOpt, ok := opts.(FindOptionsOrder); ok {
if order := orderOpt.ToOrders(); order != "" {
sess.OrderBy(order)
}
}
findPageSize := defaultFindSliceSize
+7
View File
@@ -669,3 +669,10 @@
type: 10
config: "{}"
created_unix: 946684810
-
id: 101
repo_id: 59
type: 1
config: "{}"
created_unix: 946684810
+13
View File
@@ -1693,3 +1693,16 @@
size: 0
is_fsck_enabled: true
close_issues_via_commit_in_any_branch: false
-
id: 59
owner_id: 2
owner_name: user2
lower_name: test_commit_revert
name: test_commit_revert
default_branch: main
is_empty: false
is_archived: false
is_private: true
status: 0
num_issues: 0
+1 -1
View File
@@ -66,7 +66,7 @@
num_followers: 2
num_following: 1
num_stars: 2
num_repos: 14
num_repos: 15
num_teams: 0
num_members: 0
visibility: 0
+20 -36
View File
@@ -25,7 +25,6 @@ import (
"code.gitea.io/gitea/modules/translation"
"xorm.io/builder"
"xorm.io/xorm"
)
// CommitStatus holds a single Status of a single Commit
@@ -38,7 +37,7 @@ type CommitStatus struct {
SHA string `xorm:"VARCHAR(64) NOT NULL INDEX UNIQUE(repo_sha_index)"`
TargetURL string `xorm:"TEXT"`
Description string `xorm:"TEXT"`
ContextHash string `xorm:"char(40) index"`
ContextHash string `xorm:"VARCHAR(64) index"`
Context string `xorm:"TEXT"`
Creator *user_model.User `xorm:"-"`
CreatorID int64
@@ -221,57 +220,42 @@ func CalcCommitStatus(statuses []*CommitStatus) *CommitStatus {
// CommitStatusOptions holds the options for query commit statuses
type CommitStatusOptions struct {
db.ListOptions
RepoID int64
SHA string
State string
SortType string
}
// GetCommitStatuses returns all statuses for a given commit.
func GetCommitStatuses(ctx context.Context, repo *repo_model.Repository, sha string, opts *CommitStatusOptions) ([]*CommitStatus, int64, error) {
if opts.Page <= 0 {
opts.Page = 1
}
if opts.PageSize <= 0 {
opts.Page = setting.ItemsPerPage
func (opts *CommitStatusOptions) ToConds() builder.Cond {
var cond builder.Cond = builder.Eq{
"repo_id": opts.RepoID,
"sha": opts.SHA,
}
countSession := listCommitStatusesStatement(ctx, repo, sha, opts)
countSession = db.SetSessionPagination(countSession, opts)
maxResults, err := countSession.Count(new(CommitStatus))
if err != nil {
log.Error("Count PRs: %v", err)
return nil, maxResults, err
}
statuses := make([]*CommitStatus, 0, opts.PageSize)
findSession := listCommitStatusesStatement(ctx, repo, sha, opts)
findSession = db.SetSessionPagination(findSession, opts)
sortCommitStatusesSession(findSession, opts.SortType)
return statuses, maxResults, findSession.Find(&statuses)
}
func listCommitStatusesStatement(ctx context.Context, repo *repo_model.Repository, sha string, opts *CommitStatusOptions) *xorm.Session {
sess := db.GetEngine(ctx).Where("repo_id = ?", repo.ID).And("sha = ?", sha)
switch opts.State {
case "pending", "success", "error", "failure", "warning":
sess.And("state = ?", opts.State)
cond = cond.And(builder.Eq{
"state": opts.State,
})
}
return sess
return cond
}
func sortCommitStatusesSession(sess *xorm.Session, sortType string) {
switch sortType {
func (opts *CommitStatusOptions) ToOrders() string {
switch opts.SortType {
case "oldest":
sess.Asc("created_unix")
return "created_unix ASC"
case "recentupdate":
sess.Desc("updated_unix")
return "updated_unix DESC"
case "leastupdate":
sess.Asc("updated_unix")
return "updated_unix ASC"
case "leastindex":
sess.Desc("index")
return "`index` DESC"
case "highestindex":
sess.Asc("index")
return "`index` ASC"
default:
sess.Desc("created_unix")
return "created_unix DESC"
}
}
+129 -1
View File
@@ -22,7 +22,11 @@ func TestGetCommitStatuses(t *testing.T) {
sha1 := "1234123412341234123412341234123412341234"
statuses, maxResults, err := git_model.GetCommitStatuses(db.DefaultContext, repo1, sha1, &git_model.CommitStatusOptions{ListOptions: db.ListOptions{Page: 1, PageSize: 50}})
statuses, maxResults, err := db.FindAndCount[git_model.CommitStatus](db.DefaultContext, &git_model.CommitStatusOptions{
ListOptions: db.ListOptions{Page: 1, PageSize: 50},
RepoID: repo1.ID,
SHA: sha1,
})
assert.NoError(t, err)
assert.Equal(t, int(maxResults), 5)
assert.Len(t, statuses, 5)
@@ -46,4 +50,128 @@ func TestGetCommitStatuses(t *testing.T) {
assert.Equal(t, "deploy/awesomeness", statuses[4].Context)
assert.Equal(t, structs.CommitStatusError, statuses[4].State)
assert.Equal(t, "https://try.gitea.io/api/v1/repos/user2/repo1/statuses/1234123412341234123412341234123412341234", statuses[4].APIURL(db.DefaultContext))
statuses, maxResults, err = db.FindAndCount[git_model.CommitStatus](db.DefaultContext, &git_model.CommitStatusOptions{
ListOptions: db.ListOptions{Page: 2, PageSize: 50},
RepoID: repo1.ID,
SHA: sha1,
})
assert.NoError(t, err)
assert.Equal(t, int(maxResults), 5)
assert.Empty(t, statuses)
}
func Test_CalcCommitStatus(t *testing.T) {
kases := []struct {
statuses []*git_model.CommitStatus
expected *git_model.CommitStatus
}{
{
statuses: []*git_model.CommitStatus{
{
State: structs.CommitStatusPending,
},
},
expected: &git_model.CommitStatus{
State: structs.CommitStatusPending,
},
},
{
statuses: []*git_model.CommitStatus{
{
State: structs.CommitStatusSuccess,
},
{
State: structs.CommitStatusPending,
},
},
expected: &git_model.CommitStatus{
State: structs.CommitStatusPending,
},
},
{
statuses: []*git_model.CommitStatus{
{
State: structs.CommitStatusSuccess,
},
{
State: structs.CommitStatusPending,
},
{
State: structs.CommitStatusSuccess,
},
},
expected: &git_model.CommitStatus{
State: structs.CommitStatusPending,
},
},
{
statuses: []*git_model.CommitStatus{
{
State: structs.CommitStatusError,
},
{
State: structs.CommitStatusPending,
},
{
State: structs.CommitStatusSuccess,
},
},
expected: &git_model.CommitStatus{
State: structs.CommitStatusError,
},
},
{
statuses: []*git_model.CommitStatus{
{
State: structs.CommitStatusWarning,
},
{
State: structs.CommitStatusPending,
},
{
State: structs.CommitStatusSuccess,
},
},
expected: &git_model.CommitStatus{
State: structs.CommitStatusWarning,
},
},
{
statuses: []*git_model.CommitStatus{
{
State: structs.CommitStatusSuccess,
},
{
State: structs.CommitStatusSuccess,
},
{
State: structs.CommitStatusSuccess,
},
},
expected: &git_model.CommitStatus{
State: structs.CommitStatusSuccess,
},
},
{
statuses: []*git_model.CommitStatus{
{
State: structs.CommitStatusFailure,
},
{
State: structs.CommitStatusError,
},
{
State: structs.CommitStatusWarning,
},
},
expected: &git_model.CommitStatus{
State: structs.CommitStatusError,
},
},
}
for _, kase := range kases {
assert.Equal(t, kase.expected, git_model.CalcCommitStatus(kase.statuses))
}
}
+3 -4
View File
@@ -18,7 +18,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/references"
@@ -270,7 +270,7 @@ type Comment struct {
UpdatedUnix timeutil.TimeStamp `xorm:"INDEX updated"`
// Reference issue in commit message
CommitSHA string `xorm:"VARCHAR(40)"`
CommitSHA string `xorm:"VARCHAR(64)"`
Attachments []*repo_model.Attachment `xorm:"-"`
Reactions ReactionList `xorm:"-"`
@@ -762,8 +762,7 @@ func (c *Comment) LoadPushCommits(ctx context.Context) (err error) {
c.OldCommit = data.CommitIDs[0]
c.NewCommit = data.CommitIDs[1]
} else {
repoPath := c.Issue.Repo.RepoPath()
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repoPath)
gitRepo, closer, err := gitrepo.RepositoryFromContextOrOpen(ctx, c.Issue.Repo)
if err != nil {
return err
}
+5 -3
View File
@@ -109,9 +109,11 @@ func findCodeComments(ctx context.Context, opts FindCommentsOptions, issue *Issu
var err error
if comment.RenderedContent, err = markdown.RenderString(&markup.RenderContext{
Ctx: ctx,
URLPrefix: issue.Repo.Link(),
Metas: issue.Repo.ComposeMetas(ctx),
Ctx: ctx,
Links: markup.Links{
Base: issue.Repo.Link(),
},
Metas: issue.Repo.ComposeMetas(ctx),
}, comment.Content); err != nil {
return nil, err
}
+4 -3
View File
@@ -19,6 +19,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/timeutil"
@@ -171,11 +172,11 @@ type PullRequest struct {
HeadBranch string
HeadCommitID string `xorm:"-"`
BaseBranch string
MergeBase string `xorm:"VARCHAR(40)"`
MergeBase string `xorm:"VARCHAR(64)"`
AllowMaintainerEdit bool `xorm:"NOT NULL DEFAULT false"`
HasMerged bool `xorm:"INDEX"`
MergedCommitID string `xorm:"VARCHAR(40)"`
MergedCommitID string `xorm:"VARCHAR(64)"`
MergerID int64 `xorm:"INDEX"`
Merger *user_model.User `xorm:"-"`
MergedUnix timeutil.TimeStamp `xorm:"updated INDEX"`
@@ -865,7 +866,7 @@ func PullRequestCodeOwnersReview(ctx context.Context, pull *Issue, pr *PullReque
return err
}
repo, err := git.OpenRepository(ctx, pr.BaseRepo.RepoPath())
repo, err := gitrepo.OpenRepository(ctx, pr.BaseRepo)
if err != nil {
return err
}
+1 -1
View File
@@ -116,7 +116,7 @@ type Review struct {
Content string `xorm:"TEXT"`
// Official is a review made by an assigned approver (counts towards approval)
Official bool `xorm:"NOT NULL DEFAULT false"`
CommitID string `xorm:"VARCHAR(40)"`
CommitID string `xorm:"VARCHAR(64)"`
Stale bool `xorm:"NOT NULL DEFAULT false"`
Dismissed bool `xorm:"NOT NULL DEFAULT false"`
+7 -5
View File
@@ -340,7 +340,7 @@ func GetTrackedTimeByID(ctx context.Context, id int64) (*TrackedTime, error) {
}
// GetIssueTotalTrackedTime returns the total tracked time for issues by given conditions.
func GetIssueTotalTrackedTime(ctx context.Context, opts *IssuesOptions, isClosed bool) (int64, error) {
func GetIssueTotalTrackedTime(ctx context.Context, opts *IssuesOptions, isClosed util.OptionalBool) (int64, error) {
if len(opts.IssueIDs) <= MaxQueryParameters {
return getIssueTotalTrackedTimeChunk(ctx, opts, isClosed, opts.IssueIDs)
}
@@ -363,7 +363,7 @@ func GetIssueTotalTrackedTime(ctx context.Context, opts *IssuesOptions, isClosed
return accum, nil
}
func getIssueTotalTrackedTimeChunk(ctx context.Context, opts *IssuesOptions, isClosed bool, issueIDs []int64) (int64, error) {
func getIssueTotalTrackedTimeChunk(ctx context.Context, opts *IssuesOptions, isClosed util.OptionalBool, issueIDs []int64) (int64, error) {
sumSession := func(opts *IssuesOptions, issueIDs []int64) *xorm.Session {
sess := db.GetEngine(ctx).
Table("tracked_time").
@@ -377,7 +377,9 @@ func getIssueTotalTrackedTimeChunk(ctx context.Context, opts *IssuesOptions, isC
Time int64
}
return sumSession(opts, issueIDs).
And("issue.is_closed = ?", isClosed).
SumInt(new(trackedTime), "tracked_time.time")
session := sumSession(opts, issueIDs)
if !isClosed.IsNone() {
session = session.And("issue.is_closed = ?", isClosed.IsTrue())
}
return session.SumInt(new(trackedTime), "tracked_time.time")
}
+7 -2
View File
@@ -11,6 +11,7 @@ import (
issues_model "code.gitea.io/gitea/models/issues"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/util"
"github.com/stretchr/testify/assert"
)
@@ -119,11 +120,15 @@ func TestTotalTimesForEachUser(t *testing.T) {
func TestGetIssueTotalTrackedTime(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
ttt, err := issues_model.GetIssueTotalTrackedTime(db.DefaultContext, &issues_model.IssuesOptions{MilestoneIDs: []int64{1}}, false)
ttt, err := issues_model.GetIssueTotalTrackedTime(db.DefaultContext, &issues_model.IssuesOptions{MilestoneIDs: []int64{1}}, util.OptionalBoolFalse)
assert.NoError(t, err)
assert.EqualValues(t, 3682, ttt)
ttt, err = issues_model.GetIssueTotalTrackedTime(db.DefaultContext, &issues_model.IssuesOptions{MilestoneIDs: []int64{1}}, true)
ttt, err = issues_model.GetIssueTotalTrackedTime(db.DefaultContext, &issues_model.IssuesOptions{MilestoneIDs: []int64{1}}, util.OptionalBoolTrue)
assert.NoError(t, err)
assert.EqualValues(t, 0, ttt)
ttt, err = issues_model.GetIssueTotalTrackedTime(db.DefaultContext, &issues_model.IssuesOptions{MilestoneIDs: []int64{1}}, util.OptionalBoolNone)
assert.NoError(t, err)
assert.EqualValues(t, 3682, ttt)
}
@@ -0,0 +1,11 @@
# type Repository struct {
# ID int64 `xorm:"pk autoincr"`
# }
-
id: 1
-
id: 2
-
id: 3
-
id: 10
+6
View File
@@ -552,6 +552,12 @@ var migrations = []Migration{
NewMigration("Add Index to pull_auto_merge.doer_id", v1_22.AddIndexToPullAutoMergeDoerID),
// v283 -> v284
NewMigration("Add combined Index to issue_user.uid and issue_id", v1_22.AddCombinedIndexToIssueUser),
// v284 -> v285
NewMigration("Add ignore stale approval column on branch table", v1_22.AddIgnoreStaleApprovalsColumnToProtectedBranchTable),
// v285 -> v286
NewMigration("Add PreviousDuration to ActionRun", v1_22.AddPreviousDurationToActionRun),
// v286 -> v287
NewMigration("Add support for SHA256 git repositories", v1_22.AdjustDBForSha256),
}
// GetCurrentDBVersion returns the current db version
+18
View File
@@ -0,0 +1,18 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package v1_22 //nolint
import (
"time"
"xorm.io/xorm"
)
func AddPreviousDurationToActionRun(x *xorm.Engine) error {
type ActionRun struct {
PreviousDuration time.Duration
}
return x.Sync(&ActionRun{})
}
+104
View File
@@ -0,0 +1,104 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package v1_22 //nolint
import (
"errors"
"fmt"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"xorm.io/xorm"
)
func expandHashReferencesToSha256(x *xorm.Engine) error {
alteredTables := [][2]string{
{"commit_status", "context_hash"},
{"comment", "commit_sha"},
{"pull_request", "merge_base"},
{"pull_request", "merged_commit_id"},
{"review", "commit_id"},
{"review_state", "commit_sha"},
{"repo_archiver", "commit_id"},
{"release", "sha1"},
{"repo_indexer_status", "commit_sha"},
}
db := x.NewSession()
defer db.Close()
if err := db.Begin(); err != nil {
return err
}
if !setting.Database.Type.IsSQLite3() {
if setting.Database.Type.IsMSSQL() {
// drop indexes that need to be re-created afterwards
droppedIndexes := []string{
"DROP INDEX commit_status.IDX_commit_status_context_hash",
"DROP INDEX review_state.UQE_review_state_pull_commit_user",
"DROP INDEX repo_archiver.UQE_repo_archiver_s",
}
for _, s := range droppedIndexes {
_, err := db.Exec(s)
if err != nil {
return errors.New(s + " " + err.Error())
}
}
}
for _, alts := range alteredTables {
var err error
if setting.Database.Type.IsMySQL() {
_, err = db.Exec(fmt.Sprintf("ALTER TABLE `%s` MODIFY COLUMN `%s` VARCHAR(64)", alts[0], alts[1]))
} else if setting.Database.Type.IsMSSQL() {
_, err = db.Exec(fmt.Sprintf("ALTER TABLE `%s` ALTER COLUMN `%s` VARCHAR(64)", alts[0], alts[1]))
} else {
_, err = db.Exec(fmt.Sprintf("ALTER TABLE `%s` ALTER COLUMN `%s` TYPE VARCHAR(64)", alts[0], alts[1]))
}
if err != nil {
return fmt.Errorf("alter column '%s' of table '%s' failed: %w", alts[1], alts[0], err)
}
}
if setting.Database.Type.IsMSSQL() {
recreateIndexes := []string{
"CREATE INDEX IDX_commit_status_context_hash ON commit_status(context_hash)",
"CREATE UNIQUE INDEX UQE_review_state_pull_commit_user ON review_state(user_id, pull_id, commit_sha)",
"CREATE UNIQUE INDEX UQE_repo_archiver_s ON repo_archiver(repo_id, type, commit_id)",
}
for _, s := range recreateIndexes {
_, err := db.Exec(s)
if err != nil {
return errors.New(s + " " + err.Error())
}
}
}
}
log.Debug("Updated database tables to hold SHA256 git hash references")
return db.Commit()
}
func addObjectFormatNameToRepository(x *xorm.Engine) error {
type Repository struct {
ObjectFormatName string `xorm:"VARCHAR(6) NOT NULL DEFAULT 'sha1'"`
}
if err := x.Sync(new(Repository)); err != nil {
return err
}
// Here to catch weird edge-cases where column constraints above are
// not applied by the DB backend
_, err := x.Exec("UPDATE repository set object_format_name = 'sha1' WHERE object_format_name = '' or object_format_name IS NULL")
return err
}
func AdjustDBForSha256(x *xorm.Engine) error {
if err := expandHashReferencesToSha256(x); err != nil {
return err
}
return addObjectFormatNameToRepository(x)
}
+62
View File
@@ -0,0 +1,62 @@
// Copyright 2023 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package v1_22 //nolint
import (
"testing"
"code.gitea.io/gitea/models/migrations/base"
"github.com/stretchr/testify/assert"
"xorm.io/xorm"
)
func PrepareOldRepository(t *testing.T) (*xorm.Engine, func()) {
type Repository struct { // old struct
ID int64 `xorm:"pk autoincr"`
}
// Prepare and load the testing database
return base.PrepareTestEnv(t, 0, new(Repository))
}
func Test_RepositoryFormat(t *testing.T) {
x, deferable := PrepareOldRepository(t)
defer deferable()
type Repository struct {
ID int64 `xorm:"pk autoincr"`
ObjectFormatName string `xorg:"not null default('sha1')"`
}
repo := new(Repository)
// check we have some records to migrate
count, err := x.Count(new(Repository))
assert.NoError(t, err)
assert.EqualValues(t, 4, count)
assert.NoError(t, AdjustDBForSha256(x))
repo.ID = 20
repo.ObjectFormatName = "sha256"
_, err = x.Insert(repo)
assert.NoError(t, err)
count, err = x.Count(new(Repository))
assert.NoError(t, err)
assert.EqualValues(t, 5, count)
repo = new(Repository)
ok, err := x.ID(2).Get(repo)
assert.NoError(t, err)
assert.EqualValues(t, true, ok)
assert.EqualValues(t, "sha1", repo.ObjectFormatName)
repo = new(Repository)
ok, err = x.ID(20).Get(repo)
assert.NoError(t, err)
assert.EqualValues(t, true, ok)
assert.EqualValues(t, "sha256", repo.ObjectFormatName)
}
+7 -7
View File
@@ -191,18 +191,18 @@ type Package struct {
func TryInsertPackage(ctx context.Context, p *Package) (*Package, error) {
e := db.GetEngine(ctx)
key := &Package{
OwnerID: p.OwnerID,
Type: p.Type,
LowerName: p.LowerName,
}
existing := &Package{}
has, err := e.Get(key)
has, err := e.Where(builder.Eq{
"owner_id": p.OwnerID,
"type": p.Type,
"lower_name": p.LowerName,
}).Get(existing)
if err != nil {
return nil, err
}
if has {
return key, ErrDuplicatePackage
return existing, ErrDuplicatePackage
}
if _, err = e.Insert(p); err != nil {
return nil, err
+10 -2
View File
@@ -41,12 +41,20 @@ type PackageBlob struct {
func GetOrInsertBlob(ctx context.Context, pb *PackageBlob) (*PackageBlob, bool, error) {
e := db.GetEngine(ctx)
has, err := e.Get(pb)
existing := &PackageBlob{}
has, err := e.Where(builder.Eq{
"size": pb.Size,
"hash_md5": pb.HashMD5,
"hash_sha1": pb.HashSHA1,
"hash_sha256": pb.HashSHA256,
"hash_sha512": pb.HashSHA512,
}).Get(existing)
if err != nil {
return nil, false, err
}
if has {
return pb, true, nil
return existing, true, nil
}
if _, err = e.Insert(pb); err != nil {
return nil, false, err
+13 -13
View File
@@ -46,18 +46,18 @@ type PackageFile struct {
func TryInsertFile(ctx context.Context, pf *PackageFile) (*PackageFile, error) {
e := db.GetEngine(ctx)
key := &PackageFile{
VersionID: pf.VersionID,
LowerName: pf.LowerName,
CompositeKey: pf.CompositeKey,
}
existing := &PackageFile{}
has, err := e.Get(key)
has, err := e.Where(builder.Eq{
"version_id": pf.VersionID,
"lower_name": pf.LowerName,
"composite_key": pf.CompositeKey,
}).Get(existing)
if err != nil {
return nil, err
}
if has {
return pf, ErrDuplicatePackageFile
return existing, ErrDuplicatePackageFile
}
if _, err = e.Insert(pf); err != nil {
return nil, err
@@ -93,13 +93,13 @@ func GetFileForVersionByName(ctx context.Context, versionID int64, name, key str
return nil, ErrPackageFileNotExist
}
pf := &PackageFile{
VersionID: versionID,
LowerName: strings.ToLower(name),
CompositeKey: key,
}
pf := &PackageFile{}
has, err := db.GetEngine(ctx).Get(pf)
has, err := db.GetEngine(ctx).Where(builder.Eq{
"version_id": versionID,
"lower_name": strings.ToLower(name),
"composite_key": key,
}).Get(pf)
if err != nil {
return nil, err
}
+6 -6
View File
@@ -39,17 +39,17 @@ type PackageVersion struct {
func GetOrInsertVersion(ctx context.Context, pv *PackageVersion) (*PackageVersion, error) {
e := db.GetEngine(ctx)
key := &PackageVersion{
PackageID: pv.PackageID,
LowerVersion: pv.LowerVersion,
}
existing := &PackageVersion{}
has, err := e.Get(key)
has, err := e.Where(builder.Eq{
"package_id": pv.PackageID,
"lower_version": pv.LowerVersion,
}).Get(existing)
if err != nil {
return nil, err
}
if has {
return key, ErrDuplicatePackageVersion
return existing, ErrDuplicatePackageVersion
}
if _, err = e.Insert(pv); err != nil {
return nil, err
+23
View File
@@ -0,0 +1,23 @@
// Copyright 2024 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package rpm
import (
"context"
packages_model "code.gitea.io/gitea/models/packages"
rpm_module "code.gitea.io/gitea/modules/packages/rpm"
)
// GetGroups gets all available groups
func GetGroups(ctx context.Context, ownerID int64) ([]string, error) {
return packages_model.GetDistinctPropertyValues(
ctx,
packages_model.TypeRpm,
ownerID,
packages_model.PropertyTypeFile,
rpm_module.PropertyGroup,
nil,
)
}
+1 -1
View File
@@ -39,7 +39,7 @@ type ReviewState struct {
ID int64 `xorm:"pk autoincr"`
UserID int64 `xorm:"NOT NULL UNIQUE(pull_commit_user)"`
PullID int64 `xorm:"NOT NULL INDEX UNIQUE(pull_commit_user) DEFAULT 0"` // Which PR was the review on?
CommitSHA string `xorm:"NOT NULL VARCHAR(40) UNIQUE(pull_commit_user)"` // Which commit was the head commit for the review?
CommitSHA string `xorm:"NOT NULL VARCHAR(64) UNIQUE(pull_commit_user)"` // Which commit was the head commit for the review?
UpdatedFiles map[string]ViewedState `xorm:"NOT NULL LONGTEXT JSON"` // Stores for each of the changed files of a PR whether they have been viewed, changed since last viewed, or not viewed
UpdatedUnix timeutil.TimeStamp `xorm:"updated"` // Is an accurate indicator of the order of commits as we do not expect it to be possible to make reviews on previous commits
}
+1 -1
View File
@@ -33,7 +33,7 @@ type RepoArchiver struct { //revive:disable-line:exported
RepoID int64 `xorm:"index unique(s)"`
Type git.ArchiveType `xorm:"unique(s)"`
Status ArchiverStatus
CommitID string `xorm:"VARCHAR(40) unique(s)"`
CommitID string `xorm:"VARCHAR(64) unique(s)"`
CreatedUnix timeutil.TimeStamp `xorm:"INDEX NOT NULL created"`
}
+5 -2
View File
@@ -121,8 +121,11 @@ func GetPushMirrorsSyncedOnCommit(ctx context.Context, repoID int64) ([]*PushMir
// PushMirrorsIterate iterates all push-mirror repositories.
func PushMirrorsIterate(ctx context.Context, limit int, f func(idx int, bean any) error) error {
sess := db.GetEngine(ctx).
Where("last_update + (`interval` / ?) <= ?", time.Second, time.Now().Unix()).
And("`interval` != 0").
Table("push_mirror").
Join("INNER", "`repository`", "`repository`.id = `push_mirror`.repo_id").
Where("`push_mirror`.last_update + (`push_mirror`.`interval` / ?) <= ?", time.Second, time.Now().Unix()).
And("`push_mirror`.`interval` != 0").
And("`repository`.is_archived = ?", false).
OrderBy("last_update ASC")
if limit > 0 {
sess = sess.Limit(limit)
+1 -1
View File
@@ -75,7 +75,7 @@ type Release struct {
Target string
TargetBehind string `xorm:"-"` // to handle non-existing or empty target
Title string
Sha1 string `xorm:"VARCHAR(40)"`
Sha1 string `xorm:"VARCHAR(64)"`
NumCommits int64
NumCommitsBehind int64 `xorm:"-"`
Note string `xorm:"TEXT"`
+10 -7
View File
@@ -180,7 +180,7 @@ type Repository struct {
IsFsckEnabled bool `xorm:"NOT NULL DEFAULT true"`
CloseIssuesViaCommitInAnyBranch bool `xorm:"NOT NULL DEFAULT false"`
Topics []string `xorm:"TEXT JSON"`
ObjectFormatName string `xorm:"-"`
ObjectFormatName string `xorm:"VARCHAR(6) NOT NULL DEFAULT 'sha1'"`
TrustModel TrustModelType
@@ -196,6 +196,14 @@ func init() {
db.RegisterModel(new(Repository))
}
func (repo *Repository) GetName() string {
return repo.Name
}
func (repo *Repository) GetOwnerName() string {
return repo.OwnerName
}
// SanitizedOriginalURL returns a sanitized OriginalURL
func (repo *Repository) SanitizedOriginalURL() string {
if repo.OriginalURL == "" {
@@ -276,10 +284,6 @@ func (repo *Repository) AfterLoad() {
repo.NumOpenMilestones = repo.NumMilestones - repo.NumClosedMilestones
repo.NumOpenProjects = repo.NumProjects - repo.NumClosedProjects
repo.NumOpenActionRuns = repo.NumActionRuns - repo.NumClosedActionRuns
// this is a temporary behaviour to support old repos, next step is to store the object format in the database
// and read from database so this line could be removed. To not depend on git module, we use a constant variable here
repo.ObjectFormatName = "sha1"
}
// LoadAttributes loads attributes of the repository.
@@ -584,8 +588,7 @@ func (repo *Repository) CanEnableEditor() bool {
// DescriptionHTML does special handles to description and return HTML string.
func (repo *Repository) DescriptionHTML(ctx context.Context) template.HTML {
desc, err := markup.RenderDescriptionHTML(&markup.RenderContext{
Ctx: ctx,
URLPrefix: repo.HTMLURL(),
Ctx: ctx,
// Don't use Metas to speedup requests
}, repo.Description)
if err != nil {
+1 -1
View File
@@ -27,7 +27,7 @@ const (
type RepoIndexerStatus struct { //revive:disable-line:exported
ID int64 `xorm:"pk autoincr"`
RepoID int64 `xorm:"INDEX(s)"`
CommitSha string `xorm:"VARCHAR(40)"`
CommitSha string `xorm:"VARCHAR(64)"`
IndexerType RepoIndexerType `xorm:"INDEX(s) NOT NULL DEFAULT 0"`
}
+1 -1
View File
@@ -366,7 +366,7 @@ func syncTopicsInRepository(sess db.Engine, repoID int64) error {
topicNames := make([]string, 0, 25)
if err := sess.Table("topic").Cols("name").
Join("INNER", "repo_topic", "repo_topic.topic_id = topic.id").
Where("repo_topic.repo_id = ?", repoID).Desc("topic.repo_count").Find(&topicNames); err != nil {
Where("repo_topic.repo_id = ?", repoID).Asc("topic.name").Find(&topicNames); err != nil {
return err
}