Merge branch 'origin/main' into 'next-release/main'

This commit is contained in:
oauth 2024-12-01 19:42:47 +00:00
commit f16efcbd91
11 changed files with 72 additions and 93 deletions

View file

@ -74,5 +74,5 @@ func pipelineCreate(ctx context.Context, c *cli.Command) error {
return err return err
} }
return pipelineOutput(c, []woodpecker.Pipeline{*pipeline}) return pipelineOutput(c, []*woodpecker.Pipeline{pipeline})
} }

View file

@ -58,5 +58,5 @@ func pipelineLast(ctx context.Context, c *cli.Command) error {
return err return err
} }
return pipelineOutput(c, []woodpecker.Pipeline{*pipeline}) return pipelineOutput(c, []*woodpecker.Pipeline{pipeline})
} }

View file

@ -22,6 +22,7 @@ import (
"go.woodpecker-ci.org/woodpecker/v2/cli/common" "go.woodpecker-ci.org/woodpecker/v2/cli/common"
"go.woodpecker-ci.org/woodpecker/v2/cli/internal" "go.woodpecker-ci.org/woodpecker/v2/cli/internal"
shared_utils "go.woodpecker-ci.org/woodpecker/v2/shared/utils"
"go.woodpecker-ci.org/woodpecker/v2/woodpecker-go/woodpecker" "go.woodpecker-ci.org/woodpecker/v2/woodpecker-go/woodpecker"
) )
@ -77,60 +78,51 @@ func List(ctx context.Context, c *cli.Command) error {
if err != nil { if err != nil {
return err return err
} }
resources, err := pipelineList(c, client) pipelines, err := pipelineList(c, client)
if err != nil { if err != nil {
return err return err
} }
return pipelineOutput(c, resources) return pipelineOutput(c, pipelines)
} }
func pipelineList(c *cli.Command, client woodpecker.Client) ([]woodpecker.Pipeline, error) { func pipelineList(c *cli.Command, client woodpecker.Client) ([]*woodpecker.Pipeline, error) {
resources := make([]woodpecker.Pipeline, 0)
repoIDOrFullName := c.Args().First() repoIDOrFullName := c.Args().First()
repoID, err := internal.ParseRepo(client, repoIDOrFullName) repoID, err := internal.ParseRepo(client, repoIDOrFullName)
if err != nil { if err != nil {
return resources, err return nil, err
} }
opt := woodpecker.PipelineListOptions{} opt := woodpecker.PipelineListOptions{}
before := c.Timestamp("before")
after := c.Timestamp("after")
if !before.IsZero() { if before := c.Timestamp("before"); !before.IsZero() {
opt.Before = before opt.Before = before
} }
if !after.IsZero() { if after := c.Timestamp("after"); !after.IsZero() {
opt.After = after opt.After = after
} }
pipelines, err := client.PipelineList(repoID, opt)
if err != nil {
return resources, err
}
branch := c.String("branch") branch := c.String("branch")
event := c.String("event") event := c.String("event")
status := c.String("status") status := c.String("status")
limit := int(c.Int("limit")) limit := int(c.Int("limit"))
var count int pipelines, err := shared_utils.Paginate(func(page int) ([]*woodpecker.Pipeline, error) {
for _, pipeline := range pipelines { return client.PipelineList(repoID,
if count >= limit { woodpecker.PipelineListOptions{
break ListOptions: woodpecker.ListOptions{
} Page: page,
if branch != "" && pipeline.Branch != branch { },
continue Before: opt.Before,
} After: opt.After,
if event != "" && pipeline.Event != event { Branch: branch,
continue Events: []string{event},
} Status: status,
if status != "" && pipeline.Status != status { },
continue )
} }, limit)
resources = append(resources, *pipeline) if err != nil {
count++ return nil, err
} }
return resources, nil return pipelines, nil
} }

View file

