From caf2e036054cef8c3288761d3fb15c3c23325eeb Mon Sep 17 00:00:00 2001 From: Mitrahsoft Date: Thu, 6 Aug 2026 12:36:32 +0530 Subject: [PATCH] fix(packages): show error for duplicate cleanup rules #37820 (#38786) ## Issue Gitea does not display a clear error message when a user tries to create a cleanup rule for a package type that already has an existing cleanup rule. Although the duplicate rule is detected, the user is not informed why the cleanup rule cannot be created. ## Solution Add a user-facing error message when a cleanup rule already exists for the selected package type. Also add an integration test to verify that the appropriate error message is displayed when attempting to create a duplicate cleanup rule. Fixes #37820 --- options/locale/locale_en-US.json | 3 ++- routers/web/shared/packages/packages.go | 1 + tests/integration/api_packages_test.go | 27 +++++++++++++++++++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/options/locale/locale_en-US.json b/options/locale/locale_en-US.json index 6ac76d8d45a..626aeb65d8f 100644 --- a/options/locale/locale_en-US.json +++ b/options/locale/locale_en-US.json @@ -3932,5 +3932,6 @@ "actions.general.cross_repo_desc": "Allow the selected repositories to be accessed (read-only) by all the repositories in this owner with GITEA_TOKEN when running Actions jobs.", "actions.general.cross_repo_selected": "Selected repositories", "actions.general.cross_repo_target_repos": "Target Repositories", - "actions.general.cross_repo_add": "Add Target Repository" + "actions.general.cross_repo_add": "Add Target Repository", + "packages.owner.settings.cleanuprules.type.already_exists": "A cleanup rule for this package type already exists." } diff --git a/routers/web/shared/packages/packages.go b/routers/web/shared/packages/packages.go index 80267aaaf7a..6c8a588e3d1 100644 --- a/routers/web/shared/packages/packages.go +++ b/routers/web/shared/packages/packages.go @@ -117,6 +117,7 @@ func performRuleEditPost(ctx *context.Context, owner *user_model.User, pcr *pack return } else if has { ctx.Data["Err_Type"] = true + ctx.Flash.Error(ctx.Tr("packages.owner.settings.cleanuprules.type.already_exists"), true) ctx.HTML(http.StatusOK, template) return } diff --git a/tests/integration/api_packages_test.go b/tests/integration/api_packages_test.go index 6dba3e125e7..efb32e271f6 100644 --- a/tests/integration/api_packages_test.go +++ b/tests/integration/api_packages_test.go @@ -29,6 +29,33 @@ import ( "github.com/stretchr/testify/assert" ) +func TestPackageCleanupRuleDuplicateType(t *testing.T) { + defer tests.PrepareTestEnv(t)() + + user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 4}) + session := loginUser(t, user.Name) + + // Create the first cleanup rule for the generic package type. + req := NewRequestWithValues(t, "POST", "/user/settings/packages/rules/add", map[string]string{ + "type": "generic", + "action": "save", + "keep_count": "0", + "remove_days": "0", + }) + session.MakeRequest(t, req, http.StatusSeeOther) + + // Try to create another cleanup rule for the same package type. + req = NewRequestWithValues(t, "POST", "/user/settings/packages/rules/add", map[string]string{ + "type": "generic", + "action": "save", + "keep_count": "0", + "remove_days": "0", + }) + + resp := session.MakeRequest(t, req, http.StatusOK) + assert.Contains(t, resp.Body.String(), "A cleanup rule for this package type already exists.") +} + func TestPackageAPI(t *testing.T) { defer tests.PrepareTestEnv(t)()