mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2026-09-05 20:07:25 +00:00
fix(github): resolve tag pagination loop in release hook (#6870)
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user