Skip to main content

Tasks

Tasks are commands that are ran in the context of a project. Underneath the hood, a task is simply an npm binary or a system command that is ran as a child process. Tasks are processed in a parallel thread pool within moon's orchestration layer.

Names

A task name (or identifier) is a unique resource for locating a task within a project. The name is explicitly configured as a key within the tasks setting, and can be written in camel/kebab/snake case. Names support a-z, A-Z, 0-9, _, -, /, and must start with a character.

A task name can be paired with a project name to create a target.

Types

Tasks are categorized into 1 of the following types based on their configured parameters.

  • Build - Task generates one or many artifacts, and is derived from the outputs setting.
  • Run - Task runs a one-off, long-running, or never-ending process, and is derived from the local or runInCI settings.
  • Test - Task asserts code is correct and behaves as expected. This includes linting, typechecking, unit tests, and any other form of testing.

Configuration

Tasks can be configured per project through moon.yml, or for all projects through .moon/project.yml.

Inheritance

Unlike other build systems that require the same tasks to be repeatedly defined for every project, moon uses an inheritance model where tasks are defined once at the top-level, and are then inherited by all projects.

Top-level tasks (also known as global tasks) are defined in .moon/project.yml, and are inherited by default. However, projects are able to include, exclude, or rename inherited tasks using the workspace.inheritedTasks in moon.yml.

Merge strategies

When a global task and local task of the same name exist, they are merged into a single task. To accomplish this, one of many merge strategies can be used.

Merging is applied to the parameters args, deps, env, inputs, and outputs, using the mergeArgs, mergeDeps, mergeEnv, mergeInputs and mergeOutputs options respectively. Each of these options support one of the following strategy values.

  • append (default) - Values found in the local task are merged after the values found in the global task. For example, this strategy is useful for toggling flag arguments.
  • prepend - Values found in the local task are merged before the values found in the global task. For example, this strategy is useful for applying option arguments that must come before positional arguments.
  • replace - Values found in the local task entirely replaces the values in the global task. This strategy is useful when you need full control.

All 3 of these strategies are demonstrated below, with a somewhat contrived example, but you get the point.

# Global
tasks:
build:
command:
- 'webpack'
- '--mode'
- 'production'
- '--color'
deps:
- 'designSystem:build'
inputs:
- '/webpack.config.js'
outputs:
- 'build/'

# Local
tasks:
build:
args: '--no-color --no-stats'
deps:
- 'reactHooks:build'
inputs:
- 'webpack.config.js'
options:
mergeArgs: 'append'
mergeDeps: 'prepend'
mergeInputs: 'replace'

# Merged result
tasks:
build:
command:
- 'webpack'
- '--mode'
- 'production'
- '--color'
- '--no-color'
- '--no-stats'
deps:
- 'reactHooks:build'
- 'designSystem:build'
inputs:
- 'webpack.config.js'
outputs:
- 'build/'
options:
mergeArgs: 'append'
mergeDeps: 'prepend'
mergeInputs: 'replace'