workflow

package module
v0.9.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 25, 2025 License: MIT Imports: 18 Imported by: 0

README

Introduction

Workflow provides a simple engine to sequentially run groups of shell tasks, while providing a websocket to monitor progress.

Workflows are defined using a yaml file which contains variables declaration and groups of tasks.

Tasks shell scripts can use functions like output and progress to publish meaningful information to the websocket.

Tasks can have an optional relative weight value so a progress expressed in percent is added in the status message.

Working with websocket

[TODO]

Refer to workflow_test.go for example of handling websockets

Example

This workflow declares a variable OS with the output of uname command, then it defines two groups of tasks, one for Linux and one for Darwin.

Groups are being skipped based on the content of OS

vars:
  OS: uname
groups:
  - id: linuxGroup
    skip_cmd: |
      [ "$OS" != "Linux" ]
    tasks:
      - id: task1
        weight: 50
        cmd: |
          output `ip a s eth0|grep inet`
  - id: darwinGroup
    skip_cmd: |
      [ "$OS" != "Darwin" ]
    tasks:
      - id: task1
        weight: 50
        cmd: |
          output `ifconfig en0|grep "inet "`

Documentation

Overview

Package workflow provides a simple engine to sequentially run groups of shell tasks, while providing a websocket to monitor progress.

Workflows are defined using a yaml file which contains variables declaration and groups of tasks.

Tasks shell scripts can use functions like `output` and `progress` to publish meaningful information to the websocket.

Tasks can have an optional relative `weight` value so a progress expressed in percent is added in the status message.

Example

This workflow declares a variable `OS` with the output of `uname` command, then it defines two groups of tasks, one for Linux and one for Darwin.

Groups are being skipped based on the content of `OS`

vars:
	OS: uname
groups:
  - id: linuxGroup
    skip_cmd: |
      [ "$OS" != "Linux" ]
    tasks:
      - id: task1
        weight: 50
        cmd: |
          output `ip a s eth0|grep inet`
  - id: darwinGroup
    skip_cmd: |
      [ "$OS" != "Darwin" ]
    tasks:
      - id: task1
        weight: 50
        cmd: |
          output `ifconfig en0|grep "inet "`

Index

Constants

This section is empty.

Variables

View Source
var (
	WorkflowErrorNoGroups    = fmt.Errorf("no group definitions found")
	WorkflowErrorInvalidVars = fmt.Errorf("invalid variables definition")

	WorkflowErrorGroupMissingId    = fmt.Errorf("group missing id")
	WorkflowErrorGroupMissingTasks = fmt.Errorf("group missing tasks")

	WorkflowErrorTaskMissingId      = fmt.Errorf("task missing id")
	WorkflowErrorTaskMissingCommand = fmt.Errorf("task missing cmd")

	WorkflowErrorNotFinished = fmt.Errorf("workflow not finished")
)

Errors definitions

Functions

This section is empty.

Types

type Group

type Group struct {
	Id    string  `json:"id"`
	Tasks []*Task `json:"tasks"`

	Skip        bool    `json:"skip"`
	Percent     float64 `json:"percent"`
	Started     bool    `json:"started"`
	Finished    bool    `json:"finished"`
	LastMessage string  `json:"lastMessage"`
	Error       string  `json:"error"`
	// contains filtered or unexported fields
}

func NewGroup

func NewGroup(y map[string]any) (*Group, error)

func (*Group) Progress

func (w *Group) Progress() (int, int)

type SkipCmd

type SkipCmd string

type Status

type Status struct {
	// Definition is a copy of the original workflow definition
	// For example, if you defined a multi step workflow and the original
	// definition file is changed, this will not be updated.
	Definition map[string]any `json:"definition"`

	// Vars contains all the values for variables defined in the workflow
	Vars map[string]string `json:"vars"`

	// Groups contains all the groups defined in the workflow, which in turn
	// contains all the tasks.
	Groups []*Group `json:"groups"`

	Started  bool `json:"started"`  // Workflow has been started
	Finished bool `json:"finished"` // Workflow has finished
	Percent  int  `json:"percent"`  // Workflow progress in percent, assuming all tasks have weights defined

	LastMessage string `json:"lastMessage"` // The last message returned by a task using `output`

	CurrentGroup string `json:"currentGroup"` // Currently running group
	CurrentTask  string `json:"currentTask"`  // Currently running task

	Error string `json:"error,omitempty"` // Last error
}

Status all the informations related to the workflow run.

type Task

type Task struct {
	Id     string `json:"id"`
	Cmd    string `json:"cmd"`
	Weight int    `json:"weight"`
	Exits  bool   `json:"exits"`

	Started  bool    `json:"started"`
	Finished bool    `json:"finished"`
	Percent  float64 `json:"percent"`
	Error    string  `json:"error"`

	Stdout io.ReadCloser `json:"-"`
	Stderr io.ReadCloser `json:"-"`
	Wfout  io.ReadCloser `json:"-"`
	// contains filtered or unexported fields
}

func NewTask

func NewTask(y map[string]any) (*Task, error)

func (*Task) Abort

func (t *Task) Abort() error

func (*Task) Run

func (t *Task) Run(ctx context.Context, cwd string) error

func (*Task) StderrPipe

func (t *Task) StderrPipe() (io.ReadCloser, error)

func (*Task) StdoutPipe

func (t *Task) StdoutPipe() (io.ReadCloser, error)

func (*Task) WfoutPipe

func (t *Task) WfoutPipe() (io.ReadCloser, error)

type Workflow

type Workflow struct {
	Status Status // Status of the current workflow

	sync.Mutex
	// contains filtered or unexported fields
}

func New

func New(definitionFilePath string, statusFilePath string) (*Workflow, http.Handler, error)

New returns a new Workflow with definition at definitionPath and status file to be written at statusFilePath as well as a http.HandlerFunc for handling websocket connections.

func (*Workflow) Abort

func (w *Workflow) Abort()

Abort kills current tasks and stops workflow execution

func (*Workflow) Clean

func (w *Workflow) Clean()

func (*Workflow) Continue

func (w *Workflow) Continue() error

Continue is used instead of [Start] when a status file already exists after a previous unfinished run. If the statufile does not exists, it will return a file not found error.

func (*Workflow) Percent

func (w *Workflow) Percent() float64

Percent returns the completion percentage between 0 and 100 of the workflow

func (*Workflow) Reset

func (w *Workflow) Reset() error

func (*Workflow) Start

func (w *Workflow) Start() error

Start starts the wworkflow execution and returns any error encountered

Directories

Path Synopsis
example
workflow-react command

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL