Add filter options to GetPipelines API (#3645)

Separate this change from
https://github.com/woodpecker-ci/woodpecker/pull/3506

I would like to get at least this change into v2.5.0 if possible.

---------

Co-authored-by: qwerty287 <80460567+qwerty287@users.noreply.github.com>
This commit is contained in:
Robert Kaussow
2024-04-25 09:37:42 +02:00
committed by GitHub
parent b5bc1cf48a
commit 9972c24924
10 changed files with 194 additions and 68 deletions

View File

@@ -52,9 +52,22 @@ func (s storage) GetPipelineLastBefore(repo *model.Repo, branch string, num int6
Get(pipeline))
}
func (s storage) GetPipelineList(repo *model.Repo, p *model.ListOptions) ([]*model.Pipeline, error) {
func (s storage) GetPipelineList(repo *model.Repo, p *model.ListOptions, f *model.PipelineFilter) ([]*model.Pipeline, error) {
pipelines := make([]*model.Pipeline, 0, 16)
return pipelines, s.paginate(p).Where("pipeline_repo_id = ?", repo.ID).
cond := builder.NewCond().And(builder.Eq{"pipeline_repo_id": repo.ID})
if f != nil {
if f.After != 0 {
cond = cond.And(builder.Gt{"pipeline_started": f.After})
}
if f.Before != 0 {
cond = cond.And(builder.Lt{"pipeline_started": f.Before})
}
}
return pipelines, s.paginate(p).Where(cond).
Desc("pipeline_number").
Find(&pipelines)
}

View File

@@ -18,6 +18,7 @@ package datastore
import (
"fmt"
"testing"
"time"
"github.com/franela/goblin"
"github.com/stretchr/testify/assert"
@@ -221,13 +222,35 @@ func TestPipelines(t *testing.T) {
g.Assert(err1).IsNil()
err2 := store.CreatePipeline(pipeline2, []*model.Step{}...)
g.Assert(err2).IsNil()
pipelines, err3 := store.GetPipelineList(&model.Repo{ID: 1}, &model.ListOptions{Page: 1, PerPage: 50})
pipelines, err3 := store.GetPipelineList(&model.Repo{ID: 1}, &model.ListOptions{Page: 1, PerPage: 50}, nil)
g.Assert(err3).IsNil()
g.Assert(len(pipelines)).Equal(2)
g.Assert(pipelines[0].ID).Equal(pipeline2.ID)
g.Assert(pipelines[0].RepoID).Equal(pipeline2.RepoID)
g.Assert(pipelines[0].Status).Equal(pipeline2.Status)
})
g.It("Should get filtered pipelines", func() {
dt1, _ := time.Parse(time.RFC3339, "2023-01-15T15:00:00Z")
pipeline1 := &model.Pipeline{
RepoID: repo.ID,
Started: dt1.Unix(),
}
dt2, _ := time.Parse(time.RFC3339, "2023-01-15T16:30:00Z")
pipeline2 := &model.Pipeline{
RepoID: repo.ID,
Started: dt2.Unix(),
}
err1 := store.CreatePipeline(pipeline1, []*model.Step{}...)
g.Assert(err1).IsNil()
err2 := store.CreatePipeline(pipeline2, []*model.Step{}...)
g.Assert(err2).IsNil()
pipelines, err3 := store.GetPipelineList(&model.Repo{ID: 1}, &model.ListOptions{Page: 1, PerPage: 50}, &model.PipelineFilter{Before: dt2.Unix()})
g.Assert(err3).IsNil()
g.Assert(len(pipelines)).Equal(1)
g.Assert(pipelines[0].ID).Equal(pipeline1.ID)
g.Assert(pipelines[0].RepoID).Equal(pipeline1.RepoID)
})
})
}

View File

