github.com/matthewdale/lab@v0.14.0/cmd/ci_run.go (about)

     1  package cmd
     2  
     3  import (
     4  	"fmt"
     5  	"log"
     6  	"os"
     7  	"strings"
     8  
     9  	"github.com/pkg/errors"
    10  	"github.com/spf13/cobra"
    11  	gitlab "github.com/xanzy/go-gitlab"
    12  	"github.com/zaquestion/lab/internal/git"
    13  	lab "github.com/zaquestion/lab/internal/gitlab"
    14  )
    15  
    16  // ciCreateCmd represents the run command
    17  var ciCreateCmd = &cobra.Command{
    18  	Use:     "create [branch]",
    19  	Aliases: []string{"run"},
    20  	Short:   "Create a CI pipeline",
    21  	Long: `Run the CI pipeline for the given or current branch if none provided. This API uses your GitLab token to create CI pipelines
    22  
    23  Project will be inferred from branch if not provided
    24  
    25  Note: "lab ci create" differs from "lab ci trigger" which is a different API`,
    26  	Example: `lab ci create feature_branch
    27  lab ci create -p engineering/integration_tests master`,
    28  	Run: func(cmd *cobra.Command, args []string) {
    29  		pid, branch, err := getCIRunOptions(cmd, args)
    30  		if err != nil {
    31  			log.Fatal(err)
    32  		}
    33  		pipeline, err := lab.CICreate(pid, &gitlab.CreatePipelineOptions{Ref: &branch})
    34  		if err != nil {
    35  			log.Fatal(err)
    36  		}
    37  		project, err := lab.GetProject(pid)
    38  		if err != nil {
    39  			log.Fatal(err)
    40  		}
    41  		fmt.Printf("%s/pipelines/%d", project.WebURL, pipeline.ID)
    42  	},
    43  }
    44  
    45  var ciTriggerCmd = &cobra.Command{
    46  	Use:   "trigger [branch]",
    47  	Short: "Trigger a CI pipeline",
    48  	Long: `Runs a trigger for a CI pipeline on the given or current branch if none provided. This API supports vaiables and must be called with a trigger token or from within GitLab CI.
    49  
    50  Project will be inferred from branch if not provided
    51  
    52  Note: "lab ci trigger" differs from "lab ci create" which is a different API`,
    53  	Example: `lab ci trigger feature_branch
    54  lab ci trigger -p engineering/integration_tests master
    55  lab ci trigger -p engineering/integration_tests -v foo=bar master`,
    56  	Run: func(cmd *cobra.Command, args []string) {
    57  		pid, branch, err := getCIRunOptions(cmd, args)
    58  		if err != nil {
    59  			log.Fatal(err)
    60  		}
    61  		token, err := cmd.Flags().GetString("project")
    62  		if err != nil {
    63  			log.Fatal(err)
    64  		}
    65  		vars, err := cmd.Flags().GetStringSlice("variable")
    66  		if err != nil {
    67  			log.Fatal(err)
    68  		}
    69  		ciVars, err := parseCIVariables(vars)
    70  		if err != nil {
    71  			log.Fatal(err)
    72  		}
    73  		pipeline, err := lab.CITrigger(pid, gitlab.RunPipelineTriggerOptions{
    74  			Ref:       &branch,
    75  			Token:     &token,
    76  			Variables: ciVars,
    77  		})
    78  		if err != nil {
    79  			log.Fatal(err)
    80  		}
    81  		project, err := lab.GetProject(pid)
    82  		if err != nil {
    83  			log.Fatal(err)
    84  		}
    85  		fmt.Printf("%s/pipelines/%d", project.WebURL, pipeline.ID)
    86  	},
    87  }
    88  
    89  func getCIRunOptions(cmd *cobra.Command, args []string) (interface{}, string, error) {
    90  	branch, err := git.CurrentBranch()
    91  	if err != nil {
    92  		return nil, "", err
    93  	}
    94  	var pid interface{}
    95  	if len(args) > 0 {
    96  		branch = args[0]
    97  	}
    98  
    99  	remote := determineSourceRemote(branch)
   100  	rn, err := git.PathWithNameSpace(remote)
   101  	if err != nil {
   102  		return nil, "", err
   103  	}
   104  	pid = rn
   105  
   106  	project, err := cmd.Flags().GetString("project")
   107  	if err != nil {
   108  		return nil, "", err
   109  	}
   110  	if project != "" {
   111  		p, err := lab.FindProject(project)
   112  		if err != nil {
   113  			return nil, "", err
   114  		}
   115  		pid = p.ID
   116  	}
   117  	return pid, branch, nil
   118  }
   119  
   120  func parseCIVariables(vars []string) (map[string]string, error) {
   121  	variables := make(map[string]string)
   122  	for _, v := range vars {
   123  		parts := strings.SplitN(v, "=", 2)
   124  		if len(parts) < 2 {
   125  			return nil, errors.Errorf("Invalid Variable: \"%s\", Variables must be in the format key=value", v)
   126  		}
   127  		variables[parts[0]] = parts[1]
   128  
   129  	}
   130  	return variables, nil
   131  }
   132  
   133  func init() {
   134  	ciCreateCmd.Flags().StringP("project", "p", "", "Project to create pipeline on")
   135  	ciCmd.AddCommand(ciCreateCmd)
   136  
   137  	ciTriggerCmd.Flags().StringP("project", "p", "", "Project to run pipeline trigger on")
   138  	ciTriggerCmd.Flags().StringP("token", "t", os.Getenv("CI_JOB_TOKEN"), "Pipeline trigger token, optional if run within GitLabCI")
   139  	ciTriggerCmd.Flags().StringSliceP("variable", "v", []string{}, "Variables to pass to pipeline")
   140  
   141  	ciCmd.AddCommand(ciTriggerCmd)
   142  }