Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 22 additions & 10 deletions cmd/workflow/pause.go → cmd/workflow/disable.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,28 @@ import (
"github.com/spf13/cobra"
)

func NewPauseCmd(f *cmdutil.Factory) *cobra.Command {
func NewDisableCmd(f *cmdutil.Factory) *cobra.Command {
cmd := &cobra.Command{
Use: "pause <workflow-id>",
Short: "Pause a workflow",
Args: cobra.ExactArgs(1),
Example: ` # Pause a workflow (will prompt for confirmation)
kh wf pause abc123

# Pause without prompting
kh wf pause abc123 --yes`,
Use: "disable <workflow-id>",
// pause is the original name and stays working indefinitely; scripts
// and published links depend on it.
Aliases: []string{"pause"},
Short: "Disable a workflow so it stops running",
Long: `Disable a workflow so it stops running.

Turns off a workflow without deleting it. Runs already in flight are unaffected;
the trigger simply stops firing new ones.

See also: kh workflow enable`,
Args: cobra.ExactArgs(1),
Example: ` # Disable a workflow (will prompt for confirmation)
kh wf disable abc123

# Disable without prompting
kh wf disable abc123 --yes

# pause is an alias and still works
kh wf pause abc123`,
RunE: func(cmd *cobra.Command, args []string) error {
workflowID := args[0]

Expand Down Expand Up @@ -85,7 +97,7 @@ func NewPauseCmd(f *cmdutil.Factory) *cobra.Command {

p := output.NewPrinter(f.IOStreams, cmd)
return p.PrintData(result, func(tw table.Writer) {
fmt.Fprintf(f.IOStreams.Out, "Workflow %s paused\n", workflowID)
fmt.Fprintf(f.IOStreams.Out, "Workflow %s disabled\n", workflowID)
tw.Render()
})
},
Expand Down
18 changes: 9 additions & 9 deletions cmd/workflow/pause_test.go → cmd/workflow/disable_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ func TestPauseSendsPATCH(t *testing.T) {
assert.Equal(t, "PATCH", receivedMethod)
assert.Equal(t, "/api/workflows/wf-abc", receivedPath)
assert.Equal(t, false, receivedBody["enabled"])
assert.Contains(t, outBuf.String(), "paused")
assert.Contains(t, outBuf.String(), "disabled")
}

func TestPauseYesFlagSkipsConfirmation(t *testing.T) {
Expand Down Expand Up @@ -106,7 +106,7 @@ func TestPausePromptDeclineReturnsCancelError(t *testing.T) {

// In non-TTY mode, --yes is not required and confirmation is skipped (auto-proceed)
require.NoError(t, err)
assert.Contains(t, outBuf.String(), "paused")
assert.Contains(t, outBuf.String(), "disabled")
}

func TestPauseNonTTYAutoProceeds(t *testing.T) {
Expand Down Expand Up @@ -155,20 +155,20 @@ func TestPauseHasYesFlag(t *testing.T) {
ios, _, _, _ := iostreams.Test()
f := &cmdutil.Factory{AppVersion: "1.0.0", IOStreams: ios}
parent := workflow.NewWorkflowCmd(f)
var pauseCmd *cobra.Command
var disableCmd *cobra.Command
for _, c := range parent.Commands() {
if strings.HasPrefix(c.Use, "pause") {
pauseCmd = c
if strings.HasPrefix(c.Use, "disable") {
disableCmd = c
break
}
}
require.NotNil(t, pauseCmd, "pause command not found")
require.NotNil(t, disableCmd, "disable command not found")
// --yes is a persistent flag inherited from root; verify it's accessible
flag := pauseCmd.Flags().Lookup("yes")
flag := disableCmd.Flags().Lookup("yes")
if flag == nil {
flag = pauseCmd.InheritedFlags().Lookup("yes")
flag = disableCmd.InheritedFlags().Lookup("yes")
}
_ = flag
// The test just verifies pause command exists and is wired correctly
assert.NotNil(t, pauseCmd)
assert.NotNil(t, disableCmd)
}
33 changes: 22 additions & 11 deletions cmd/workflow/resume.go → cmd/workflow/enable.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,28 @@ import (
"github.com/spf13/cobra"
)

func NewResumeCmd(f *cmdutil.Factory) *cobra.Command {
func NewEnableCmd(f *cmdutil.Factory) *cobra.Command {
cmd := &cobra.Command{
Use: "resume <workflow-id>",
Aliases: []string{"activate"},
Short: "Resume a paused workflow",
Args: cobra.ExactArgs(1),
Example: ` # Resume a workflow (will prompt for confirmation)
kh wf resume abc123

# Resume without prompting
kh wf resume abc123 --yes`,
Use: "enable <workflow-id>",
// resume is the original name and stays working indefinitely; scripts
// and published links depend on it.
Aliases: []string{"resume", "activate"},
Short: "Enable a workflow so it runs on its trigger",
Long: `Enable a workflow so it runs on its trigger.

Turns on a workflow that is currently disabled. This is the last step after
creating one - a workflow does nothing until it is enabled.

See also: kh workflow disable`,
Args: cobra.ExactArgs(1),
Example: ` # Enable a workflow (will prompt for confirmation)
kh wf enable abc123

# Enable without prompting
kh wf enable abc123 --yes

# resume is an alias and still works
kh wf resume abc123`,
RunE: func(cmd *cobra.Command, args []string) error {
workflowID := args[0]

Expand Down Expand Up @@ -88,7 +99,7 @@ func NewResumeCmd(f *cmdutil.Factory) *cobra.Command {

p := output.NewPrinter(f.IOStreams, cmd)
return p.PrintData(result, func(tw table.Writer) {
fmt.Fprintf(f.IOStreams.Out, "Workflow %s resumed\n", workflowID)
fmt.Fprintf(f.IOStreams.Out, "Workflow %s enabled\n", workflowID)
tw.Render()
})
},
Expand Down
66 changes: 66 additions & 0 deletions cmd/workflow/enable_disable_aliases_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package workflow_test

// enable/disable are the primary names, but resume/pause were the originals and
// are kept working indefinitely - scripts, tutorials and published doc links
// depend on them. These tests pin that promise: each alias must reach the same
// command and send the same request body, so a future rename cannot quietly
// drop one.

import (
"testing"

"github.com/keeperhub/cli/cmd/workflow"
"github.com/keeperhub/cli/pkg/cmdutil"
"github.com/keeperhub/cli/pkg/iostreams"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

// findSubcommand returns the subcommand reachable by the given name or alias.
func findSubcommand(t *testing.T, name string) (string, bool) {
t.Helper()
ios, _, _, _ := iostreams.Test()
root := workflow.NewWorkflowCmd(&cmdutil.Factory{IOStreams: ios})
for _, c := range root.Commands() {
if c.Name() == name {
return c.Name(), true
}
for _, alias := range c.Aliases {
if alias == name {
return c.Name(), true
}
}
}
return "", false
}

func TestEnableIsReachableByItsAliases(t *testing.T) {
for _, name := range []string{"enable", "resume", "activate"} {
resolved, found := findSubcommand(t, name)
require.True(t, found, "%q should reach a subcommand", name)
assert.Equal(t, "enable", resolved, "%q should resolve to enable", name)
}
}

func TestDisableIsReachableByItsAliases(t *testing.T) {
for _, name := range []string{"disable", "pause"} {
resolved, found := findSubcommand(t, name)
require.True(t, found, "%q should reach a subcommand", name)
assert.Equal(t, "disable", resolved, "%q should resolve to disable", name)
}
}

func TestEnableAndDisableCrossReferenceEachOther(t *testing.T) {
// "enable" is the word people search for; someone who lands on one should
// be told about the other rather than having to guess the opposite verb.
ios, _, _, _ := iostreams.Test()
root := workflow.NewWorkflowCmd(&cmdutil.Factory{IOStreams: ios})

longByName := map[string]string{}
for _, c := range root.Commands() {
longByName[c.Name()] = c.Long
}

assert.Contains(t, longByName["enable"], "kh workflow disable")
assert.Contains(t, longByName["disable"], "kh workflow enable")
}
4 changes: 2 additions & 2 deletions cmd/workflow/resume_test.go → cmd/workflow/enable_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,9 @@ func TestResumeSendsPATCHWithEnabledTrue(t *testing.T) {
require.NoError(t, err)
assert.Equal(t, "PATCH", receivedMethod)
assert.Equal(t, "/api/workflows/wf-abc", receivedPath)
// The inverse of pause: this is the assertion that distinguishes the two.
// The inverse of disable: this is the assertion that distinguishes the two.
assert.Equal(t, true, receivedBody["enabled"])
assert.Contains(t, outBuf.String(), "resumed")
assert.Contains(t, outBuf.String(), "enabled")
}

func TestResumeYesFlagSkipsConfirmation(t *testing.T) {
Expand Down
4 changes: 2 additions & 2 deletions cmd/workflow/workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ func NewWorkflowCmd(f *cmdutil.Factory) *cobra.Command {
cmd.AddCommand(NewDeleteCmd(f))
cmd.AddCommand(NewUpdateCmd(f))
cmd.AddCommand(NewGoLiveCmd(f))
cmd.AddCommand(NewPauseCmd(f))
cmd.AddCommand(NewResumeCmd(f))
cmd.AddCommand(NewDisableCmd(f))
cmd.AddCommand(NewEnableCmd(f))

return cmd
}
2 changes: 1 addition & 1 deletion cmd/workflow/workflow_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func TestWorkflowCmdHas9Subcommands(t *testing.T) {
f := newTestFactory()
wfCmd := workflow.NewWorkflowCmd(f)
cmds := wfCmd.Commands()
assert.Equal(t, 9, len(cmds), "expected 9 subcommands: list, run, get, go-live, pause, resume, create, delete, update")
assert.Equal(t, 9, len(cmds), "expected 9 subcommands: list, run, get, go-live, disable, enable, create, delete, update")
}

func TestWorkflowCmdHasAlias(t *testing.T) {
Expand Down
4 changes: 2 additions & 2 deletions docs/kh_workflow.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ Manage workflows
* [kh](kh.md) - KeeperHub CLI
* [kh workflow create](kh_workflow_create.md) - Create a workflow
* [kh workflow delete](kh_workflow_delete.md) - Delete a workflow
* [kh workflow disable](kh_workflow_disable.md) - Disable a workflow so it stops running
* [kh workflow enable](kh_workflow_enable.md) - Enable a workflow so it runs on its trigger
* [kh workflow get](kh_workflow_get.md) - Get a workflow
* [kh workflow go-live](kh_workflow_go-live.md) - Publish a workflow
* [kh workflow list](kh_workflow_list.md) - List workflows
* [kh workflow pause](kh_workflow_pause.md) - Pause a workflow
* [kh workflow resume](kh_workflow_resume.md) - Resume a paused workflow
* [kh workflow run](kh_workflow_run.md) - Run a workflow
* [kh workflow update](kh_workflow_update.md) - Update a workflow

28 changes: 20 additions & 8 deletions docs/kh_workflow_pause.md → docs/kh_workflow_disable.md
Original file line number Diff line number Diff line change
@@ -1,25 +1,37 @@
## kh workflow pause
## kh workflow disable

Pause a workflow
Disable a workflow so it stops running

### Synopsis

Disable a workflow so it stops running.

Turns off a workflow without deleting it. Runs already in flight are unaffected;
the trigger simply stops firing new ones.

See also: kh workflow enable

```
kh workflow pause <workflow-id> [flags]
kh workflow disable <workflow-id> [flags]
```

### Examples

```
# Pause a workflow (will prompt for confirmation)
kh wf pause abc123
# Disable a workflow (will prompt for confirmation)
kh wf disable abc123

# Disable without prompting
kh wf disable abc123 --yes

# Pause without prompting
kh wf pause abc123 --yes
# pause is an alias and still works
kh wf pause abc123
```

### Options

```
-h, --help help for pause
-h, --help help for disable
-y, --yes Skip confirmation prompt
```

Expand Down
51 changes: 51 additions & 0 deletions docs/kh_workflow_enable.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
## kh workflow enable

Enable a workflow so it runs on its trigger

### Synopsis

Enable a workflow so it runs on its trigger.

Turns on a workflow that is currently disabled. This is the last step after
creating one - a workflow does nothing until it is enabled.

See also: kh workflow disable

```
kh workflow enable <workflow-id> [flags]
```

### Examples

```
# Enable a workflow (will prompt for confirmation)
kh wf enable abc123

# Enable without prompting
kh wf enable abc123 --yes

# resume is an alias and still works
kh wf resume abc123
```

### Options

```
-h, --help help for enable
-y, --yes Skip confirmation prompt
```

### Options inherited from parent commands

```
-H, --host string KeeperHub host (default: app.keeperhub.com)
--jq string Filter JSON output with a jq expression
--json Output as JSON
--no-color Disable color output
--org string Organization ID to use (overrides default from auth)
```

### SEE ALSO

* [kh workflow](kh_workflow.md) - Manage workflows

39 changes: 0 additions & 39 deletions docs/kh_workflow_resume.md

This file was deleted.

Loading