@@ -543,6 +543,10 @@ func (_m *Store) DeleteUser(_a0 *model.User) error {
func (_m *Store) ForgeCreate(_a0 *model.Forge) error {
ret := _m.Called(_a0)
if len(ret) == 0 {
panic("no return value specified for ForgeCreate")
}
var r0 error
if rf, ok := ret.Get(0).(func(*model.Forge) error); ok {
r0 = rf(_a0)
@@ -557,6 +561,10 @@ func (_m *Store) ForgeCreate(_a0 *model.Forge) error {
func (_m *Store) ForgeDelete(_a0 *model.Forge) error {
ret := _m.Called(_a0)
if len(ret) == 0 {
panic("no return value specified for ForgeDelete")
}
var r0 error
if rf, ok := ret.Get(0).(func(*model.Forge) error); ok {
r0 = rf(_a0)
@@ -567,62 +575,14 @@ func (_m *Store) ForgeDelete(_a0 *model.Forge) error {
return r0
}
// ForgeFindByRepo provides a mock function with given fields: _a0
func (_m *Store) ForgeFindByRepo(_a0 *model.Repo) (*model.Forge, error) {
ret := _m.Called(_a0)
var r0 *model.Forge
var r1 error
if rf, ok := ret.Get(0).(func(*model.Repo) (*model.Forge, error)); ok {
return rf(_a0)
}
if rf, ok := ret.Get(0).(func(*model.Repo) *model.Forge); ok {
r0 = rf(_a0)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*model.Forge)
}
}
if rf, ok := ret.Get(1).(func(*model.Repo) error); ok {
r1 = rf(_a0)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// ForgeFindByUser provides a mock function with given fields: _a0
func (_m *Store) ForgeFindByUser(_a0 *model.User) (*model.Forge, error) {
ret := _m.Called(_a0)
var r0 *model.Forge
var r1 error
if rf, ok := ret.Get(0).(func(*model.User) (*model.Forge, error)); ok {
return rf(_a0)
}
if rf, ok := ret.Get(0).(func(*model.User) *model.Forge); ok {
r0 = rf(_a0)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).(*model.Forge)
}
}
if rf, ok := ret.Get(1).(func(*model.User) error); ok {
r1 = rf(_a0)
} else {
r1 = ret.Error(1)
}
return r0, r1
}
// ForgeGet provides a mock function with given fields: _a0
func (_m *Store) ForgeGet(_a0 int64) (*model.Forge, error) {
ret := _m.Called(_a0)
if len(ret) == 0 {
panic("no return value specified for ForgeGet")
}
var r0 *model.Forge
var r1 error
if rf, ok := ret.Get(0).(func(int64) (*model.Forge, error)); ok {
@@ -649,6 +609,10 @@ func (_m *Store) ForgeGet(_a0 int64) (*model.Forge, error) {
func (_m *Store) ForgeList(p *model.ListOptions) ([]*model.Forge, error) {
ret := _m.Called(p)
if len(ret) == 0 {
panic("no return value specified for ForgeList")
}
var r0 []*model.Forge
var r1 error
if rf, ok := ret.Get(0).(func(*model.ListOptions) ([]*model.Forge, error)); ok {
@@ -675,6 +639,10 @@ func (_m *Store) ForgeList(p *model.ListOptions) ([]*model.Forge, error) {
func (_m *Store) ForgeUpdate(_a0 *model.Forge) error {
ret := _m.Called(_a0)
if len(ret) == 0 {
panic("no return value specified for ForgeUpdate")
}
var r0 error
if rf, ok := ret.Get(0).(func(*model.Forge) error); ok {
r0 = rf(_a0)
@@ -833,9 +801,9 @@ func (_m *Store) GetPipelineLastBefore(_a0 *model.Repo, _a1 string, _a2 int64) (
return r0, r1
}
// GetPipelineList provides a mock function with given fields: _a0, _a1
func (_m *Store) GetPipelineList(_a0 *model.Repo, _a1 *model.ListOptions) ([]*model.Pipeline, error) {
ret := _m.Called(_a0, _a1)
// GetPipelineList provides a mock function with given fields: _a0, _a1, _a2
func (_m *Store) GetPipelineList(_a0 *model.Repo, _a1 *model.ListOptions, _a2 *model.PipelineFilter) ([]*model.Pipeline, error) {
ret := _m.Called(_a0, _a1, _a2)
if len(ret) == 0 {
panic("no return value specified for GetPipelineList")
@@ -843,19 +811,19 @@ func (_m *Store) GetPipelineList(_a0 *model.Repo, _a1 *model.ListOptions) ([]*mo
var r0 []*model.Pipeline
var r1 error
if rf, ok := ret.Get(0).(func(*model.Repo, *model.ListOptions) ([]*model.Pipeline, error)); ok {
return rf(_a0, _a1)
if rf, ok := ret.Get(0).(func(*model.Repo, *model.ListOptions, *model.PipelineFilter) ([]*model.Pipeline, error)); ok {
return rf(_a0, _a1, _a2)
}
if rf, ok := ret.Get(0).(func(*model.Repo, *model.ListOptions) []*model.Pipeline); ok {
r0 = rf(_a0, _a1)
if rf, ok := ret.Get(0).(func(*model.Repo, *model.ListOptions, *model.PipelineFilter) []*model.Pipeline); ok {
r0 = rf(_a0, _a1, _a2)
} else {
if ret.Get(0) != nil {
r0 = ret.Get(0).([]*model.Pipeline)
}
}
if rf, ok := ret.Get(1).(func(*model.Repo, *model.ListOptions) error); ok {
r1 = rf(_a0, _a1)
if rf, ok := ret.Get(1).(func(*model.Repo, *model.ListOptions, *model.PipelineFilter) error); ok {
r1 = rf(_a0, _a1, _a2)
} else {
r1 = ret.Error(1)
}

View File

@@ -75,7 +75,7 @@ type Store interface {
// GetPipelineLastBefore gets the last pipeline before pipeline number N.
GetPipelineLastBefore(*model.Repo, string, int64) (*model.Pipeline, error)
// GetPipelineList gets a list of pipelines for the repository
GetPipelineList(*model.Repo, *model.ListOptions) ([]*model.Pipeline, error)
GetPipelineList(*model.Repo, *model.ListOptions, *model.PipelineFilter) ([]*model.Pipeline, error)
// GetActivePipelineList gets a list of the active pipelines for the repository
GetActivePipelineList(repo *model.Repo) ([]*model.Pipeline, error)
// GetPipelineQueue gets a list of pipelines in queue.