Skip to content

Commit 555aeb0

Browse files
committed
fix(bitbucketcloud): optimize commit info fetch
Replace paginated GetCommits API with direct GetCommit lookup to eliminate performance bottleneck on repositories with many commits. When SHA is unavailable, fetch branch info first to get HEAD commit SHA, then use GetCommit for single-commit retrieval. This reduces webhook processing time from 49 seconds to <1 second on repositories with 2333+ commits by avoiding pagination through entire commit history. Fixes: #2336 https://issues.redhat.com/browse/SRVKP-10617 Signed-off-by: Zaki Shaikh <zashaikh@redhat.com> Assisted-by: Claude Sonnet 4.5 (via Claude Code)
1 parent 41a632b commit 555aeb0

File tree

3 files changed

+72
-25
lines changed

3 files changed

+72
-25
lines changed

pkg/provider/bitbucketcloud/bitbucket.go

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -221,31 +221,44 @@ func (v *Provider) SetClient(_ context.Context, run *params.Run, event *info.Eve
221221
}
222222

223223
func (v *Provider) GetCommitInfo(_ context.Context, event *info.Event) error {
224-
branchortag := event.SHA
225-
if branchortag == "" {
226-
branchortag = event.HeadBranch
224+
// If we don't have a SHA, get it from the branch first
225+
sha := event.SHA
226+
if sha == "" && event.HeadBranch != "" {
227+
v.Logger.Infof("fetching branch info to get commit SHA for branch: %s", event.HeadBranch)
228+
branchInfo, err := v.Client().Repositories.Repository.GetBranch(&bitbucket.RepositoryBranchOptions{
229+
Owner: event.Organization,
230+
RepoSlug: event.Repository,
231+
BranchName: event.HeadBranch,
232+
})
233+
if err != nil {
234+
return err
235+
}
236+
// Extract hash from Target map
237+
if hash, ok := branchInfo.Target["hash"].(string); ok {
238+
sha = hash
239+
} else {
240+
return fmt.Errorf("cannot extract commit hash from branch %s", event.HeadBranch)
241+
}
227242
}
228-
response, err := v.Client().Repositories.Commits.GetCommits(&bitbucket.CommitsOptions{
229-
Owner: event.Organization,
230-
RepoSlug: event.Repository,
231-
Branchortag: branchortag,
243+
244+
// Use GetCommit API for direct single-commit fetch (no pagination)
245+
v.Logger.Infof("fetching commit info using GetCommit API for SHA: %s", sha)
246+
response, err := v.Client().Repositories.Commits.GetCommit(&bitbucket.CommitsOptions{
247+
Owner: event.Organization,
248+
RepoSlug: event.Repository,
249+
Revision: sha,
232250
})
233251
if err != nil {
234252
return err
235253
}
254+
236255
commitMap, ok := response.(map[string]any)
237256
if !ok {
238-
return fmt.Errorf("cannot convert")
239-
}
240-
values, ok := commitMap["values"].([]any)
241-
if !ok {
242-
return fmt.Errorf("cannot convert")
243-
}
244-
if len(values) == 0 {
245-
return fmt.Errorf("we did not get commit information from commit: %s", event.SHA)
257+
return fmt.Errorf("cannot convert commit response")
246258
}
259+
247260
commitinfo := &types.Commit{}
248-
err = mapstructure.Decode(values[0], commitinfo)
261+
err = mapstructure.Decode(commitMap, commitinfo)
249262
if err != nil {
250263
return err
251264
}

pkg/provider/bitbucketcloud/bitbucket_test.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -244,12 +244,13 @@ func TestGetCommitInfo(t *testing.T) {
244244
for _, tt := range tests {
245245
t.Run(tt.name, func(t *testing.T) {
246246
ctx, _ := rtesting.SetupFakeContext(t)
247+
observer, _ := zapobserver.New(zap.InfoLevel)
248+
fakelogger := zap.New(observer).Sugar()
247249
bbclient, mux, tearDown := bbcloudtest.SetupBBCloudClient(t)
248250
defer tearDown()
249-
v := &Provider{bbClient: bbclient}
250-
bbcloudtest.MuxCommits(t, mux, tt.event, []types.Commit{
251-
tt.commitinfo,
252-
})
251+
v := &Provider{Logger: fakelogger, bbClient: bbclient}
252+
bbcloudtest.MuxCommit(t, mux, tt.event, tt.commitinfo)
253+
bbcloudtest.MuxBranch(t, mux, tt.event, tt.commitinfo)
253254
bbcloudtest.MuxRepoInfo(t, mux, tt.event, tt.repoinfo)
254255

255256
if err := v.GetCommitInfo(ctx, tt.event); (err != nil) != tt.wantErr {

pkg/provider/bitbucketcloud/test/bbcloudtest.go

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -122,15 +122,48 @@ func MuxListDirFiles(t *testing.T, mux *http.ServeMux, event *info.Event, dirs m
122122
}
123123
}
124124

125-
func MuxCommits(t *testing.T, mux *http.ServeMux, event *info.Event, commits []types.Commit) {
125+
// MuxCommit mocks the GetCommit API (single commit, not paginated).
126+
func MuxCommit(t *testing.T, mux *http.ServeMux, event *info.Event, commit types.Commit) {
126127
t.Helper()
127128

128-
path := fmt.Sprintf("/repositories/%s/%s/commits/%s", event.Organization, event.Repository, event.SHA)
129+
shas := []string{}
130+
if event.SHA != "" {
131+
shas = append(shas, event.SHA)
132+
}
133+
if commit.Hash != "" && commit.Hash != event.SHA {
134+
shas = append(shas, commit.Hash)
135+
}
136+
if len(shas) == 0 {
137+
shas = append(shas, "HEAD")
138+
}
139+
140+
for _, sha := range shas {
141+
path := fmt.Sprintf("/repositories/%s/%s/commit/%s", event.Organization, event.Repository, sha)
142+
mux.HandleFunc(path, func(rw http.ResponseWriter, _ *http.Request) {
143+
// GetCommit returns a single commit object, not {values: [...]}
144+
b, _ := json.Marshal(commit)
145+
fmt.Fprint(rw, string(b))
146+
})
147+
}
148+
}
149+
150+
func MuxBranch(t *testing.T, mux *http.ServeMux, event *info.Event, commit types.Commit) {
151+
t.Helper()
152+
153+
if event.HeadBranch == "" {
154+
return
155+
}
156+
157+
path := fmt.Sprintf("/repositories/%s/%s/refs/branches/%s", event.Organization, event.Repository, event.HeadBranch)
129158
mux.HandleFunc(path, func(rw http.ResponseWriter, _ *http.Request) {
130-
dircontents := map[string][]types.Commit{
131-
"values": commits,
159+
// Return the commit hash that this branch points to
160+
branch := map[string]interface{}{
161+
"name": event.HeadBranch,
162+
"target": map[string]interface{}{
163+
"hash": commit.Hash,
164+
},
132165
}
133-
b, _ := json.Marshal(dircontents)
166+
b, _ := json.Marshal(branch)
134167
fmt.Fprint(rw, string(b))
135168
})
136169
}

0 commit comments

Comments
 (0)