From dbed39d63292517918c3b1a74aeb71ac8910beb7 Mon Sep 17 00:00:00 2001
From: Lunny Xiao <xiaolunwen@gmail.com>
Date: Sun, 2 Mar 2025 21:01:28 -0800
Subject: [PATCH] Add migrations and doctor fixes (#33556)

Fix #33535
---
 models/actions/runner.go         | 14 ++++++++++++++
 models/actions/variable.go       | 14 ++++++++++++++
 models/migrations/migrations.go  |  1 +
 models/migrations/v1_24/v314.go  | 19 +++++++++++++++++++
 models/secret/secret.go          | 14 ++++++++++++++
 services/doctor/dbconsistency.go | 19 +++++++++++++++++++
 6 files changed, 81 insertions(+)
 create mode 100644 models/migrations/v1_24/v314.go

diff --git a/models/actions/runner.go b/models/actions/runner.go
index 798a647180..97db0ca7ea 100644
--- a/models/actions/runner.go
+++ b/models/actions/runner.go
@@ -337,3 +337,17 @@ func FixRunnersWithoutBelongingRepo(ctx context.Context) (int64, error) {
 	}
 	return res.RowsAffected()
 }
+
+func CountWrongRepoLevelRunners(ctx context.Context) (int64, error) {
+	var result int64
+	_, err := db.GetEngine(ctx).SQL("SELECT count(`id`) FROM `action_runner` WHERE `repo_id` > 0 AND `owner_id` > 0").Get(&result)
+	return result, err
+}
+
+func UpdateWrongRepoLevelRunners(ctx context.Context) (int64, error) {
+	result, err := db.GetEngine(ctx).Exec("UPDATE `action_runner` SET `owner_id` = 0 WHERE `repo_id` > 0 AND `owner_id` > 0")
+	if err != nil {
+		return 0, err
+	}
+	return result.RowsAffected()
+}
diff --git a/models/actions/variable.go b/models/actions/variable.go
index 163bb12c93..1929cffbd8 100644
--- a/models/actions/variable.go
+++ b/models/actions/variable.go
@@ -147,3 +147,17 @@ func GetVariablesOfRun(ctx context.Context, run *ActionRun) (map[string]string,
 
 	return variables, nil
 }
+
+func CountWrongRepoLevelVariables(ctx context.Context) (int64, error) {
+	var result int64
+	_, err := db.GetEngine(ctx).SQL("SELECT count(`id`) FROM `action_variable` WHERE `repo_id` > 0 AND `owner_id` > 0").Get(&result)
+	return result, err
+}
+
+func UpdateWrongRepoLevelVariables(ctx context.Context) (int64, error) {
+	result, err := db.GetEngine(ctx).Exec("UPDATE `action_variable` SET `owner_id` = 0 WHERE `repo_id` > 0 AND `owner_id` > 0")
+	if err != nil {
+		return 0, err
+	}
+	return result.RowsAffected()
+}
diff --git a/models/migrations/migrations.go b/models/migrations/migrations.go
index 87d674a440..fd291c5692 100644
--- a/models/migrations/migrations.go
+++ b/models/migrations/migrations.go
@@ -374,6 +374,7 @@ func prepareMigrationTasks() []*migration {
 		// Gitea 1.23.0-rc0 ends at migration ID number 311 (database version 312)
 		newMigration(312, "Add DeleteBranchAfterMerge to AutoMerge", v1_24.AddDeleteBranchAfterMergeForAutoMerge),
 		newMigration(313, "Move PinOrder from issue table to a new table issue_pin", v1_24.MovePinOrderToTableIssuePin),
+		newMigration(314, "Update OwnerID as zero for repository level action tables", v1_24.UpdateOwnerIDOfRepoLevelActionsTables),
 	}
 	return preparedMigrations
 }
diff --git a/models/migrations/v1_24/v314.go b/models/migrations/v1_24/v314.go
new file mode 100644
index 0000000000..e537be13b5
--- /dev/null
+++ b/models/migrations/v1_24/v314.go
@@ -0,0 +1,19 @@
+// Copyright 2025 The Gitea Authors. All rights reserved.
+// SPDX-License-Identifier: MIT
+
+package v1_24 //nolint
+
+import (
+	"xorm.io/xorm"
+)
+
+func UpdateOwnerIDOfRepoLevelActionsTables(x *xorm.Engine) error {
+	if _, err := x.Exec("UPDATE `action_runner` SET `owner_id` = 0 WHERE `repo_id` > 0 AND `owner_id` > 0"); err != nil {
+		return err
+	}
+	if _, err := x.Exec("UPDATE `action_variable` SET `owner_id` = 0 WHERE `repo_id` > 0 AND `owner_id` > 0"); err != nil {
+		return err
+	}
+	_, err := x.Exec("UPDATE `secret` SET `owner_id` = 0 WHERE `repo_id` > 0 AND `owner_id` > 0")
+	return err
+}
diff --git a/models/secret/secret.go b/models/secret/secret.go
index ce0ad65a79..eab9cf0712 100644
--- a/models/secret/secret.go
+++ b/models/secret/secret.go
@@ -165,3 +165,17 @@ func GetSecretsOfTask(ctx context.Context, task *actions_model.ActionTask) (map[
 
 	return secrets, nil
 }
+
+func CountWrongRepoLevelSecrets(ctx context.Context) (int64, error) {
+	var result int64
+	_, err := db.GetEngine(ctx).SQL("SELECT count(`id`) FROM `secret` WHERE `repo_id` > 0 AND `owner_id` > 0").Get(&result)
+	return result, err
+}
+
+func UpdateWrongRepoLevelSecrets(ctx context.Context) (int64, error) {
+	result, err := db.GetEngine(ctx).Exec("UPDATE `secret` SET `owner_id` = 0 WHERE `repo_id` > 0 AND `owner_id` > 0")
+	if err != nil {
+		return 0, err
+	}
+	return result.RowsAffected()
+}
diff --git a/services/doctor/dbconsistency.go b/services/doctor/dbconsistency.go
index 7cb7445148..62326ed07c 100644
--- a/services/doctor/dbconsistency.go
+++ b/services/doctor/dbconsistency.go
@@ -12,6 +12,7 @@ import (
 	issues_model "code.gitea.io/gitea/models/issues"
 	"code.gitea.io/gitea/models/migrations"
 	repo_model "code.gitea.io/gitea/models/repo"
+	secret_model "code.gitea.io/gitea/models/secret"
 	"code.gitea.io/gitea/modules/log"
 	"code.gitea.io/gitea/modules/setting"
 )
@@ -164,6 +165,24 @@ func prepareDBConsistencyChecks() []consistencyCheck {
 			Fixer:        repo_model.DeleteOrphanedTopics,
 			FixedMessage: "Removed",
 		},
+		{
+			Name:         "Repository level Runners with non-zero owner_id",
+			Counter:      actions_model.CountWrongRepoLevelRunners,
+			Fixer:        actions_model.UpdateWrongRepoLevelRunners,
+			FixedMessage: "Corrected",
+		},
+		{
+			Name:         "Repository level Variables with non-zero owner_id",
+			Counter:      actions_model.CountWrongRepoLevelVariables,
+			Fixer:        actions_model.UpdateWrongRepoLevelVariables,
+			FixedMessage: "Corrected",
+		},
+		{
+			Name:         "Repository level Secrets with non-zero owner_id",
+			Counter:      secret_model.CountWrongRepoLevelSecrets,
+			Fixer:        secret_model.UpdateWrongRepoLevelSecrets,
+			FixedMessage: "Corrected",
+		},
 	}
 
 	// TODO: function to recalc all counters