Skip to content

Commit

Permalink
Merge pull request #726 from bmeneguele/fix-ci-bridge
Browse files Browse the repository at this point in the history
Allow users to specify CI brigde jobs by their name
  • Loading branch information
bmeneg authored Aug 11, 2021
2 parents 5a1fd5d + 94f5faa commit 867b3ce
Show file tree
Hide file tree
Showing 6 changed files with 60 additions and 22 deletions.
10 changes: 7 additions & 3 deletions cmd/ci.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ import (
"github.com/spf13/cobra"
)

// Hold --follow flag value that is common for all ci command
var followBridge bool
// Hold --follow and --bridge values that are common to all ci command
var (
followBridge bool
bridgeName string
)

// ciCmd represents the ci command
var ciCmd = &cobra.Command{
Expand All @@ -14,6 +17,7 @@ var ciCmd = &cobra.Command{
}

func init() {
ciCmd.PersistentFlags().Bool("follow", false, "Follow downstream pipelines in a multi-projects setup")
ciCmd.PersistentFlags().Bool("follow", false, "Follow bridge jobs (downstream pipelines) in a multi-projects setup")
ciCmd.PersistentFlags().String("bridge", "", "Bridge job (downstream pipeline) name")
RootCmd.AddCommand(ciCmd)
}
14 changes: 11 additions & 3 deletions cmd/ci_artifacts.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ var ciArtifactsCmd = &cobra.Command{
Example: heredoc.Doc(`
lab ci artifacts upstream feature_branch
lab ci artifacts upstream 125 --merge-request
lab ci artifacts upstream 125:'my custom stage' --merge-request`),
lab ci artifacts upstream 125:'my custom stage' --merge-request
lab ci artifacts upstream 125:'build' --merge-request --bridge 'security-tests'`),
PersistentPreRun: labPersistentPreRun,
Run: func(cmd *cobra.Command, args []string) {
var (
Expand All @@ -44,9 +45,16 @@ var ciArtifactsCmd = &cobra.Command{
log.Fatal(err)
}

followBridge, err = cmd.Flags().GetBool("follow")
bridgeName, err = cmd.Flags().GetString("bridge")
if err != nil {
log.Fatal(err)
} else if bridgeName != "" {
followBridge = true
} else {
followBridge, err = cmd.Flags().GetBool("follow")
if err != nil {
log.Fatal(err)
}
}

path, err := cmd.Flags().GetString("artifact-path")
Expand All @@ -65,7 +73,7 @@ var ciArtifactsCmd = &cobra.Command{
}
projectID := project.ID

r, outpath, err := lab.CIArtifacts(projectID, pipelineID, jobName, path, followBridge)
r, outpath, err := lab.CIArtifacts(projectID, pipelineID, jobName, path, followBridge, bridgeName)
if err != nil {
log.Fatal(err)
}
Expand Down
14 changes: 11 additions & 3 deletions cmd/ci_status.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ var ciStatusCmd = &cobra.Command{
Example: heredoc.Doc(`
lab ci status
lab ci status upstream 608 --merge-request
lab ci status 600 --wait`),
lab ci status 600 --wait
lab ci status upstream 125 --merge-request --bridge 'security-tests'`),
RunE: nil,
PersistentPreRun: labPersistentPreRun,
Run: func(cmd *cobra.Command, args []string) {
Expand All @@ -37,9 +38,16 @@ var ciStatusCmd = &cobra.Command{
log.Fatal(err)
}

followBridge, err = cmd.Flags().GetBool("follow")
bridgeName, err = cmd.Flags().GetString("bridge")
if err != nil {
log.Fatal(err)
} else if bridgeName != "" {
followBridge = true
} else {
followBridge, err = cmd.Flags().GetBool("follow")
if err != nil {
log.Fatal(err)
}
}

rn, pipelineID, err := getPipelineFromArgs(args, forMR)
Expand All @@ -65,7 +73,7 @@ var ciStatusCmd = &cobra.Command{
fmt.Fprintln(w, "Stage:\tName\t-\tStatus")
for {
// fetch all of the CI Jobs from the API
jobStructList, err = lab.CIJobs(pid, pipelineID, followBridge)
jobStructList, err = lab.CIJobs(pid, pipelineID, followBridge, bridgeName)
if err != nil {
log.Fatal(errors.Wrap(err, "failed to find ci jobs"))
}
Expand Down
14 changes: 11 additions & 3 deletions cmd/ci_trace.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ var ciTraceCmd = &cobra.Command{
Example: heredoc.Doc(`
lab ci trace upstream feature_branch
lab ci trace upstream 18 --merge-request
lab ci trace upstream 18:'my custom stage' --merge-request`),
lab ci trace upstream 18:'my custom stage' --merge-request
lab ci trace upstream 18:'my custom stage' --merge-request --bridge 'security-tests'`),
PersistentPreRun: labPersistentPreRun,
Run: func(cmd *cobra.Command, args []string) {
var (
Expand All @@ -54,9 +55,16 @@ var ciTraceCmd = &cobra.Command{
log.Fatal(err)
}

followBridge, err = cmd.Flags().GetBool("follow")
bridgeName, err = cmd.Flags().GetString("bridge")
if err != nil {
log.Fatal(err)
} else if bridgeName != "" {
followBridge = true
} else {
followBridge, err = cmd.Flags().GetBool("follow")
if err != nil {
log.Fatal(err)
}
}

rn, pipelineID, err := getPipelineFromArgs(branchArgs, forMR)
Expand Down Expand Up @@ -89,7 +97,7 @@ func doTrace(ctx context.Context, w io.Writer, pid interface{}, pipelineID int,
if ctx.Err() == context.Canceled {
break
}
trace, job, err := lab.CITrace(pid, pipelineID, name, followBridge)
trace, job, err := lab.CITrace(pid, pipelineID, name, followBridge, bridgeName)
if err != nil || job == nil || trace == nil {
return errors.Wrap(err, "failed to find job")
}
Expand Down
14 changes: 11 additions & 3 deletions cmd/ci_view.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ var ciViewCmd = &cobra.Command{
'c' to cancel job`),
Example: heredoc.Doc(`
lab ci view
lab ci view upstream --merge-request`),
lab ci view upstream --merge-request
lab ci view upstream --merge-request --bridge 'security-tests'`),
PersistentPreRun: labPersistentPreRun,
Run: func(cmd *cobra.Command, args []string) {
a := tview.NewApplication()
Expand All @@ -60,9 +61,16 @@ var ciViewCmd = &cobra.Command{
log.Fatal(err)
}

followBridge, err = cmd.Flags().GetBool("follow")
bridgeName, err = cmd.Flags().GetString("bridge")
if err != nil {
log.Fatal(err)
} else if bridgeName != "" {
followBridge = true
} else {
followBridge, err = cmd.Flags().GetBool("follow")
if err != nil {
log.Fatal(err)
}
}

rn, pipelineID, err = getPipelineFromArgs(args, forMR)
Expand Down Expand Up @@ -491,7 +499,7 @@ func updateJobs(app *tview.Application, jobsCh chan []*gitlab.Job) {
time.Sleep(time.Second * 1)
continue
}
jobStructList, err := lab.CIJobs(projectID, pipelineID, followBridge)
jobStructList, err := lab.CIJobs(projectID, pipelineID, followBridge, bridgeName)
if len(jobStructList) == 0 || err != nil {
app.Stop()
log.Fatal(errors.Wrap(err, "failed to find ci jobs"))
Expand Down
16 changes: 9 additions & 7 deletions internal/gitlab/gitlab.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import (

"github.com/pkg/errors"
gitlab "github.com/xanzy/go-gitlab"
"github.com/zaquestion/lab/internal/config"
"github.com/zaquestion/lab/internal/git"
"github.com/zaquestion/lab/internal/logger"
)
Expand Down Expand Up @@ -1224,7 +1223,7 @@ func GroupSearch(query string) (*gitlab.Group, error) {
// CIJobs returns a list of jobs in the pipeline with given id.
// This function by default doesn't follow bridge jobs.
// The jobs are returned sorted by their CreatedAt time
func CIJobs(pid interface{}, id int, followBridge bool) ([]JobStruct, error) {
func CIJobs(pid interface{}, id int, followBridge bool, bridgeName string) ([]JobStruct, error) {
opts := &gitlab.ListJobsOptions{
ListOptions: gitlab.ListOptions{
PerPage: maxItemsPerPage,
Expand Down Expand Up @@ -1270,6 +1269,10 @@ func CIJobs(pid interface{}, id int, followBridge bool) ([]JobStruct, error) {
}

for _, bridge := range bridgeList {
if bridgeName != "" && bridge.Name != bridgeName {
continue
}

// Unfortunately the GitLab API doesn't exposes the project ID nor name that the
// bridge job points to, since it might be extarnal to the config core.host
// hostname, hence the WebURL is exposed.
Expand All @@ -1278,7 +1281,6 @@ func CIJobs(pid interface{}, id int, followBridge bool) ([]JobStruct, error) {
// search for.
// WebURL format:
// <core.host>/<bridged-project-name-with-namespace>/-/pipelines/<id>
host := config.MainConfig.GetString("core.host")
projectName := strings.Replace(bridge.DownstreamPipeline.WebURL, host+"/", "", 1)
pipelineText := fmt.Sprintf("/-/pipelines/%d", bridge.DownstreamPipeline.ID)
projectName = strings.Replace(projectName, pipelineText, "", 1)
Expand Down Expand Up @@ -1324,8 +1326,8 @@ func CIJobs(pid interface{}, id int, followBridge bool) ([]JobStruct, error) {
// 1. Last Running Job
// 2. First Pending Job
// 3. Last Job in Pipeline
func CITrace(pid interface{}, id int, name string, followBridge bool) (io.Reader, *gitlab.Job, error) {
jobs, err := CIJobs(pid, id, followBridge)
func CITrace(pid interface{}, id int, name string, followBridge bool, bridgeName string) (io.Reader, *gitlab.Job, error) {
jobs, err := CIJobs(pid, id, followBridge, bridgeName)
if len(jobs) == 0 || err != nil {
return nil, nil, err
}
Expand Down Expand Up @@ -1372,8 +1374,8 @@ func CITrace(pid interface{}, id int, name string, followBridge bool) (io.Reader
// together with the upstream filename. If path is specified and refers to
// a single file within the artifacts archive, that file is returned instead.
// If no name is provided, the last job with an artifacts file is picked.
func CIArtifacts(pid interface{}, id int, name, path string, followBridge bool) (io.Reader, string, error) {
jobs, err := CIJobs(pid, id, followBridge)
func CIArtifacts(pid interface{}, id int, name, path string, followBridge bool, bridgeName string) (io.Reader, string, error) {
jobs, err := CIJobs(pid, id, followBridge, bridgeName)
if len(jobs) == 0 || err != nil {
return nil, "", err
}
Expand Down

0 comments on commit 867b3ce

Please sign in to comment.