4 Commits

Author SHA1 Message Date
Lunny Xiao
465a6f01ee Merge branch 'main' into lunny/fix_webhook 2026-04-20 21:01:30 +00:00
Lunny Xiao
b43f36abd4 Merge branch 'main' into lunny/fix_webhook 2026-04-20 19:48:45 +00:00
Lunny Xiao
ab7dc97518 Fix lint 2026-04-20 12:34:52 -07:00
Lunny Xiao
469a6d3466 Fix webhook 2026-04-20 12:19:36 -07:00
15 changed files with 218 additions and 268 deletions

View File

@@ -39,7 +39,7 @@ jobs:
make unit-test-coverage make unit-test-coverage
services: services:
gitea: gitea:
image: docker.gitea.com/gitea:1.26.1 image: docker.gitea.com/gitea:1.26.0
cmd: cmd:
- bash - bash
- -c - -c

View File

@@ -61,19 +61,11 @@ func runReleaseAttachmentDelete(_ stdctx.Context, cmd *cli.Command) error {
return err return err
} }
var existing []*gitea.Attachment existing, _, err := client.ListReleaseAttachments(ctx.Owner, ctx.Repo, release.ID, gitea.ListReleaseAttachmentsOptions{
for page := 1; ; { ListOptions: gitea.ListOptions{Page: -1},
page_attachments, resp, err := client.ListReleaseAttachments(ctx.Owner, ctx.Repo, release.ID, gitea.ListReleaseAttachmentsOptions{ })
ListOptions: gitea.ListOptions{Page: page, PageSize: 50}, if err != nil {
}) return err
if err != nil {
return err
}
existing = append(existing, page_attachments...)
if resp == nil || resp.NextPage == 0 {
break
}
page = resp.NextPage
} }
for _, name := range ctx.Args().Slice()[1:] { for _, name := range ctx.Args().Slice()[1:] {

View File

@@ -109,20 +109,11 @@ func runPullDetail(_ stdctx.Context, cmd *cli.Command, index string) error {
return err return err
} }
var reviews []*gitea.PullReview reviews, _, err := client.ListPullReviews(ctx.Owner, ctx.Repo, idx, gitea.ListPullReviewsOptions{
for page := 1; ; { ListOptions: gitea.ListOptions{Page: -1},
page_reviews, resp, err := client.ListPullReviews(ctx.Owner, ctx.Repo, idx, gitea.ListPullReviewsOptions{ })
ListOptions: gitea.ListOptions{Page: page, PageSize: 50}, if err != nil {
}) fmt.Printf("error while loading reviews: %v\n", err)
if err != nil {
fmt.Printf("error while loading reviews: %v\n", err)
break
}
reviews = append(reviews, page_reviews...)
if resp == nil || resp.NextPage == 0 {
break
}
page = resp.NextPage
} }
if ctx.IsSet("output") { if ctx.IsSet("output") {

View File

@@ -11,25 +11,19 @@ import (
// GetReleaseByTag finds a release by its tag name. // GetReleaseByTag finds a release by its tag name.
func GetReleaseByTag(owner, repo, tag string, client *gitea.Client) (*gitea.Release, error) { func GetReleaseByTag(owner, repo, tag string, client *gitea.Client) (*gitea.Release, error) {
for page := 1; ; { rl, _, err := client.ListReleases(owner, repo, gitea.ListReleasesOptions{
rl, resp, err := client.ListReleases(owner, repo, gitea.ListReleasesOptions{ ListOptions: gitea.ListOptions{Page: -1},
ListOptions: gitea.ListOptions{Page: page, PageSize: 50}, })
}) if err != nil {
if err != nil { return nil, err
return nil, err }
if len(rl) == 0 {
return nil, fmt.Errorf("repo does not have any release")
}
for _, r := range rl {
if r.TagName == tag {
return r, nil
} }
if page == 1 && len(rl) == 0 {
return nil, fmt.Errorf("repo does not have any release")
}
for _, r := range rl {
if r.TagName == tag {
return r, nil
}
}
if resp == nil || resp.NextPage == 0 {
break
}
page = resp.NextPage
} }
return nil, fmt.Errorf("release tag does not exist") return nil, fmt.Errorf("release tag does not exist")
} }

View File

@@ -89,30 +89,26 @@ func runWebhooksCreate(ctx stdctx.Context, cmd *cli.Command) error {
config["secret"] = secret config["secret"] = secret
} }
if branchFilter != "" {
config["branch_filter"] = branchFilter
}
if authHeader != "" {
config["authorization_header"] = authHeader
}
var hook *gitea.Hook var hook *gitea.Hook
if c.IsGlobal { if c.IsGlobal {
return fmt.Errorf("global webhooks not yet supported in this version") return fmt.Errorf("global webhooks not yet supported in this version")
} else if len(c.Org) > 0 { } else if len(c.Org) > 0 {
hook, _, err = client.CreateOrgHook(c.Org, gitea.CreateHookOption{ hook, _, err = client.CreateOrgHook(c.Org, gitea.CreateHookOption{
Type: webhookType, Type: webhookType,
Config: config, Config: config,
Events: events, Events: events,
Active: active, Active: active,
BranchFilter: branchFilter,
AuthorizationHeader: authHeader,
}) })
} else { } else {
hook, _, err = client.CreateRepoHook(c.Owner, c.Repo, gitea.CreateHookOption{ hook, _, err = client.CreateRepoHook(c.Owner, c.Repo, gitea.CreateHookOption{
Type: webhookType, Type: webhookType,
Config: config, Config: config,
Events: events, Events: events,
Active: active, Active: active,
BranchFilter: branchFilter,
AuthorizationHeader: authHeader,
}) })
} }
if err != nil { if err != nil {

View File

@@ -79,8 +79,6 @@ func TestWebhookConfigConstruction(t *testing.T) {
name string name string
url string url string
secret string secret string
branchFilter string
authHeader string
expectedKeys []string expectedKeys []string
expectedValues map[string]string expectedValues map[string]string
}{ }{
@@ -106,44 +104,16 @@ func TestWebhookConfigConstruction(t *testing.T) {
"secret": "my-secret", "secret": "my-secret",
}, },
}, },
{
name: "Config with branch filter",
url: "https://example.com/webhook",
branchFilter: "main,develop",
expectedKeys: []string{"url", "http_method", "content_type", "branch_filter"},
expectedValues: map[string]string{
"url": "https://example.com/webhook",
"http_method": "post",
"content_type": "json",
"branch_filter": "main,develop",
},
},
{
name: "Config with auth header",
url: "https://example.com/webhook",
authHeader: "Bearer token123",
expectedKeys: []string{"url", "http_method", "content_type", "authorization_header"},
expectedValues: map[string]string{
"url": "https://example.com/webhook",
"http_method": "post",
"content_type": "json",
"authorization_header": "Bearer token123",
},
},
{ {
name: "Complete config", name: "Complete config",
url: "https://example.com/webhook", url: "https://example.com/webhook",
secret: "secret123", secret: "secret123",
branchFilter: "main", expectedKeys: []string{"url", "http_method", "content_type", "secret"},
authHeader: "X-Token: abc",
expectedKeys: []string{"url", "http_method", "content_type", "secret", "branch_filter", "authorization_header"},
expectedValues: map[string]string{ expectedValues: map[string]string{
"url": "https://example.com/webhook", "url": "https://example.com/webhook",
"http_method": "post", "http_method": "post",
"content_type": "json", "content_type": "json",
"secret": "secret123", "secret": "secret123",
"branch_filter": "main",
"authorization_header": "X-Token: abc",
}, },
}, },
} }
@@ -159,12 +129,6 @@ func TestWebhookConfigConstruction(t *testing.T) {
if tt.secret != "" { if tt.secret != "" {
config["secret"] = tt.secret config["secret"] = tt.secret
} }
if tt.branchFilter != "" {
config["branch_filter"] = tt.branchFilter
}
if tt.authHeader != "" {
config["authorization_header"] = tt.authHeader
}
// Check all expected keys exist // Check all expected keys exist
for _, key := range tt.expectedKeys { for _, key := range tt.expectedKeys {
@@ -184,11 +148,13 @@ func TestWebhookConfigConstruction(t *testing.T) {
func TestWebhookCreateOptions(t *testing.T) { func TestWebhookCreateOptions(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
webhookType string webhookType string
events []string events []string
active bool active bool
config map[string]string config map[string]string
branchFilter string
authHeader string
}{ }{
{ {
name: "Gitea webhook", name: "Gitea webhook",
@@ -200,6 +166,8 @@ func TestWebhookCreateOptions(t *testing.T) {
"http_method": "post", "http_method": "post",
"content_type": "json", "content_type": "json",
}, },
branchFilter: "main",
authHeader: "X-Token: abc",
}, },
{ {
name: "Slack webhook", name: "Slack webhook",
@@ -228,16 +196,20 @@ func TestWebhookCreateOptions(t *testing.T) {
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
option := gitea.CreateHookOption{ option := gitea.CreateHookOption{
Type: gitea.HookType(tt.webhookType), Type: gitea.HookType(tt.webhookType),
Config: tt.config, Config: tt.config,
Events: tt.events, Events: tt.events,
Active: tt.active, Active: tt.active,
BranchFilter: tt.branchFilter,
AuthorizationHeader: tt.authHeader,
} }
assert.Equal(t, gitea.HookType(tt.webhookType), option.Type) assert.Equal(t, gitea.HookType(tt.webhookType), option.Type)
assert.Equal(t, tt.events, option.Events) assert.Equal(t, tt.events, option.Events)
assert.Equal(t, tt.active, option.Active) assert.Equal(t, tt.active, option.Active)
assert.Equal(t, tt.config, option.Config) assert.Equal(t, tt.config, option.Config)
assert.Equal(t, tt.branchFilter, option.BranchFilter)
assert.Equal(t, tt.authHeader, option.AuthorizationHeader)
}) })
} }
} }

View File

@@ -97,11 +97,14 @@ func runWebhooksUpdate(ctx stdctx.Context, cmd *cli.Command) error {
if cmd.IsSet("secret") { if cmd.IsSet("secret") {
config["secret"] = cmd.String("secret") config["secret"] = cmd.String("secret")
} }
branchFilter := hook.BranchFilter
if cmd.IsSet("branch-filter") { if cmd.IsSet("branch-filter") {
config["branch_filter"] = cmd.String("branch-filter") branchFilter = cmd.String("branch-filter")
} }
authHeader := hook.AuthorizationHeader
if cmd.IsSet("authorization-header") { if cmd.IsSet("authorization-header") {
config["authorization_header"] = cmd.String("authorization-header") authHeader = cmd.String("authorization-header")
} }
// Update events if specified // Update events if specified
@@ -126,15 +129,19 @@ func runWebhooksUpdate(ctx stdctx.Context, cmd *cli.Command) error {
return fmt.Errorf("global webhooks not yet supported in this version") return fmt.Errorf("global webhooks not yet supported in this version")
} else if len(c.Org) > 0 { } else if len(c.Org) > 0 {
_, err = client.EditOrgHook(c.Org, int64(webhookID), gitea.EditHookOption{ _, err = client.EditOrgHook(c.Org, int64(webhookID), gitea.EditHookOption{
Config: config, Config: config,
Events: events, Events: events,
Active: &active, Active: &active,
BranchFilter: branchFilter,
AuthorizationHeader: authHeader,
}) })
} else { } else {
_, err = client.EditRepoHook(c.Owner, c.Repo, int64(webhookID), gitea.EditHookOption{ _, err = client.EditRepoHook(c.Owner, c.Repo, int64(webhookID), gitea.EditHookOption{
Config: config, Config: config,
Events: events, Events: events,
Active: &active, Active: &active,
BranchFilter: branchFilter,
AuthorizationHeader: authHeader,
}) })
} }
if err != nil { if err != nil {

View File

@@ -128,12 +128,10 @@ func TestUpdateActiveInactiveFlags(t *testing.T) {
func TestUpdateConfigPreservation(t *testing.T) { func TestUpdateConfigPreservation(t *testing.T) {
// Test that existing configuration is preserved when not updated // Test that existing configuration is preserved when not updated
originalConfig := map[string]string{ originalConfig := map[string]string{
"url": "https://old.example.com/webhook", "url": "https://old.example.com/webhook",
"secret": "old-secret", "secret": "old-secret",
"branch_filter": "main", "http_method": "post",
"authorization_header": "Bearer old-token", "content_type": "json",
"http_method": "post",
"content_type": "json",
} }
tests := []struct { tests := []struct {
@@ -147,53 +145,32 @@ func TestUpdateConfigPreservation(t *testing.T) {
"url": "https://new.example.com/webhook", "url": "https://new.example.com/webhook",
}, },
expectedConfig: map[string]string{ expectedConfig: map[string]string{
"url": "https://new.example.com/webhook", "url": "https://new.example.com/webhook",
"secret": "old-secret", "secret": "old-secret",
"branch_filter": "main", "http_method": "post",
"authorization_header": "Bearer old-token", "content_type": "json",
"http_method": "post",
"content_type": "json",
}, },
}, },
{ {
name: "Update secret and auth header", name: "Update secret",
updates: map[string]string{ updates: map[string]string{
"secret": "new-secret", "secret": "new-secret",
"authorization_header": "X-Token: new-token",
}, },
expectedConfig: map[string]string{ expectedConfig: map[string]string{
"url": "https://old.example.com/webhook", "url": "https://old.example.com/webhook",
"secret": "new-secret", "secret": "new-secret",
"branch_filter": "main", "http_method": "post",
"authorization_header": "X-Token: new-token", "content_type": "json",
"http_method": "post",
"content_type": "json",
},
},
{
name: "Clear branch filter",
updates: map[string]string{
"branch_filter": "",
},
expectedConfig: map[string]string{
"url": "https://old.example.com/webhook",
"secret": "old-secret",
"branch_filter": "",
"authorization_header": "Bearer old-token",
"http_method": "post",
"content_type": "json",
}, },
}, },
{ {
name: "No updates", name: "No updates",
updates: map[string]string{}, updates: map[string]string{},
expectedConfig: map[string]string{ expectedConfig: map[string]string{
"url": "https://old.example.com/webhook", "url": "https://old.example.com/webhook",
"secret": "old-secret", "secret": "old-secret",
"branch_filter": "main", "http_method": "post",
"authorization_header": "Bearer old-token", "content_type": "json",
"http_method": "post",
"content_type": "json",
}, },
}, },
} }
@@ -217,6 +194,61 @@ func TestUpdateConfigPreservation(t *testing.T) {
} }
} }
func TestUpdateBranchFilterAndAuthHeaderHandling(t *testing.T) {
tests := []struct {
name string
originalBranchFilter string
originalAuthHeader string
setBranchFilter bool
newBranchFilter string
setAuthorizationHeader bool
newAuthHeader string
expectedBranchFilter string
expectedAuthHeader string
}{
{
name: "Preserve values",
originalBranchFilter: "main",
originalAuthHeader: "Bearer old-token",
expectedBranchFilter: "main",
expectedAuthHeader: "Bearer old-token",
},
{
name: "Update branch filter",
originalBranchFilter: "main",
setBranchFilter: true,
newBranchFilter: "develop",
expectedBranchFilter: "develop",
expectedAuthHeader: "",
},
{
name: "Update authorization header",
originalAuthHeader: "Bearer old-token",
setAuthorizationHeader: true,
newAuthHeader: "X-Token: new-token",
expectedBranchFilter: "",
expectedAuthHeader: "X-Token: new-token",
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
branchFilter := tt.originalBranchFilter
if tt.setBranchFilter {
branchFilter = tt.newBranchFilter
}
authHeader := tt.originalAuthHeader
if tt.setAuthorizationHeader {
authHeader = tt.newAuthHeader
}
assert.Equal(t, tt.expectedBranchFilter, branchFilter)
assert.Equal(t, tt.expectedAuthHeader, authHeader)
})
}
}
func TestUpdateEventsHandling(t *testing.T) { func TestUpdateEventsHandling(t *testing.T) {
tests := []struct { tests := []struct {
name string name string

View File

@@ -180,25 +180,19 @@ func fetchIssueSelectables(login *config.Login, owner, repo string, done chan is
r.MilestoneList[i] = m.Title r.MilestoneList[i] = m.Title
} }
labels, _, err := c.ListRepoLabels(owner, repo, gitea.ListLabelsOptions{
ListOptions: gitea.ListOptions{Page: -1},
})
if err != nil {
r.Err = err
done <- r
return
}
r.LabelMap = make(map[string]int64) r.LabelMap = make(map[string]int64)
r.LabelList = make([]string, 0) r.LabelList = make([]string, len(labels))
for page := 1; ; { for i, l := range labels {
labels, resp, err := c.ListRepoLabels(owner, repo, gitea.ListLabelsOptions{ r.LabelMap[l.Name] = l.ID
ListOptions: gitea.ListOptions{Page: page, PageSize: 50}, r.LabelList[i] = l.Name
})
if err != nil {
r.Err = err
done <- r
return
}
for _, l := range labels {
r.LabelMap[l.Name] = l.ID
r.LabelList = append(r.LabelList, l.Name)
}
if resp == nil || resp.NextPage == 0 {
break
}
page = resp.NextPage
} }
done <- r done <- r

View File

@@ -67,13 +67,21 @@ func WebhookDetails(hook *gitea.Hook) {
if method, ok := hook.Config["http_method"]; ok { if method, ok := hook.Config["http_method"]; ok {
fmt.Printf("- **HTTP Method**: %s\n", method) fmt.Printf("- **HTTP Method**: %s\n", method)
} }
if branchFilter, ok := hook.Config["branch_filter"]; ok && branchFilter != "" { branchFilter := hook.BranchFilter
if branchFilter == "" {
branchFilter = hook.Config["branch_filter"]
}
if branchFilter != "" {
fmt.Printf("- **Branch Filter**: %s\n", branchFilter) fmt.Printf("- **Branch Filter**: %s\n", branchFilter)
} }
if _, hasSecret := hook.Config["secret"]; hasSecret { if _, hasSecret := hook.Config["secret"]; hasSecret {
fmt.Printf("- **Secret**: (configured)\n") fmt.Printf("- **Secret**: (configured)\n")
} }
if _, hasAuth := hook.Config["authorization_header"]; hasAuth { hasAuth := hook.AuthorizationHeader != ""
if !hasAuth {
_, hasAuth = hook.Config["authorization_header"]
}
if hasAuth {
fmt.Printf("- **Authorization Header**: (configured)\n") fmt.Printf("- **Authorization Header**: (configured)\n")
} }
} }

View File

@@ -81,17 +81,17 @@ func TestWebhookDetails(t *testing.T) {
ID: 123, ID: 123,
Type: "gitea", Type: "gitea",
Config: map[string]string{ Config: map[string]string{
"url": "https://example.com/webhook", "url": "https://example.com/webhook",
"content_type": "json", "content_type": "json",
"http_method": "post", "http_method": "post",
"branch_filter": "main,develop", "secret": "secret-value",
"secret": "secret-value",
"authorization_header": "Bearer token123",
}, },
Events: []string{"push", "pull_request", "issues"}, BranchFilter: "main,develop",
Active: true, AuthorizationHeader: "Bearer token123",
Created: now.Add(-24 * time.Hour), Events: []string{"push", "pull_request", "issues"},
Updated: now, Active: true,
Created: now.Add(-24 * time.Hour),
Updated: now,
}, },
}, },
{ {
@@ -238,16 +238,14 @@ func TestWebhookConfigHandling(t *testing.T) {
{ {
name: "Config with all fields", name: "Config with all fields",
config: map[string]string{ config: map[string]string{
"url": "https://example.com/webhook", "url": "https://example.com/webhook",
"secret": "my-secret", "secret": "my-secret",
"authorization_header": "Bearer token", "content_type": "json",
"content_type": "json", "http_method": "post",
"http_method": "post",
"branch_filter": "main",
}, },
expectedURL: "https://example.com/webhook", expectedURL: "https://example.com/webhook",
hasSecret: true, hasSecret: true,
hasAuthHeader: true, hasAuthHeader: false,
}, },
{ {
name: "Config with minimal fields", name: "Config with minimal fields",
@@ -341,17 +339,17 @@ func TestWebhookDetailsFormatting(t *testing.T) {
ID: 123, ID: 123,
Type: "gitea", Type: "gitea",
Config: map[string]string{ Config: map[string]string{
"url": "https://example.com/webhook", "url": "https://example.com/webhook",
"content_type": "json", "content_type": "json",
"http_method": "post", "http_method": "post",
"branch_filter": "main,develop", "secret": "secret-value",
"secret": "secret-value",
"authorization_header": "Bearer token123",
}, },
Events: []string{"push", "pull_request", "issues"}, BranchFilter: "main,develop",
Active: true, AuthorizationHeader: "Bearer token123",
Created: now.Add(-24 * time.Hour), Events: []string{"push", "pull_request", "issues"},
Updated: now, Active: true,
Created: now.Add(-24 * time.Hour),
Updated: now,
} }
// Test that all expected fields are included in details // Test that all expected fields are included in details
@@ -379,8 +377,8 @@ func TestWebhookDetailsFormatting(t *testing.T) {
assert.Equal(t, "https://example.com/webhook", hook.Config["url"]) assert.Equal(t, "https://example.com/webhook", hook.Config["url"])
assert.Equal(t, "json", hook.Config["content_type"]) assert.Equal(t, "json", hook.Config["content_type"])
assert.Equal(t, "post", hook.Config["http_method"]) assert.Equal(t, "post", hook.Config["http_method"])
assert.Equal(t, "main,develop", hook.Config["branch_filter"]) assert.Equal(t, "main,develop", hook.BranchFilter)
assert.Contains(t, hook.Config, "secret") assert.Contains(t, hook.Config, "secret")
assert.Contains(t, hook.Config, "authorization_header") assert.Equal(t, "Bearer token123", hook.AuthorizationHeader)
assert.Equal(t, []string{"push", "pull_request", "issues"}, hook.Events) assert.Equal(t, []string{"push", "pull_request", "issues"}, hook.Events)
} }

View File

@@ -13,23 +13,16 @@ import (
// ResolveLabelNames returns a list of label IDs for a given list of label names // ResolveLabelNames returns a list of label IDs for a given list of label names
func ResolveLabelNames(client *gitea.Client, owner, repo string, labelNames []string) ([]int64, error) { func ResolveLabelNames(client *gitea.Client, owner, repo string, labelNames []string) ([]int64, error) {
labelIDs := make([]int64, 0, len(labelNames)) labelIDs := make([]int64, 0, len(labelNames))
page := 1 labels, _, err := client.ListRepoLabels(owner, repo, gitea.ListLabelsOptions{
for { ListOptions: gitea.ListOptions{Page: -1},
labels, resp, err := client.ListRepoLabels(owner, repo, gitea.ListLabelsOptions{ })
ListOptions: gitea.ListOptions{Page: page, PageSize: 50}, if err != nil {
}) return nil, err
if err != nil { }
return nil, err for _, l := range labels {
if utils.Contains(labelNames, l.Name) {
labelIDs = append(labelIDs, l.ID)
} }
for _, l := range labels {
if utils.Contains(labelNames, l.Name) {
labelIDs = append(labelIDs, l.ID)
}
}
if resp == nil || resp.NextPage == 0 {
break
}
page = resp.NextPage
} }
return labelIDs, nil return labelIDs, nil
} }

View File

@@ -166,19 +166,11 @@ func generateToken(login config.Login, user, pass, otp, scopes string) (string,
} }
client := login.Client(opts...) client := login.Client(opts...)
var tl []*gitea.AccessToken tl, _, err := client.ListAccessTokens(gitea.ListAccessTokensOptions{
for page := 1; ; { ListOptions: gitea.ListOptions{Page: -1},
page_tokens, resp, err := client.ListAccessTokens(gitea.ListAccessTokensOptions{ })
ListOptions: gitea.ListOptions{Page: page, PageSize: 50}, if err != nil {
}) return "", err
if err != nil {
return "", err
}
tl = append(tl, page_tokens...)
if resp == nil || resp.NextPage == 0 {
break
}
page = resp.NextPage
} }
host, _ := os.Hostname() host, _ := os.Hostname()
tokenName := host + "-tea" tokenName := host + "-tea"

View File

@@ -19,22 +19,11 @@ import (
// a matching private key in ~/.ssh/. If no match is found, path is empty. // a matching private key in ~/.ssh/. If no match is found, path is empty.
func findSSHKey(client *gitea.Client) (string, error) { func findSSHKey(client *gitea.Client) (string, error) {
// get keys registered on gitea instance // get keys registered on gitea instance
var keys []*gitea.PublicKey keys, _, err := client.ListMyPublicKeys(gitea.ListPublicKeysOptions{
for page := 1; ; { ListOptions: gitea.ListOptions{Page: -1},
page_keys, resp, err := client.ListMyPublicKeys(gitea.ListPublicKeysOptions{ })
ListOptions: gitea.ListOptions{Page: page, PageSize: 50}, if err != nil || len(keys) == 0 {
}) return "", err
if err != nil {
return "", err
}
keys = append(keys, page_keys...)
if resp == nil || resp.NextPage == 0 {
break
}
page = resp.NextPage
}
if len(keys) == 0 {
return "", nil
} }
// enumerate ~/.ssh/*.pub files // enumerate ~/.ssh/*.pub files

View File

@@ -14,19 +14,11 @@ import (
func ListPullReviewComments(ctx *context.TeaContext, idx int64) ([]*gitea.PullReviewComment, error) { func ListPullReviewComments(ctx *context.TeaContext, idx int64) ([]*gitea.PullReviewComment, error) {
c := ctx.Login.Client() c := ctx.Login.Client()
var reviews []*gitea.PullReview reviews, _, err := c.ListPullReviews(ctx.Owner, ctx.Repo, idx, gitea.ListPullReviewsOptions{
for page := 1; ; { ListOptions: gitea.ListOptions{Page: -1},
page_reviews, resp, err := c.ListPullReviews(ctx.Owner, ctx.Repo, idx, gitea.ListPullReviewsOptions{ })
ListOptions: gitea.ListOptions{Page: page, PageSize: 50}, if err != nil {
}) return nil, err
if err != nil {
return nil, err
}
reviews = append(reviews, page_reviews...)
if resp == nil || resp.NextPage == 0 {
break
}
page = resp.NextPage
} }
var allComments []*gitea.PullReviewComment var allComments []*gitea.PullReviewComment