From 5db9f4fa9275c56d9581398021e5cea631c2e4c8 Mon Sep 17 00:00:00 2001 From: Lunny Xiao Date: Fri, 16 Jan 2026 09:36:06 -0800 Subject: [PATCH] Add migrations rather than doctor command --- models/migrations/migrations.go | 1 + models/migrations/v1_26/v325.go | 18 ++++++++ models/migrations/v1_26/v325_test.go | 36 +++++++++++++++ services/doctor/attachment.go | 66 ---------------------------- 4 files changed, 55 insertions(+), 66 deletions(-) create mode 100644 models/migrations/v1_26/v325.go create mode 100644 models/migrations/v1_26/v325_test.go delete mode 100644 services/doctor/attachment.go diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go index fa11acaee2..9975729fd6 100644 --- a/models/migrations/migrations.go +++ b/models/migrations/migrations.go @@ -399,6 +399,7 @@ func prepareMigrationTasks() []*migration { newMigration(323, "Add support for actions concurrency", v1_26.AddActionsConcurrency), newMigration(324, "Fix closed milestone completeness for milestones with no issues", v1_26.FixClosedMilestoneCompleteness), + newMigration(325, "Fix missed repo_id when migrate attachments", v1_26.FixMissedRepoIDWhenMigrateAttachments), } return preparedMigrations } diff --git a/models/migrations/v1_26/v325.go b/models/migrations/v1_26/v325.go new file mode 100644 index 0000000000..30c9c2d1b1 --- /dev/null +++ b/models/migrations/v1_26/v325.go @@ -0,0 +1,18 @@ +// Copyright 2025 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_26 + +import ( + "xorm.io/xorm" +) + +func FixMissedRepoIDWhenMigrateAttachments(x *xorm.Engine) error { + _, err := x.Exec("UPDATE `attachment` SET `repo_id` = (SELECT `repo_id` FROM `issue` WHERE `issue`.`id` = `attachment`.`issue_id`) WHERE `issue_id` > 0 AND (`repo_id` IS NULL OR `repo_id` = 0);") + if err != nil { + return err + } + + _, err = x.Exec("UPDATE `attachment` SET `repo_id` = (SELECT `repo_id` FROM `release` WHERE `release`.`id` = `attachment`.`release_id`) WHERE `release_id` > 0 AND (`repo_id` IS NULL OR `repo_id` = 0);") + return err +} diff --git a/models/migrations/v1_26/v325_test.go b/models/migrations/v1_26/v325_test.go new file mode 100644 index 0000000000..4a9105ea87 --- /dev/null +++ b/models/migrations/v1_26/v325_test.go @@ -0,0 +1,36 @@ +// Copyright 2026 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package v1_26 + +import ( + "testing" + + "code.gitea.io/gitea/models/migrations/base" + "code.gitea.io/gitea/modules/timeutil" + + "github.com/stretchr/testify/require" +) + +func Test_FixMissedRepoIDWhenMigrateAttachments(t *testing.T) { + type Attachment struct { + ID int64 `xorm:"pk autoincr"` + UUID string `xorm:"uuid UNIQUE"` + RepoID int64 `xorm:"INDEX"` // this should not be zero + IssueID int64 `xorm:"INDEX"` // maybe zero when creating + ReleaseID int64 `xorm:"INDEX"` // maybe zero when creating + UploaderID int64 `xorm:"INDEX DEFAULT 0"` // Notice: will be zero before this column added + CommentID int64 `xorm:"INDEX"` + Name string + DownloadCount int64 `xorm:"DEFAULT 0"` + Size int64 `xorm:"DEFAULT 0"` + CreatedUnix timeutil.TimeStamp `xorm:"created"` + CustomDownloadURL string `xorm:"-"` + } + + // Prepare and load the testing database + x, deferrable := base.PrepareTestEnv(t, 0, new(Attachment)) + defer deferrable() + + require.NoError(t, FixMissedRepoIDWhenMigrateAttachments(x)) +} diff --git a/services/doctor/attachment.go b/services/doctor/attachment.go deleted file mode 100644 index 0a20d9750e..0000000000 --- a/services/doctor/attachment.go +++ /dev/null @@ -1,66 +0,0 @@ -// Copyright 2022 The Gitea Authors. All rights reserved. -// SPDX-License-Identifier: MIT - -package doctor - -import ( - "context" - - "code.gitea.io/gitea/models/db" - "code.gitea.io/gitea/modules/log" -) - -func init() { - Register(&Check{ - Title: "Fix attachment which have issue_id or release_id lost repo_id", - Name: "fix-attachment-repo-id", - IsDefault: false, - Run: fixAttachmentRepoIDCheck, - AbortIfFailed: false, - SkipDatabaseInitialization: false, - Priority: 1, - }) -} - -func fixAttachmentRepoIDCheck(ctx context.Context, logger log.Logger, autofix bool) error { - countIssue, err := db.GetEngine(ctx). - Where("`issue_id` > 0 AND (`repo_id` IS NULL OR `repo_id` = 0)"). - Table("attachment").Cols("id").Count() - if err != nil { - return err - } - - countRelease, err := db.GetEngine(ctx). - Where("`release_id` > 0 AND (`repo_id` IS NULL OR `repo_id` = 0)"). - Table("attachment").Cols("id").Count() - if err != nil { - return err - } - count := countIssue + countRelease - if count == 0 { - logger.Info("No attachment repo_id issues found.") - return nil - } - - logger.Warn("Found %d(issue), %d(release) attachments with missing repo_id.", countIssue, countRelease) - - if !autofix { - return nil - } - - updatedIssue, err := db.GetEngine(ctx).Exec("UPDATE `attachment` SET `repo_id` = (SELECT `repo_id` FROM `issue` WHERE `issue`.`id` = `attachment`.`issue_id`) WHERE `issue_id` > 0 AND (`repo_id` IS NULL OR `repo_id` = 0);") - if err != nil { - return err - } - cntIssue, _ := updatedIssue.RowsAffected() - - updatedRelease, err := db.GetEngine(ctx).Exec("UPDATE `attachment` SET `repo_id` = (SELECT `repo_id` FROM `release` WHERE `release`.`id` = `attachment`.`release_id`) WHERE `release_id` > 0 AND (`repo_id` IS NULL OR `repo_id` = 0);") - if err != nil { - return err - } - cntRelease, _ := updatedRelease.RowsAffected() - - logger.Info("Fixed attachment repo_id issues %d and release %d successfully.", cntIssue, cntRelease) - - return nil -}