@universal-packages/workflows v1.11.2
Workflows
Automate, customize, and execute your software development workflows right from your local machine.
Install
npm install @universal-packages/workflowsWorkflow
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
allowDescribedTargetsOnTestbooleandefault: falseBy 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.stepUsableLocationstringdefault: ./srcWhere all the step usable should be loaded from.variablesobjectA map of variables to be used across the workflow by interpolating them, for example:run: echo "Workflow variable: $<< variables.my-key >>"workflowsLocationstringdefault: ./Where all the workflows should be loaded from and in which auniversal-workflowsdirectory 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 deploySchema
namestringThe name of the workflow.environmentObjectThe environment variables that should be passed to all the routines and steps.maxConcurrentRoutinesnumberdefault: CPU cores count - 1The maximum number of routines that should be executed in parallel.targetstringThe target that should be used by all the routines and steps.targetsObjectTargets 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.enginestringRequiredThe name of the engine to be configuredengineOptionsObjectThe options to be passed to the engine.
workingDirectorystringThe working directory to be used by all the routines and steps.routinesObjectThe routines that should be executed independent and in parallel unless specified otherwise.<routineName>ObjectEvery key in the routines object is the routine name.strategyObjectA 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.matrixObject~RequiredDefine 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. Forfailthe workflow will stop the rest of the routines, forcontinuethe workflow will continue running the rest.includeObject~RequiredExpand 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: catwill 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 >>"
ifstringIf this evaluates totruethe routine will be executed if not it will be skipped.routines: example_if: if: $<< outputs.test-strategy.exists == 'true' >>dependsOnstring | 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: exampleenvironmentObjectThe 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. Forfailthe workflow will not run the dependent routines, forcontinuethe workflow will continue running the dependent routines.targetstringThe target that should be used by all the steps of the routine.unlessstringIf this evaluates tofalsethe routine will be executed if not it will be skipped.routines: example_unless: unless: $<< outputs.test-strategy.too_many == 'true' >>workingDirectorystringThe working directory to be used by all the steps of the routine.stepsArrayThe steps that should be executed.environmentObjectThe environment variables that should be used by the step over the routine and workflow environment.ifstringIf this evaluates totruethe step will be executed if not it will be skipped.inputstring | string[]Input to pass to the process. For example when a process requires any kind of input like a yes/no question.namestringThe step name, named steps can be used to access their outputs in other routines steps though theoutputsscope.onFailure'continue' | 'fail'default: 'fail'The action to be taken when the step fails. Forfailthe routine will fail right away, forcontinuethe routine will continue running the rest of the steps.runstringThe command to be run by the step.setVariableObjectSet a variable to be used in the workflow by evaluating the value string.namestringThe name of the variable.valuestringThe expression to be evaluated to set the variable. Here theoutputis accessible to get the output of just run step.
unlessstringIf this evaluates tofalsethe step will be executed if not it will be skipped.usestringThe name of the usable to be used by the step.targetstringThe 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-directoriesStatic 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
environmentObjectdefault: <Step environment>Environment variables to pass to the process.inputstring | string[]Input to pass to the process. For example when a process requires any kind of input like a yes/no question.workingDirectorystringdefault: <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.
License
11 months ago
11 months ago
11 months ago
11 months ago
11 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago