diff --git a/action/pipeline/exec.go b/action/pipeline/exec.go index ae91d641..2217408c 100644 --- a/action/pipeline/exec.go +++ b/action/pipeline/exec.go @@ -8,6 +8,7 @@ import ( "os" "os/signal" "path/filepath" + "slices" "strings" "syscall" @@ -16,6 +17,7 @@ import ( "github.com/go-vela/cli/version" api "github.com/go-vela/server/api/types" "github.com/go-vela/server/compiler" + "github.com/go-vela/server/compiler/types/pipeline" "github.com/go-vela/server/constants" "github.com/go-vela/worker/executor" "github.com/go-vela/worker/runtime" @@ -114,6 +116,20 @@ func (c *Config) Exec(client compiler.Engine) error { return err } + // create a slice for steps to be removed + stepsToRemove := c.SkipSteps + + // print and remove steps + if len(stepsToRemove) > 0 { + for _, stepName := range stepsToRemove { + logrus.Info("skipping step: ", stepName) + } + + if err := skipSteps(_pipeline, stepsToRemove); err != nil { + return err + } + } + // create current directory path for local mount mount := fmt.Sprintf("%s:%s:rw", base, constants.WorkspaceDefault) @@ -214,3 +230,48 @@ func (c *Config) Exec(client compiler.Engine) error { return nil } + +// skipSteps filters out steps to be removed from the pipeline. +func skipSteps(_pipeline *pipeline.Build, stepsToRemove []string) error { + // filter out steps to be removed + if len(_pipeline.Stages) > 0 { + // counter for total steps to run + totalSteps := 0 + + for i, stage := range _pipeline.Stages { + filteredStageSteps := stage.Steps[:0] + + for _, step := range stage.Steps { + if !slices.Contains(stepsToRemove, step.Name) { + filteredStageSteps = append(filteredStageSteps, step) + totalSteps++ + } + } + + _pipeline.Stages[i].Steps = filteredStageSteps + } + + // check if any steps are left to run, excluding "init" step + if totalSteps <= 1 { + return fmt.Errorf("no steps left to run after removing skipped steps") + } + } else { + // if not using stages + filteredSteps := _pipeline.Steps[:0] + + for _, step := range _pipeline.Steps { + if !slices.Contains(stepsToRemove, step.Name) { + filteredSteps = append(filteredSteps, step) + } + } + + _pipeline.Steps = filteredSteps + + // check if any steps are left to run, excluding "init" step + if len(_pipeline.Steps) <= 1 { + return fmt.Errorf("no steps left to run after removing skipped steps") + } + } + + return nil +} diff --git a/action/pipeline/pipeline.go b/action/pipeline/pipeline.go index 8eb6bad1..abe8ee4f 100644 --- a/action/pipeline/pipeline.go +++ b/action/pipeline/pipeline.go @@ -16,6 +16,7 @@ type Config struct { Target string Org string Repo string + SkipSteps []string Ref string File string FileChangeset []string diff --git a/command/pipeline/exec.go b/command/pipeline/exec.go index 8eeb0513..8651052b 100644 --- a/command/pipeline/exec.go +++ b/command/pipeline/exec.go @@ -134,6 +134,15 @@ var CommandExec = &cli.Command{ Value: constants.PipelineTypeYAML, }, + // Step Flags + + &cli.StringSliceFlag{ + EnvVars: []string{"VELA_SKIP_STEP", "SKIP_STEP"}, + Name: "skip-step", + Aliases: []string{"sk", "skip"}, + Usage: "skip a step in the pipeline", + }, + // Compiler Template Flags &cli.StringFlag{ @@ -151,7 +160,7 @@ var CommandExec = &cli.Command{ &cli.StringSliceFlag{ EnvVars: []string{"VELA_TEMPLATE_FILE", "PIPELINE_TEMPLATE_FILE"}, Name: "template-file", - Aliases: []string{"tf, tfs, template-files"}, + Aliases: []string{"tf", "tfs", "template-files"}, Usage: "enables using a local template file for expansion in the form :", }, &cli.IntFlag{ @@ -218,17 +227,21 @@ EXAMPLES: $ {{.HelpName}} --volume /tmp/bar.txt:/tmp/bar.txt:rw 7. Execute a local Vela pipeline with type of go $ {{.HelpName}} --pipeline-type go - 8. Execute a local Vela pipeline with local templates + 8. Execute a local Vela pipeline with specific step skipped + $ {{.HelpName}} --skip-step echo_hello --skip-step 'echo goodbye' + 9. Execute a local Vela pipeline with specific template step skipped + $ {{.HelpName}} --skip-step