@universal-packages/workflows
v1.10.5
Published
Workflows automation tool
Downloads
51,774
Readme
Workflows
Automate, customize, and execute your software development workflows right from your local machine.
Install
npm install @universal-packages/workflows
Workflow
The Workflow
class is the main class of this library. For the sake of simplicity, you will likely never need to instantiate one in a manual way. Instead, you will use the factory static method Workflow.buildFrom
that uses universal-plugin-config-loader
to load workflow descriptors inside the universal-workflows
directory.
Static methods
buildFrom(name: string, [options?: Object])
Creates a new Workflow
instance from a workflow descriptor loaded form the universal-workflows
directory.
import { Workflow } from '@universal-packages/workflows'
const workflow = Workflow.buildFrom('test-and-deploy')
await workflow.run()
Options
allowDescribedTargetsOnTest
boolean
default: false
By default workflows use the test target to run commands in a test environment, but if you want to use the described targets in the workflow descriptor you can set this option totrue
.stepUsableLocation
string
default: ./src
Where all the step usable should be loaded from.variables
object
A map of variables to be used across the workflow by interpolating them, for example:run: echo "Workflow variable: $<< variables.my-key >>"
workflowsLocation
string
default: ./
Where all the workflows should be loaded from and in which auniversal-workflows
directory or file should be found. Take a look at universal-plugin-config-loader to learn how we load workflow files. Workflows can even be loaded from a the package.json file.
Workflows descriptors
The workflow descriptor is a YAML file that describes the routines and steps that should be executed. The file should be located in the universal-workflows
directory.
name: test-and-deploy
routines:
test:
steps:
- run: npm run test:coverage
deploy:
steps:
- run: npm run build
- run: npm run deploy
Schema
name
string
The name of the workflow.environment
Object
The environment variables that should be passed to all the routines and steps.maxConcurrentRoutines
number
default: CPU cores count - 1
The maximum number of routines that should be executed in parallel.target
string
The target that should be used by all the routines and steps.targets
Object
Targets to be prepared to use in the routines and steps, A Target basically describes an engine to be passed to the sub process run system see universal-sub-process to learn more about engines. Engines should be installed in the project for the workflow to find them and configure them.engine
string
Required
The name of the engine to be configuredengineOptions
Object
The options to be passed to the engine.
workingDirectory
string
The working directory to be used by all the routines and steps.routines
Object
The routines that should be executed independent and in parallel unless specified otherwise.<routineName>
Object
Every key in the routines object is the routine name.strategy
Object
A strategy to be used to run multiple routine configurations based in the same routine, a matrix or an include should be specified. This works similar to what Github Actions does with matrix strategies.matrix
Object
~Required
Define one or more variables followed by an array of values. For example, the following matrix has a variable called version with the value [10, 12, 14] and a variable called os with the value [ubuntu-latest, windows-latest]:routines: example_matrix: strategy: matrix: version: [10, 12, 14] os: [ubuntu-latest, windows-latest]
An strategy will run for each possible combination of the variables. In this example, the workflow will run six jobs, one for each combination of the os and version variables.
onFailure
'continue' | 'fail'
default: 'fail'
The action to be taken when one of the strategy routines fails. Forfail
the workflow will stop the rest of the routines, forcontinue
the workflow will continue running the rest.include
Object
~Required
Expand existing matrix configurations or to add new configurations. The value of include is a list of objects.For example, this matrix:
strategy: matrix: fruit: [apple, pear] animal: [cat, dog] include: - color: green - color: pink animal: cat - fruit: apple shape: circle - fruit: banana - fruit: banana animal: cat
will result in six routines with the following matrix combinations:
{fruit: apple, animal: cat, color: pink, shape: circle}
{fruit: apple, animal: dog, color: green, shape: circle}
{fruit: pear, animal: cat, color: pink}
{fruit: pear, animal: dog, color: green}
{fruit: banana}
{fruit: banana, animal: cat}
You can access the strategy values in the steps interpolating strategy values within the step.
steps: - run: echo "The fruit is $<< strategy.fruit >>"
if
string
If this evaluates totrue
the routine will be executed if not it will be skipped.routines: example_if: if: $<< outputs.test-strategy.exists == 'true' >>
dependsOn
string | string[]
The routine will only run after and if the specified routine(s) completed successfully or was skipped.routines: example: steps: - run: echo "Hello, world!" example_depends_on: dependsOn: example
environment
Object
The environment variables that should be passed to the steps of the routine.onFailure
'continue' | 'fail'
default: 'fail'
The action to be taken when the routine fails. Forfail
the workflow will not run the dependent routines, forcontinue
the workflow will continue running the dependent routines.target
string
The target that should be used by all the steps of the routine.unless
string
If this evaluates tofalse
the routine will be executed if not it will be skipped.routines: example_unless: unless: $<< outputs.test-strategy.too_many == 'true' >>
workingDirectory
string
The working directory to be used by all the steps of the routine.steps
Array
The steps that should be executed.environment
Object
The environment variables that should be used by the step over the routine and workflow environment.if
string
If this evaluates totrue
the step will be executed if not it will be skipped.input
string | string[]
Input to pass to the process. For example when a process requires any kind of input like a yes/no question.name
string
The step name, named steps can be used to access their outputs in other routines steps though theoutputs
scope.onFailure
'continue' | 'fail'
default: 'fail'
The action to be taken when the step fails. Forfail
the routine will fail right away, forcontinue
the routine will continue running the rest of the steps.run
string
The command to be run by the step.setVariable
Object
Set a variable to be used in the workflow by evaluating the value string.name
string
The name of the variable.value
string
The expression to be evaluated to set the variable. Here theoutput
is accessible to get the output of just run step.
unless
string
If this evaluates tofalse
the step will be executed if not it will be skipped.use
string
The name of the usable to be used by the step.target
string
The target that should be used by the step.
Workflow
will emit events regarding execution status and output.
workflow.on('*', (event) => console.log(event))
workflow.on('running', (event) => console.log(event))
workflow.on('success', (event) => console.log(event))
workflow.on('failure', (event) => console.log(event))
workflow.on('stopping', (event) => console.log(event))
workflow.on('stopped', (event) => console.log(event))
workflow.on('error', (event) => console.log(event))
workflow.on('end', (event) => console.log(event))
workflow.on('routine:running', (event) => console.log(event))
workflow.on('routine:skipped', (event) => console.log(event))
workflow.on('routine:success', (event) => console.log(event))
workflow.on('routine:failure', (event) => console.log(event))
workflow.on('routine:stopping', (event) => console.log(event))
workflow.on('routine:stopped', (event) => console.log(event))
workflow.on('routine:error', (event) => console.log(event))
workflow.on('step:running', (event) => console.log(event))
workflow.on('step:skipped', (event) => console.log(event))
workflow.on('step:success', (event) => console.log(event))
workflow.on('step:failure', (event) => console.log(event))
workflow.on('step:stopping', (event) => console.log(event))
workflow.on('step:stopped', (event) => console.log(event))
workflow.on('step:error', (event) => console.log(event))
workflow.on('step:output', (event) => console.log(event))
BaseUsable
Normally you will run commands in a step by specifying the run
property, but some times you may want to encapsulate a more complex logic in a reusable way and then specify the usable
property to run it.
import { BaseUsable } from '@universal-packages/workflows'
export default class PrepareDirectories extends BaseUsable {
static name = 'prepare-directories'
async use() {
const files = await this.runSubProcess('ls')
if (files.includes('dist')) {
await this.runSubProcess('rm -rf dist')
}
await this.runSubProcess('mkdir dist')
this.pushOutput('Directories are ready')
}
}
Then in you workflow descriptor you can specify the usable
property.
name: test-and-deploy
steps:
- use: prepare-directories
Static properties
name
string
The name of the usable that will be used in the workflow descriptor.
Instance methods
use()
async
This is the what the step will do when it is executed.
runSubProcess(command: string, [options?: Object])
async
Runs a command in a sub process and return the stdout as a string.
Options
environment
Object
default: <Step environment>
Environment variables to pass to the process.input
string | string[]
Input to pass to the process. For example when a process requires any kind of input like a yes/no question.workingDirectory
string
default: <Step workingDirectory>
The working directory to run the command in.
pushOutput(output: string)
Pushes an output to the step output.
fail([error: Error])
Fails the step with an optional error.
internalStop()
async
If the step has received a stop signal, it will try to stop the step by calling this method. You should try to stop the step as soon as possible.
Instance properties
environment
Object
The environment variables passed by the workflow system to the step.
scope
Object
The scope object that contain useful information about the workflow, like outputs
from other named steps or the strategy
values.
with
Object
The variables described in the with
part of the step in the workflow descriptor.
workingDirectory
string
The working directory where the step should run.
Typescript
This library is developed in TypeScript and shipped fully typed.
Contributing
The development of this library happens in the open on GitHub, and we are grateful to the community for contributing bugfixes and improvements. Read below to learn how you can take part in improving this library.