Back to Moon

moon

website/docs/config/project.mdx

2.2.453.3 KB
Original Source

import HeadingApiLink from '@site/src/components/Docs/HeadingApiLink'; import RequiredLabel from '@site/src/components/Docs/RequiredLabel'; import VersionLabel from '@site/src/components/Docs/VersionLabel';

The moon.* configuration file is not required but can be used to define additional metadata for a project, override inherited tasks, and more at the project-level. When used, this file must exist in a project's root, as configured in projects.

dependsOn

<HeadingApiLink to="/api/types/interface/ProjectConfig#dependsOn" />

Explicitly defines other projects that this project depends on, primarily when generating the project and task graphs. The most common use case for this is building those projects before building this one. When defined, this setting requires an array of project names, which are the keys found in the projects map.

yaml
dependsOn:
  - 'apiClients'
  - 'designSystem'

A dependency object can also be defined, where a specific scope can be assigned, which accepts "production" (default), "development", "build", or "peer".

yaml
dependsOn:
  - id: 'apiClients'
    scope: 'production'
  - id: 'designSystem'
    scope: 'peer'

Learn more about implicit and explicit dependencies.

Metadata

id<VersionLabel version="1.18.0" />

<HeadingApiLink to="/api/types/interface/ProjectConfig#id" />

Overrides the name (identifier) of the project, which was configured in or derived from the projects setting in .moon/workspace.*. This setting is useful when using glob based project location, and want to avoid using the folder name as the project name.

yaml
id: 'custom-id'

:::info

All references to the project must use the new identifier, including project and task dependencies.

:::

language

<HeadingApiLink to="/api/types/interface/ProjectConfig#language" />

The primary programming language the project is written in. This setting is required for task inheritance, editor extensions, and more. Supports the following values:

  • bash - A Bash based project (Unix only).
  • batch - A Batch/PowerShell based project (Windows only).
  • go - A Go based project.
  • javascript - A JavaScript based project.
  • php - A PHP based project.
  • python - A Python based project.
  • ruby - A Ruby based project.
  • rust - A Rust based project.
  • typescript - A TypeScript based project.
  • unknown (default) - When not configured or inferred.
  • * - A custom language. Values will be converted to kebab-case.
yaml
language: 'javascript'

# Custom
language: 'kotlin'

For convenience, when this setting is not defined, moon will attempt to detect the language based on configuration files found in the project root. This only applies to non-custom languages!

owners<VersionLabel version="1.8.0" />

<HeadingApiLink to="/api/types/interface/ProjectConfig#owners" />

Defines ownership of source code within the current project, by mapping file system paths to owners. An owner is either a user, team, or group.

Currently supports GitHub, GitLab, and Bitbucket (via app).

customGroups<RequiredLabel text="Bitbucket" />

<HeadingApiLink to="/api/types/interface/OwnersConfig#customGroups" />

When using the Code Owners for Bitbucket app, this setting provides a way to define custom groups that will be injected at the top of the CODEOWNERS file. These groups must be unique across all projects.

yaml
owners:
  customGroups:
    '@@@backend': ['@"user name"', '@@team']

defaultOwner

<HeadingApiLink to="/api/types/interface/OwnersConfig#defaultOwner" />

The default owner for all paths. This setting is optional in some cases but helps to avoid unnecessary repetition.

yaml
owners:
  defaultOwner: '@frontend'

optional<RequiredLabel text="GitLab" />

<HeadingApiLink to="/api/types/interface/OwnersConfig#optional" />

For GitLab, marks the project's code owners section as optional. Defaults to false.

yaml
owners:
  optional: true

paths

<HeadingApiLink to="/api/types/interface/OwnersConfig#paths" />

The primary setting for defining ownership of source code within the current project. This setting supports 2 formats, the first being a list of file paths relative from the current project. This format requires defaultOwner to be defined, and only supports 1 owner for every path (the default owner).

yaml
owners:
  defaultOwner: '@frontend'
  paths:
    - '**/*.ts'
    - '**/*.tsx'
    - '*.config.js'

The second format provides far more granularity, allowing for multiple owners per path. This format requires a map, where the key is a file path relative from the current project, and the value is a list of owners. Paths with an empty list of owners will fallback to defaultOwner.

yaml
owners:
  defaultOwner: '@frontend'
  paths:
    '**/*.rs': ['@backend']
    '**/*.js': []
    '*.config.js': ['@frontend', '@frontend-infra']

The syntax for owners is dependent on the provider you are using for version control (GitHub, GitLab, Bitbucket). moon provides no validation or guarantees that these are correct.

requiredApprovals<RequiredLabel text="Bitbucket / GitLab" />

<HeadingApiLink to="/api/types/interface/OwnersConfig#requiredApprovals" />

Requires a specific number of approvals for a pull/merge request to be satisfied. Defaults to 1.

yaml
owners:
  requiredApprovals: 2

layer

<HeadingApiLink to="/api/types/interface/ProjectConfig#layer" />

The layer within a stack. Supports the following values:

  • application - An application of any kind.
  • automation - An automated testing suite, like E2E, integration, or visual tests. <VersionLabel version="1.16.0" />
  • configuration - Configuration files or infrastructure. <VersionLabel version="1.22.0" />
  • library - A self-contained, shareable, and publishable set of code.
  • scaffolding - Templates or generators for scaffolding. <VersionLabel version="1.22.0" />
  • tool - An internal tool, CLI, one-off script, etc.
  • unknown (default) - When not configured.
yaml
layer: 'application'

:::info

The project layer is used in task inheritance, constraints and boundaries, editor extensions, and more!

:::

project

<HeadingApiLink to="/api/types/interface/ProjectConfig#project" />

The project setting defines metadata about the project itself.

yaml
project:
  title: 'moon'
  description: 'A monorepo management tool.'
  channel: '#moon'
  owner: 'infra.platform'
  maintainers: ['miles.johnson']

The information listed within project is purely informational and primarily displayed within the CLI. However, this setting exists for you, your team, and your company, as a means to identify and organize all projects. Feel free to build your own tooling around these settings!

channel

<HeadingApiLink to="/api/types/interface/ProjectMetadataConfig#channel" />

The Slack, Discord, Teams, IRC, etc channel name (with leading #) in which to discuss the project.

description<RequiredLabel />

<HeadingApiLink to="/api/types/interface/ProjectMetadataConfig#description" />

A description of what the project does and aims to achieve. Be as descriptive as possible, as this is the kind of information search engines would index on.

maintainers

<HeadingApiLink to="/api/types/interface/ProjectMetadataConfig#maintainers" />

A list of people/developers that maintain the project, review code changes, and can provide support. Can be a name, email, LDAP name, GitHub username, etc, the choice is yours.

title

<HeadingApiLink to="/api/types/interface/ProjectMetadataConfig#name" />

A human readable name of the project. This is different from the unique project name configured in projects.

owner

<HeadingApiLink to="/api/types/interface/ProjectMetadataConfig#owner" />

The team or organization that owns the project. Can be a title, LDAP name, GitHub team, etc. We suggest not listing people/developers as the owner, use maintainers instead.

Custom fields<VersionLabel version="2.0.0" />

<HeadingApiLink to="/api/types/interface/ProjectMetadataConfig#metadata" />

Additional fields can be configured as custom metadata to associate to this project. Supports all value types that are valid JSON.

yaml
project:
  # ...
  deprecated: true

stack<VersionLabel version="1.22.0" />

<HeadingApiLink to="/api/types/interface/ProjectConfig#stack" />

The technology stack this project belongs to, primarily for categorization. Supports the following values:

  • backend - Server-side APIs, etc.
  • data - Data sources, database layers, etc. <VersionLabel version="2.0.0" />
  • frontend - Client-side user interfaces, etc.
  • infrastructure - Cloud/server infrastructure, Docker, etc.
  • systems - Low-level systems programming.
  • unknown (default) - When not configured.
yaml
stack: 'frontend'

:::info

The project stack is also used in constraints and boundaries!

:::

tags

<HeadingApiLink to="/api/types/interface/ProjectConfig#tags" />

Tags are a simple mechanism for categorizing projects. They can be used to group projects together for easier querying, enforcing of project boundaries and constraints, task inheritance, and more.

yaml
tags:
  - 'react'
  - 'prisma'

Integrations

docker<VersionLabel version="1.27.0" />

<HeadingApiLink to="/api/types/interface/ProjectConfig#docker" />

Configures Docker integration for the current project.

file

<HeadingApiLink to="/api/types/interface/ProjectDockerConfig#file" />

Configures the Dockerfile generation process when moon docker file is executed.

buildTask

<HeadingApiLink to="/api/types/interface/ProjectDockerFileConfig#buildTask" />

The name of a task within the current project that will be used for building the project before running it. If not defined, does nothing.

yaml
docker:
  file:
    buildTask: 'build'

image

<HeadingApiLink to="/api/types/interface/ProjectDockerFileConfig#image" />

The Docker image to use in the base stage. Defaults to an image based on the first detected toolchain.

yaml
docker:
  file:
    image: 'node:latest'

runPrune<VersionLabel version="2.0.0" />

<HeadingApiLink to="/api/types/interface/ProjectDockerFileConfig#runPrune" />

Run the moon docker prune command after building the project, but before starting it. Defaults to true.

yaml
docker:
  file:
    runPrune: false

runSetup<VersionLabel version="2.0.0" />

<HeadingApiLink to="/api/types/interface/ProjectDockerFileConfig#runSetup" />

Run the moon docker setup command after scaffolding, but before building the project. Defaults to true.

yaml
docker:
  file:
    runSetup: false

startTask

<HeadingApiLink to="/api/types/interface/ProjectDockerFileConfig#startTask" />

The name of a task within the current project that will run the project after it has been built (if required). This task will be used as CMD within the Dockerfile.

yaml
docker:
  file:
    startTask: 'start'

template<VersionLabel version="2.0.0" />

<HeadingApiLink to="/api/types/interface/ProjectDockerFileConfig#template" />

A custom template file, relative from the workspace root, to use when rendering the Dockerfile. Powered by Tera.

yaml
docker:
  file:
    template: 'templates/Dockerfile.tera'

scaffold

<HeadingApiLink to="/api/types/interface/ProjectDockerConfig#scaffold" />

Configures aspects of the Docker scaffolding process when moon docker scaffold is executed. Only applies to the sources skeleton.

configsPhaseGlobs

<HeadingApiLink to="/api/types/interface/ProjectDockerScaffoldConfig#configsPhaseGlobs" />

List of globs in which to copy project-relative files into the .moon/docker/configs skeleton. When not defined, defaults to **/*. Applies to both project and workspace level scaffolding.

yaml
docker:
  scaffold:
    configsPhaseGlobs:
      - '*.json'

sourcesPhaseGlobs

<HeadingApiLink to="/api/types/interface/ProjectDockerScaffoldConfig#sourcesPhaseGlobs" />

List of globs in which to copy project-relative files into the .moon/docker/sources skeleton. When not defined, defaults to **/*. Applies to both project and workspace level scaffolding.

yaml
docker:
  scaffold:
    sourcesPhaseGlobs:
      - 'src/**/*'

Tasks

env

<HeadingApiLink to="/api/types/interface/ProjectConfig#env" />

The env field is map of strings that are passed as environment variables to all tasks within the current project. Project-level variables will not override task-level variables of the same name.

yaml
env:
  NODE_ENV: 'production'

View the task env setting for more usage examples and information.

fileGroups

<HeadingApiLink to="/api/types/interface/ProjectConfig#fileGroups" />

Defines file groups to be used by local tasks. By default, this setting is not required for the following reasons:

  • File groups are an optional feature, and are designed for advanced use cases.
  • File groups defined in .moon/tasks/**/* will be inherited by all projects.

When defined this setting requires a map, where the key is the file group name, and the value is a list of globs or file paths, or environment variables. Globs and paths are relative to a project (even when defined globally).

yaml
# Example groups
fileGroups:
  configs:
    - '*.config.{js,cjs,mjs}'
    - '*.json'
  sources:
    - 'src/**/*'
    - 'types/**/*'
  tests:
    - 'tests/**/*'
    - '**/__tests__/**/*'
  assets:
    - 'assets/**/*'
    - 'images/**/*'
    - 'static/**/*'
    - '**/*.{scss,css}'

Once your groups have been defined, you can reference them within args, inputs, outputs, and more, using token functions and variables.

yaml
tasks:
  build:
    command: 'vite build'
    inputs:
      - '@group(configs)'
      - '@group(sources)'

tasks

<HeadingApiLink to="/api/types/interface/ProjectConfig#tasks" />

Tasks are actions that are ran within the context of a project, and commonly wrap an npm binary or system command. This setting requires a map, where the key is a unique name for the task, and the value is an object of task parameters.

yaml
tasks:
  format:
    command: 'prettier'
  lint:
    command: 'eslint'
  test:
    command: 'jest'
  typecheck:
    command: 'tsc'

extends<VersionLabel version="1.12.0" />

<HeadingApiLink to="/api/types/interface/TaskConfig#extends" />

The extends field can be used to extend the settings from a sibling task within the same project, or inherited from the global scope. This is useful for composing similar tasks with different arguments or options.

When extending another task, the same merge strategies used for inheritance are applied.

yaml
tasks:
  lint:
    command: 'eslint .'
    inputs:
      - 'src/**/*'

  lint-fix:
    extends: 'lint'
    args: '--fix'
    preset: 'utility'

description<VersionLabel version="1.22.0" />

<HeadingApiLink to="/api/types/interface/TaskConfig#description" />

A human-readable description of what the task does. This information is displayed within the moon project and moon task commands.

yaml
tasks:
  build:
    description: 'Builds the project using Vite'
    command: 'vite build'

command

<HeadingApiLink to="/api/types/interface/TaskConfig#command" />

The command field is a single command to execute for the task, including the command binary/name (must be first) and any optional arguments. This field supports task inheritance and merging of arguments.

This setting can be defined using a string, or an array of strings. We suggest using arrays when dealing with many args, or the args string cannot be parsed easily.

yaml
tasks:
  format:
    # Using a string
    command: 'prettier --check .'
    # Using an array
    command:
      - 'prettier'
      - '--check'
      - '.'

:::info

If you need to support pipes, redirects, or multiple commands, use script instead. Learn more about commands vs scripts.

:::

args

<HeadingApiLink to="/api/types/interface/TaskConfig#args" />

The args field is a collection of additional arguments to append to the command when executing the task. This field exists purely to provide arguments for inherited tasks.

This setting can be defined using a string, or an array of strings. We suggest using arrays when dealing with many args, or the args string cannot be parsed easily.

yaml
tasks:
  test:
    command: 'jest'
    # Using a string
    args: '--color --maxWorkers 3'
    # Using an array
    args:
      - '--color'
      - '--maxWorkers'
      - '3'

However, for the array approach to work correctly, each argument must be its own distinct item, including argument values. For example:

yaml
tasks:
  test:
    command: 'jest'
    args:
      # Valid
      - '--maxWorkers'
      - '3'
      # Also valid
      - '--maxWorkers=3'
      # Invalid
      - '--maxWorkers 3'

deps

<HeadingApiLink to="/api/types/interface/TaskConfig#deps" />

The deps field is a list of other tasks (known as targets), either within this project or found in another project, that will be executed before this task. It achieves this by generating a directed task graph based on the project graph.

yaml
tasks:
  build:
    command: 'webpack'
    deps:
      - 'apiClients:build'
      - 'designSystem:build'
      # A task within the current project
      - 'codegen'

Args & env

Furthermore, for each dependency target, you can configure additional command line arguments and environment variables that'll be passed to the dependent task when it is ran. The args field supports a list of strings, while env is an object of key-value pairs.

yaml
tasks:
  build:
    command: 'webpack'
    deps:
      - target: 'apiClients:build'
        args: ['--env', 'production']
        env:
          NODE_ENV: 'production'

Dependencies of inherited tasks will be excluded and renamed according to the workspace.inheritedTasks setting. This process only uses filters from the current project, and not filters from dependent projects. Furthermore, args and env are not deeply merged.

Optional

By default, all dependencies are required to exist when tasks are being built and expanded, but this isn't always true when dealing with composition and inheritance. For dependencies that may not exist based on what's inherited, you can mark it as optional.

yaml
tasks:
  build:
    command: 'webpack'
    deps:
      - target: 'apiClients:build'
        optional: true

env

<HeadingApiLink to="/api/types/interface/TaskConfig#env" />

The env field is map of strings that are passed as environment variables when running the command. Variables defined here will take precedence over those loaded with envFile.

yaml
tasks:
  build:
    command: 'webpack'
    env:
      NODE_ENV: 'production'

Variables also support substitution using the syntax ${VAR_NAME}. When using substitution, only variables in the current process can be referenced, and not those currently defined in env.

yaml
tasks:
  build:
    command: 'webpack'
    env:
      APP_TARGET: '${REGION}-${ENVIRONMENT}'

inputs

<HeadingApiLink to="/api/types/interface/TaskConfig#inputs" />

The inputs field is a list of sources that calculate whether to execute this task based on the environment and files that have been touched since the last time the task has been ran. If not defined or inherited, then all files within a project are considered an input (**/*), excluding root-level tasks.

Inputs support the following source types:

yaml
tasks:
  lint:
    command: 'eslint'
    inputs:
      # Config files anywhere within the project
      - '**/.eslintignore'
      - '**/.eslintrc.js'
      # Config files at the workspace root
      - '/.eslintignore'
      - '/.eslintrc.js'
      # Tokens
      - '$projectRoot'
      - '@group(sources)'

Environment variables

Environment variables can be used as inputs and must start with a $. Wildcard variables can use * to match any character.

yaml
tasks:
  example:
    inputs:
      - '$FOO_CACHE'
      - '$FOO_*'

:::caution

When using an environment variable, we assume it's not defined by default, and will trigger an affected state when it is defined. If the environment variable always exists, then the task will always run and bypass the cache.

:::

File paths

File paths support project and workspace relative file/folder patterns. They can be defined as a literal path, or a file:// URI <VersionLabel inline version="1.39.0" />, or as an object with a file property <VersionLabel inline version="1.39.0" />. Additionally, the following parameters are supported as a URI query or as object fields:

  • content, match, matches (string) - When determining affected state, will match against the file's content using the defined regex pattern, instead of relying on file existence.
  • optional (boolean) - When hashing and set to true and the file is missing, will not log a warning. When set to false and the file is missing, will fail with an error. Defaults to logging a warning.
yaml
tasks:
  example:
    inputs:
      # Literal paths
      - 'project/relative/file.js'
      - '/workspace/relative/file.js'
      # Using file protocol
      - 'file://project/relative/file.js?optional'
      - 'file:///workspace/relative/file.js?content=a|b|c'
      # Using an object
      - file: 'project/relative/file.js'
        optional: true
      - file: '/workspace/relative/file.js'
        content: 'a|b|c'

File groups<VersionLabel version="1.41.0" />

A file group input will reference the defined files/globs within from a file group in the current project. It can be defined with a group:// URI, or as an object with a group property. Additionally, the following parameters are supported as a URI query or as object fields:

  • format, as (string) - The format in which to gather the file group results. Supported values are static (default), files, dirs, globs, envs, and root.
yaml
fileGroups:
  sources:
    - 'src/**/*'

tasks:
  build:
    # ...
    inputs:
      # Using group protocol
      - 'group://sources?format=dirs'
      # Using an object
      - group: 'sources'
        format: 'dirs'

Glob patterns

Glob patterns support project and workspace relative file/folder patterns. They can be defined as a literal path, or a glob:// URI <VersionLabel inline version="1.39.0" />, or as an object with a glob property <VersionLabel inline version="1.39.0" />. Additionally, the following parameters are supported as a URI query or as object fields:

  • cache (boolean) - When gathering inputs for hashing, defines whether the glob results should be cached for the duration of the moon process. Defaults to true.
yaml
tasks:
  example:
    inputs:
      # Literal paths
      - 'project/relative/file.*'
      - '/workspace/relative/**/*'
      # Using glob protocol
      - 'glob://project/relative/file.*?cache=false'
      - 'glob:///workspace/relative/**/*?cache'
      # Using an object
      - glob: 'project/relative/file.*'
        cache: false
      - glob: '/workspace/relative/**/*'

Globs can also be negated by prefixing the path with !, which will exclude all files that match the glob.

yaml
tasks:
  example:
    inputs:
      - '!**/*.md'
      - 'glob://!/workspace/relative/**/*'
      - glob: '!/workspace/relative/**/*'

:::warning

Glob patterns that contain ?, for example *.tsx?, cannot be used in URI format, as it conflicts with the query string syntax. Use the path or object format instead.

:::

:::danger

Be aware that files that match the glob, but are ignored via .gitignore (or similar), will not be considered an input. To work around this, use explicit file inputs.

:::

External projects<VersionLabel version="1.41.0" />

Tasks can also depend on files and globs from other projects within the same workspace. This is useful for handling cross-project relationships without needing to define explicit task dependencies.

External projects can be defined as a project:// URI, or as an object with a project property, both of which require a project identifier, or ^ for all dependent projects. Additionally, the following parameters are supported as a URI query or as object fields:

  • group, fileGroup (id) - The name of a file group within the external project in which file and glob patterns will be used for matching. Takes precedence over filter.
  • filter (string[]) - A list of project relative glob patterns that will be used for matching.

If neither group nor filter are defined, all files within the external project are considered a match (**/*).

yaml
tasks:
  example:
    inputs:
      # Using project protocol
      - 'project://foo'
      - 'project://bar?group=sources'
      - 'project://baz?filter=src/**/*'
      # Using an object
      - project: 'foo'
      - project: 'bar'
        group: 'sources'
      - project: 'baz'
        filter: ['src/**/*']

outputs

<HeadingApiLink to="/api/types/interface/TaskConfig#outputs" />

The outputs field is a list of files and folders that are created as a result of executing this task, typically from a build or compilation related task. Outputs are necessary for incremental caching and hydration. If you'd prefer to avoid that functionality, omit this field.

File paths

File paths support project and workspace relative file/folder patterns. They can be defined as a literal path, or a file:// URI <VersionLabel inline version="1.41.0" />, or as an object with a file property <VersionLabel inline version="1.41.0" />. Additionally, the following parameters are supported as a URI query or as object fields:

  • optional (boolean) - When archiving and set to true and the file is missing, will not fail with a missing output error. Defaults to false.
yaml
tasks:
  example:
    inputs:
      # Literal paths
      - 'build/'
      # Using file protocol
      - 'file://build/'
      # Using an object
      - file: 'build/'
        optional: true

Glob patterns

Glob patterns support project and workspace relative file/folder patterns. They can be defined as a literal path, or a glob:// URI <VersionLabel inline version="1.41.0" />, or as an object with a glob property <VersionLabel inline version="1.41.0" />. Additionally, the following parameters are supported as a URI query or as object fields:

  • optional (boolean) - When archiving and set to true and the glob produced no results, will not fail with a missing output error. Defaults to false.
yaml
tasks:
  example:
    inputs:
      # Literal paths
      - 'build/**/*.js'
      - '!build/internal.js'
      # Using glob protocol
      - 'glob://build/**/*.js'
      # Using an object
      - glob: 'build/**/*.js'

:::warning

Glob patterns that contain ?, for example *.tsx?, cannot be used in URI format, as it conflicts with the query string syntax. Use the path or object format instead.

:::

:::danger

When using globs and moon hydrates an output (a cache hit), all files not matching the glob will be deleted. Ensure that all files critical for the build to function correctly are included.

:::

preset<VersionLabel version="1.28.0" />

<HeadingApiLink to="/api/types/interface/TaskConfig#preset" />

Applies the chosen preset to the task. A preset defines a collection of task options that will be inherited as the default, and can then be overridden within the task itself. The following presets are available:

Tasks named "dev", "start", or "serve" are marked as server automatically.

yaml
tasks:
  dev:
    command: 'webpack server'
    preset: 'server'

script<VersionLabel version="1.27.0" />

<HeadingApiLink to="/api/types/interface/TaskConfig#script" />

The script field is one or many commands to execute for the task, with support for pipes, redirects, and more. This field does not support task inheritance merging, and can only be defined with a string.

If defined, will supersede command and args.

yaml
tasks:
  exec:
    # Single command
    script: 'cp ./in ./out'
    # Multiple commands
    script: 'rm -rf ./out && cp ./in ./out'
    # Pipes
    script: 'ps aux | grep 3000'
    # Redirects
    script: './gen.sh > out.json'

:::info

If you need to support merging during task inheritance, use command instead. Learn more about commands vs scripts.

:::

toolchains<VersionLabel version="1.31.0" />

<HeadingApiLink to="/api/types/interface/TaskConfig#toolchain" />

The toolchain field defines additional toolchain(s) the command runs on, where to locate its executable, and more. By default, moon will set to a value based on the project's language, default toolchains.default, or via detection.

yaml
tasks:
  env:
    command: 'printenv'
    toolchains: 'system'

This setting also supports multiple values.

yaml
tasks:
  build:
    command: 'npm run build'
    toolchains: ['javascript', 'node', 'npm']

options

<HeadingApiLink to="/api/types/interface/TaskConfig#options" />

The options field is an object of configurable options that can be used to modify the task and its execution. The following fields can be provided, with merge related fields supporting all merge strategies.

yaml
tasks:
  typecheck:
    command: 'tsc --noEmit'
    options:
      mergeArgs: 'replace'
      runFromWorkspaceRoot: true

affectedFiles

<HeadingApiLink to="/api/types/interface/TaskOptionsConfig#affectedFiles" />

When enabled and the --affected option is provided, all affected files that match this task's inputs will be passed as relative file paths as command line arguments, and as a MOON_AFFECTED_FILES environment variable.

If there are no affected files, . (current directory) will be passed instead for arguments, and an empty value for the environment variable. This functionality can be changed with the affectedPassInputs setting.

yaml
tasks:
  lint:
    command: 'eslint'
    options:
      affectedFiles: true
      # Only pass args
      affectedFiles: 'args'
      # Only set env var
      affectedFiles: 'env'

:::caution

When using this option, ensure that explicit files or . are not present in the args list. Furthermore, this functionality will only work if the task's command supports an arbitrary list of files being passed as arguments.

:::

This setting also supports an object format with additional parameters. The pass field is required, which accepts a value described above.

yaml
tasks:
  lint:
    command: 'eslint'
    options:
      affectedFiles:
        pass: 'args'

The following additional parameters are supported:

  • filter (boolean) <VersionLabel version="2.1.0" /> - A list of glob patterns to filter the affected files list before passing to the task. Globs must start with ** to match against absolute paths.
  • ignoreProjectBoundary (boolean) <VersionLabel version="2.1.0" /> - When matching affected files, ignore the project boundary and include workspace relative files. Otherwise, only files within the project are matched. Defaults to false.
  • passDotWhenNoResults (boolean) <VersionLabel version="2.1.0" /> - When no affected files are found, will pass . instead of an empty or no value. Defaults to true.
  • passInputsWhenNoMatch (boolean) - When no affected files are found, will pass all configured inputs as relative file paths instead. Defaults to false.

allowFailure<VersionLabel version="1.13.0" />

<HeadingApiLink to="/api/types/interface/TaskOptionsConfig#allowFailure" />

Allows a task to fail without failing the entire pipeline. When enabled, the following changes occur:

  • Other tasks cannot depend on this task, as we can't ensure it's side-effect free.
  • For moon run, the process will not bail early and will run to completion.
  • For moon ci, the process will not exit with a non-zero exit code, if the only failing tasks are allowed to fail.
yaml
tasks:
  lint:
    command: 'eslint'
    options:
      allowFailure: true

cache

<HeadingApiLink to="/api/types/interface/TaskOptionsConfig#cache" />

Whether to cache the task's execution result using our smart hashing system. If disabled, will not create a cache hash, and will not persist a task's outputs. Supports the following values:

  • true (default) - Cache the task's output.
  • false - Do not cache the task's output.
  • local - Only cache locally. <VersionLabel version="1.40.0" />
  • remote - Only cache remotely. <VersionLabel version="1.40.0" />

We suggest disabling caching when defining cleanup tasks, one-off scripts, or file system heavy operations.

yaml
tasks:
  clean:
    command: 'rm -rf ./temp'
    options:
      cache: false

cacheKey<VersionLabel version="1.35.0" />

<HeadingApiLink to="/api/types/interface/TaskOptionsConfig#cacheKey" />

A custom key to include in the cache and task hashing process. Can be used to invalidate local and remote caches.

yaml
tasks:
  build:
    command: 'some-costly-build'
    options:
      cacheKey: 'v1'

cacheLifetime<VersionLabel version="1.29.0" />

<HeadingApiLink to="/api/types/interface/TaskOptionsConfig#cacheLifetime" />

The lifetime in which a cached task will live before being marked as stale and re-running. This applies to a task even if it does not produce outputs.

The lifetime can be configured in a human-readable string format, for example, 1 day, 3 hr, 1m, etc. If the lifetime is not defined, the cache will live forever, or until the task inputs are touched.

yaml
tasks:
  build:
    command: 'some-costly-build'
    options:
      cacheLifetime: '1 day'

String formats are powered by the humantime crate.

envFile

<HeadingApiLink to="/api/types/interface/TaskOptionsConfig#envFile" />

A boolean or path to a .env file (also know as dotenv file) that defines a collection of environment variables for the current task. Variables will be loaded on project creation, but will not override those defined in env.

Variables defined in the file support value substitution/expansion by wrapping the variable name in curly brackets, such as ${VAR_NAME}.

yaml
tasks:
  build:
    command: 'webpack'
    options:
      # Defaults to .env
      envFile: true
      # Or
      envFile: '.env.production'
      # Or from the workspace root
      envFile: '/.env.shared'

When set to true, moon will load the following files in order, with later files taking precedence over earlier ones:

  • /.env
  • /.env.local
  • .env
  • .env.local
  • .env.<task_id>
  • .env.<task_id>.local

Additionally, a list of file paths can also be provided. When using a list, the order of the files is important, as environment variables from all files will be aggregated into a single map, with subsequent files taking precedence over previous ones. Once aggregated, the variables will be passed to the task, but will not override those defined in env.

yaml
tasks:
  build:
    command: 'webpack'
    options:
      envFile:
        - '.env'
        - '.env.production'

inferInputs<VersionLabel version="1.31.0" />

<HeadingApiLink to="/api/types/interface/TaskOptionsConfig#inferInputs" />

Automatically infer inputs based on the following parameters configured within the task's command, script, args, or env. Defaults to false.

yaml
tasks:
  build:
    # ...
    options:
      inferInputs: false

internal<VersionLabel version="1.23.0" />

<HeadingApiLink to="/api/types/interface/TaskOptionsConfig#internal" />

Marks the task as internal only. Internal tasks can not be explicitly ran on the command line, but can be depended on by other tasks.

yaml
tasks:
  prepare:
    # ...
    options:
      internal: true

interactive<VersionLabel version="1.12.0" />

<HeadingApiLink to="/api/types/interface/TaskOptionsConfig#interactive" />

Marks the task as interactive. Interactive tasks run in isolation so that they can interact with stdin.

This setting also disables caching, turns of CI, and other functionality, similar to the preset setting.

yaml
tasks:
  init:
    # ...
    options:
      interactive: true

merge<VersionLabel version="1.29.0" />

<HeadingApiLink to="/api/types/interface/TaskOptionsConfig#merge" />

The strategy to use when merging args, deps, env, inputs, and outputs with an inherited task. This option can be overridden with the field specific merge options below.

mergeArgs

<HeadingApiLink to="/api/types/interface/TaskOptionsConfig#mergeArgs" />

The strategy to use when merging the args list with an inherited task. Defaults to "append".

mergeDeps

<HeadingApiLink to="/api/types/interface/TaskOptionsConfig#mergeDeps" />

The strategy to use when merging the deps list with an inherited task. Defaults to "append".

mergeEnv

<HeadingApiLink to="/api/types/interface/TaskOptionsConfig#mergeEnv" />

The strategy to use when merging the env map with an inherited task. Defaults to "append".

mergeInputs

<HeadingApiLink to="/api/types/interface/TaskOptionsConfig#mergeInputs" />

The strategy to use when merging the inputs list with an inherited task. Defaults to "append".

mergeOutputs

<HeadingApiLink to="/api/types/interface/TaskOptionsConfig#mergeOutputs" />

The strategy to use when merging the outputs list with an inherited task. Defaults to "append".

mergeToolchains

<HeadingApiLink to="/api/types/interface/TaskOptionsConfig#mergeToolchains" />

The strategy to use when merging the toolchains list with an inherited task. Defaults to "append".

mutex<VersionLabel version="1.24.0" />

<HeadingApiLink to="/api/types/interface/TaskOptionsConfig#mutex" />

Creates an exclusive lock on a "virtual resource", preventing other tasks using the same "virtual resource" from running concurrently.

If you have many tasks that require exclusive access to a resource that can't be tracked by moon (like a database, an ignored file, a file that's not part of the project, or a remote resource) you can use the mutex option to prevent them from running at the same time.

yaml
tasks:
  a:
    # ...
    options:
      mutex: 'virtual_resource_name'

  # b doesn't necessarily have to be in the same project
  b:
    # ...
    options:
      mutex: 'virtual_resource_name'

os<VersionLabel version="1.28.0" />

<HeadingApiLink to="/api/types/interface/TaskOptionsConfig#os" />

When defined, the task will only run on the configured operating system. For other operating systems, the task becomes a no-operation. Supports the values linux, macos, and windows.

Can be defined as a single value, or a list of values.

yaml
tasks:
  build-unix:
    # ...
    options:
      os: ['linux', 'macos']

  build-windows:
    # ...
    options:
      os: 'windows'

outputStyle

<HeadingApiLink to="/api/types/interface/TaskOptionsConfig#outputStyle" />

Controls how stdout/stderr is displayed when the task is ran as a transitive target. By default, this setting is not defined and defers to the action pipeline, but can be overridden with one of the following values:

  • buffer - Buffers output and displays after the task has exited (either success or failure).
  • buffer-only-failure - Like buffer, but only displays on failures.
  • hash - Ignores output and only displays the generated hash.
  • none - Ignores output.
  • stream - Streams output directly to the terminal. Will prefix each line of output with the target.
yaml
tasks:
  test:
    # ...
    options:
      outputStyle: 'stream'

persistent<VersionLabel version="1.6.0" />

<HeadingApiLink to="/api/types/interface/TaskOptionsConfig#persistent" />

Marks the task as persistent (continuously running). Persistent tasks are handled differently than non-persistent tasks in the action graph. When running a target, all persistent tasks are ran last and in parallel, after all their dependencies have completed.

This is extremely useful for running a server (or a watcher) in the background while other tasks are running.

yaml
tasks:
  dev:
    # ...
    options:
      persistent: true

We suggest using the preset setting instead, which enables this setting, amongst other useful settings.

priority<VersionLabel version="1.35.0" />

<HeadingApiLink to="/api/types/interface/TaskOptionsConfig#priority" />

The priority level determines the position of the task within the action pipeline queue. A task with a higher priority will run sooner rather than later, while still respecting the topological order. Supports the following levels:

  • critical
  • high
  • normal (default)
  • low
yaml
tasks:
  build:
    # ...
    options:
      priority: 'high'

retryCount

<HeadingApiLink to="/api/types/interface/TaskOptionsConfig#retryCount" />

The number of attempts the task will retry execution before returning a failure. This is especially useful for flaky tasks. Defaults to 0.

yaml
tasks:
  test:
    # ...
    options:
      retryCount: 3

runDepsInParallel

<HeadingApiLink to="/api/types/interface/TaskOptionsConfig#runDepsInParallel" />

Whether to run the task's direct deps in parallel or serial (in order). Defaults to true.

When disabled, this does not run dependencies of dependencies in serial, only direct dependencies.

yaml
tasks:
  start:
    # ...
    deps:
      - '~:clean'
      - '~:build'
    options:
      runDepsInParallel: false

runInCI

<HeadingApiLink to="/api/types/interface/TaskOptionsConfig#runInCI" />

Whether to run the task automatically in a CI (continuous integration) environment when affected by changed files using the moon ci command. Supports the following values:

  • always - Always run in CI, regardless if affected or not. <VersionLabel version="1.31.0" />
  • affected, true (default) - Only run in CI if affected by changed files.
  • false - Never run in CI.
  • only - Only run in CI, and not locally, if affected by changed files. <VersionLabel version="1.41.0" />
  • skip - Skip running in CI but run locally and allow task relationships to be valid. <VersionLabel version="1.41.0" />
yaml
tasks:
  build:
    # ...
    options:
      runInCI: false

runInSyncPhase<VersionLabel version="2.1.0" />

<HeadingApiLink to="/api/types/interface/TaskOptionsConfig#runInSyncPhase" />

Whether to run the task automatically during moon sync. Defaults to false.

yaml
tasks:
  generate-schema:
    # ...
    options:
      runInSyncPhase: true

runFromWorkspaceRoot

<HeadingApiLink to="/api/types/interface/TaskOptionsConfig#runFromWorkspaceRoot" />

Whether to use the workspace root as the working directory when executing a task. Defaults to false and runs from the task's project root.

yaml
tasks:
  typecheck:
    # ...
    options:
      runFromWorkspaceRoot: true

shell

<HeadingApiLink to="/api/types/interface/TaskOptionsConfig#shell" />

Whether to run the command within a shell or not. Defaults to true for system toolchain or Windows, and false otherwise. The shell to run is determined by the unixShell and windowsShell options respectively.

yaml
tasks:
  native:
    command: 'echo $SHELL'
    options:
      shell: true

However, if you'd like to use a different shell, or customize the shell's arguments, or have granular control, you can set shell to false and configure a fully qualified command.

yaml
tasks:
  native:
    command: '/bin/zsh -c "echo $SHELL"'
    options:
      shell: false

timeout<VersionLabel version="1.26.0" />

<HeadingApiLink to="/api/types/interface/TaskOptionsConfig#timeout" />

The maximum time in seconds that the task is allowed to run, before it is force cancelled. If not defined, will run indefinitely.

yaml
tasks:
  build:
    # ...
    options:
      timeout: 120

unixShell<VersionLabel version="1.21.0" />

<HeadingApiLink to="/api/types/interface/TaskOptionsConfig#unixShell" />

Customize the shell to run with when on a Unix operating system. Accepts bash, elvish, fish, ion, murex, nu, pwsh, xonsh, or zsh. If not defined, will derive the shell from the SHELL environment variable, or defaults to bash.

yaml
tasks:
  native:
    command: 'echo $SHELL'
    options:
      unixShell: 'fish'

windowsShell<VersionLabel version="1.21.0" />

<HeadingApiLink to="/api/types/interface/TaskOptionsConfig#windowsShell" />

Customize the shell to run with when on a Windows operating system. Accepts bash (typically via Git), elvish, fish, murex, nu, pwsh, or xonsh. If not defined, defaults to pwsh.

yaml
tasks:
  native:
    command: 'echo $SHELL'
    options:
      windowsShell: 'bash'

Overrides

Dictates how a project interacts with settings defined at the top-level.

toolchains

<HeadingApiLink to="/api/types/interface/ProjectConfig#toolchains" />

default<VersionLabel version="1.31.0" />

<HeadingApiLink to="/api/types/interface/ProjectToolchainConfig#default" />

The default toolchain for all task's within the current project. When a task's toolchain has not been explicitly configured, the toolchain will fallback to this configured value, otherwise the toolchain will be detected from the project's environment.

yaml
toolchains:
  default: 'node'

*<VersionLabel version="2.0.0" />

Configures and overrides workspace-level settings for specific toolchains. The key is the name of the toolchain, and the value is an object of settings to override.

yaml
toolchains:
  typescript:
    # Disable refs for this project
    syncProjectReferences: false

Alternatively, if you want to disable a toolchain for a project, you can set the value to false or null, which will prevent the toolchain from being auto-detected and used within the project.

yaml
toolchains:
  typescript: false

workspace

<HeadingApiLink to="/api/types/interface/ProjectConfig#workspace" />

inheritedTasks

<HeadingApiLink to="/api/types/interface/ProjectWorkspaceConfig#inheritedTasks" />

Provides a layer of control when inheriting tasks from .moon/tasks/**/*.

exclude

The optional exclude setting permits a project to exclude specific tasks from being inherited. It accepts a list of strings, where each string is the name of a global task to exclude.

yaml
workspace:
  inheritedTasks:
    # Exclude the inherited `test` task for this project
    exclude: ['test']

Exclusion is applied after inclusion and before renaming.

include

The optional include setting permits a project to only include specific inherited tasks (works like an allow/white list). It accepts a list of strings, where each string is the name of a global task to include.

When this field is not defined, the project will inherit all tasks from the global project config.

yaml
workspace:
  inheritedTasks:
    # Include *no* tasks (works like a full exclude)
    include: []

    # Only include the `lint` and `test` tasks for this project
    include:
      - 'lint'
      - 'test'

Inclusion is applied before exclusion and renaming.

rename

The optional rename setting permits a project to rename the inherited task within the current project. It accepts a map of strings, where the key is the original name (found in the global project config), and the value is the new name to use.

For example, say we have 2 tasks in the global project config called buildPackage and buildApplication, but we only need 1, and since we're an application, we should omit and rename.

yaml
workspace:
  inheritedTasks:
    exclude: ['buildPackage']
    rename:
      buildApplication: 'build'

Renaming occurs after inclusion and exclusion.