Skip to content

Commit 5bc73ca

Browse files
authored
Delete unreferenced packages when deleting a package version (#20977)
Delete a package if its last version got deleted. Otherwise removing the owner works only after the clean up job ran. Fix #20969
1 parent 1670109 commit 5bc73ca

File tree

2 files changed

+78
-2
lines changed

2 files changed

+78
-2
lines changed

models/packages/package.go

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,9 +224,16 @@ func FindUnreferencedPackages(ctx context.Context) ([]*Package, error) {
224224
Find(&ps)
225225
}
226226

227-
// HasOwnerPackages tests if a user/org has packages
227+
// HasOwnerPackages tests if a user/org has accessible packages
228228
func HasOwnerPackages(ctx context.Context, ownerID int64) (bool, error) {
229-
return db.GetEngine(ctx).Where("owner_id = ?", ownerID).Exist(&Package{})
229+
return db.GetEngine(ctx).
230+
Table("package_version").
231+
Join("INNER", "package", "package.id = package_version.package_id").
232+
Where(builder.Eq{
233+
"package_version.is_internal": false,
234+
"package.owner_id": ownerID,
235+
}).
236+
Exist(&PackageVersion{})
230237
}
231238

232239
// HasRepositoryPackages tests if a repository has packages

models/packages/package_test.go

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
// Copyright 2022 The Gitea Authors. All rights reserved.
2+
// Use of this source code is governed by a MIT-style
3+
// license that can be found in the LICENSE file.
4+
5+
package packages_test
6+
7+
import (
8+
"path/filepath"
9+
"testing"
10+
11+
"code.gitea.io/gitea/models/db"
12+
packages_model "code.gitea.io/gitea/models/packages"
13+
"code.gitea.io/gitea/models/unittest"
14+
user_model "code.gitea.io/gitea/models/user"
15+
16+
_ "code.gitea.io/gitea/models"
17+
18+
"github.com/stretchr/testify/assert"
19+
)
20+
21+
func TestMain(m *testing.M) {
22+
unittest.MainTest(m, &unittest.TestOptions{
23+
GiteaRootPath: filepath.Join("..", ".."),
24+
})
25+
}
26+
27+
func TestHasOwnerPackages(t *testing.T) {
28+
assert.NoError(t, unittest.PrepareTestDatabase())
29+
30+
owner := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
31+
32+
p, err := packages_model.TryInsertPackage(db.DefaultContext, &packages_model.Package{
33+
OwnerID: owner.ID,
34+
LowerName: "package",
35+
})
36+
assert.NotNil(t, p)
37+
assert.NoError(t, err)
38+
39+
// A package without package versions gets automatically cleaned up and should return false
40+
has, err := packages_model.HasOwnerPackages(db.DefaultContext, owner.ID)
41+
assert.False(t, has)
42+
assert.NoError(t, err)
43+
44+
pv, err := packages_model.GetOrInsertVersion(db.DefaultContext, &packages_model.PackageVersion{
45+
PackageID: p.ID,
46+
LowerVersion: "internal",
47+
IsInternal: true,
48+
})
49+
assert.NotNil(t, pv)
50+
assert.NoError(t, err)
51+
52+
// A package with an internal package version gets automaticaly cleaned up and should return false
53+
has, err = packages_model.HasOwnerPackages(db.DefaultContext, owner.ID)
54+
assert.False(t, has)
55+
assert.NoError(t, err)
56+
57+
pv, err = packages_model.GetOrInsertVersion(db.DefaultContext, &packages_model.PackageVersion{
58+
PackageID: p.ID,
59+
LowerVersion: "normal",
60+
IsInternal: false,
61+
})
62+
assert.NotNil(t, pv)
63+
assert.NoError(t, err)
64+
65+
// A package with a normal package version should return true
66+
has, err = packages_model.HasOwnerPackages(db.DefaultContext, owner.ID)
67+
assert.True(t, has)
68+
assert.NoError(t, err)
69+
}

0 commit comments

Comments
 (0)