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