Merge branch 'fix/7462' into 'main'

fix: ci trigger does interactively ask for job (#7462)

Closes #7462

See merge request https://gitlab.com/gitlab-org/cli/-/merge_requests/1411

Merged-by: Shekhar Patnaik <spatnaik@gitlab.com>
Approved-by: Shekhar Patnaik <spatnaik@gitlab.com>
Approved-by: Jaime Martinez <jmartinez@gitlab.com>
Reviewed-by: Jaime Martinez <jmartinez@gitlab.com>
Co-authored-by: Andreas Weber <weber.andreas@gmail.com>
This commit is contained in:
Shekhar Patnaik 2024-02-16 19:44:20 +00:00
commit 3003a14f49
4 changed files with 76 additions and 50 deletions

View File

@ -209,21 +209,30 @@ func getJobIdInteractive(inputs *JobInputs, opts *JobOptions) (int, error) {
var selectedJob string
for _, job := range jobs {
jobOptions = append(jobOptions, fmt.Sprintf("%s (%d) - %s", job.Name, job.ID, job.Status))
if inputs.SelectionPredicate == nil || inputs.SelectionPredicate(job) {
jobOptions = append(jobOptions, fmt.Sprintf("%s (%d) - %s", job.Name, job.ID, job.Status))
}
}
messagePrompt := inputs.SelectionPrompt
if messagePrompt == "" {
messagePrompt = "Select pipeline job to trace:"
}
promptOpts := &survey.Select{
Message: "Select pipeline job to trace:",
Message: messagePrompt,
Options: jobOptions,
}
if len(jobOptions) > 0 {
err = prompt.AskOne(promptOpts, &selectedJob)
if err != nil {
if errors.Is(err, terminal.InterruptErr) {
return 0, nil
err = prompt.AskOne(promptOpts, &selectedJob)
if err != nil {
if errors.Is(err, terminal.InterruptErr) {
return 0, nil
}
return 0, err
}
return 0, err
}
if selectedJob != "" {
@ -231,43 +240,45 @@ func getJobIdInteractive(inputs *JobInputs, opts *JobOptions) (int, error) {
m := re.FindAllStringSubmatch(selectedJob, -1)
return utils.StringToInt(m[0][1]), nil
} else if len(jobs) > 0 {
return jobs[0].ID, nil
} else {
pipeline, err := api.GetPipeline(opts.ApiClient, pipelineId, nil, opts.Repo.FullName())
if err != nil {
return 0, err
}
// use commit statuses to show external jobs
cs, err := api.GetCommitStatuses(opts.ApiClient, opts.Repo.FullName(), pipeline.SHA)
if err != nil {
return 0, nil
}
c := opts.IO.Color()
fmt.Fprint(opts.IO.StdOut, "Getting external jobs...")
for _, status := range cs {
var s string
switch status.Status {
case "success":
s = c.Green(status.Status)
case "error":
s = c.Red(status.Status)
default:
s = c.Gray(status.Status)
}
fmt.Fprintf(opts.IO.StdOut, "(%s) %s\nURL: %s\n\n", s, c.Bold(status.Name), c.Gray(status.TargetURL))
}
return 0, nil
}
pipeline, err := api.GetPipeline(opts.ApiClient, pipelineId, nil, opts.Repo.FullName())
if err != nil {
return 0, err
}
// use commit statuses to show external jobs
cs, err := api.GetCommitStatuses(opts.ApiClient, opts.Repo.FullName(), pipeline.SHA)
if err != nil {
return 0, nil
}
c := opts.IO.Color()
fmt.Fprint(opts.IO.StdOut, "Getting external jobs...\n")
for _, status := range cs {
var s string
switch status.Status {
case "success":
s = c.Green(status.Status)
case "error":
s = c.Red(status.Status)
default:
s = c.Gray(status.Status)
}
fmt.Fprintf(opts.IO.StdOut, "(%s) %s\nURL: %s\n\n", s, c.Bold(status.Name), c.Gray(status.TargetURL))
}
return 0, nil
}
type JobInputs struct {
JobName string
Branch string
PipelineId int
JobName string
Branch string
PipelineId int
SelectionPrompt string
SelectionPredicate func(s *gitlab.Job) bool
}
type JobOptions struct {
@ -282,6 +293,9 @@ func TraceJob(inputs *JobInputs, opts *JobOptions) error {
fmt.Fprintln(opts.IO.StdErr, "invalid job ID:", inputs.JobName)
return err
}
if jobID == 0 {
return nil
}
fmt.Fprintln(opts.IO.StdOut)
return runTrace(context.Background(), opts.ApiClient, opts.IO.StdOut, opts.Repo.FullName(), jobID)
}

View File

@ -164,7 +164,7 @@ func TestGetJobId(t *testing.T) {
name: "when getJobId with pipelineId is requested, ask for job and give no answer",
jobName: "",
pipelineId: 123,
expectedOut: 1122,
expectedOut: 0,
askOneStubs: []string{""},
httpMocks: []httpMock{
{

View File

@ -47,9 +47,10 @@ func NewCmdRetry(f *cmdutils.Factory) *cobra.Command {
pipelineId, _ := cmd.Flags().GetInt("pipeline-id")
jobID, err := ciutils.GetJobId(&ciutils.JobInputs{
JobName: jobName,
Branch: branch,
PipelineId: pipelineId,
JobName: jobName,
Branch: branch,
PipelineId: pipelineId,
SelectionPrompt: "Select pipeline job to retry:",
}, &ciutils.JobOptions{
ApiClient: apiClient,
IO: f.IO,
@ -60,6 +61,10 @@ func NewCmdRetry(f *cmdutils.Factory) *cobra.Command {
return err
}
if jobID == 0 {
return nil
}
job, err := api.RetryPipelineJob(apiClient, jobID, repo.FullName())
if err != nil {
return cmdutils.WrapError(err, fmt.Sprintf("Could not retry job with ID: %d", jobID))

View File

@ -9,6 +9,7 @@ import (
"github.com/MakeNowJust/heredoc"
"github.com/spf13/cobra"
"github.com/xanzy/go-gitlab"
)
func NewCmdTrigger(f *cmdutils.Factory) *cobra.Command {
@ -27,7 +28,6 @@ func NewCmdTrigger(f *cmdutils.Factory) *cobra.Command {
# Trigger manual job with name lint
`),
Long: ``,
Args: cobra.ExactArgs(1),
RunE: func(cmd *cobra.Command, args []string) error {
var err error
@ -46,21 +46,28 @@ func NewCmdTrigger(f *cmdutils.Factory) *cobra.Command {
}
branch, _ := cmd.Flags().GetString("branch")
pipelineId, _ := cmd.Flags().GetInt("pipeline-id")
jobID, err := ciutils.GetJobId(&ciutils.JobInputs{
JobName: jobName,
Branch: branch,
PipelineId: pipelineId,
JobName: jobName,
Branch: branch,
PipelineId: pipelineId,
SelectionPrompt: "Select pipeline job to trigger:",
SelectionPredicate: func(s *gitlab.Job) bool {
return s.Status == "manual"
},
}, &ciutils.JobOptions{
ApiClient: apiClient,
IO: f.IO,
Repo: repo,
})
if err != nil {
fmt.Fprintln(f.IO.StdErr, "invalid job ID:", args[0])
fmt.Fprintln(f.IO.StdErr, "invalid job ID:", jobName)
return err
}
if jobID == 0 {
return nil
}
job, err := api.PlayPipelineJob(apiClient, jobID, repo.FullName())
if err != nil {
return cmdutils.WrapError(err, fmt.Sprintf("Could not trigger job with ID: %d", jobID))