Skip to main content

moon v1.19 - Improvements to task dependencies, codegen, and more

· 5 min read
Miles Johnson

In this release, we're introducing some long-awaited and requested improvements.

Configure args and env vars for task dependencies

This has been a long standing request from the community, and we're happy to finally deliver it. Starting with v1.19, you can now configure optional command line arguments and environment variables for each task deps entry. These values will be passed to the task when it is executed.

Here's an example of what both patterns look like. The target field is required when configuring an object, and both the args and env fields can be mixed and matched.

moon.yml
tasks:
build:
command: 'vite build'
deps:
# Just a target
- '^:build'

# With args (string)
- target: '^:build'
args: '--mode production'

# With env vars
- target: '^:build'
env:
NODE_ENV: 'production'

# With args (array) and env vars
- target: '^:build'
args:
- '--mode'
- 'production'
env:
NODE_ENV: 'production'

When using this functionality, there are a few things to understand about its implementation, and how it affects the rest of the pipeline:

  • When extending or inheriting a task and a merger is required, and this task has a dependency with a colliding target, the args and env fields will NOT be deeply merged. Whichever task is inherited last will have its deps used.
  • When multiple dependencies of the same target are ran in the action pipeline, but with differing args or env vars, only 1 will run at a time. We try to avoid running them in parallel to avoid collisions and corrupting outputs.
  • Arguments and environment variables do NOT support tokens.
  • If dependencies all write to the same output, cleaning the output is your responsibility, not moon's.

Codegen improvements

Code generation is one of moon's oldest features, and hasn't been improved in quite a while. We felt the time was right to give it a little love.

Extend other templates

This has been a request for over a year, and we finally found the time to put it on the roadmap. Starting with this release, you can now extend other templates using the extends setting in template.yml, which supports a list of template names.

Templates will be recursively extended from top to bottom, and all files and variables will be inherited and merged at the top-level.

template.yml
title: 'npm package'
extends: ['node-common']

Configure a default destination

When you call moon generate you must provide a destination directory for the generated files, or we'll prompt you to provide one. But what if you wanted to standardize the destination? For example, a package scaffolding template should go to packages/. This is now possible with the optional destination setting in template.yml.

If no destination is provided to moon generate, we'll use this default destination.

template.yml
title: 'npm package'
destination: 'packages/[name | kebab_case]'
variables:
name:
type: 'string'
default: ''
required: true
prompt: 'Package name?'
info

For better interoperability, this setting can also reference variables using [var] syntax, and can also use Tera filters. Learn more about this in the code generation documentation.

Resolved long-standing experiments

moon has a concept of experiments, where certain features are gated behind a flag. This allows us to support new and old functionality in parallel, and also allow users to gradually upgrade when encountering a breaking change. For many months now, we've had 2 experiments running, and have decided on a path forward.

The first is experiments.interweavedTaskInheritance, which would inherit global and local tasks in order, interweaved within each other. The old implementation would inherit global first, then local second, distinctly grouping them. Since this experiment was introduced, we have not received a single bug report or issue. This is a good sign that the new behavior is working as expected, and as such, have decided to move forward with this experiment and make it the new implementation. The old implementation has been removed entirely.

The second is experiments.taskOutputBoundaries, which was rather controversial when introduced. This experiment would trigger an error anytime a task's outputs overlapped within another task's outputs. The reason for this change, is that multiple tasks writing to the same output location could "corrupt" the expected state, and trigger unexpected results when hydrating from the cache. However in practice, this restriction has caused more headache and introduced a steeper learning curve then expected. It also caused problems with tasks that extend from another, resulting in the same outputs being used. Because of this, we've decided to not move forward with this experiment, and allow whatever task outputs you wish (we trust you're smart enough to not shoot yourself in the foot).

Other changes

View the official release for a full list of changes.

  • Updated proto to v0.26 (from v0.25), which includes a new shims implementation.
  • Updated VS Code extension to support multiple VS Code workspace folders.