fix: package cleaned rule fails if the keep count is too high (#9468)

If the keep count of a cleanup rule is greater than the number of available packages, it fails with:

```
panic(boundsError{x: int64(x), signed: true, y: y, code: boundsSliceB})
.../packages/packages.go:175
.../routers/web/org/setting_packages.go:108
```

Regression of https://codeberg.org/forgejo/forgejo/pulls/9219/files

Refs https://codeberg.org/forgejo/forgejo/issues/9461

<!--start release-notes-assistant-->

## Release notes
<!--URL:https://codeberg.org/forgejo/forgejo-->
- Bug fixes
  - [PR](https://codeberg.org/forgejo/forgejo/pulls/9468): <!--number 9468 --><!--line 0 --><!--description cGFja2FnZSBjbGVhbmVkIHJ1bGUgZmFpbHMgaWYgdGhlIGtlZXAgY291bnQgaXMgdG9vIGhpZ2g=-->package cleaned rule fails if the keep count is too high<!--description-->
<!--end release-notes-assistant-->

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/9468
Reviewed-by: Gusted <gusted@noreply.codeberg.org>
Reviewed-by: Mathieu Fenniak <mfenniak@noreply.codeberg.org>
Co-authored-by: Earl Warren <contact@earl-warren.org>
Co-committed-by: Earl Warren <contact@earl-warren.org>
This commit is contained in:
Earl Warren 2025-09-29 16:28:43 +02:00 committed by Earl Warren
commit 710600f459
3 changed files with 17 additions and 2 deletions

View file

@ -172,7 +172,8 @@ func SetRulePreviewContext(ctx *context.Context, owner *user_model.User) {
ctx.ServerError("SearchVersions", err)
return
}
for _, pv := range pvs[pcr.KeepCount:] {
keep := min(len(pvs), pcr.KeepCount)
for _, pv := range pvs[keep:] {
if skip, err := container_service.ShouldBeSkipped(ctx, pcr, p, pv); err != nil {
ctx.ServerError("ShouldBeSkipped", err)
return

View file

@ -69,7 +69,8 @@ func ExecuteCleanupRules(outerCtx context.Context) error {
return fmt.Errorf("CleanupRule [%d]: SearchVersions failed: %w", pcr.ID, err)
}
versionDeleted := false
for _, pv := range pvs[pcr.KeepCount:] {
keep := min(len(pvs), pcr.KeepCount)
for _, pv := range pvs[keep:] {
if pcr.Type == packages_model.TypeContainer {
if skip, err := container_service.ShouldBeSkipped(ctx, pcr, p, pv); err != nil {
return fmt.Errorf("CleanupRule [%d]: container.ShouldBeSkipped failed: %w", pcr.ID, err)

View file

@ -573,6 +573,19 @@ func TestPackageCleanup(t *testing.T) {
KeepCount: 2,
},
},
{
Name: "KeepCountGreaterThanTotal",
Versions: []version{
{Version: "keep", ShouldExist: true},
{Version: "v1.0", ShouldExist: true},
{Version: "test-3", ShouldExist: true},
{Version: "test-4", ShouldExist: true},
},
Rule: &packages_model.PackageCleanupRule{
Enabled: true,
KeepCount: 2000,
},
},
{
Name: "KeepPattern",
Versions: []version{