npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@universal-packages/workflows

v1.11.2

Published

Workflows automation tool

Downloads

66,296

Readme

Workflows

npm version Testing codecov

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 to true.

  • 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 a universal-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 configured
    • engineOptions 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. For fail the workflow will stop the rest of the routines, for continue 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 to true 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. For fail the workflow will not run the dependent routines, for continue 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 to false 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 to true 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 the outputs scope.

        • onFailure 'continue' | 'fail' default: 'fail' The action to be taken when the step fails. For fail the routine will fail right away, for continue 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 the output is accessible to get the output of just run step.
        • unless string If this evaluates to false 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.

License

MIT licensed.