Skip to content

Commit 8cd9356

Browse files
authored
feat(api): load runs with searchWorkflows (#5201)
Signed-off-by: francois samin <[email protected]>
1 parent 0372f01 commit 8cd9356

9 files changed

+80
-35
lines changed

engine/api/router_util.go

+7-13
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,13 @@ func FormString(r *http.Request, s string) string {
8181
return r.FormValue(s)
8282
}
8383

84+
// FormIntr return a int
85+
func FormInt(r *http.Request, s string) int {
86+
v := r.FormValue(s)
87+
i, _ := strconv.Atoi(v)
88+
return i
89+
}
90+
8491
// QueryString return a string from a query parameter
8592
func QueryString(r *http.Request, s string) string {
8693
return r.FormValue(s)
@@ -156,19 +163,6 @@ func QuerySort(r *http.Request) (map[string]SortOrder, error) {
156163
return res, nil
157164
}
158165

159-
// FormInt return a int from query params
160-
func FormInt(r *http.Request, s string) (int, error) {
161-
stringValue := FormString(r, s)
162-
if stringValue == "" {
163-
return 0, nil
164-
}
165-
i, err := strconv.Atoi(stringValue)
166-
if err != nil {
167-
return i, sdk.WrapError(sdk.ErrInvalidNumber, "FormInt> %s is not a integer", stringValue)
168-
}
169-
return i, nil
170-
}
171-
172166
// requestVarInt return int value for a var in Request
173167
func requestVarInt(r *http.Request, s string) (int64, error) {
174168
vars := mux.Vars(r)

engine/api/timeline.go

+1-4
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,7 @@ func (api *API) getTimelineHandler() service.Handler {
1717
consumer := getAPIConsumer(ctx)
1818

1919
// Get index of the first element to return
20-
currentItem, err := FormInt(r, "currentItem")
21-
if err != nil {
22-
return sdk.WrapError(err, "invalid format for current item")
23-
}
20+
currentItem := FormInt(r, "currentItem")
2421

2522
// Get workflow to mute
2623
timelineFilter, err := user.LoadTimelineFilter(api.mustDB(), consumer.AuthentifiedUser.ID)

engine/api/workflow.go

+5-4
Original file line numberDiff line numberDiff line change
@@ -771,10 +771,11 @@ func (api *API) getWorkflowNotificationsConditionsHandler() service.Handler {
771771
func (api *API) getSearchWorkflowHandler() service.Handler {
772772
return func(ctx context.Context, w http.ResponseWriter, r *http.Request) error {
773773
var dao workflow.WorkflowDAO
774-
dao.Filters.ProjectKey = r.FormValue("project")
775-
dao.Filters.WorkflowName = r.FormValue("name")
776-
dao.Filters.VCSServer = r.FormValue("vcs")
777-
dao.Filters.ApplicationRepository = r.FormValue("repository")
774+
dao.Filters.ProjectKey = FormString(r, "project")
775+
dao.Filters.WorkflowName = FormString(r, "name")
776+
dao.Filters.VCSServer = FormString(r, "vcs")
777+
dao.Filters.ApplicationRepository = FormString(r, "repository")
778+
dao.Loaders.WithRuns = FormInt(r, "runs")
778779
dao.Loaders.WithFavoritesForUserID = getAPIConsumer(ctx).AuthentifiedUserID
779780

780781
groupIDS := getAPIConsumer(ctx).GetGroupIDs()

engine/api/workflow/dao_run.go

+29-12
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212

1313
"github.com/fsamin/go-dump"
1414
"github.com/go-gorp/gorp"
15+
"github.com/lib/pq"
1516
"go.opencensus.io/stats"
1617

1718
"github.com/ovh/cds/engine/api/database/gorpmapping"
@@ -238,6 +239,15 @@ func LoadLastRun(db gorp.SqlExecutor, projectkey, workflowname string, loadOpts
238239
return loadRun(db, loadOpts, query, projectkey, workflowname)
239240
}
240241

242+
// LoadLastRuns returns the last run per workflowIDs
243+
func LoadLastRuns(db gorp.SqlExecutor, workflowIDs []int64, limit int) ([]sdk.WorkflowRun, error) {
244+
query := fmt.Sprintf(`select %s
245+
from workflow_run
246+
where workflow_run.workflow_id = ANY($1)
247+
order by workflow_run.workflow_id, workflow_run.num desc limit $2`, wfRunfields)
248+
return loadRuns(db, query, pq.Int64Array(workflowIDs), limit)
249+
}
250+
241251
// LoadRun returns a specific run
242252
func LoadRun(ctx context.Context, db gorp.SqlExecutor, projectkey, workflowname string, number int64, loadOpts LoadRunOptions) (*sdk.WorkflowRun, error) {
243253
_, end := observability.Span(ctx, "workflow.LoadRun",
@@ -284,6 +294,22 @@ func LoadAndLockRunByJobID(db gorp.SqlExecutor, id int64, loadOpts LoadRunOption
284294
return loadRun(db, loadOpts, query, id)
285295
}
286296

297+
func loadRuns(db gorp.SqlExecutor, query string, args ...interface{}) ([]sdk.WorkflowRun, error) {
298+
runs := []Run{}
299+
if _, err := db.Select(&runs, query, args...); err != nil {
300+
return nil, sdk.WrapError(err, "Unable to load runs")
301+
}
302+
wruns := make([]sdk.WorkflowRun, len(runs))
303+
for i := range runs {
304+
wr := sdk.WorkflowRun(runs[i])
305+
if err := loadRunTags(db, &wr); err != nil {
306+
return nil, sdk.WrapError(err, "Unable to load tags")
307+
}
308+
wruns[i] = wr
309+
}
310+
return wruns, nil
311+
}
312+
287313
//LoadRuns loads all runs
288314
//It returns runs, offset, limit count and an error
289315
func LoadRuns(db gorp.SqlExecutor, projectkey, workflowname string, offset, limit int, tagFilter map[string]string) ([]sdk.WorkflowRun, int, int, int, error) {
@@ -367,18 +393,9 @@ func LoadRuns(db gorp.SqlExecutor, projectkey, workflowname string, offset, limi
367393
args = append(args, strings.Join(tags, ","))
368394
}
369395

370-
runs := []Run{}
371-
if _, err := db.Select(&runs, query, args...); err != nil {
372-
return nil, 0, 0, 0, sdk.WrapError(errc, "Unable to load runs")
373-
}
374-
wruns := make([]sdk.WorkflowRun, len(runs))
375-
for i := range runs {
376-
wr := sdk.WorkflowRun(runs[i])
377-
if err := loadRunTags(db, &wr); err != nil {
378-
return nil, 0, 0, 0, sdk.WrapError(err, "Unable to load tags")
379-
}
380-
381-
wruns[i] = wr
396+
wruns, err := loadRuns(db, query, args...)
397+
if err != nil {
398+
return nil, 0, 0, 0, err
382399
}
383400

384401
return wruns, offset, limit, int(count), nil

engine/api/workflow/factory_dao.go

+31
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ type LoadAllWorkflowsOptionsLoaders struct {
8484
WithLabels bool
8585
WithAudits bool
8686
WithFavoritesForUserID string
87+
WithRuns int
8788
}
8889

8990
type WorkflowDAO struct {
@@ -282,6 +283,13 @@ func (dao WorkflowDAO) GetLoaders() []gorpmapping.GetOptionFunc {
282283
})
283284
}
284285

286+
if dao.Loaders.WithRuns != 0 {
287+
loaders = append(loaders, func(db gorp.SqlExecutor, i interface{}) error {
288+
ws := i.(*[]Workflow)
289+
return dao.withRuns(db, ws, dao.Loaders.WithRuns)
290+
})
291+
}
292+
285293
loaders = append(loaders,
286294
func(db gorp.SqlExecutor, i interface{}) error {
287295
ws := i.(*[]Workflow)
@@ -628,6 +636,29 @@ func (dao WorkflowDAO) withLabels(db gorp.SqlExecutor, ws *[]Workflow) error {
628636
return nil
629637
}
630638

639+
func (dao WorkflowDAO) withRuns(db gorp.SqlExecutor, ws *[]Workflow, limit int) error {
640+
var ids = make([]int64, 0, len(*ws))
641+
for _, w := range *ws {
642+
ids = append(ids, w.ID)
643+
}
644+
645+
runs, err := LoadLastRuns(db, ids, limit)
646+
if err != nil {
647+
return err
648+
}
649+
650+
for x := range *ws {
651+
w := &(*ws)[x]
652+
for _, run := range runs {
653+
if w.ID == run.WorkflowID {
654+
w.Runs = append(w.Runs, run)
655+
}
656+
}
657+
}
658+
659+
return nil
660+
}
661+
631662
func (dao WorkflowDAO) withFavorites(db gorp.SqlExecutor, ws *[]Workflow, userID string) error {
632663
workflowIDs, err := UserFavoriteWorkflowIDs(db, userID)
633664
if err != nil {

engine/api/workflow/factory_dao_test.go

+1
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,7 @@ func TestLoadAllWorkflows(t *testing.T) {
8181
WithIntegrations: true,
8282
WithPipelines: true,
8383
WithTemplate: true,
84+
WithRuns: 10,
8485
},
8586
},
8687
}

engine/api/workflow_test.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -1982,7 +1982,10 @@ func Test_getSearchWorkflowHandler(t *testing.T) {
19821982
BuitinConsumerAuthenticationToken: jws,
19831983
})
19841984

1985-
wfs, err := sdkclientAdmin.WorkflowSearch(cdsclient.WithQueryParameter("repository", "ovh/"+repofullName))
1985+
wfs, err := sdkclientAdmin.WorkflowSearch(
1986+
cdsclient.WithQueryParameter("repository", "ovh/"+repofullName),
1987+
cdsclient.WithQueryParameter("runs", "10"),
1988+
)
19861989
require.NoError(t, err)
19871990
require.Len(t, wfs, 1)
19881991
require.Equal(t, wf.Name, wfs[0].Name)

engine/api/workflow_trigger.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ func (api *API) getWorkflowTriggerConditionHandler() service.Handler {
1818
vars := mux.Vars(r)
1919
key := vars["key"]
2020
name := vars["permWorkflowName"]
21-
id, _ := FormInt(r, "nodeID")
21+
id := FormInt(r, "nodeID")
2222

2323
proj, err := project.Load(api.mustDB(), key, project.LoadOptions.WithVariables, project.LoadOptions.WithIntegrations)
2424
if err != nil {

sdk/workflow.go

+1
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ type Workflow struct {
6464
FromTemplate string `json:"from_template,omitempty" db:"-" cli:"-"`
6565
TemplateUpToDate bool `json:"template_up_to_date,omitempty" db:"-" cli:"-"`
6666
URLs URL `json:"urls" yaml:"-" db:"-" cli:"-"`
67+
Runs []WorkflowRun `json:"runs,omitempty" yaml:"-" db:"-" cli:"-"`
6768
}
6869

6970
type PurgeTags []string

0 commit comments

Comments
 (0)