fix(10359): Count releases correctly when using filters (q) (#10387)

This PR fixes the issue https://codeberg.org/forgejo/forgejo/issues/10359

## Checklist

The [contributor guide](https://forgejo.org/docs/next/contributor/) contains information that will be helpful to first time contributors. There also are a few [conditions for merging Pull Requests in Forgejo repositories](https://codeberg.org/forgejo/governance/src/branch/main/PullRequestsAgreement.md). You are also welcome to join the [Forgejo development chatroom](https://matrix.to/#/#forgejo-development:matrix.org).

### Tests

- I added test coverage for Go changes...
  - [x] in their respective `*_test.go` for unit tests.
  - [x] in the `tests/integration` directory if it involves interactions with a live Forgejo server.
- I added test coverage for JavaScript changes...
  - [ ] in `web_src/js/*.test.js` if it can be unit tested.
  - [ ] in `tests/e2e/*.test.e2e.js` if it requires interactions with a live Forgejo server (see also the [developer guide for JavaScript testing](https://codeberg.org/forgejo/forgejo/src/branch/forgejo/tests/e2e/README.md#end-to-end-tests)).

### Documentation

- [ ] I created a pull request [to the documentation](https://codeberg.org/forgejo/docs) to explain to Forgejo users how to use this change.
- [ ] I did not document these changes and I do not expect someone else to do it.

### Release notes

- [ ] I do not want this change to show in the release notes.
- [ ] I want the title to show in the release notes with a link to this pull request.
- [ ] I want the content of the `release-notes/<pull request number>.md` to be be used for the release notes instead of the title.

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

## Release notes
<!--URL:https://codeberg.org/forgejo/forgejo-->
- Bug fixes
  - [PR](https://codeberg.org/forgejo/forgejo/pulls/10387): <!--number 10387 --><!--line 0 --><!--description Zml4KDEwMzU5KTogQ291bnQgcmVsZWFzZXMgY29ycmVjdGx5IHdoZW4gdXNpbmcgZmlsdGVycyAocSk=-->fix(10359): Count releases correctly when using filters (q)<!--description-->
<!--end release-notes-assistant-->

Reviewed-on: https://codeberg.org/forgejo/forgejo/pulls/10387
Reviewed-by: Mathieu Fenniak <mfenniak@noreply.codeberg.org>
Co-authored-by: Rodrigo Villablanca <villa061004@gmail.com>
Co-committed-by: Rodrigo Villablanca <villa061004@gmail.com>
This commit is contained in:
Rodrigo Villablanca 2025-12-11 05:13:21 +01:00 committed by Mathieu Fenniak
commit ebc36a9ec7
3 changed files with 87 additions and 13 deletions

View file

@ -79,10 +79,18 @@ type ReleaseInfo struct {
CommitStatuses []*git_model.CommitStatus
}
func getReleaseInfos(ctx *context.Context, opts *repo_model.FindReleasesOptions) ([]*ReleaseInfo, error) {
func getReleaseInfos(ctx *context.Context, opts *repo_model.FindReleasesOptions) ([]*ReleaseInfo, int64, error) {
releases, err := db.Find[repo_model.Release](ctx, opts)
if err != nil {
return nil, err
return nil, 0, err
}
counts := int64(len(releases))
if !opts.IsListAll() {
counts, err = db.Count[repo_model.Release](ctx, opts)
if err != nil {
return nil, 0, err
}
}
for _, release := range releases {
@ -90,7 +98,7 @@ func getReleaseInfos(ctx *context.Context, opts *repo_model.FindReleasesOptions)
}
if err = repo_model.GetReleaseAttachments(ctx, releases...); err != nil {
return nil, err
return nil, 0, err
}
// Temporary cache commits count of used branches to speed up.
@ -111,7 +119,7 @@ func getReleaseInfos(ctx *context.Context, opts *repo_model.FindReleasesOptions)
if user_model.IsErrUserNotExist(err) {
r.Publisher = user_model.NewGhostUser()
} else {
return nil, err
return nil, 0, err
}
}
cacheUsers[r.PublisherID] = r.Publisher
@ -126,17 +134,17 @@ func getReleaseInfos(ctx *context.Context, opts *repo_model.FindReleasesOptions)
Ctx: ctx,
}, r.Note)
if err != nil {
return nil, err
return nil, 0, err
}
err = r.LoadArchiveDownloadCount(ctx)
if err != nil {
return nil, err
return nil, 0, err
}
if !r.IsDraft {
if err := calReleaseNumCommitsBehind(ctx.Repo, r, countCache); err != nil {
return nil, err
return nil, 0, err
}
}
@ -147,7 +155,7 @@ func getReleaseInfos(ctx *context.Context, opts *repo_model.FindReleasesOptions)
if canReadActions {
statuses, _, err := git_model.GetLatestCommitStatus(ctx, r.Repo.ID, r.Sha1, db.ListOptionsAll)
if err != nil {
return nil, err
return nil, 0, err
}
info.CommitStatus = git_model.CalcCommitStatus(statuses)
@ -157,7 +165,7 @@ func getReleaseInfos(ctx *context.Context, opts *repo_model.FindReleasesOptions)
releaseInfos = append(releaseInfos, info)
}
return releaseInfos, nil
return releaseInfos, counts, nil
}
// Releases render releases list page
@ -188,7 +196,7 @@ func Releases(ctx *context.Context) {
writeAccess := ctx.Repo.CanWrite(unit.TypeReleases)
ctx.Data["CanCreateRelease"] = writeAccess && !ctx.Repo.Repository.IsArchived
releases, err := getReleaseInfos(ctx, &repo_model.FindReleasesOptions{
releases, releasesCount, err := getReleaseInfos(ctx, &repo_model.FindReleasesOptions{
ListOptions: listOptions,
// only show draft releases for users who can write, read-only users shouldn't see draft releases.
IncludeDrafts: writeAccess,
@ -208,8 +216,7 @@ func Releases(ctx *context.Context) {
ctx.Data["Releases"] = releases
addVerifyTagToContext(ctx)
numReleases := ctx.Data["NumReleases"].(int64)
pager := context.NewPagination(int(numReleases), listOptions.PageSize, listOptions.Page, 5)
pager := context.NewPagination(int(releasesCount), listOptions.PageSize, listOptions.Page, 5)
pager.SetDefaultParams(ctx)
ctx.Data["Page"] = pager
@ -341,7 +348,7 @@ func SingleRelease(ctx *context.Context) {
writeAccess := ctx.Repo.CanWrite(unit.TypeReleases)
ctx.Data["CanCreateRelease"] = writeAccess && !ctx.Repo.Repository.IsArchived
releases, err := getReleaseInfos(ctx, &repo_model.FindReleasesOptions{
releases, _, err := getReleaseInfos(ctx, &repo_model.FindReleasesOptions{
ListOptions: db.ListOptions{Page: 1, PageSize: 1},
RepoID: ctx.Repo.Repository.ID,
// Include tags in the search too.

View file

@ -122,3 +122,52 @@ func TestCalReleaseNumCommitsBehind(t *testing.T) {
assert.Equal(t, expectedComputation[r.TagName], actual, "wrong computed fields for %s: %#v", r.TagName, r)
}
}
func Test_getReleaseInfos(t *testing.T) {
testCases := []struct {
name string
listOptions db.ListOptions
expectedRepoCount int
expectedCount int64
}{
{
name: "page 1 with page size 1",
listOptions: db.ListOptions{Page: 1, PageSize: 1},
expectedRepoCount: 1,
expectedCount: 3,
},
{
name: "page 1 with page size 10",
listOptions: db.ListOptions{Page: 1, PageSize: 10},
expectedRepoCount: 3,
expectedCount: 3,
},
{
name: "list all",
listOptions: db.ListOptions{ListAll: true},
expectedRepoCount: 3,
expectedCount: 3,
},
}
unittest.PrepareTestEnv(t)
ctx, _ := contexttest.MockContext(t, "user1/repo-release/releases")
contexttest.LoadRepo(t, ctx, 1)
contexttest.LoadGitRepo(t, ctx)
assert.NoError(t, db.Insert(ctx, &repo_model.Release{RepoID: ctx.Repo.Repository.ID, Title: "myrel 1", TagName: "myrel_v1.0"}))
assert.NoError(t, db.Insert(ctx, &repo_model.Release{RepoID: ctx.Repo.Repository.ID, Title: "myrel 2", TagName: "myrel_v2.0"}))
assert.NoError(t, db.Insert(ctx, &repo_model.Release{RepoID: ctx.Repo.Repository.ID, Title: "myrel 3", TagName: ""}))
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
repos, count, err := getReleaseInfos(ctx, &repo_model.FindReleasesOptions{
RepoID: ctx.Repo.Repository.ID,
Keyword: "myrel",
ListOptions: tc.listOptions,
})
require.NoError(t, err)
assert.Len(t, repos, tc.expectedRepoCount)
assert.Equal(t, tc.expectedCount, count)
})
}
}

View file

@ -359,6 +359,24 @@ func TestViewReleaseListKeyword(t *testing.T) {
}, links)
}
func TestViewReleaseListKeywordNoPagination(t *testing.T) {
defer tests.PrepareTestEnv(t)()
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 1})
link := repo.Link() + "/releases?q=testing&limit=1"
session := loginUser(t, "user1")
req := NewRequest(t, "GET", link)
rsp := session.MakeRequest(t, req, http.StatusOK)
htmlDoc := NewHTMLParser(t, rsp.Body)
releases := htmlDoc.Find("#release-list li.ui.grid")
assert.Equal(t, 1, releases.Length())
pagination := htmlDoc.Find("div.pagination")
assert.Zero(t, pagination.Length())
}
func TestReleaseOnCommit(t *testing.T) {
defer tests.PrepareTestEnv(t)()