1package disable
2
3import (
4	"errors"
5	"fmt"
6	"net/http"
7
8	"github.com/cli/cli/v2/api"
9	"github.com/cli/cli/v2/internal/ghrepo"
10	"github.com/cli/cli/v2/pkg/cmd/workflow/shared"
11	"github.com/cli/cli/v2/pkg/cmdutil"
12	"github.com/cli/cli/v2/pkg/iostreams"
13	"github.com/spf13/cobra"
14)
15
16type DisableOptions struct {
17	HttpClient func() (*http.Client, error)
18	IO         *iostreams.IOStreams
19	BaseRepo   func() (ghrepo.Interface, error)
20
21	Selector string
22	Prompt   bool
23}
24
25func NewCmdDisable(f *cmdutil.Factory, runF func(*DisableOptions) error) *cobra.Command {
26	opts := &DisableOptions{
27		IO:         f.IOStreams,
28		HttpClient: f.HttpClient,
29	}
30
31	cmd := &cobra.Command{
32		Use:   "disable [<workflow-id> | <workflow-name>]",
33		Short: "Disable a workflow",
34		Long:  "Disable a workflow, preventing it from running or showing up when listing workflows.",
35		Args:  cobra.MaximumNArgs(1),
36		RunE: func(cmd *cobra.Command, args []string) error {
37			// support `-R, --repo` override
38			opts.BaseRepo = f.BaseRepo
39
40			if len(args) > 0 {
41				opts.Selector = args[0]
42			} else if !opts.IO.CanPrompt() {
43				return cmdutil.FlagErrorf("workflow ID or name required when not running interactively")
44			} else {
45				opts.Prompt = true
46			}
47
48			if runF != nil {
49				return runF(opts)
50			}
51			return runDisable(opts)
52		},
53	}
54
55	return cmd
56}
57
58func runDisable(opts *DisableOptions) error {
59	c, err := opts.HttpClient()
60	if err != nil {
61		return fmt.Errorf("could not build http client: %w", err)
62	}
63	client := api.NewClientFromHTTP(c)
64
65	repo, err := opts.BaseRepo()
66	if err != nil {
67		return fmt.Errorf("could not determine base repo: %w", err)
68	}
69
70	states := []shared.WorkflowState{shared.Active}
71	workflow, err := shared.ResolveWorkflow(
72		opts.IO, client, repo, opts.Prompt, opts.Selector, states)
73	if err != nil {
74		var fae shared.FilteredAllError
75		if errors.As(err, &fae) {
76			return errors.New("there are no enabled workflows to disable")
77		}
78		return err
79	}
80
81	path := fmt.Sprintf("repos/%s/actions/workflows/%d/disable", ghrepo.FullName(repo), workflow.ID)
82	err = client.REST(repo.RepoHost(), "PUT", path, nil, nil)
83	if err != nil {
84		return fmt.Errorf("failed to disable workflow: %w", err)
85	}
86
87	if opts.IO.CanPrompt() {
88		cs := opts.IO.ColorScheme()
89		fmt.Fprintf(opts.IO.Out, "%s Disabled %s\n", cs.SuccessIconWithColor(cs.Red), cs.Bold(workflow.Name))
90	}
91
92	return nil
93}
94