fix(github): resolve tag pagination loop in release hook (#6870)

This commit is contained in:
Anay Garodia
2026-07-20 09:56:25 +02:00
committed by GitHub
parent 735238e482
commit 099df99494
2 changed files with 59 additions and 3 deletions
+5 -3
View File
@@ -787,10 +787,10 @@ func (c *client) getTagCommitSHA(ctx context.Context, repo *model.Repo, tagName
return "", err
}
page := 1
opts := &github.ListOptions{Page: 1}
var tag *github.RepositoryTag
for {
tags, _, err := gh.Repositories.ListTags(ctx, repo.Owner, repo.Name, &github.ListOptions{Page: page})
for opts.Page > 0 {
tags, resp, err := gh.Repositories.ListTags(ctx, repo.Owner, repo.Name, opts)
if err != nil {
return "", err
}
@@ -804,6 +804,8 @@ func (c *client) getTagCommitSHA(ctx context.Context, repo *model.Repo, tagName
if tag != nil {
break
}
opts.Page = resp.NextPage
}
if tag == nil {
return "", fmt.Errorf("could not find tag %s", tagName)
+54
View File
@@ -325,3 +325,57 @@ func TestHook(t *testing.T) {
assert.Empty(t, pipeline.ChangedFiles)
})
}
func TestGetTagCommitSHA(t *testing.T) {
// Tags API paginates 30 per page; put the target tag on the second page
// to exercise pagination instead of a first-page match.
mockedHTTPClient := github_mock.NewMockedHTTPClient(
github_mock.WithRequestMatchPages(
github_mock.GetReposTagsByOwnerByRepo,
[]github.RepositoryTag{
{Name: github.Ptr("v1.0.0")},
{Name: github.Ptr("v1.0.1")},
},
[]github.RepositoryTag{
{Name: github.Ptr("v1.0.2")},
{
Name: github.Ptr("v1.0.3"),
Commit: &github.Commit{SHA: github.Ptr("deadbeefcafe")},
},
},
),
)
gh, err := github.NewClient(github.WithHTTPClient(mockedHTTPClient))
require.NoError(t, err)
ctx := context.WithValue(context.Background(), githubClientKey, gh)
mockStore := store_mocks.NewMockStore(t)
mockStore.On("GetUser", mock.Anything).Return(&model.User{
ID: 1,
Login: "6543",
AccessToken: "token",
}, nil)
mockStore.On("GetRepoNameFallback", mock.Anything, mock.Anything, mock.Anything).Return(&model.Repo{
ID: 1,
ForgeRemoteID: "1",
Owner: "6543",
Name: "hello-world",
UserID: 1,
}, nil)
ctx = store.InjectToContext(ctx, mockStore)
c := &client{API: defaultAPI, url: defaultURL}
t.Run("finds a tag beyond the first page", func(t *testing.T) {
sha, err := c.getTagCommitSHA(ctx, &model.Repo{ForgeRemoteID: "1", FullName: "6543/hello-world"}, "v1.0.3")
require.NoError(t, err)
assert.Equal(t, "deadbeefcafe", sha)
})
t.Run("returns an error instead of looping forever when the tag does not exist", func(t *testing.T) {
_, err := c.getTagCommitSHA(ctx, &model.Repo{ForgeRemoteID: "1", FullName: "6543/hello-world"}, "does-not-exist")
require.Error(t, err)
})
}