mirror of
https://github.com/woodpecker-ci/woodpecker.git
synced 2025-09-03 12:43:48 +00:00
Add filter to list repository pipelines API (#4416)
This commit is contained in:
parent
9fedc88a9c
commit
52fb493495
7 changed files with 95 additions and 15 deletions
|
@ -2966,6 +2966,24 @@ const docTemplate = `{
|
||||||
"description": "only return pipelines after this RFC3339 date",
|
"description": "only return pipelines after this RFC3339 date",
|
||||||
"name": "after",
|
"name": "after",
|
||||||
"in": "query"
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "filter pipelines by branch",
|
||||||
|
"name": "branch",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "filter pipelines by webhook events (comma separated)",
|
||||||
|
"name": "event",
|
||||||
|
"in": "query"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "string",
|
||||||
|
"description": "filter pipelines by strings contained in ref",
|
||||||
|
"name": "ref",
|
||||||
|
"in": "query"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"responses": {
|
"responses": {
|
||||||
|
|
|
@ -22,6 +22,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
|
@ -116,14 +117,32 @@ func createTmpPipeline(event model.WebhookEvent, commit *model.Commit, user *mod
|
||||||
// @Param perPage query int false "for response pagination, max items per page" default(50)
|
// @Param perPage query int false "for response pagination, max items per page" default(50)
|
||||||
// @Param before query string false "only return pipelines before this RFC3339 date"
|
// @Param before query string false "only return pipelines before this RFC3339 date"
|
||||||
// @Param after query string false "only return pipelines after this RFC3339 date"
|
// @Param after query string false "only return pipelines after this RFC3339 date"
|
||||||
|
// @Param branch query string false "filter pipelines by branch"
|
||||||
|
// @Param event query string false "filter pipelines by webhook events (comma separated)"
|
||||||
|
// @Param ref query string false "filter pipelines by strings contained in ref"
|
||||||
func GetPipelines(c *gin.Context) {
|
func GetPipelines(c *gin.Context) {
|
||||||
repo := session.Repo(c)
|
repo := session.Repo(c)
|
||||||
before := c.Query("before")
|
|
||||||
after := c.Query("after")
|
|
||||||
|
|
||||||
filter := new(model.PipelineFilter)
|
filter := &model.PipelineFilter{
|
||||||
|
Branch: c.Query("branch"),
|
||||||
|
RefContains: c.Query("ref"),
|
||||||
|
}
|
||||||
|
|
||||||
if before != "" {
|
if events := c.Query("event"); events != "" {
|
||||||
|
eventList := strings.Split(events, ",")
|
||||||
|
wel := make(model.WebhookEventList, 0, len(eventList))
|
||||||
|
for _, event := range events {
|
||||||
|
we := model.WebhookEvent(event)
|
||||||
|
if err := we.Validate(); err != nil {
|
||||||
|
_ = c.AbortWithError(http.StatusBadRequest, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
wel = append(wel, we)
|
||||||
|
}
|
||||||
|
filter.Events = wel
|
||||||
|
}
|
||||||
|
|
||||||
|
if before := c.Query("before"); before != "" {
|
||||||
beforeDt, err := time.Parse(time.RFC3339, before)
|
beforeDt, err := time.Parse(time.RFC3339, before)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = c.AbortWithError(http.StatusBadRequest, err)
|
_ = c.AbortWithError(http.StatusBadRequest, err)
|
||||||
|
@ -132,7 +151,7 @@ func GetPipelines(c *gin.Context) {
|
||||||
filter.Before = beforeDt.Unix()
|
filter.Before = beforeDt.Unix()
|
||||||
}
|
}
|
||||||
|
|
||||||
if after != "" {
|
if after := c.Query("after"); after != "" {
|
||||||
afterDt, err := time.Parse(time.RFC3339, after)
|
afterDt, err := time.Parse(time.RFC3339, after)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
_ = c.AbortWithError(http.StatusBadRequest, err)
|
_ = c.AbortWithError(http.StatusBadRequest, err)
|
||||||
|
|
|
@ -63,6 +63,9 @@ func (Pipeline) TableName() string {
|
||||||
type PipelineFilter struct {
|
type PipelineFilter struct {
|
||||||
Before int64
|
Before int64
|
||||||
After int64
|
After int64
|
||||||
|
Branch string
|
||||||
|
Events []WebhookEvent
|
||||||
|
RefContains string
|
||||||
}
|
}
|
||||||
|
|
||||||
// IsMultiPipeline checks if step list contain more than one parent step.
|
// IsMultiPipeline checks if step list contain more than one parent step.
|
||||||
|
|
|
@ -52,7 +52,7 @@ func wrapDelete(c int64, err error) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s storage) paginate(p *model.ListOptions) *xorm.Session {
|
func (s storage) paginate(p *model.ListOptions) *xorm.Session {
|
||||||
if p.All {
|
if p == nil || p.All {
|
||||||
return s.engine.NewSession()
|
return s.engine.NewSession()
|
||||||
}
|
}
|
||||||
if p.PerPage < 1 {
|
if p.PerPage < 1 {
|
||||||
|
|
|
@ -65,6 +65,18 @@ func (s storage) GetPipelineList(repo *model.Repo, p *model.ListOptions, f *mode
|
||||||
if f.Before != 0 {
|
if f.Before != 0 {
|
||||||
cond = cond.And(builder.Lt{"created": f.Before})
|
cond = cond.And(builder.Lt{"created": f.Before})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if f.Branch != "" {
|
||||||
|
cond = cond.And(builder.Eq{"branch": f.Branch})
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(f.Events) != 0 {
|
||||||
|
cond = cond.And(builder.In("event", f.Events))
|
||||||
|
}
|
||||||
|
|
||||||
|
if f.RefContains != "" {
|
||||||
|
cond = cond.And(builder.Like{"ref", f.RefContains})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return pipelines, s.paginate(p).Where(cond).
|
return pipelines, s.paginate(p).Where(cond).
|
||||||
|
|
|
@ -213,21 +213,49 @@ func TestPipelines(t *testing.T) {
|
||||||
pipeline1 := &model.Pipeline{
|
pipeline1 := &model.Pipeline{
|
||||||
RepoID: repo.ID,
|
RepoID: repo.ID,
|
||||||
Status: model.StatusFailure,
|
Status: model.StatusFailure,
|
||||||
|
Event: model.EventCron,
|
||||||
|
Ref: "refs/heads/some-branch",
|
||||||
|
Branch: "some-branch",
|
||||||
}
|
}
|
||||||
pipeline2 := &model.Pipeline{
|
pipeline2 := &model.Pipeline{
|
||||||
RepoID: repo.ID,
|
RepoID: repo.ID,
|
||||||
Status: model.StatusSuccess,
|
Status: model.StatusSuccess,
|
||||||
|
Event: model.EventPull,
|
||||||
|
Ref: "refs/pull/32",
|
||||||
|
Branch: "main",
|
||||||
}
|
}
|
||||||
err1 := store.CreatePipeline(pipeline1, []*model.Step{}...)
|
err := store.CreatePipeline(pipeline1, []*model.Step{}...)
|
||||||
g.Assert(err1).IsNil()
|
g.Assert(err).IsNil()
|
||||||
err2 := store.CreatePipeline(pipeline2, []*model.Step{}...)
|
err = store.CreatePipeline(pipeline2, []*model.Step{}...)
|
||||||
g.Assert(err2).IsNil()
|
g.Assert(err).IsNil()
|
||||||
pipelines, err3 := store.GetPipelineList(&model.Repo{ID: 1}, &model.ListOptions{Page: 1, PerPage: 50}, nil)
|
pipelines, err := store.GetPipelineList(&model.Repo{ID: 1}, &model.ListOptions{Page: 1, PerPage: 50}, nil)
|
||||||
g.Assert(err3).IsNil()
|
g.Assert(err).IsNil()
|
||||||
g.Assert(len(pipelines)).Equal(2)
|
g.Assert(len(pipelines)).Equal(2)
|
||||||
g.Assert(pipelines[0].ID).Equal(pipeline2.ID)
|
g.Assert(pipelines[0].ID).Equal(pipeline2.ID)
|
||||||
g.Assert(pipelines[0].RepoID).Equal(pipeline2.RepoID)
|
g.Assert(pipelines[0].RepoID).Equal(pipeline2.RepoID)
|
||||||
g.Assert(pipelines[0].Status).Equal(pipeline2.Status)
|
g.Assert(pipelines[0].Status).Equal(pipeline2.Status)
|
||||||
|
|
||||||
|
pipelines, err = store.GetPipelineList(&model.Repo{ID: 1}, nil, &model.PipelineFilter{
|
||||||
|
Branch: "main",
|
||||||
|
})
|
||||||
|
g.Assert(err).IsNil()
|
||||||
|
g.Assert(len(pipelines)).Equal(1)
|
||||||
|
g.Assert(pipelines[0].ID).Equal(pipeline2.ID)
|
||||||
|
|
||||||
|
pipelines, err = store.GetPipelineList(&model.Repo{ID: 1}, nil, &model.PipelineFilter{
|
||||||
|
Events: []model.WebhookEvent{model.EventCron},
|
||||||
|
})
|
||||||
|
g.Assert(err).IsNil()
|
||||||
|
g.Assert(len(pipelines)).Equal(1)
|
||||||
|
g.Assert(pipelines[0].ID).Equal(pipeline1.ID)
|
||||||
|
|
||||||
|
pipelines, err = store.GetPipelineList(&model.Repo{ID: 1}, nil, &model.PipelineFilter{
|
||||||
|
Events: []model.WebhookEvent{model.EventCron, model.EventPull},
|
||||||
|
RefContains: "32",
|
||||||
|
})
|
||||||
|
g.Assert(err).IsNil()
|
||||||
|
g.Assert(len(pipelines)).Equal(1)
|
||||||
|
g.Assert(pipelines[0].ID).Equal(pipeline2.ID)
|
||||||
})
|
})
|
||||||
|
|
||||||
g.It("Should get filtered pipelines", func() {
|
g.It("Should get filtered pipelines", func() {
|
||||||
|
|
|
@ -105,7 +105,7 @@ export default class WoodpeckerClient extends ApiClient {
|
||||||
|
|
||||||
async getPipelineList(
|
async getPipelineList(
|
||||||
repoId: number,
|
repoId: number,
|
||||||
opts?: PaginationOptions & { before?: string; after?: string },
|
opts?: PaginationOptions & { before?: string; after?: string; ref?: string; branch?: string; events?: string },
|
||||||
): Promise<Pipeline[]> {
|
): Promise<Pipeline[]> {
|
||||||
const query = encodeQueryString(opts);
|
const query = encodeQueryString(opts);
|
||||||
return this._get(`/api/repos/${repoId}/pipelines?${query}`) as Promise<Pipeline[]>;
|
return this._get(`/api/repos/${repoId}/pipelines?${query}`) as Promise<Pipeline[]>;
|
||||||
|
|
Loading…
Reference in a new issue