Skip to content

Commit

Permalink
Merge pull request #22 from flant/last-scheduled-pipelines
Browse files Browse the repository at this point in the history
get last 10 scheduled pipelines
  • Loading branch information
marriva committed Aug 9, 2023
2 parents 8600fc5 + 1301dea commit 27f9889
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 76 deletions.
88 changes: 76 additions & 12 deletions cmd/projects/schedules.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ package projects

import (
"fmt"
"math"
"os"
"regexp"
"strings"
"text/tabwriter"

go_sort "sort"

"github.com/flant/glaball/pkg/client"
"github.com/flant/glaball/pkg/limiter"
"github.com/flant/glaball/pkg/sort/v2"
Expand All @@ -19,6 +22,10 @@ import (
"github.com/xanzy/go-gitlab"
)

const (
pipelinesCount = 10
)

var (
listProjectsPipelinesOptions = gitlab.ListProjectsOptions{ListOptions: gitlab.ListOptions{PerPage: 100}}
active *bool
Expand Down Expand Up @@ -196,8 +203,10 @@ func ListPipelineSchedulesCmd() error {

if s := v.Struct.(ProjectPipelineSchedule).Schedule; s != nil {
count = 1
owner = s.Owner.Username
if s.LastPipeline.Status == "" {
if s.Owner != nil {
owner = s.Owner.Username
}
if s.LastPipeline == nil || s.LastPipeline.Status == "" {
pipelineStatus = "unknown"
} else {
pipelineStatus = s.LastPipeline.Status
Expand Down Expand Up @@ -352,7 +361,7 @@ func ListPipelineCleanupSchedulesCmd() error {
for _, v := range toList.Typed() {
wg.Add(1)
go listPipelineSchedules(v.Host, v.Struct.(*ProjectFile).Project, gitlab.ListPipelineSchedulesOptions{PerPage: 100},
desc, wg, schedules, cacheFunc)
desc, false, wg, schedules, cacheFunc)
}

go func() {
Expand Down Expand Up @@ -543,7 +552,7 @@ func listProjectsPipelines(h *client.Host, opt gitlab.ListProjectsOptions, desc

for _, v := range list {
wg.Add(1)
go listPipelineSchedules(h, v, gitlab.ListPipelineSchedulesOptions{PerPage: 100}, desc, wg, data, options...)
go listPipelineSchedules(h, v, gitlab.ListPipelineSchedulesOptions{PerPage: 100}, desc, false, wg, data, options...)
}

if resp.NextPage > 0 {
Expand All @@ -554,7 +563,7 @@ func listProjectsPipelines(h *client.Host, opt gitlab.ListProjectsOptions, desc
}

func listPipelineSchedules(h *client.Host, project *gitlab.Project, opt gitlab.ListPipelineSchedulesOptions,
desc []*regexp.Regexp, wg *limiter.Limiter, data chan<- interface{}, options ...gitlab.RequestOptionFunc) {
desc []*regexp.Regexp, withLastPipelines bool, wg *limiter.Limiter, data chan<- interface{}, options ...gitlab.RequestOptionFunc) {

defer wg.Done()

Expand Down Expand Up @@ -585,18 +594,21 @@ filter:
if active == nil && status == nil {
data <- sort.Element{
Host: h,
Struct: ProjectPipelineSchedule{project, nil},
Struct: ProjectPipelineSchedule{project, nil, nil},
Cached: resp.Header.Get("X-From-Cache") == "1"}
}
} else {
for _, v := range filteredList {
// get entire pipeline schedule to make lastpipeline struct accessible
// note: init new variables with the same names
wg.Lock()
v, resp, err := h.Client.PipelineSchedules.GetPipelineSchedule(project.ID, v.ID, options...)
if err != nil {
wg.Error(h, err)
wg.Unlock()
continue
}
wg.Unlock()
// check pipeline schedule state
if active != nil && v.Active != *active {
continue
Expand All @@ -606,24 +618,76 @@ filter:
if status != nil && (v.LastPipeline.Status == "" || v.LastPipeline.Status != *status) {
continue
}

var pipelines []*gitlab.Pipeline

// get last pipelines
if withLastPipelines {
perPage := 100

wg.Lock()
pipelines, resp, err = h.Client.PipelineSchedules.ListPipelinesTriggeredBySchedule(project.ID, v.ID, &gitlab.ListPipelinesTriggeredByScheduleOptions{PerPage: perPage}, options...)
if err != nil {
wg.Error(h, err)
wg.Unlock()
continue
}
wg.Unlock()

if resp.TotalPages > 1 {
// count last page
// https://gitlab.com/gitlab-org/gitlab/-/issues/369095
for perPage > pipelinesCount {
if resp.TotalItems%perPage > pipelinesCount {
break
}
perPage--
}
lastPage := math.Ceil(float64(resp.TotalItems) / float64(perPage))

wg.Lock()
pipelines, resp, err = h.Client.PipelineSchedules.ListPipelinesTriggeredBySchedule(project.ID, v.ID, &gitlab.ListPipelinesTriggeredByScheduleOptions{
Page: int(lastPage),
PerPage: perPage,
}, options...)
if err != nil {
wg.Error(h, err)
wg.Unlock()
continue
}
wg.Unlock()
}

if len(pipelines) > pipelinesCount {
pipelines = pipelines[len(pipelines)-pipelinesCount:]
}

// sort descending
// https://gitlab.com/gitlab-org/gitlab/-/issues/369095
go_sort.Slice(pipelines, func(i, j int) bool {
return pipelines[i].ID >= pipelines[j].ID
})
}

// push result to channel
data <- sort.Element{
Host: h,
Struct: ProjectPipelineSchedule{project, v},
Struct: ProjectPipelineSchedule{project, v, pipelines},
Cached: resp.Header.Get("X-From-Cache") == "1"}
}
}

if resp.NextPage > 0 {
wg.Add(1)
opt.Page = resp.NextPage
go listPipelineSchedules(h, project, opt, desc, wg, data, options...)
go listPipelineSchedules(h, project, opt, desc, false, wg, data, options...)
}
}

type ProjectPipelineSchedule struct {
Project *gitlab.Project `json:"project,omitempty"`
Schedule *gitlab.PipelineSchedule `json:"schedule,omitempty"`
Project *gitlab.Project `json:"project,omitempty"`
Schedule *gitlab.PipelineSchedule `json:"schedule,omitempty"`
Pipelines []*gitlab.Pipeline `json:"pipelines,omitempty"`
}

type Schedules []*gitlab.PipelineSchedule
Expand All @@ -650,8 +714,8 @@ func (a Schedules) Descriptions() string {
}

func ListPipelineSchedules(h *client.Host, project *gitlab.Project, opt gitlab.ListPipelineSchedulesOptions,
desc []*regexp.Regexp, wg *limiter.Limiter, data chan<- interface{}, options ...gitlab.RequestOptionFunc) {
listPipelineSchedules(h, project, opt, desc, wg, data, options...)
desc []*regexp.Regexp, withLastPipelines bool, wg *limiter.Limiter, data chan<- interface{}, options ...gitlab.RequestOptionFunc) {
listPipelineSchedules(h, project, opt, desc, withLastPipelines, wg, data, options...)
}

func takeOwnership(h *client.Host, schedule ProjectPipelineSchedule,
Expand Down
36 changes: 18 additions & 18 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -7,49 +7,49 @@ require (
github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137
github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79
github.com/hashicorp/go-cleanhttp v0.5.2
github.com/hashicorp/go-hclog v1.4.0
github.com/hashicorp/go-retryablehttp v0.7.2
github.com/imdario/mergo v0.3.13
github.com/hashicorp/go-hclog v1.5.0
github.com/hashicorp/go-retryablehttp v0.7.4
github.com/imdario/mergo v0.3.16
github.com/jmoiron/sqlx v1.3.5
github.com/peterbourgon/diskv v2.0.1+incompatible
github.com/spf13/cobra v1.6.1
github.com/spf13/viper v1.15.0
github.com/xanzy/go-gitlab v0.80.2
github.com/spf13/cobra v1.7.0
github.com/spf13/viper v1.16.0
github.com/xanzy/go-gitlab v0.90.0
gopkg.in/yaml.v3 v3.0.1
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/fatih/color v1.14.1 // indirect
github.com/fatih/color v1.15.0 // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/protobuf v1.5.3 // indirect
github.com/google/go-querystring v1.1.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.17 // indirect
github.com/mattn/go-isatty v0.0.19 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pelletier/go-toml/v2 v2.0.6 // indirect
github.com/pelletier/go-toml/v2 v2.0.9 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/spf13/afero v1.9.4 // indirect
github.com/spf13/cast v1.5.0 // indirect
github.com/spf13/afero v1.9.5 // indirect
github.com/spf13/cast v1.5.1 // indirect
github.com/spf13/jwalterweatherman v1.1.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/subosito/gotenv v1.4.2 // indirect
golang.org/x/net v0.7.0 // indirect
golang.org/x/oauth2 v0.5.0 // indirect
golang.org/x/sys v0.5.0 // indirect
golang.org/x/text v0.7.0 // indirect
golang.org/x/net v0.14.0 // indirect
golang.org/x/oauth2 v0.11.0 // indirect
golang.org/x/sys v0.11.0 // indirect
golang.org/x/text v0.12.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/protobuf v1.28.1 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
)

require (
github.com/armon/go-radix v1.0.0
github.com/google/btree v1.1.2 // indirect
github.com/stretchr/testify v1.8.1
github.com/stretchr/testify v1.8.4
golang.org/x/time v0.3.0 // indirect
)

0 comments on commit 27f9889

Please sign in to comment.