@ -22,7 +22,7 @@ func TestPipelineList(t *testing.T) {
pipelines []*woodpecker.Pipeline pipelines []*woodpecker.Pipeline
pipelineErr error pipelineErr error
args []string args []string
expected []woodpecker.Pipeline expected []*woodpecker.Pipeline
wantErr error wantErr error
}{ }{
{ {
@ -34,53 +34,12 @@ func TestPipelineList(t *testing.T) {
{ID: 3, Branch: "main", Event: "push", Status: "failure"}, {ID: 3, Branch: "main", Event: "push", Status: "failure"},
}, },
args: []string{"ls", "repo/name"}, args: []string{"ls", "repo/name"},
expected: []woodpecker.Pipeline{ expected: []*woodpecker.Pipeline{
{ID: 1, Branch: "main", Event: "push", Status: "success"}, {ID: 1, Branch: "main", Event: "push", Status: "success"},
{ID: 2, Branch: "develop", Event: "pull_request", Status: "running"}, {ID: 2, Branch: "develop", Event: "pull_request", Status: "running"},
{ID: 3, Branch: "main", Event: "push", Status: "failure"}, {ID: 3, Branch: "main", Event: "push", Status: "failure"},
}, },
}, },
{
name: "filter by branch",
repoID: 1,
pipelines: []*woodpecker.Pipeline{
{ID: 1, Branch: "main", Event: "push", Status: "success"},
{ID: 2, Branch: "develop", Event: "pull_request", Status: "running"},
{ID: 3, Branch: "main", Event: "push", Status: "failure"},
},
args: []string{"ls", "--branch", "main", "repo/name"},
expected: []woodpecker.Pipeline{
{ID: 1, Branch: "main", Event: "push", Status: "success"},
{ID: 3, Branch: "main", Event: "push", Status: "failure"},
},
},
{
name: "filter by event",
repoID: 1,
pipelines: []*woodpecker.Pipeline{
{ID: 1, Branch: "main", Event: "push", Status: "success"},
{ID: 2, Branch: "develop", Event: "pull_request", Status: "running"},
{ID: 3, Branch: "main", Event: "push", Status: "failure"},
},
args: []string{"ls", "--event", "push", "repo/name"},
expected: []woodpecker.Pipeline{
{ID: 1, Branch: "main", Event: "push", Status: "success"},
{ID: 3, Branch: "main", Event: "push", Status: "failure"},
},
},
{
name: "filter by status",
repoID: 1,
pipelines: []*woodpecker.Pipeline{
{ID: 1, Branch: "main", Event: "push", Status: "success"},
{ID: 2, Branch: "develop", Event: "pull_request", Status: "running"},
{ID: 3, Branch: "main", Event: "push", Status: "failure"},
},
args: []string{"ls", "--status", "success", "repo/name"},
expected: []woodpecker.Pipeline{
{ID: 1, Branch: "main", Event: "push", Status: "success"},
},
},
{ {
name: "limit results", name: "limit results",
repoID: 1, repoID: 1,
@ -90,7 +49,7 @@ func TestPipelineList(t *testing.T) {
{ID: 3, Branch: "main", Event: "push", Status: "failure"}, {ID: 3, Branch: "main", Event: "push", Status: "failure"},
}, },
args: []string{"ls", "--limit", "2", "repo/name"}, args: []string{"ls", "--limit", "2", "repo/name"},
expected: []woodpecker.Pipeline{ expected: []*woodpecker.Pipeline{
{ID: 1, Branch: "main", Event: "push", Status: "success"}, {ID: 1, Branch: "main", Event: "push", Status: "success"},
{ID: 2, Branch: "develop", Event: "pull_request", Status: "running"}, {ID: 2, Branch: "develop", Event: "pull_request", Status: "running"},
}, },
@ -107,7 +66,15 @@ func TestPipelineList(t *testing.T) {
for _, tt := range testtases { for _, tt := range testtases {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
mockClient := mocks.NewClient(t) mockClient := mocks.NewClient(t)
mockClient.On("PipelineList", mock.Anything, mock.Anything).Return(tt.pipelines, tt.pipelineErr) mockClient.On("PipelineList", mock.Anything, mock.Anything).Return(func(_ int64, opt woodpecker.PipelineListOptions) ([]*woodpecker.Pipeline, error) {
if tt.pipelineErr != nil {
return nil, tt.pipelineErr
}
if opt.Page == 1 {
return tt.pipelines, nil
}
return []*woodpecker.Pipeline{}, nil
}).Maybe()
mockClient.On("RepoLookup", mock.Anything).Return(&woodpecker.Repo{ID: tt.repoID}, nil) mockClient.On("RepoLookup", mock.Anything).Return(&woodpecker.Repo{ID: tt.repoID}, nil)
command := buildPipelineListCmd() command := buildPipelineListCmd()

View file

@ -50,7 +50,7 @@ var Command = &cli.Command{
}, },
} }
func pipelineOutput(c *cli.Command, resources []woodpecker.Pipeline, fd ...io.Writer) error { func pipelineOutput(c *cli.Command, pipelines []*woodpecker.Pipeline, fd ...io.Writer) error {
outFmt, outOpt := output.ParseOutputOptions(c.String("output")) outFmt, outOpt := output.ParseOutputOptions(c.String("output"))
noHeader := c.Bool("output-no-headers") noHeader := c.Bool("output-no-headers")
@ -74,7 +74,7 @@ func pipelineOutput(c *cli.Command, resources []woodpecker.Pipeline, fd ...io.Wr
if err != nil { if err != nil {
return err return err
} }
if err := tmpl.Execute(out, resources); err != nil { if err := tmpl.Execute(out, pipelines); err != nil {
return err return err
} }
case "table": case "table":
@ -89,7 +89,7 @@ func pipelineOutput(c *cli.Command, resources []woodpecker.Pipeline, fd ...io.Wr
if !noHeader { if !noHeader {
table.WriteHeader(cols) table.WriteHeader(cols)
} }
for _, resource := range resources { for _, resource := range pipelines {
if err := table.Write(cols, resource); err != nil { if err := table.Write(cols, resource); err != nil {
return err return err
} }

View file

@ -47,7 +47,7 @@ func TestPipelineOutput(t *testing.T) {
}, },
} }
pipelines := []woodpecker.Pipeline{ pipelines := []*woodpecker.Pipeline{
{ {
Number: 1, Number: 1,
Status: "success", Status: "success",

View file

@ -65,5 +65,5 @@ func pipelineShow(ctx context.Context, c *cli.Command) error {
return err return err
} }
return pipelineOutput(c, []woodpecker.Pipeline{*pipeline}) return pipelineOutput(c, []*woodpecker.Pipeline{pipeline})
} }

View file

@ -1,14 +1,17 @@
<template> <template>
<span class="text-xs font-medium inline-flex"> <span class="text-xs font-medium inline-flex">
<span <span
class="pl-2 pr-1 py-0.5 bg-wp-state-neutral-100 text-gray-300 border-2 border-wp-state-neutral-100 rounded-l-full" class="pl-2 pr-1 py-0.5 bg-wp-state-neutral-100 text-gray-300 border-2 border-wp-state-neutral-100 rounded-l-full flex items-center"
:class="{ :class="{
'rounded-r-full pr-2': value === undefined, 'rounded-r-full pr-2': value === undefined,
}" }"
> >
{{ label }} {{ label }}
</span> </span>
<span v-if="value !== undefined" class="pl-1 pr-2 py-0.5 border-2 border-wp-state-neutral-100 rounded-r-full"> <span
v-if="value !== undefined"
class="pl-1 pr-2 py-0.5 border-2 border-wp-state-neutral-100 rounded-r-full flex items-center"
>
{{ value }} {{ value }}
</span> </span>
</span> </span>

View file

@ -2,10 +2,10 @@
<Scaffold v-if="org" enable-tabs :go-back="goBack"> <Scaffold v-if="org" enable-tabs :go-back="goBack">
<template #title> <template #title>
<span> <span>
<router-link :to="{ name: 'org' }" class="hover:underline"> <router-link :to="{ name: 'org' }" class="hover:underline">{{
{{ org.name }} org.name
<!-- eslint-disable-next-line @intlify/vue-i18n/no-raw-text --> /* eslint-disable-next-line @intlify/vue-i18n/no-raw-text */
</router-link> }}</router-link>
/ /
{{ $t('settings') }} {{ $t('settings') }}
</span> </span>

View file

@ -10,7 +10,7 @@
</InputField> </InputField>
<InputField :label="$t('user.settings.cli_and_api.token')"> <InputField :label="$t('user.settings.cli_and_api.token')">
<template #headerActions> <template #titleActions>
<Button class="ml-auto" :text="$t('user.settings.cli_and_api.reset_token')" @click="resetToken" /> <Button class="ml-auto" :text="$t('user.settings.cli_and_api.reset_token')" @click="resetToken" />
</template> </template>
<pre class="code-box">{{ token }}</pre> <pre class="code-box">{{ token }}</pre>

View file

@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"net/url" "net/url"
"strconv" "strconv"
"strings"
"time" "time"
) )
@ -31,8 +32,12 @@ const (
type PipelineListOptions struct { type PipelineListOptions struct {
ListOptions ListOptions
Before time.Time Before time.Time
After time.Time After time.Time
Branch string
Events []string
RefContains string
Status string
} }
type CronListOptions struct { type CronListOptions struct {
@ -77,6 +82,18 @@ func (opt *PipelineListOptions) QueryEncode() string {
if !opt.After.IsZero() { if !opt.After.IsZero() {
query.Add("after", opt.After.Format(time.RFC3339)) query.Add("after", opt.After.Format(time.RFC3339))
} }
if opt.Branch != "" {
query.Add("branch", opt.Branch)
}
if len(opt.Events) > 0 {
query.Add("event", strings.Join(opt.Events, ","))
}
if opt.RefContains != "" {
query.Add("ref", opt.RefContains)
}
if opt.Status != "" {
query.Add("status", opt.Status)
}
return query.Encode() return query.Encode()
} }