mirror of
https://github.com/go-task/task.git
synced 2026-10-23 11:48:55 +03:00
v3.54.0
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Changelog
|
||||
|
||||
## Unreleased
|
||||
## v3.54.0 - 2026-10-01
|
||||
|
||||
### 🚀 Features
|
||||
|
||||
|
||||
@@ -1 +1 @@
|
||||
3.53.1
|
||||
3.54.0
|
||||
|
||||
@@ -3,39 +3,106 @@ import type { DefaultTheme } from 'vitepress';
|
||||
// Navigation for the `/docs` section. next.ts is the source of both sidebars;
|
||||
// cmd/release copies it over latest.ts alongside the content it describes. See
|
||||
// the "Documentation channels" section of website/src/next/docs/contributing.md.
|
||||
//
|
||||
// Grouped by what the reader is trying to do: get going, learn Task, look
|
||||
// something up, follow the project. The DocSearch crawler puts the active
|
||||
// sidebar section into hierarchy.lvl0, so these labels are also the breadcrumbs
|
||||
// on every search result.
|
||||
export const sidebar: DefaultTheme.SidebarItem[] = [
|
||||
{
|
||||
text: 'Installation',
|
||||
link: '/docs/installation'
|
||||
text: 'Overview',
|
||||
link: '/docs/'
|
||||
},
|
||||
{
|
||||
text: 'Getting Started',
|
||||
link: '/docs/getting-started'
|
||||
items: [
|
||||
{
|
||||
text: 'Installation',
|
||||
link: '/docs/installation'
|
||||
},
|
||||
{
|
||||
text: 'Quick Start',
|
||||
link: '/docs/getting-started'
|
||||
},
|
||||
{
|
||||
text: 'Editors and Integrations',
|
||||
link: '/docs/integrations'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: 'Guide',
|
||||
link: '/docs/guide'
|
||||
},
|
||||
{
|
||||
text: 'Remote Taskfiles',
|
||||
link: '/docs/remote-taskfiles'
|
||||
link: '/docs/guide/',
|
||||
items: [
|
||||
{
|
||||
text: 'Writing and running tasks',
|
||||
collapsed: false,
|
||||
items: [
|
||||
{ text: 'Defining tasks', link: '/docs/guide/defining-tasks' },
|
||||
{ text: 'Running tasks', link: '/docs/guide/running-tasks' }
|
||||
]
|
||||
},
|
||||
{
|
||||
text: 'Variables and arguments',
|
||||
collapsed: false,
|
||||
items: [
|
||||
{ text: 'Variables', link: '/docs/guide/variables' },
|
||||
{ text: 'Command-line arguments', link: '/docs/guide/arguments' },
|
||||
{
|
||||
text: 'Validation and prompts',
|
||||
link: '/docs/guide/required-variables'
|
||||
},
|
||||
{ text: 'Secret variables', link: '/docs/guide/secret-variables' }
|
||||
]
|
||||
},
|
||||
{
|
||||
text: 'Task execution',
|
||||
collapsed: false,
|
||||
items: [
|
||||
{
|
||||
text: 'Dependencies and task calls',
|
||||
link: '/docs/guide/dependencies'
|
||||
},
|
||||
{ text: 'Loops', link: '/docs/guide/loops' },
|
||||
{
|
||||
text: 'Conditional execution',
|
||||
link: '/docs/guide/conditional-execution'
|
||||
},
|
||||
{
|
||||
text: 'Errors and cleanup',
|
||||
link: '/docs/guide/errors-and-cleanup'
|
||||
},
|
||||
{ text: 'Up-to-date checks', link: '/docs/guide/up-to-date' },
|
||||
{ text: 'Watch mode', link: '/docs/guide/watch' }
|
||||
]
|
||||
},
|
||||
{
|
||||
text: 'Environment and output',
|
||||
collapsed: false,
|
||||
items: [
|
||||
{ text: 'Environment variables', link: '/docs/guide/environment' },
|
||||
{ text: 'Platforms and shells', link: '/docs/guide/platforms' },
|
||||
{ text: 'Output and logging', link: '/docs/guide/output' }
|
||||
]
|
||||
},
|
||||
{
|
||||
text: 'Including Taskfiles',
|
||||
collapsed: false,
|
||||
items: [
|
||||
{ text: 'Including Taskfiles', link: '/docs/guide/includes' },
|
||||
{ text: 'Remote Taskfiles', link: '/docs/remote-taskfiles' }
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: 'Reference',
|
||||
collapsed: true,
|
||||
collapsed: false,
|
||||
items: [
|
||||
{
|
||||
text: 'Taskfile Schema',
|
||||
link: '/docs/reference/schema'
|
||||
},
|
||||
{
|
||||
text: 'Environment',
|
||||
link: '/docs/reference/environment'
|
||||
},
|
||||
{
|
||||
text: 'Configuration',
|
||||
link: '/docs/reference/config'
|
||||
},
|
||||
{
|
||||
text: 'CLI',
|
||||
link: '/docs/reference/cli'
|
||||
@@ -44,6 +111,14 @@ export const sidebar: DefaultTheme.SidebarItem[] = [
|
||||
text: 'Templating',
|
||||
link: '/docs/reference/templating'
|
||||
},
|
||||
{
|
||||
text: 'Environment',
|
||||
link: '/docs/reference/environment'
|
||||
},
|
||||
{
|
||||
text: 'Configuration',
|
||||
link: '/docs/reference/config'
|
||||
},
|
||||
{
|
||||
text: 'Package API',
|
||||
link: '/docs/reference/package'
|
||||
@@ -51,88 +126,96 @@ export const sidebar: DefaultTheme.SidebarItem[] = [
|
||||
]
|
||||
},
|
||||
{
|
||||
text: 'Experiments',
|
||||
text: 'Project',
|
||||
collapsed: true,
|
||||
link: '/docs/experiments/',
|
||||
items: [
|
||||
{
|
||||
text: 'Env Precedence (#1038)',
|
||||
link: '/docs/experiments/env-precedence'
|
||||
text: 'Changelog',
|
||||
link: '/docs/changelog'
|
||||
},
|
||||
{
|
||||
text: 'Gentle Force (#1200)',
|
||||
link: '/docs/experiments/gentle-force'
|
||||
text: 'FAQ',
|
||||
link: '/docs/faq'
|
||||
},
|
||||
{
|
||||
text: 'Remote Taskfiles (#1317)',
|
||||
link: '/docs/experiments/remote-taskfiles'
|
||||
text: 'Taskfile Versions',
|
||||
link: '/docs/taskfile-versions'
|
||||
},
|
||||
{
|
||||
text: 'Community',
|
||||
link: '/docs/community'
|
||||
},
|
||||
{
|
||||
text: 'Experiments',
|
||||
collapsed: true,
|
||||
link: '/docs/experiments/',
|
||||
items: [
|
||||
{
|
||||
text: 'Env Precedence (#1038)',
|
||||
link: '/docs/experiments/env-precedence'
|
||||
},
|
||||
{
|
||||
text: 'Gentle Force (#1200)',
|
||||
link: '/docs/experiments/gentle-force'
|
||||
},
|
||||
{
|
||||
text: 'Remote Taskfiles (#1317)',
|
||||
link: '/docs/experiments/remote-taskfiles'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: 'Deprecations',
|
||||
collapsed: true,
|
||||
link: '/docs/deprecations/',
|
||||
items: [
|
||||
{
|
||||
text: 'Completion Scripts',
|
||||
link: '/docs/deprecations/completion-scripts'
|
||||
},
|
||||
{
|
||||
text: 'Template Functions',
|
||||
link: '/docs/deprecations/template-functions'
|
||||
},
|
||||
{
|
||||
text: 'Version 2 Schema (#1197)',
|
||||
link: '/docs/deprecations/version-2-schema'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: 'Security',
|
||||
collapsed: true,
|
||||
link: '/docs/security/',
|
||||
items: [
|
||||
{
|
||||
text: 'Incident Response Plan',
|
||||
link: '/docs/security/incident-response-plan'
|
||||
},
|
||||
{
|
||||
text: 'Threat Model',
|
||||
link: '/docs/security/threat-model'
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: 'Deprecations',
|
||||
collapsed: true,
|
||||
link: '/docs/deprecations/',
|
||||
items: [
|
||||
{
|
||||
text: 'Completion Scripts',
|
||||
link: '/docs/deprecations/completion-scripts'
|
||||
},
|
||||
{
|
||||
text: 'Template Functions',
|
||||
link: '/docs/deprecations/template-functions'
|
||||
},
|
||||
{
|
||||
text: 'Version 2 Schema (#1197)',
|
||||
link: '/docs/deprecations/version-2-schema'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: 'Taskfile Versions',
|
||||
link: '/docs/taskfile-versions'
|
||||
},
|
||||
{
|
||||
text: 'Integrations',
|
||||
link: '/docs/integrations'
|
||||
},
|
||||
{
|
||||
text: 'Community',
|
||||
link: '/docs/community'
|
||||
},
|
||||
{
|
||||
text: 'Style Guide',
|
||||
link: '/docs/styleguide'
|
||||
},
|
||||
{
|
||||
text: 'Contributing',
|
||||
link: '/docs/contributing'
|
||||
},
|
||||
{
|
||||
text: 'Releasing',
|
||||
link: '/docs/releasing'
|
||||
},
|
||||
{
|
||||
text: 'Security',
|
||||
collapsed: true,
|
||||
link: '/docs/security/',
|
||||
items: [
|
||||
{
|
||||
text: 'Incident Response Plan',
|
||||
link: '/docs/security/incident-response-plan'
|
||||
text: 'Contributing',
|
||||
link: '/docs/contributing'
|
||||
},
|
||||
{
|
||||
text: 'Threat Model',
|
||||
link: '/docs/security/threat-model'
|
||||
text: 'Style Guide',
|
||||
link: '/docs/styleguide'
|
||||
},
|
||||
{
|
||||
text: 'Releasing',
|
||||
link: '/docs/releasing'
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
text: 'Changelog',
|
||||
link: '/docs/changelog'
|
||||
},
|
||||
{
|
||||
text: 'FAQ',
|
||||
link: '/docs/faq'
|
||||
}
|
||||
];
|
||||
|
||||
77
website/src/latest/agents.md
Normal file
77
website/src/latest/agents.md
Normal file
@@ -0,0 +1,77 @@
|
||||
---
|
||||
title: Task documentation for coding agents
|
||||
description:
|
||||
A compact map of Task's documentation, plus the execution semantics that are
|
||||
easiest to get wrong when generating a Taskfile.
|
||||
outline: deep
|
||||
---
|
||||
|
||||
# Task documentation for coding agents
|
||||
|
||||
Task is a cross-platform task runner and build tool. Its configuration file is
|
||||
normally named `Taskfile.yml`, and new files should use schema version `3`.
|
||||
|
||||
Every page linked below is also available as raw Markdown: append `.md` to its
|
||||
URL. The curated index is at [/llms.txt](/llms.txt) and the full corpus at
|
||||
[/llms-full.txt](/llms-full.txt).
|
||||
|
||||
## Where to look
|
||||
|
||||
- [Quick Start](./docs/getting-started.md): the shape of a Taskfile.
|
||||
- [Taskfile Schema](./docs/reference/schema.md): the source of truth for keys,
|
||||
types and accepted values. Check here before assuming a field exists.
|
||||
- [CLI](./docs/reference/cli.md): commands, flags and exit codes.
|
||||
- [Templating](./docs/reference/templating.md): every template function and
|
||||
special variable. Check here before inventing one.
|
||||
- [Guide](./docs/guide/): task definitions, inputs, execution and shared
|
||||
Taskfiles.
|
||||
- [Errors and cleanup](./docs/guide/errors-and-cleanup.md): failure handling and
|
||||
`defer`.
|
||||
- [Secret variables](./docs/guide/secret-variables.md): masking and its limits.
|
||||
- [Resolution order](./docs/guide/variables.md#resolution-order) and
|
||||
[Task dependencies](./docs/guide/dependencies.md#task-dependencies): for when
|
||||
the behaviour matters more than the procedure.
|
||||
|
||||
## Semantics that are easy to get wrong
|
||||
|
||||
1. `vars` are not exported to `cmds`: use templates to read them there. Dynamic
|
||||
variables (`sh:`) also receive previously resolved scalar variables in their
|
||||
shell environment. `env` is exported to commands. Root-level `env` also
|
||||
participates in templates; task-level `env` does not. A template keeps any
|
||||
value resolved from other sources, or renders empty if none exists.
|
||||
2. A constant in a task's own `vars:` overrides the command line. Put the
|
||||
default in global `vars:`, or use a template such as
|
||||
<span v-pre>`NAME: '{{.NAME | default "World"}}'`</span> to preserve caller
|
||||
input.
|
||||
3. The included Taskfile's own `vars:` are applied after `includes.vars`. A
|
||||
constant overrides the include's value; a self-referencing template with
|
||||
`default` can preserve it.
|
||||
4. Everything in `deps` may run concurrently and in any order. A `task:`
|
||||
reference inside `cmds` runs at its position and blocks the next command. If
|
||||
order matters, use `cmds`.
|
||||
5. Each command runs in its own shell. Nothing carries over between them, not
|
||||
`cd` and not an exported variable. Use Task's `dir:` and `env:` instead.
|
||||
6. A template renders text. Use `ref:` to pass an array or a map without
|
||||
flattening it to a string.
|
||||
7. A passing `status:` means the task is already up to date and is skipped. A
|
||||
failing `preconditions:` means the task must not run at all. They are not
|
||||
interchangeable.
|
||||
8. `defer:` commands run in reverse order of declaration, and run whether the
|
||||
task succeeded or failed.
|
||||
9. Remote Taskfiles execute code from wherever they are fetched. See
|
||||
[Remote Taskfiles](./docs/remote-taskfiles.md) for the trust and checksum
|
||||
rules.
|
||||
10. Portability is about every command inside a task, not just Task itself. A
|
||||
task is only cross-platform if its commands are.
|
||||
|
||||
## Before writing a Taskfile
|
||||
|
||||
- Confirm the feature exists in the schema for the version in use.
|
||||
- Prefer plain, readable tasks over dense templating.
|
||||
- Use `deps` only where concurrent execution is actually correct.
|
||||
- Never embed credentials. Read them from the environment or a secret manager.
|
||||
`secret: true` masks a value in Task's own logs, but it only works on `vars:`,
|
||||
not on `env:`, and it never masks what a command itself prints. Treat it as
|
||||
one less place a secret is echoed, not as protection.
|
||||
- Give tasks a `desc:` so they show up in `task --list`, and validate inputs
|
||||
with `requires:` or `preconditions:`.
|
||||
@@ -150,6 +150,8 @@ experiment.
|
||||
We're looking for feedback on a couple of different proposals, so please give
|
||||
them a go and let us know what you think. :pray:
|
||||
|
||||
[map-variables]:
|
||||
../docs/guide/variables.md#parsing-json-yaml-into-map-variables
|
||||
[v3.37.0]: https://github.com/go-task/task/releases/tag/v3.37.0
|
||||
[slim-sprig-math]: https://sprig.taskfile.dev/math.html
|
||||
[slim-sprig-list]: https://sprig.taskfile.dev/lists.html
|
||||
|
||||
225
website/src/latest/blog/completion-engine.md
Normal file
225
website/src/latest/blog/completion-engine.md
Normal file
@@ -0,0 +1,225 @@
|
||||
---
|
||||
title: One Completion Engine for Every Shell
|
||||
description:
|
||||
A new completion engine that gives every shell the same suggestions, and that
|
||||
can finally complete your required variables.
|
||||
author: vmaerten
|
||||
date: 2026-10-01
|
||||
tags: ['new-features', 'completion']
|
||||
outline: deep
|
||||
editLink: false
|
||||
---
|
||||
|
||||
# One Completion Engine for Every Shell
|
||||
|
||||
<AuthorCard :author="$frontmatter.author" />
|
||||
|
||||
Task has shipped shell completions for a long time. They were written as one
|
||||
script per shell: a Bash script, a Zsh script, a Fish script, one for PowerShell
|
||||
and one for Nushell. Each of them had to work out on its own what your Taskfile
|
||||
contains and what flags Task accepts. Over the years, they drifted.
|
||||
|
||||
<!-- more -->
|
||||
|
||||
[Task v3.54.0][release] brings a shared completion engine to Bash, Zsh, Fish,
|
||||
PowerShell and Nushell. It is the default behind `task --completion <shell>`.
|
||||
Let me show you what it fixes.
|
||||
|
||||
## The same TAB, five different answers
|
||||
|
||||
With the old scripts, asking Task to complete the value of `--output` could
|
||||
produce different answers depending on the shell:
|
||||
|
||||
```shell
|
||||
# bash, zsh, fish
|
||||
$ task --output <TAB>
|
||||
interleaved group prefixed
|
||||
|
||||
# powershell
|
||||
PS> task --output <TAB>
|
||||
build deploy
|
||||
```
|
||||
|
||||
PowerShell had no idea `--output` takes a value, so it fell back to listing task
|
||||
names where a value was expected.
|
||||
|
||||
The differences also affected which Taskfile was read:
|
||||
|
||||
```shell
|
||||
$ task --dir ./sub <TAB>
|
||||
```
|
||||
|
||||
The old Zsh, Fish and PowerShell scripts suggested tasks from the _current_
|
||||
directory, since none of them passed `--dir` along when asking Task for a task
|
||||
list. Bash and Nushell handled it correctly.
|
||||
|
||||
Behind these symptoms was one structural problem: the logic lived in the
|
||||
scripts. Several scripts maintained their own lists of flags and descriptions,
|
||||
so adding a flag meant updating each of them. Some also parsed the
|
||||
human-readable output of `--list-all` to learn about your tasks. Here is part of
|
||||
what the Fish completion had to do:
|
||||
|
||||
```fish
|
||||
sed -e '1d; s/\* \(.*\):[[:space:]]\{2,\}\(.*\)[[:space:]]\{2,\}(\(aliases.*\))/\1\t\2\t\3/'
|
||||
```
|
||||
|
||||
Even reformatting a line of `task --list-all` could break those completions.
|
||||
|
||||
## One engine instead of five scripts
|
||||
|
||||
The new scripts hand the command line over to a hidden `task __complete`
|
||||
command. The binary returns suggestions and instructions for the shell, such as
|
||||
whether to offer files or preserve the order of the results.
|
||||
|
||||
Each wrapper still handles the details of its shell: reading the words under the
|
||||
cursor, quoting values and displaying suggestions. Task names, required
|
||||
variables and flags now come from one implementation in the binary.
|
||||
|
||||
## What this unlocks
|
||||
|
||||
### Completing required variables
|
||||
|
||||
This is the one I wanted for a long time. The old scripts did not suggest a
|
||||
task's [required variables][requires] or their allowed values. The engine does:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
deploy:
|
||||
desc: Deploy the app
|
||||
requires:
|
||||
vars:
|
||||
- name: ENVIRONMENT
|
||||
enum: [dev, staging, prod]
|
||||
- REGION
|
||||
cmds:
|
||||
- ./deploy.sh
|
||||
```
|
||||
|
||||
```shell
|
||||
$ task deploy <TAB>
|
||||
ENVIRONMENT=dev ENVIRONMENT=staging ENVIRONMENT=prod REGION=
|
||||
```
|
||||
|
||||
Variables with an `enum` give you the allowed values directly. Variables without
|
||||
one give you `VAR=`. The engine returns these suggestions in the order of your
|
||||
`requires` block.
|
||||
|
||||
Assignments already on the command line are left out of the suggestions:
|
||||
|
||||
```shell
|
||||
$ task deploy ENVIRONMENT=prod <TAB>
|
||||
REGION=
|
||||
```
|
||||
|
||||
Once both variables are supplied, completion offers task names again so you can
|
||||
add another task to the same command. When several tasks are already named, the
|
||||
engine combines their required variables without suggesting a name twice.
|
||||
|
||||
Enums defined by reference work too:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
vars:
|
||||
ALLOWED_ENVS: [dev, staging, prod]
|
||||
|
||||
tasks:
|
||||
deploy:
|
||||
requires:
|
||||
vars:
|
||||
- name: ENVIRONMENT
|
||||
enum:
|
||||
ref: .ALLOWED_ENVS
|
||||
```
|
||||
|
||||
This uses the same enum resolver as the [interactive prompt][prompt-post], with
|
||||
one important limit: completion does not run `sh:` variables. If an enum needs a
|
||||
shell command to produce its values, completion offers `ENVIRONMENT=` instead.
|
||||
|
||||
### Everything else, everywhere
|
||||
|
||||
All five shells now get their task names, aliases, flags and flag values from
|
||||
the engine. `--dir`, `--taskfile` and `--global` are honoured when loading the
|
||||
Taskfile, so completing inside another directory works. Completing `--taskfile`
|
||||
offers `.yml` and `.yaml` files, plus directories you can navigate into.
|
||||
|
||||
Flags gated behind an [experiment][experiments] are another good example. They
|
||||
are read from Task's own flag set at the moment you press TAB, so they show up
|
||||
when the experiment is enabled. The wrappers no longer need separate flag lists
|
||||
or their own checks of `task --experiments`.
|
||||
|
||||
The suggestions are shared, but the shells still control how they are inserted
|
||||
and displayed. For example, PowerShell can add a space after `VAR=`, older Bash
|
||||
versions may sort the results, and Nushell does not append a trailing space.
|
||||
|
||||
## Completions should never surprise you
|
||||
|
||||
Completion runs on a keystroke, so it is allowed to do very little:
|
||||
|
||||
- No remote Taskfile downloads. Completion uses local files and cached remote
|
||||
Taskfiles. If an uncached include prevents the Taskfile from loading, task
|
||||
suggestions are unavailable until it has been fetched by a normal Task run.
|
||||
- Nothing is read from stdin. A Taskfile supplied with `--taskfile -` is skipped
|
||||
during completion.
|
||||
- No `sh:` variable is evaluated. Pressing TAB never runs a command from your
|
||||
Taskfile.
|
||||
- A broken or missing Taskfile still leaves you with flag completion.
|
||||
|
||||
## Load the new completions
|
||||
|
||||
Starting with Task v3.54.0, `--completion` generates the new wrappers. If your
|
||||
shell configuration already runs that command at startup, restart your shell
|
||||
after upgrading. If you saved a completion script to a file, regenerate it with
|
||||
the updated binary.
|
||||
|
||||
Here are the startup commands for each shell:
|
||||
|
||||
::: code-group
|
||||
|
||||
```shell [bash]
|
||||
# ~/.bashrc
|
||||
eval "$(task --completion bash)"
|
||||
```
|
||||
|
||||
```shell [zsh]
|
||||
# ~/.zshrc
|
||||
eval "$(task --completion zsh)"
|
||||
```
|
||||
|
||||
```shell [fish]
|
||||
# ~/.config/fish/config.fish
|
||||
task --completion fish | source
|
||||
```
|
||||
|
||||
```powershell [powershell]
|
||||
# Add to your PowerShell profile ($PROFILE)
|
||||
Invoke-Expression (&task --completion powershell | Out-String)
|
||||
```
|
||||
|
||||
```nu [nushell]
|
||||
# Add to config.nu; completions are loaded in the next shell
|
||||
mkdir ($nu.data-dir | path join "vendor/autoload")
|
||||
task --completion nu | save --force ($nu.data-dir | path join "vendor/autoload/task-completions.nu")
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
The [installation docs][install] cover saving scripts to completion directories,
|
||||
Nushell's external completer and the Zsh `verbose` and `show-aliases` settings.
|
||||
|
||||
## Feedback
|
||||
|
||||
Please tell us how it behaves in your shell. If a suggestion is missing or
|
||||
inserted incorrectly, include your Task version, shell version and a small
|
||||
Taskfile that reproduces it. You can find us on our [Discord server][discord] or
|
||||
[open an issue][gh-issue].
|
||||
|
||||
[release]: https://github.com/go-task/task/releases/tag/v3.54.0
|
||||
[requires]: /docs/reference/schema#requires
|
||||
[prompt-post]: /blog/if-and-variable-prompt
|
||||
[experiments]: /docs/experiments/
|
||||
[install]: /docs/installation#setup-completions
|
||||
[discord]: https://discord.com/invite/6TY36E39UK
|
||||
[gh-issue]: https://github.com/go-task/task/issues
|
||||
@@ -135,7 +135,7 @@ project][sponsor]!
|
||||
[uroot-base]: https://github.com/u-root/u-root/blob/main/pkg/core/base.go
|
||||
[middleware]:
|
||||
https://github.com/mvdan/sh/blob/master/x/coreutils/coreutils.go
|
||||
[task-core-utils]: /docs/reference/environment#task-core-utils
|
||||
[task-core-utils]: ../docs/reference/environment.md#task-core-utils
|
||||
[discord]: https://discord.com/invite/6TY36E39UK
|
||||
[gh-issue]: https://github.com/go-task/task/issues
|
||||
[sponsor]: /donate
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
---
|
||||
title: Changelog
|
||||
description:
|
||||
Release history for Task, including new features, improvements, fixes, and
|
||||
breaking changes
|
||||
section: Project
|
||||
docType: project
|
||||
outline: deep
|
||||
editLink: false
|
||||
---
|
||||
@@ -8,7 +13,54 @@ editLink: false
|
||||
|
||||
::: v-pre
|
||||
|
||||
## v3.53.0 - 2026-08-18
|
||||
## v3.54.0 - 2026-10-01
|
||||
|
||||
### 🚀 Features
|
||||
|
||||
- Added versioned Homebrew casks (`go-task@<major>.<minor>`) to install a
|
||||
specific minor version of Task (#3023 by @vmaerten).
|
||||
- Added a `remote.headers` config option to send HTTP headers when downloading a
|
||||
remote Taskfile, configured per host. Header values support templating
|
||||
functions, e.g. `{{env "GITLAB_TOKEN"}}`. This keeps the credential out of the
|
||||
include URL, where it would leak into error messages and the confirmation
|
||||
prompt (#2329 by @vmaerten).
|
||||
|
||||
### 🐛 Fixes
|
||||
|
||||
- Fixed remote Git Taskfile cache poisoning on shared hosts (GHSA-679p-658w-m3wr,
|
||||
reported by @danielcadev, fixed by @vmaerten).
|
||||
- Fixed tasks cancelled by the user returning exit code `201` instead of `205`
|
||||
(#3040, #3041 by @r3wretrhy).
|
||||
- Fixed a bug on Windows where watching source paths did not work as expected
|
||||
(#2863, #3028 by @pd93).
|
||||
- Fixed a remote Taskfile whose server refuses the credentials being reported as
|
||||
a missing Taskfile. A `401` now stops the search and reports the status code,
|
||||
instead of retrying every default Taskfile name and concluding that no
|
||||
Taskfile exists (#2329 by @vmaerten).
|
||||
|
||||
- `task --completion <shell>` now serves a new completion engine that unifies
|
||||
Bash, Fish, Zsh, Nushell and PowerShell behind a single `task __complete`
|
||||
command, so every shell offers the same suggestions: task names, aliases,
|
||||
flags, flag values and per-task CLI variables. The Zsh `show-aliases` and
|
||||
`verbose` zstyles keep working, now backed by the `--no-aliases` and
|
||||
`--no-descriptions` completion flags (#2897 by @vmaerten).
|
||||
|
||||
### 📦 Package API
|
||||
|
||||
- Bumped the minimum Go version to 1.26. Task follows Go's two-latest support
|
||||
window, and is now tested against 1.26 and 1.27. This only affects projects
|
||||
importing Task as a Go module (#2920 by @vmaerten).
|
||||
|
||||
### Other
|
||||
|
||||
- Refactored some functional options to always return a concrete type instead of
|
||||
an interface and moved options into their own file (#3037 by @pd93).
|
||||
- Refactored the execext package to use mvdan/sh's new BashOpts API (#3035 by
|
||||
@pd93).
|
||||
|
||||
## v3.53.1 - 2026-08-18
|
||||
|
||||
### 🚀 Features
|
||||
|
||||
- **Remote Taskfiles are now generally available!** This has been an
|
||||
experimental feature for 3 years, but is now enabled by default. Massive
|
||||
@@ -16,21 +68,37 @@ editLink: false
|
||||
here). We've also given the
|
||||
[Remote Taskfiles documentation](https://taskfile.dev/docs/remote-taskfiles) a
|
||||
bit of a polish (#1317, #2906 by @pd93).
|
||||
- Added a per-command `timeout` that terminates a command once it exceeds the
|
||||
given duration (Go duration syntax). It covers shell commands, task calls,
|
||||
deferred commands, `deps` and the `if` condition, obeys `ignore_error`, and
|
||||
reports exit code `124`. Callers that join a `run: once` or `when_changed`
|
||||
task already running now honor their own `timeout`, and inherit that task's
|
||||
failure instead of being told it succeeded (#1569, #2898 by @vmaerten).
|
||||
- Considerably improve performance of fingerprinting on large repositories
|
||||
(monorepos). Fingerprinting is up to 86% faster and make up to 70% fewer
|
||||
memory allocations on the more advanced scenarios. Benchmarks were added as
|
||||
well. We're basically skipping work when not needed. (#2853, #2883 by
|
||||
@Napolitain, #2884 by @Napolitain).
|
||||
- Updated taskfile versions doc to mention when version checks were introduced
|
||||
(#2184 by @jubr).
|
||||
- Fixed `joinUrl` collapsing the `//` in a URL scheme (e.g. producing
|
||||
`http:/localhost` instead of `http://localhost`) (#2915 by @vsaraikin).
|
||||
- Added support for `enum.ref` in `--interactive` prompts. Required vars using
|
||||
`enum.ref` now show the selection list like static enums, instead of falling
|
||||
back to free-form input (#2817 by @vmaerten).
|
||||
- Further improved fingerprinting performance on large repositories: hashing
|
||||
source files now reuses a single buffer, reducing memory allocations by ~98%
|
||||
and wall-clock time by ~7% (#2925 by @vmaerten).
|
||||
- `includes.excludes` can now exclude a whole namespace: append `:*` to the
|
||||
namespace name, e.g. `excludes: ['debug:*']`. Bare entries still match a
|
||||
single task name exactly (#2300, #2959 by @xmxxc).
|
||||
- Added support for `enum.ref` in `--interactive` prompts. Required vars using
|
||||
`enum.ref` now show the selection list like static enums, instead of falling
|
||||
back to free-form input (#2817 by @vmaerten).
|
||||
- Added Nushell completions, available via `task --completion nu`. They complete
|
||||
task names and aliases, every flag with its description, and the values of
|
||||
`--completion`, `--output` and `--sort` (#2966 by @vmaerten).
|
||||
- Added a verbose log line for failed tasks. In `--verbose` mode, a task whose
|
||||
command exits non-zero now reports `task: "<name>" failed: <error>` instead of
|
||||
stopping without a trace (#2240 by @Drino).
|
||||
|
||||
### 🐛 Fixes
|
||||
|
||||
- Fixed a pinned `checksum:` not being verified when a remote Taskfile came from
|
||||
the cache (#2980 by @vmaerten).
|
||||
- Fixed the fingerprint variable (`{{.CHECKSUM}}`/`{{.TIMESTAMP}}`) ignoring a
|
||||
`method:` set at the Taskfile level: the variable now follows the same method
|
||||
resolution as the up-to-date check. Only the variable matching the effective
|
||||
@@ -38,37 +106,31 @@ editLink: false
|
||||
gets `{{.TIMESTAMP}}` and no longer a `{{.CHECKSUM}}` (which now renders as an
|
||||
empty string), and neither variable is injected when the effective method is
|
||||
`none` (#2924 by @vmaerten).
|
||||
- `includes.excludes` can now exclude a whole namespace: append `:*` to the
|
||||
namespace name, e.g. `excludes: ['debug:*']`. Bare entries still match a
|
||||
single task name exactly (#2300, #2959 by @xmxxc).
|
||||
- Fixed `ref:` in `for: matrix:` and `enum:` only accepting literal lists. Refs
|
||||
computed with template functions like `keys` or `splitList` no longer fail
|
||||
with "must resolve to a list" (#2544, #2956 by @no-hup).
|
||||
- Fixed pressing `Esc` at an interactive variable prompt not cancelling the run
|
||||
(#2942 by @anilnatha).
|
||||
- Fixed `joinUrl` collapsing the `//` in a URL scheme (e.g. producing
|
||||
`http:/localhost` instead of `http://localhost`) (#2915 by @vsaraikin).
|
||||
- Fixed the JSON schema rejecting `ignore_error` on a command inside a `for`
|
||||
loop. Editors no longer flag a Taskfile that Task runs perfectly fine (#2044
|
||||
by @gokeefe-atb).
|
||||
- Fixed the JSON schema rejecting more keys the Taskfile parser accepts:
|
||||
`ignore_error` on a `task:` call, and `if`, `set` and `shopt` on a command
|
||||
inside a `for` loop (#2967 by @vmaerten).
|
||||
- Added a verbose log line for failed tasks. In `--verbose` mode, a task whose
|
||||
command exits non-zero now reports `task: "<name>" failed: <error>` instead of
|
||||
stopping without a trace (#2240 by @Drino).
|
||||
- Fixed pressing `Esc` at an interactive variable prompt not cancelling the run
|
||||
(#2942 by @anilnatha).
|
||||
- Added Nushell completions, available via `task --completion nu`. They complete
|
||||
task names and aliases, every flag with its description, and the values of
|
||||
`--completion`, `--output` and `--sort` (#2966 by @vmaerten).
|
||||
- Added a per-command `timeout` that terminates a command once it exceeds the
|
||||
given duration (Go duration syntax). It covers shell commands, task calls,
|
||||
deferred commands, `deps` and the `if` condition, obeys `ignore_error`, and
|
||||
reports exit code `124`. Callers that join a `run: once` or `when_changed`
|
||||
task already running now honor their own `timeout`, and inherit that task's
|
||||
failure instead of being told it succeeded (#1569, #2898 by @vmaerten).
|
||||
- Fixed a pinned `checksum:` not being verified when a remote Taskfile came from
|
||||
the cache (#2980 by @vmaerten).
|
||||
|
||||
### 📚 Documentation & Website
|
||||
|
||||
- Updated taskfile versions doc to mention when version checks were introduced
|
||||
(#2184 by @jubr).
|
||||
- Load the sidebar data and titles/excerpts from the blog post markdown document
|
||||
and its frontmatter on the website (#2981 by @pd93).
|
||||
|
||||
## v3.53.0 - 2026-08-18
|
||||
|
||||
- Failed due to an issue with our release process.
|
||||
|
||||
## v3.52.0 - 2026-07-02
|
||||
|
||||
- Fixed --interactive prompts for required vars sometimes appearing in a random
|
||||
|
||||
@@ -3,6 +3,8 @@ title: Community
|
||||
description:
|
||||
Task community contributions, installation methods, and integrations
|
||||
maintained by third parties
|
||||
section: Project
|
||||
docType: project
|
||||
outline: deep
|
||||
---
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ title: Contributing
|
||||
description:
|
||||
Comprehensive guide for contributing to the Task project, including setup,
|
||||
development, testing, and submitting PRs
|
||||
section: Contributing
|
||||
docType: contributing
|
||||
outline: deep
|
||||
---
|
||||
|
||||
@@ -126,6 +128,19 @@ by using `task website` (requires `nodejs` & `pnpm`). All content is written in
|
||||
Markdown and is located in the `website/src` directory. All Markdown documents
|
||||
should have an 80 character line wrap limit (enforced by Prettier).
|
||||
|
||||
Search is provided by Algolia DocSearch. The crawler runs on Algolia's side and
|
||||
is configured through their dashboard, but `website/docsearch.config.js` holds
|
||||
the same configuration in the repository so it can be read and reviewed. If you
|
||||
change one, change the other. A page's `section:` frontmatter is what the
|
||||
crawler shows as the breadcrumb on a search result, while `docType:` powers its
|
||||
search facet, so a new page needs both.
|
||||
|
||||
After building the site, run `pnpm check:links` from `website/` to check links
|
||||
in the generated Markdown pages and LLM indexes. The LLM plugin is patched in
|
||||
`website/patches/` to resolve links before it moves directory indexes such as
|
||||
`docs/guide/index.md` to `docs/guide.md`. When upgrading the plugin, retain the
|
||||
patch until upstream handles those links, and check both documentation channels.
|
||||
|
||||
When making a change, consider whether a change to the [Usage
|
||||
Guide][usage-guide] is necessary. This document contains descriptions and
|
||||
examples of how to use Task features. If you're adding a new feature, try to
|
||||
@@ -140,14 +155,17 @@ for fields in the docs and the schema should match.
|
||||
|
||||
#### Documentation channels
|
||||
|
||||
The docs and the blog exist in two copies, so that taskfile.dev never announces
|
||||
a feature that is not in the released binary yet:
|
||||
The docs, the blog and the coding-agent guide exist in two copies, so that
|
||||
taskfile.dev never announces a feature that is not in the released binary yet:
|
||||
|
||||
| Directory | Channel | Published on |
|
||||
| -------------------------------- | -------- | ----------------- |
|
||||
| `website/src/next/{docs,blog}` | `next` | next.taskfile.dev |
|
||||
| `website/src/latest/{docs,blog}` | `latest` | taskfile.dev |
|
||||
|
||||
The coding-agent guide follows the same channels as `src/next/agents.md` and
|
||||
`src/latest/agents.md`, and is promoted at release time too.
|
||||
|
||||
Everything else - the homepage, the team, adopters, images - is shared by both
|
||||
channels and goes live as soon as the site is deployed.
|
||||
|
||||
@@ -253,9 +271,9 @@ If you have questions, feel free to ask them in the `#help` forum channel on our
|
||||
[discord-server]: https://discord.gg/6TY36E39UK
|
||||
[discussion]: https://github.com/go-task/task/discussions
|
||||
[conventional-commits]: https://www.conventionalcommits.org
|
||||
[experiments]: ./experiments/
|
||||
[experiments-workflow]: ./experiments/#workflow
|
||||
[styleguide]: ./styleguide
|
||||
[cli-reference]: ./reference/cli
|
||||
[schema-reference]: ./reference/schema
|
||||
[usage-guide]: ./guide
|
||||
[experiments]: ./experiments/index.md
|
||||
[experiments-workflow]: ./experiments/index.md#workflow
|
||||
[styleguide]: ./styleguide.md
|
||||
[cli-reference]: ./reference/cli.md
|
||||
[schema-reference]: ./reference/schema.md
|
||||
[usage-guide]: ./guide/index.md
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
---
|
||||
title: 'Completion Scripts'
|
||||
description: Deprecation of direct completion scripts in Task’s Git directory
|
||||
section: Project
|
||||
docType: project
|
||||
outline: deep
|
||||
---
|
||||
|
||||
@@ -21,5 +23,5 @@ the future as the scripts may be moved or deleted entirely. Any configuration
|
||||
should be updated to use the [new method for generating shell
|
||||
completions][completions] instead.
|
||||
|
||||
[completions]: /docs/installation#setup-completions
|
||||
[completions]: ../installation.md#setup-completions
|
||||
[task]: https://github.com/go-task/task
|
||||
|
||||
@@ -3,6 +3,8 @@ title: Deprecations
|
||||
description:
|
||||
Guide to deprecated features in Task and how to migrate to the new
|
||||
alternatives
|
||||
section: Project
|
||||
docType: project
|
||||
outline: deep
|
||||
---
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ title: 'Template Functions'
|
||||
description:
|
||||
Deprecation of some templating functions in Task, with guidance on their
|
||||
replacements.
|
||||
section: Project
|
||||
docType: project
|
||||
outline: deep
|
||||
---
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
---
|
||||
title: 'Version 2 Schema (#1197)'
|
||||
description: Deprecation of Taskfile schema version 2 and migration to version 3
|
||||
section: Project
|
||||
docType: project
|
||||
outline: deep
|
||||
---
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
title: 'Env Precedence (#1038)'
|
||||
description:
|
||||
Experiment to change the precedence of environment variables in Task
|
||||
section: Project
|
||||
docType: project
|
||||
outline: deep
|
||||
---
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
---
|
||||
title: 'Gentle Force (#1200)'
|
||||
description: Experiment to modify the behavior of the --force flag in Task
|
||||
section: Project
|
||||
docType: project
|
||||
outline: deep
|
||||
---
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
---
|
||||
title: Experiments
|
||||
description: Guide to Task’s experimental features and how to use them
|
||||
section: Project
|
||||
docType: project
|
||||
outline: deep
|
||||
---
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
---
|
||||
title: Remote Taskfiles (#1317)
|
||||
description: Experimentation for using Taskfiles stored in remote locations
|
||||
section: Project
|
||||
docType: project
|
||||
outline: deep
|
||||
---
|
||||
|
||||
@@ -9,6 +12,6 @@ The Remote Taskfiles experiment has now [been released][changelog] :tada:. To
|
||||
learn more, you can read the [remote Taskfile docs][remote-taskfile-docs] or
|
||||
check out our [blog post][blog-post].
|
||||
|
||||
[changelog]: ../changelog.md#v3511---2026-05-16
|
||||
[changelog]: ../changelog.md#v3-51-1-2026-05-16
|
||||
[remote-taskfile-docs]: ../remote-taskfiles.md
|
||||
[blog-post]: ../../blog/remote-taskfiles
|
||||
[blog-post]: ../../blog/remote-taskfiles.md
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
---
|
||||
title: '--- Template ---'
|
||||
description: Template for documenting a new experiment.
|
||||
---
|
||||
|
||||
# \{Name of Experiment\} (#\{Issue\})
|
||||
@@ -33,4 +34,4 @@ information.
|
||||
|
||||
\{Short explanation of how users should migrate to the new behavior\}
|
||||
|
||||
[enabling-experiments]: /docs/experiments/#enabling-experiments
|
||||
[enabling-experiments]: ./index.md#enabling-experiments
|
||||
|
||||
@@ -3,6 +3,8 @@ title: FAQ
|
||||
description:
|
||||
Frequently asked questions about Task, including ETAs, shell limitations, and
|
||||
Windows compatibility
|
||||
section: Project
|
||||
docType: project
|
||||
outline: deep
|
||||
---
|
||||
|
||||
@@ -104,7 +106,7 @@ This is possible because Task compiles a small set of core utilities in Go and
|
||||
enables them by default on Windows for greater compatibility.
|
||||
|
||||
It's possible to control whether these builtin core utilities are used or not
|
||||
with the [`TASK_CORE_UTILS`](/docs/reference/environment#task-core-utils)
|
||||
with the [`TASK_CORE_UTILS`](./reference/environment.md#task-core-utils)
|
||||
environment variable:
|
||||
|
||||
```bash
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
---
|
||||
title: Getting Started
|
||||
title: Quick Start
|
||||
description: Guide for getting started with Task
|
||||
section: Getting Started
|
||||
docType: guide
|
||||
outline: deep
|
||||
---
|
||||
|
||||
# Getting Started
|
||||
# Quick Start {#getting-started}
|
||||
|
||||
The following guide will help introduce you to the basics of Task. We'll cover
|
||||
how to create a Taskfile, how to write a basic task and how to call it. If you
|
||||
haven't installed Task yet, head over to our [installation guide](installation).
|
||||
haven't installed Task yet, head over to our
|
||||
[installation guide](./installation.md).
|
||||
|
||||
## Creating your first Taskfile
|
||||
|
||||
@@ -72,9 +75,9 @@ task default
|
||||
|
||||
Note that we don't have to specify the name of the Taskfile. Task will
|
||||
automatically look for a file called `Taskfile.yml` (or any of Task's
|
||||
[supported file names](/docs/guide#supported-file-names)) in the current
|
||||
directory. Additionally, tasks with the name `default` are special. They can
|
||||
also be run without specifying the task name.
|
||||
[supported file names](./guide/running-tasks.md#supported-file-names)) in the
|
||||
current directory. Additionally, tasks with the name `default` are special. They
|
||||
can also be run without specifying the task name.
|
||||
|
||||
If you created a Taskfile in a different directory, you can run it by passing
|
||||
the absolute or relative path to the directory as an argument using the `--dir`
|
||||
@@ -131,5 +134,6 @@ task build
|
||||
That's about it for the basics, but there's _so much_ more that you can do with
|
||||
Task. Check out the rest of the documentation to learn more about all the
|
||||
features Task has to offer! We recommend taking a look at the
|
||||
[usage guide](/docs/guide) next. Alternatively, you can check out our reference
|
||||
docs for the [Taskfile schema](reference/schema) and [CLI](reference/cli).
|
||||
[usage guide](./guide/index.md) next. Alternatively, you can check out our
|
||||
reference docs for the [Taskfile schema](./reference/schema.md) and
|
||||
[CLI](./reference/cli.md).
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
140
website/src/latest/docs/guide/arguments.md
Normal file
140
website/src/latest/docs/guide/arguments.md
Normal file
@@ -0,0 +1,140 @@
|
||||
---
|
||||
title: Command-line arguments
|
||||
description:
|
||||
Supply variables with NAME=value, forward arguments after --, and capture
|
||||
values with wildcard task names.
|
||||
section: Guide
|
||||
docType: guide
|
||||
outline: deep
|
||||
---
|
||||
|
||||
# Command-line arguments {#passing-arguments}
|
||||
|
||||
Choose how to pass input based on what needs to receive it:
|
||||
|
||||
| Input | Example | Read it with |
|
||||
| ----------------------- | ---------------------- | --------------------------------------- |
|
||||
| A Task variable | `task greet NAME=Bob` | <span v-pre>`{{.NAME}}`</span> |
|
||||
| Arguments for a command | `task yarn -- install` | <span v-pre>`{{.CLI_ARGS}}`</span> |
|
||||
| Part of a task name | `task start:api` | <span v-pre>`{{index .MATCH 0}}`</span> |
|
||||
|
||||
## Pass named values {#variable-assignments}
|
||||
|
||||
Pass `NAME=value` to supply a Task variable. A default in the root `vars` block
|
||||
can be overridden from the command line:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
vars:
|
||||
NAME: World
|
||||
|
||||
tasks:
|
||||
greet:
|
||||
cmds:
|
||||
- echo "Hello, {{.NAME}}!"
|
||||
```
|
||||
|
||||
```shell
|
||||
task greet NAME=Bob
|
||||
task greet "NAME=Jane Doe"
|
||||
```
|
||||
|
||||
Quote assignments that contain spaces. These assignments work across shells,
|
||||
including Windows, and are shared by all tasks in the invocation:
|
||||
|
||||
```shell
|
||||
task build test ENV=production
|
||||
```
|
||||
|
||||
A value declared in a task's own `vars` can override the command-line value. See
|
||||
[variable resolution](./variables.md#resolution-order) for precedence and
|
||||
configurable defaults. To set values in a command's shell environment, see
|
||||
[Environment variables](./environment.md).
|
||||
|
||||
## Forward command arguments {#forwarding-cli-arguments-to-commands}
|
||||
|
||||
Everything after `--` is available in `.CLI_ARGS`, including values containing
|
||||
`=`. Insert it into a command to forward those arguments. This example runs
|
||||
`yarn install`:
|
||||
|
||||
```shell
|
||||
$ task yarn -- install
|
||||
```
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
yarn:
|
||||
cmds:
|
||||
- yarn {{.CLI_ARGS}}
|
||||
```
|
||||
|
||||
## Capture task-name inputs {#wildcard-arguments}
|
||||
|
||||
Use `*` in a task name to turn a call such as `task start:api` into an input.
|
||||
Task captures each wildcard in the `.MATCH` array. Give the captured values
|
||||
names with `vars` so their meaning stays clear:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
start:*:*:
|
||||
vars:
|
||||
SERVICE: '{{index .MATCH 0}}'
|
||||
REPLICAS: '{{index .MATCH 1}}'
|
||||
cmds:
|
||||
- echo "Starting {{.SERVICE}} with {{.REPLICAS}} replicas"
|
||||
|
||||
start:*:
|
||||
vars:
|
||||
SERVICE: '{{index .MATCH 0}}'
|
||||
cmds:
|
||||
- echo "Starting {{.SERVICE}}"
|
||||
```
|
||||
|
||||
The first captured value becomes `SERVICE`:
|
||||
|
||||
```shell
|
||||
$ task start:foo
|
||||
Starting foo
|
||||
```
|
||||
|
||||
You can use whitespace in your arguments as long as you quote the task name:
|
||||
|
||||
```shell
|
||||
$ task "start:foo bar"
|
||||
Starting foo bar
|
||||
```
|
||||
|
||||
If multiple matching tasks are found, the first one listed in the Taskfile will
|
||||
be used. If you are using included Taskfiles, tasks in parent files will be
|
||||
considered first.
|
||||
|
||||
```shell
|
||||
$ task start:foo:3
|
||||
Starting foo with 3 replicas
|
||||
```
|
||||
|
||||
Wildcard task names also work with aliases:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
start:*:
|
||||
aliases: [run:*]
|
||||
vars:
|
||||
SERVICE: '{{index .MATCH 0}}'
|
||||
cmds:
|
||||
- echo "Running {{.SERVICE}}"
|
||||
```
|
||||
|
||||
Call the task through the `run:*` alias:
|
||||
|
||||
```shell
|
||||
$ task run:foo
|
||||
Running foo
|
||||
```
|
||||
186
website/src/latest/docs/guide/conditional-execution.md
Normal file
186
website/src/latest/docs/guide/conditional-execution.md
Normal file
@@ -0,0 +1,186 @@
|
||||
---
|
||||
title: Conditional execution
|
||||
description:
|
||||
Skip optional work with if, enforce requirements with preconditions, and ask
|
||||
for confirmation before execution with prompt.
|
||||
section: Guide
|
||||
docType: guide
|
||||
outline: deep
|
||||
---
|
||||
|
||||
# Conditional execution
|
||||
|
||||
Decide what a failed check should mean before choosing a setting: skip optional
|
||||
work, stop with an error, or ask the user whether to continue.
|
||||
|
||||
| What do you need? | Use |
|
||||
| -------------------------------- | ---------------------------------------------------------------------------------------------------- |
|
||||
| Skip optional work | [`if`](#conditional-execution-with-if) |
|
||||
| Stop when a requirement is unmet | [`preconditions`](#using-programmatic-checks-to-cancel-the-execution-of-a-task-and-its-dependencies) |
|
||||
| Ask before executing commands | [`prompt`](#confirmation-prompts) |
|
||||
| Skip work already completed | [Up-to-date checks](./up-to-date.md) |
|
||||
|
||||
## Skip optional work {#conditional-execution-with-if}
|
||||
|
||||
An `if` condition is a shell command. Exit code `0` allows execution; a non-zero
|
||||
exit code skips the guarded task or command without failing the run.
|
||||
|
||||
### Skip a whole task {#task-level-if}
|
||||
|
||||
Use a task-level condition for optional work. This task only runs when a `docs/`
|
||||
directory exists:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
docs:
|
||||
if: test -d docs
|
||||
cmds:
|
||||
- echo 'Building documentation'
|
||||
```
|
||||
|
||||
Run `task docs` with and without the directory. If it is absent, Task skips the
|
||||
task and its dependencies. Other tasks in the invocation can continue.
|
||||
|
||||
### Skip one command {#command-level-if}
|
||||
|
||||
Put `if` on a command when the rest of the task should still run:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
build:
|
||||
cmds:
|
||||
- cmd: echo 'Building documentation'
|
||||
if: test -d docs
|
||||
- echo 'Building the application'
|
||||
```
|
||||
|
||||
`task build` always prints the application message. It prints the documentation
|
||||
message first only if `docs/` exists.
|
||||
|
||||
### Check a Task variable {#using-templates-in-if-conditions}
|
||||
|
||||
Template comparisons produce `true` or `false`, which are also shell commands
|
||||
with the corresponding exit codes. Put a configurable default at the root:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
vars:
|
||||
ENABLE_FEATURE: 'false'
|
||||
|
||||
tasks:
|
||||
feature:
|
||||
if: '{{eq .ENABLE_FEATURE "true"}}'
|
||||
cmds:
|
||||
- echo 'Feature is enabled'
|
||||
```
|
||||
|
||||
`task feature ENABLE_FEATURE=true` runs the command. Without that override, Task
|
||||
skips it.
|
||||
|
||||
### Filter loop iterations {#using-if-with-for-loops}
|
||||
|
||||
A command's condition is evaluated for each iteration, with that iteration's
|
||||
values:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
process-items:
|
||||
cmds:
|
||||
- for: ['a', 'b', 'c']
|
||||
cmd: echo "processing {{.ITEM}}"
|
||||
if: '[ "{{.ITEM}}" != "b" ]'
|
||||
```
|
||||
|
||||
Run `task process-items` to print `processing a` and `processing c`. See
|
||||
[Loops](./loops.md) for the other iteration forms.
|
||||
|
||||
## Enforce a requirement {#using-programmatic-checks-to-cancel-the-execution-of-a-task-and-its-dependencies}
|
||||
|
||||
Use `preconditions` when missing a requirement should fail the task. Every check
|
||||
must exit with code `0`. Add `msg` to explain how to resolve a failure:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
generate-files:
|
||||
preconditions:
|
||||
- sh: test -f .env
|
||||
msg: 'Create a .env file before generating files.'
|
||||
cmds:
|
||||
- mkdir -p directory
|
||||
- touch directory/file.txt
|
||||
```
|
||||
|
||||
`task generate-files` fails with the message if `.env` is missing. Create the
|
||||
file and run it again to generate `directory/file.txt`.
|
||||
|
||||
A plain shell string also works when no custom message is needed. A failed
|
||||
precondition fails tasks that call or depend on this task. Dependencies of the
|
||||
checked task have already run before its preconditions are evaluated; put a
|
||||
check on the task whose commands need protecting.
|
||||
|
||||
`--force` bypasses preconditions as well as up-to-date checks.
|
||||
|
||||
### Choose skip or failure {#if-vs-preconditions}
|
||||
|
||||
Use `if` when skipping is an acceptable result. Use `preconditions` when a
|
||||
caller should receive an error instead. To require a variable or restrict its
|
||||
allowed values, use [Validation and prompts](./required-variables.md).
|
||||
|
||||
## Ask for confirmation {#confirmation-prompts}
|
||||
|
||||
Use `prompt` to ask for approval before a task's commands run. For example, this
|
||||
task asks before deleting a local build directory:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
clean:
|
||||
prompt: Remove the local build directory?
|
||||
cmds:
|
||||
- rm -rf build/
|
||||
```
|
||||
|
||||
Run `task clean` in a terminal and answer the confirmation. Declining stops the
|
||||
task with [exit code](../reference/cli.md#exit-codes) `205`.
|
||||
|
||||
Unlike
|
||||
[prompts for missing input](./required-variables.md#prompting-for-missing-variables-interactively),
|
||||
confirmation prompts do not require `--interactive`. Supplying every required
|
||||
variable does not bypass them.
|
||||
|
||||
For several confirmations, use a list:
|
||||
|
||||
```yaml
|
||||
prompt:
|
||||
- Remove the local build directory?
|
||||
- Have you saved everything you need from it?
|
||||
```
|
||||
|
||||
Task asks after dependencies have completed and before running `cmds`. If
|
||||
approval must precede other tasks, call them from `cmds` in the prompted task
|
||||
instead of listing them as dependencies.
|
||||
|
||||
Use `task --yes clean` (or `task -y clean`) to accept automatically. In CI or
|
||||
another environment without a terminal, confirmation fails unless automatic
|
||||
acceptance is enabled.
|
||||
|
||||
::: tip Related guide
|
||||
|
||||
<span id="limiting-when-tasks-run"></span>
|
||||
|
||||
To control how often a task runs when several tasks call it, use
|
||||
[`run: once` or `run: when_changed`](./dependencies.md#repeated-calls). These
|
||||
settings apply within one invocation. Use [up-to-date checks](./up-to-date.md)
|
||||
to skip completed work across invocations.
|
||||
|
||||
:::
|
||||
229
website/src/latest/docs/guide/defining-tasks.md
Normal file
229
website/src/latest/docs/guide/defining-tasks.md
Normal file
@@ -0,0 +1,229 @@
|
||||
---
|
||||
title: Defining tasks
|
||||
description:
|
||||
Task syntax shortcuts, internal tasks, aliases, the directory a task runs in,
|
||||
and the help text Task shows for it.
|
||||
section: Guide
|
||||
docType: guide
|
||||
outline: deep
|
||||
searchKeywords:
|
||||
task-aliases: [aliases, task aliases]
|
||||
---
|
||||
|
||||
# Defining tasks
|
||||
|
||||
Define tasks under `tasks`. Each task has a name and a list of commands in
|
||||
`cmds`. Add `desc` to explain what a task does:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
greet:
|
||||
desc: Print a greeting
|
||||
cmds:
|
||||
- echo "Hello, World!"
|
||||
```
|
||||
|
||||
Run `task greet` to execute it, or `task --list` to see its description. See
|
||||
[Running tasks](./running-tasks.md) for selecting a Taskfile and previewing
|
||||
commands.
|
||||
|
||||
## Choose a task name
|
||||
|
||||
The name under `tasks` is the name you pass to the CLI. Call your main task
|
||||
`default` if it should run when someone types `task` without a name.
|
||||
|
||||
Use `desc` for the short explanation shown by `task --list`, `aliases` for
|
||||
alternative names, and `label` to customize log messages. The sections below
|
||||
show each independently.
|
||||
|
||||
## Use command shortcuts {#short-task-syntax}
|
||||
|
||||
Use shorthand syntax for tasks that only need commands. Use the full form when
|
||||
you need properties such as `env`, `vars`, `desc` or `silent`:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
build: go build -v -o ./app{{exeExt}} .
|
||||
|
||||
run:
|
||||
- task: build
|
||||
- ./app{{exeExt}} -h localhost -p 8080
|
||||
```
|
||||
|
||||
## Keep helpers internal {#internal-tasks}
|
||||
|
||||
Set `internal: true` on a helper that should only be called by other tasks. It
|
||||
stays out of `task --list` and `task --list-all`, and a direct CLI call fails.
|
||||
Expose a public task that supplies the helper's inputs:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
build-image-1:
|
||||
cmds:
|
||||
- task: build-image
|
||||
vars:
|
||||
DOCKER_IMAGE: image-1
|
||||
|
||||
build-image:
|
||||
internal: true
|
||||
cmds:
|
||||
- docker build -t {{.DOCKER_IMAGE}} .
|
||||
```
|
||||
|
||||
## Set the working directory {#task-directory}
|
||||
|
||||
Set `dir` when commands need to run in a subdirectory. Relative paths are
|
||||
resolved from the Taskfile's execution directory:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
serve:
|
||||
dir: public/www
|
||||
cmds:
|
||||
# run http server
|
||||
- caddy
|
||||
```
|
||||
|
||||
Run `task serve` to start the server in `public/www`. Task creates the directory
|
||||
if it does not exist. For included Taskfiles, configure the
|
||||
[include directory](./includes.md#directory-of-included-taskfile).
|
||||
|
||||
## Add shorter names {#task-aliases}
|
||||
|
||||
Aliases are alternative names for tasks. They can be used to make it easier and
|
||||
quicker to run tasks with long or hard-to-type names. You can use them on the
|
||||
command line, when [calling sub-tasks](./dependencies.md#calling-another-task)
|
||||
in your Taskfile and when [including tasks](./includes.md) with aliases from
|
||||
another Taskfile. They can also be used together with
|
||||
[namespace aliases](./includes.md#namespace-aliases).
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
generate:
|
||||
aliases: [gen]
|
||||
cmds:
|
||||
- task: gen-mocks
|
||||
|
||||
generate-mocks:
|
||||
aliases: [gen-mocks]
|
||||
cmds:
|
||||
- echo "generating..."
|
||||
```
|
||||
|
||||
## Customize log labels {#overriding-task-name}
|
||||
|
||||
Use `label` to customize the name shown in summaries and status messages. Labels
|
||||
can contain templates. They do not rename the task you call:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
default:
|
||||
cmds:
|
||||
- task: print
|
||||
vars:
|
||||
MESSAGE: hello
|
||||
- task: print
|
||||
vars:
|
||||
MESSAGE: world
|
||||
|
||||
print:
|
||||
label: 'print-{{.MESSAGE}}'
|
||||
cmds:
|
||||
- echo "{{.MESSAGE}}"
|
||||
```
|
||||
|
||||
## Describe public tasks {#help}
|
||||
|
||||
Running `task --list` (or `task -l`) lists all tasks with a description. The
|
||||
following Taskfile:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
build:
|
||||
desc: Build the Go binary.
|
||||
cmds:
|
||||
- go build -v main.go
|
||||
|
||||
test:
|
||||
desc: Run all Go tests.
|
||||
cmds:
|
||||
- go test -race ./...
|
||||
|
||||
js:
|
||||
cmds:
|
||||
- esbuild --bundle --minify js/index.js > public/bundle.js
|
||||
|
||||
css:
|
||||
cmds:
|
||||
- esbuild --bundle --minify css/index.css > public/bundle.css
|
||||
```
|
||||
|
||||
would print the following output:
|
||||
|
||||
```shell
|
||||
* build: Build the Go binary.
|
||||
* test: Run all Go tests.
|
||||
```
|
||||
|
||||
Use `--list-all` (or `-a`) to also list tasks without a description. Internal
|
||||
tasks remain hidden.
|
||||
|
||||
## Explain a task in detail {#display-summary-of-task}
|
||||
|
||||
Running `task --summary task-name` will show a summary of a task. The following
|
||||
Taskfile:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
release:
|
||||
deps: [build]
|
||||
summary: |
|
||||
Release your project to GitHub
|
||||
|
||||
It will build your project before starting the release.
|
||||
Please make sure that you have set GITHUB_TOKEN before starting.
|
||||
cmds:
|
||||
- your-release-tool
|
||||
|
||||
build:
|
||||
cmds:
|
||||
- your-build-tool
|
||||
```
|
||||
|
||||
`task --summary release` prints:
|
||||
|
||||
```
|
||||
task: release
|
||||
|
||||
Release your project to GitHub
|
||||
|
||||
It will build your project before starting the release.
|
||||
Please make sure that you have set GITHUB_TOKEN before starting.
|
||||
|
||||
dependencies:
|
||||
- build
|
||||
|
||||
commands:
|
||||
- your-release-tool
|
||||
```
|
||||
|
||||
If a summary is missing, the description will be printed. If the task does not
|
||||
have a summary or a description, a warning is printed.
|
||||
|
||||
Showing a summary does not execute the task.
|
||||
266
website/src/latest/docs/guide/dependencies.md
Normal file
266
website/src/latest/docs/guide/dependencies.md
Normal file
@@ -0,0 +1,266 @@
|
||||
---
|
||||
title: Dependencies and task calls
|
||||
description:
|
||||
Run checks before a build, put tasks in order, pass variables, and control
|
||||
repeated calls and cleanup.
|
||||
section: Guide
|
||||
docType: guide
|
||||
outline: deep
|
||||
---
|
||||
|
||||
# Dependencies and task calls
|
||||
|
||||
A build often needs several steps: lint the code, run tests, then compile. Use
|
||||
`deps` when the checks can run in parallel, or task calls in `cmds` when each
|
||||
step must finish before the next starts.
|
||||
|
||||
## Run dependencies first {#task-dependencies}
|
||||
|
||||
In a Go project, this Taskfile runs lint and tests before building:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
build:
|
||||
deps: [lint, test]
|
||||
cmds:
|
||||
- go build ./...
|
||||
|
||||
lint:
|
||||
cmds:
|
||||
- go vet ./...
|
||||
|
||||
test:
|
||||
cmds:
|
||||
- go test ./...
|
||||
```
|
||||
|
||||
Run `task build`. Task starts `lint` and `test` concurrently and waits for both
|
||||
to succeed before running `go build`. If either fails, the build command does
|
||||
not run.
|
||||
|
||||
The order of entries in `deps` does not set their execution order. Use
|
||||
[task calls in `cmds`](#calling-another-task) if tests must wait for lint to
|
||||
finish.
|
||||
|
||||
You can also group tasks without adding commands. Add this task to the same
|
||||
Taskfile to run only the checks with `task check`:
|
||||
|
||||
```yaml
|
||||
tasks:
|
||||
check:
|
||||
deps: [lint, test]
|
||||
```
|
||||
|
||||
## Run task calls in order {#calling-another-task}
|
||||
|
||||
To run lint, then tests, then the build, replace `build` in the example above
|
||||
with:
|
||||
|
||||
```yaml
|
||||
tasks:
|
||||
build:
|
||||
cmds:
|
||||
- task: lint
|
||||
- task: test
|
||||
- go build ./...
|
||||
```
|
||||
|
||||
Task waits for each command or task call to succeed before starting the next. If
|
||||
lint fails, neither tests nor the build run.
|
||||
|
||||
Each called task still runs its own dependencies first. You can combine the two
|
||||
forms: use `deps` for independent prerequisites and `cmds` for the steps that
|
||||
need an order.
|
||||
|
||||
::: tip Calling tasks from another Taskfile
|
||||
|
||||
To call a task declared in the root Taskfile from an
|
||||
[included Taskfile](./includes.md), add a leading `:`, for example
|
||||
`task: :build`.
|
||||
|
||||
:::
|
||||
|
||||
## Pass variables to a task
|
||||
|
||||
Use the object form of a task call to provide `vars`. You can also set
|
||||
`silent: true` to hide the command being executed for that call:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
greet:
|
||||
cmds:
|
||||
- echo "Hello, {{.RECIPIENT}}!"
|
||||
|
||||
greet:all:
|
||||
cmds:
|
||||
- task: greet
|
||||
vars: { RECIPIENT: 'World' }
|
||||
- task: greet
|
||||
vars: { RECIPIENT: 'Cruel World' }
|
||||
silent: true
|
||||
```
|
||||
|
||||
`task greet:all` prints both greetings in order. The second call still prints
|
||||
its greeting: [silent mode](./output.md#silent-mode) hides the command, not its
|
||||
output.
|
||||
|
||||
The same `task`, `vars`, and `silent` fields work in `deps`. Use
|
||||
[references](./variables.md#referencing-other-variables) to pass arrays and maps
|
||||
without turning them into strings. To call a task for each value in a list, see
|
||||
[Looping over tasks](./loops.md#looping-over-tasks).
|
||||
|
||||
## Control parallel work
|
||||
|
||||
Dependencies run concurrently by default. To run tasks from the command line in
|
||||
parallel too, use `task --parallel lint test` (or `task -p lint test`).
|
||||
|
||||
### Limit concurrent tasks {#limiting-how-much-runs-at-once}
|
||||
|
||||
Use `--concurrency` (or `-C`) when tasks compete for resources such as database
|
||||
connections or memory:
|
||||
|
||||
```shell
|
||||
task --concurrency 2 build
|
||||
```
|
||||
|
||||
The default is `0`, meaning no limit. A limit of `1` restricts concurrency but
|
||||
does not establish an order between dependencies; use task calls in `cmds` when
|
||||
order matters.
|
||||
|
||||
### Cancel on failure {#fail-fast-dependencies}
|
||||
|
||||
By default, Task lets the other dependencies finish if one fails. In either
|
||||
case, the parent task's commands do not run after a dependency failure.
|
||||
|
||||
Set `failfast: true` on a task to cancel its remaining dependency work when one
|
||||
dependency fails. For the build example:
|
||||
|
||||
```yaml
|
||||
tasks:
|
||||
build:
|
||||
deps: [lint, test]
|
||||
failfast: true
|
||||
cmds:
|
||||
- go build ./...
|
||||
```
|
||||
|
||||
Already-running commands receive cancellation; this does not undo work they have
|
||||
completed. You can also set `failfast: true` in [`.taskrc.yml`][config] or use
|
||||
`task --failfast build`. The CLI flag also applies to tasks started with
|
||||
`--parallel`.
|
||||
|
||||
### Read parallel output {#interleaved-output-is-expected}
|
||||
|
||||
Concurrent tasks can interleave their output, and the order may change between
|
||||
runs. Set `output: prefixed` to label each line with its task, or
|
||||
`output: group` to print each command's buffered output in one block when that
|
||||
command finishes. A group is per command, so blocks from different tasks can
|
||||
still alternate. See [Output and logging](./output.md) for examples.
|
||||
|
||||
## Control repeated calls {#repeated-calls}
|
||||
|
||||
A shared dependency can be reached through several tasks. By default, Task
|
||||
attempts to run it for each call. Use `run` to control repeated calls within one
|
||||
invocation:
|
||||
|
||||
| Value | Behavior |
|
||||
| ------------------ | ------------------------------------------------- |
|
||||
| `always` (default) | Attempt to run the task on every call. |
|
||||
| `once` | Run the task once, even if it is called again. |
|
||||
| `when_changed` | Run once for each distinct set of call variables. |
|
||||
|
||||
Set `run` on a task, or at the root of the Taskfile to provide a default for all
|
||||
tasks. A task's own setting takes precedence.
|
||||
|
||||
### Run shared setup once {#running-a-task-only-once}
|
||||
|
||||
If lint and tests both need setup, mark the setup task with `run: once`:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
check:
|
||||
deps: [lint, test]
|
||||
|
||||
lint:
|
||||
deps: [setup]
|
||||
cmds:
|
||||
- echo "Linting"
|
||||
|
||||
test:
|
||||
deps: [setup]
|
||||
cmds:
|
||||
- echo "Testing"
|
||||
|
||||
setup:
|
||||
run: once
|
||||
cmds:
|
||||
- echo "Setting up"
|
||||
```
|
||||
|
||||
`task check` prints `Setting up` once. Both lint and tests wait for that setup
|
||||
to finish. Without `run: once`, setup runs for each task that depends on it.
|
||||
|
||||
### Run once per input {#once-per-set-of-variables}
|
||||
|
||||
Use `run: when_changed` when a task may be called several times with the same
|
||||
inputs:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
default:
|
||||
cmds:
|
||||
- task: generate
|
||||
vars: { CONTENT: '1' }
|
||||
- task: generate
|
||||
vars: { CONTENT: '2' }
|
||||
- task: generate
|
||||
vars: { CONTENT: '2' }
|
||||
|
||||
generate:
|
||||
run: when_changed
|
||||
cmds:
|
||||
- echo {{.CONTENT}}
|
||||
```
|
||||
|
||||
This prints `1` and `2`. The third call repeats the second call's variables and
|
||||
is skipped.
|
||||
|
||||
The `run` settings do not remember earlier invocations of Task. To skip work
|
||||
when files or external artifacts have not changed, use
|
||||
[up-to-date checks](./up-to-date.md).
|
||||
|
||||
## Clean up after a task {#doing-task-cleanup-with-defer}
|
||||
|
||||
Use `defer` when a task acquires a resource that needs to be released. For
|
||||
example, this task starts Docker Compose services, runs integration tests, and
|
||||
stops the services even if the tests fail:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
integration:
|
||||
cmds:
|
||||
- docker compose up -d
|
||||
- defer: docker compose down
|
||||
- go test -tags=integration ./...
|
||||
```
|
||||
|
||||
Cleanup is registered when Task reaches the `defer` entry. Dependencies run
|
||||
before `cmds`, so a failed dependency prevents that registration. Keep the
|
||||
resource setup, `defer`, and the work that uses the resource in the command
|
||||
sequence, as above.
|
||||
|
||||
For multiple cleanup steps, cleanup tasks, and inspecting failures with
|
||||
`.EXIT_CODE`, see
|
||||
[Errors and cleanup](./errors-and-cleanup.md#cleanup-with-defer).
|
||||
|
||||
[config]: ../reference/config.md
|
||||
142
website/src/latest/docs/guide/environment.md
Normal file
142
website/src/latest/docs/guide/environment.md
Normal file
@@ -0,0 +1,142 @@
|
||||
---
|
||||
title: Environment variables
|
||||
description:
|
||||
Set environment variables on a single task or on every task, and load them
|
||||
from `.env` files.
|
||||
section: Guide
|
||||
docType: guide
|
||||
outline: deep
|
||||
---
|
||||
|
||||
# Environment variables
|
||||
|
||||
Use `env` for values a program reads from its environment. In this example, the
|
||||
shell reads `GREETING` with `$GREETING`:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
greet:
|
||||
env:
|
||||
GREETING: Hello, World!
|
||||
cmds:
|
||||
- echo "$GREETING"
|
||||
```
|
||||
|
||||
Run `task greet` to print the greeting. Task uses the same shell syntax on
|
||||
supported platforms, including Windows. For values used in Task templates, use
|
||||
[Variables](./variables.md#env-and-vars-are-not-the-same-thing).
|
||||
|
||||
## Set values for commands {#task}
|
||||
|
||||
Put `env` on a task to configure its commands, or at the root to provide values
|
||||
for every task:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
env:
|
||||
GREETING: Hello, World!
|
||||
|
||||
tasks:
|
||||
greet:
|
||||
cmds:
|
||||
- echo "$GREETING"
|
||||
|
||||
greet:local:
|
||||
env:
|
||||
GREETING: Hello from this task!
|
||||
cmds:
|
||||
- echo "$GREETING"
|
||||
```
|
||||
|
||||
With no `GREETING` in the process environment, `task greet` uses the root value
|
||||
and `task greet:local` uses the task's value.
|
||||
|
||||
By default, a variable already present in the process environment takes
|
||||
precedence over Taskfile `env` values. If the result differs from the example,
|
||||
check the environment used to launch Task. The
|
||||
[Env Precedence experiment](../experiments/env-precedence.md) changes this rule.
|
||||
|
||||
`env` values support templates and dynamic `sh` commands. For example, an entry
|
||||
<span v-pre>`BUILD_MODE: '{{.MODE}}'`</span> exports a Task variable to a
|
||||
command's environment. A `vars` entry alone is not exported to commands in
|
||||
`cmds`.
|
||||
|
||||
## Load values from files {#env-files}
|
||||
|
||||
Use `dotenv` to load values from files instead of repeating them in the
|
||||
Taskfile. Create these two files in your project:
|
||||
|
||||
::: code-group
|
||||
|
||||
```dotenv [.env]
|
||||
GREETING=Hello from .env!
|
||||
```
|
||||
|
||||
```yaml [Taskfile.yml]
|
||||
version: '3'
|
||||
|
||||
dotenv: ['.env']
|
||||
|
||||
tasks:
|
||||
greet:
|
||||
cmds:
|
||||
- echo "$GREETING"
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
Run `task greet` to use the value from `.env`, assuming the process environment
|
||||
does not already set `GREETING`.
|
||||
|
||||
### Choose file precedence
|
||||
|
||||
When several dotenv files define a name, the **first file wins**. Put local
|
||||
overrides before shared defaults:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
vars:
|
||||
ENV: development
|
||||
|
||||
tasks:
|
||||
greet:
|
||||
dotenv:
|
||||
- .env.local
|
||||
- .env.{{.ENV}}
|
||||
- .env
|
||||
cmds:
|
||||
- echo "$GREETING"
|
||||
```
|
||||
|
||||
`task greet ENV=testing` selects `.env.testing` for the middle entry. This
|
||||
example puts `dotenv` on the task so it can use call variables; root-level
|
||||
dotenv files are loaded before those variables are available. Missing dotenv
|
||||
files are skipped. Keep files containing local credentials out of version
|
||||
control.
|
||||
|
||||
### Load values for one task
|
||||
|
||||
Put `dotenv` on a task when only that task needs the file. Explicit task-level
|
||||
`env` values take precedence over values loaded from dotenv files:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
greet:
|
||||
dotenv: ['.env']
|
||||
env:
|
||||
GREETING: Hello from the task!
|
||||
cmds:
|
||||
- echo "$GREETING"
|
||||
```
|
||||
|
||||
The process environment still takes precedence by default. Dotenv paths can
|
||||
contain templates, as in <span v-pre>`'{{.HOME}}/.env'`</span>.
|
||||
|
||||
The `dotenv` key is not supported inside included Taskfiles. Load shared values
|
||||
in the entrypoint Taskfile instead. See [Including Taskfiles](./includes.md).
|
||||
97
website/src/latest/docs/guide/errors-and-cleanup.md
Normal file
97
website/src/latest/docs/guide/errors-and-cleanup.md
Normal file
@@ -0,0 +1,97 @@
|
||||
---
|
||||
title: Errors and cleanup
|
||||
description:
|
||||
Continue after selected command failures with ignore_error, schedule cleanup
|
||||
with defer, and inspect a failed command's exit code.
|
||||
section: Guide
|
||||
docType: guide
|
||||
outline: deep
|
||||
---
|
||||
|
||||
# Errors and cleanup
|
||||
|
||||
By default, a failed command stops its task. Use `ignore_error` when a failure
|
||||
can be tolerated, and `defer` for cleanup that must run after work finishes. For
|
||||
concurrent dependencies, see
|
||||
[fail-fast behavior](./dependencies.md#fail-fast-dependencies).
|
||||
|
||||
## Clean up after a task {#cleanup-with-defer}
|
||||
|
||||
Schedule a cleanup command with `defer`. Once Task reaches that entry in `cmds`,
|
||||
it registers the command to run when the task finishes, including if a later
|
||||
command fails. Deferred commands run in reverse order of registration. A `defer`
|
||||
that Task never reaches is not registered, for example when an earlier command
|
||||
or a dependency fails.
|
||||
|
||||
In this example, Task removes `tmpdir/` after the work command finishes:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
default:
|
||||
cmds:
|
||||
- mkdir -p tmpdir/
|
||||
- defer: rm -rf tmpdir/
|
||||
- echo 'Work completed' > tmpdir/result.txt
|
||||
```
|
||||
|
||||
Run `task`, then check that `tmpdir/` was removed. Replace the last command with
|
||||
`exit 1` to try the failure path: cleanup still runs and Task reports the
|
||||
failure. The directory name here is for the example; choose a task-specific path
|
||||
for real work.
|
||||
|
||||
### Reuse a cleanup task
|
||||
|
||||
Use a deferred task call when several tasks share the same cleanup:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
default:
|
||||
cmds:
|
||||
- mkdir -p tmpdir/
|
||||
- defer: { task: cleanup }
|
||||
- echo 'Work completed' > tmpdir/result.txt
|
||||
|
||||
cleanup: rm -rf tmpdir/
|
||||
```
|
||||
|
||||
### Inspect a failed command
|
||||
|
||||
A special variable `.EXIT_CODE` is exposed when a command exited with a non-zero
|
||||
[exit code](../reference/cli.md#exit-codes). You can check its presence to know
|
||||
if the task completed successfully or not:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
default:
|
||||
cmds:
|
||||
- defer:
|
||||
echo '{{if .EXIT_CODE}}Failed with
|
||||
{{.EXIT_CODE}}!{{else}}Success!{{end}}'
|
||||
- exit 1
|
||||
```
|
||||
|
||||
## Continue after an error {#ignoring-command-errors}
|
||||
|
||||
Set `ignore_error: true` on a command to continue after it fails:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
example:
|
||||
cmds:
|
||||
- cmd: exit 1
|
||||
ignore_error: true
|
||||
- echo "Continuing after the failed command"
|
||||
```
|
||||
|
||||
Without `ignore_error`, the `echo` command would not run.
|
||||
|
||||
You can also set `ignore_error` on a task to apply it to that task's commands.
|
||||
The setting does not propagate to other tasks called through `cmds` or `deps`.
|
||||
247
website/src/latest/docs/guide/includes.md
Normal file
247
website/src/latest/docs/guide/includes.md
Normal file
@@ -0,0 +1,247 @@
|
||||
---
|
||||
title: Including Taskfiles
|
||||
description:
|
||||
Reuse tasks across projects with `includes`, covering namespaces, optional and
|
||||
internal includes, flattening, and per-include variables.
|
||||
section: Guide
|
||||
docType: guide
|
||||
outline: deep
|
||||
searchKeywords:
|
||||
namespace-aliases: [aliases, namespace aliases]
|
||||
---
|
||||
|
||||
# Including Taskfiles {#including-other-taskfiles}
|
||||
|
||||
Use `includes` to split a project into smaller Taskfiles or reuse tasks across
|
||||
projects. Give each included file a namespace, then call its tasks through that
|
||||
name.
|
||||
|
||||
Start with a Markdown file at `docs/README.md`, then create these two Taskfiles:
|
||||
|
||||
::: code-group
|
||||
|
||||
```yaml [Taskfile.yml]
|
||||
version: '3'
|
||||
|
||||
includes:
|
||||
docs:
|
||||
taskfile: ./docs/Taskfile.yml
|
||||
dir: ./docs
|
||||
```
|
||||
|
||||
```yaml [docs/Taskfile.yml]
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
build:
|
||||
cmds:
|
||||
- mkdir -p build
|
||||
- cp README.md build/index.md
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
Run `task docs:build` to copy `docs/README.md` to `docs/build/index.md`. The
|
||||
`docs` namespace comes from the include key, not the directory name. You can
|
||||
also call `docs:build` from another task's `cmds` or `deps`.
|
||||
|
||||
An include path can point to a file or a directory. With `docs: ./docs`, Task
|
||||
looks for a supported Taskfile name in that directory. Paths are relative to the
|
||||
including file, and included Taskfiles must use the same schema version.
|
||||
|
||||
## Set the working directory {#directory-of-included-taskfile}
|
||||
|
||||
The `dir: ./docs` setting makes the included task read `docs/README.md` and
|
||||
write into `docs/build/`, even when you run `task docs:build` from the project
|
||||
root.
|
||||
|
||||
Without `dir`, included tasks use the including Taskfile's execution directory.
|
||||
The same commands would look for `README.md` and create `build/` at the project
|
||||
root. A Taskfile's location alone does not set its execution directory.
|
||||
|
||||
Individual tasks can also specify their own
|
||||
[working directory](./defining-tasks.md#task-directory).
|
||||
|
||||
## Configure reusable tasks {#vars-of-included-taskfiles}
|
||||
|
||||
Use `vars` on an include to configure reusable tasks. This example includes the
|
||||
same file twice with different image names:
|
||||
|
||||
::: code-group
|
||||
|
||||
```yaml [Taskfile.yml]
|
||||
version: '3'
|
||||
|
||||
includes:
|
||||
backend:
|
||||
taskfile: ./taskfiles/Docker.yml
|
||||
vars:
|
||||
DOCKER_IMAGE: backend_image
|
||||
frontend:
|
||||
taskfile: ./taskfiles/Docker.yml
|
||||
vars:
|
||||
DOCKER_IMAGE: frontend_image
|
||||
```
|
||||
|
||||
```yaml [taskfiles/Docker.yml]
|
||||
version: '3'
|
||||
|
||||
vars:
|
||||
DOCKER_IMAGE: '{{.DOCKER_IMAGE | default "app"}}'
|
||||
|
||||
tasks:
|
||||
build:
|
||||
cmds:
|
||||
- echo 'Building {{.DOCKER_IMAGE}}'
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
`task backend:build` prints `Building backend_image`; `task frontend:build`
|
||||
prints `Building frontend_image`.
|
||||
|
||||
The template default in the included file is deliberate. A constant value in
|
||||
that file's `vars` would override the value supplied by the include. See
|
||||
[variable precedence](./variables.md#resolution-order) for the full rules.
|
||||
|
||||
## Shorten namespace names {#namespace-aliases}
|
||||
|
||||
Add namespace `aliases` to shorten frequently used task names:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
includes:
|
||||
documentation:
|
||||
taskfile: ./docs/Taskfile.yml
|
||||
dir: ./docs
|
||||
aliases: [docs]
|
||||
```
|
||||
|
||||
Both `task documentation:build` and `task docs:build` call the same task.
|
||||
Namespace aliases can be combined with
|
||||
[task aliases](./defining-tasks.md#task-aliases).
|
||||
|
||||
## Allow a missing file {#optional-includes}
|
||||
|
||||
Use `optional: true` when a missing local Taskfile should not prevent the rest
|
||||
of the project from running:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
includes:
|
||||
local:
|
||||
taskfile: ./Taskfile.local.yml
|
||||
optional: true
|
||||
|
||||
tasks:
|
||||
greet:
|
||||
cmds:
|
||||
- echo 'Hello, World!'
|
||||
```
|
||||
|
||||
`task greet` works even without `Taskfile.local.yml`. Optional includes do not
|
||||
make tasks from a missing file available.
|
||||
|
||||
## Keep included tasks internal {#internal-includes}
|
||||
|
||||
Use `internal: true` when all tasks in an included file are helpers for your
|
||||
public tasks:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
includes:
|
||||
docs:
|
||||
taskfile: ./docs/Taskfile.yml
|
||||
dir: ./docs
|
||||
internal: true
|
||||
|
||||
tasks:
|
||||
build:
|
||||
cmds:
|
||||
- task: docs:build
|
||||
```
|
||||
|
||||
With the `docs/Taskfile.yml` from the first example, `task build` works, but
|
||||
`task docs:build` cannot be called directly. Internal tasks are also hidden from
|
||||
task listings.
|
||||
|
||||
## Remove the namespace {#flatten-includes}
|
||||
|
||||
Use `flatten: true` to expose included tasks without a namespace:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
includes:
|
||||
docs:
|
||||
taskfile: ./docs/Taskfile.yml
|
||||
dir: ./docs
|
||||
flatten: true
|
||||
```
|
||||
|
||||
With the first example's included file, call `task build` instead of
|
||||
`task docs:build`. Calls within the Taskfile can also use the flattened name.
|
||||
|
||||
If the root Taskfile already defines `build`, this inclusion fails with a name
|
||||
collision. Keep the namespace or exclude the conflicting included task.
|
||||
|
||||
## Exclude selected tasks {#exclude-tasks-from-being-included}
|
||||
|
||||
Use `excludes` to remove selected tasks from an include. Names match exactly;
|
||||
append `:*` to exclude a namespace:
|
||||
|
||||
::: code-group
|
||||
|
||||
```yaml [Taskfile.yml]
|
||||
version: '3'
|
||||
|
||||
includes:
|
||||
tools:
|
||||
taskfile: ./Tools.yml
|
||||
excludes: [debug, 'internal:*']
|
||||
```
|
||||
|
||||
```yaml [Tools.yml]
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
check: echo 'Checking project'
|
||||
debug: echo 'Debug details'
|
||||
internal:setup: echo 'Internal setup'
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
`task tools:check` works. `task tools:debug` and `task tools:internal:setup`
|
||||
fail because those tasks were excluded. `excludes` also works with `flatten`.
|
||||
|
||||
## Choose a file by OS {#os-specific-taskfiles}
|
||||
|
||||
Use the `OS` template function to select a file for the current platform:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
includes:
|
||||
build: ./Taskfile_{{OS}}.yml
|
||||
```
|
||||
|
||||
Provide files such as `Taskfile_linux.yml`, `Taskfile_darwin.yml`, and
|
||||
`Taskfile_windows.yml` for the platforms you support. If only a few commands
|
||||
differ,
|
||||
[platform restrictions](./platforms.md#platform-specific-tasks-and-commands) may
|
||||
be easier to maintain.
|
||||
|
||||
::: tip Related guide
|
||||
|
||||
<span id="remote-taskfiles"></span>
|
||||
|
||||
Replace the local path with an HTTP or Git location to reuse tasks maintained
|
||||
outside the project. Only run remote Taskfiles from sources you trust; they
|
||||
execute commands on your machine. See [Remote Taskfiles](../remote-taskfiles.md)
|
||||
for a complete example, checksum pinning, and offline use.
|
||||
|
||||
:::
|
||||
68
website/src/latest/docs/guide/index.md
Normal file
68
website/src/latest/docs/guide/index.md
Normal file
@@ -0,0 +1,68 @@
|
||||
---
|
||||
title: Guide
|
||||
description:
|
||||
Learn to define tasks, supply inputs, control execution, configure the
|
||||
environment and output, and include other Taskfiles.
|
||||
section: Guide
|
||||
docType: guide
|
||||
outline: deep
|
||||
---
|
||||
|
||||
# Guide
|
||||
|
||||
Use the guide to learn a feature or solve a specific problem. If you are new to
|
||||
Task, start with the [Quick Start](../getting-started.md). For accepted keys,
|
||||
flags and functions, use the [Taskfile Schema](../reference/schema.md),
|
||||
[CLI](../reference/cli.md) and [Templating](../reference/templating.md)
|
||||
references.
|
||||
|
||||
<GuideRedirect />
|
||||
|
||||
## Writing and running tasks {#writing-and-running-tasks}
|
||||
|
||||
- [Defining tasks](./defining-tasks.md): command lists, descriptions, aliases
|
||||
and display labels.
|
||||
- [Running tasks](./running-tasks.md): choosing a Taskfile, running from other
|
||||
directories, previewing commands and using interactive applications.
|
||||
|
||||
## Variables and arguments {#variables-and-environment}
|
||||
|
||||
- [Variables](./variables.md): declaring values, computing them with shell
|
||||
commands, preserving types and understanding resolution order.
|
||||
- [Command-line arguments](./arguments.md): assigning variables, forwarding
|
||||
arguments with `--` and capturing values from task names.
|
||||
- [Validation and prompts](./required-variables.md): requiring inputs,
|
||||
restricting allowed values and asking for missing values.
|
||||
- [Secret variables](./secret-variables.md): loading sensitive values and
|
||||
masking them in Task's command logs.
|
||||
|
||||
## Task execution {#controlling-what-runs}
|
||||
|
||||
- [Dependencies and task calls](./dependencies.md): running tasks concurrently
|
||||
or in sequence, limiting concurrency and controlling repeated calls.
|
||||
- [Loops](./loops.md): repeating commands or task calls over values, files and
|
||||
matrices.
|
||||
- [Conditional execution](./conditional-execution.md): skipping optional work
|
||||
with `if`, enforcing requirements with `preconditions` and asking for
|
||||
[confirmation](./conditional-execution.md#confirmation-prompts).
|
||||
- [Errors and cleanup](./errors-and-cleanup.md): continuing after selected
|
||||
failures and running cleanup with `defer`.
|
||||
- [Up-to-date checks](./up-to-date.md): skipping unchanged builds, checking for
|
||||
missing outputs and combining file checks with custom conditions.
|
||||
- [Watch mode](./watch.md): rerunning tasks when source files change.
|
||||
|
||||
## Environment and output {#execution-environment}
|
||||
|
||||
- [Environment variables](./environment.md): setting the environment for
|
||||
commands and loading `.env` files.
|
||||
- [Platforms and shells](./platforms.md): selecting platform-specific commands,
|
||||
understanding shell context and setting shell options.
|
||||
- [Output and logging](./output.md): streaming, grouping and prefixing output,
|
||||
hiding command echoes and displaying CI annotations.
|
||||
|
||||
## Including Taskfiles {#composing-taskfiles}
|
||||
|
||||
- [Including Taskfiles](./includes.md): sharing tasks with namespaces,
|
||||
configuring includes and passing variables to them.
|
||||
- [Remote Taskfiles](../remote-taskfiles.md): loading Taskfiles over HTTP or Git
|
||||
and managing trust, checksums and cached copies.
|
||||
275
website/src/latest/docs/guide/loops.md
Normal file
275
website/src/latest/docs/guide/loops.md
Normal file
@@ -0,0 +1,275 @@
|
||||
---
|
||||
title: Loops
|
||||
description:
|
||||
Repeat a command over a static list, a matrix, a variable, your task's
|
||||
sources, or other tasks.
|
||||
section: Guide
|
||||
docType: guide
|
||||
outline: deep
|
||||
---
|
||||
|
||||
# Loops
|
||||
|
||||
Use `for` to repeat a command or task call with different values. Start with a
|
||||
list, then choose a different input source when the values come from a variable,
|
||||
files, or several combinations.
|
||||
|
||||
## Repeat a command {#looping-over-a-static-list}
|
||||
|
||||
In a project containing `README.md` and `LICENSE`, this task saves a copy of
|
||||
each file in `backup/`. Put `for` beside `cmd` and read the current filename
|
||||
through `.ITEM`:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
backup:
|
||||
cmds:
|
||||
- mkdir -p backup
|
||||
- for: [README.md, LICENSE]
|
||||
cmd: cp '{{.ITEM}}' backup/
|
||||
```
|
||||
|
||||
Run `task backup` to create `backup/README.md` and `backup/LICENSE`. Command
|
||||
loops run in list order. Use [dependency loops](#looping-over-dependencies) for
|
||||
iterations that may run concurrently.
|
||||
|
||||
For a changing set of files, use
|
||||
[a source glob](#looping-over-your-task-s-sources-or-generated-files) instead of
|
||||
maintaining a fixed list.
|
||||
|
||||
## Read values from variables {#looping-over-variables}
|
||||
|
||||
Use `var` to read an existing variable. Strings are split on whitespace:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
greet:
|
||||
vars:
|
||||
NAMES: Alice Bob
|
||||
cmds:
|
||||
- for: { var: NAMES }
|
||||
cmd: echo "Hello, {{.ITEM}}!"
|
||||
```
|
||||
|
||||
For another separator, set `split`:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
greet:
|
||||
vars:
|
||||
NAMES: Alice,Bob
|
||||
cmds:
|
||||
- for: { var: NAMES, split: ',' }
|
||||
cmd: echo "Hello, {{.ITEM}}!"
|
||||
```
|
||||
|
||||
Arrays preserve values containing spaces:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
greet:
|
||||
vars:
|
||||
NAMES: ['Alice Smith', 'Bob Jones']
|
||||
cmds:
|
||||
- for: { var: NAMES }
|
||||
cmd: echo "Hello, {{.ITEM}}!"
|
||||
```
|
||||
|
||||
Maps expose the key as `.KEY` and the value as `.ITEM`. Their iteration order is
|
||||
not guaranteed:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
services:
|
||||
vars:
|
||||
PORTS:
|
||||
map: { api: 8080, worker: 9090 }
|
||||
cmds:
|
||||
- for: { var: PORTS }
|
||||
cmd: echo "{{.KEY}} uses port {{.ITEM}}"
|
||||
```
|
||||
|
||||
Dynamic variables work too. This example reads newline-separated names from an
|
||||
existing `names.txt` file:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
greet:
|
||||
vars:
|
||||
NAMES:
|
||||
sh: cat names.txt
|
||||
cmds:
|
||||
- for: { var: NAMES, split: "\n" }
|
||||
cmd: echo "Hello, {{.ITEM}}!"
|
||||
```
|
||||
|
||||
## Name the current item {#renaming-variables}
|
||||
|
||||
Use `as` to name the current item when that makes a command easier to read:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
greet:
|
||||
cmds:
|
||||
- for: { var: NAMES, as: NAME }
|
||||
cmd: echo "Hello, {{.NAME}}!"
|
||||
vars:
|
||||
NAMES: [Alice, Bob]
|
||||
```
|
||||
|
||||
## Repeat a task call {#looping-over-tasks}
|
||||
|
||||
Put `task` beside `for` to reuse another task for each item:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
default:
|
||||
cmds:
|
||||
- for: [api, worker]
|
||||
task: check
|
||||
vars:
|
||||
SERVICE: '{{.ITEM}}'
|
||||
|
||||
check:
|
||||
cmds:
|
||||
- echo "Checking {{.SERVICE}}"
|
||||
```
|
||||
|
||||
`task` checks `api` before `worker`. Each call finishes before the next starts.
|
||||
You can also template the task name itself:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
default:
|
||||
cmds:
|
||||
- for: [api, worker]
|
||||
task: check:{{.ITEM}}
|
||||
|
||||
check:api: echo 'Checking API'
|
||||
check:worker: echo 'Checking worker'
|
||||
```
|
||||
|
||||
## Run iterations in parallel {#looping-over-dependencies}
|
||||
|
||||
Use a loop in `deps` when the calls can run concurrently:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
default:
|
||||
deps:
|
||||
- for: [api, worker]
|
||||
task: check
|
||||
vars:
|
||||
SERVICE: '{{.ITEM}}'
|
||||
|
||||
check:
|
||||
cmds:
|
||||
- echo "Checking {{.SERVICE}}"
|
||||
```
|
||||
|
||||
The messages may appear in either order. All the input forms shown on this page
|
||||
also work with dependency loops. See
|
||||
[Dependencies and task calls](./dependencies.md) for concurrency limits and
|
||||
repeated-call policies.
|
||||
|
||||
## Try every combination {#looping-over-a-matrix}
|
||||
|
||||
Use `matrix` to visit every combination of several lists:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
targets:
|
||||
cmds:
|
||||
- for:
|
||||
matrix:
|
||||
OS: [linux, darwin]
|
||||
ARCH: [amd64, arm64]
|
||||
cmd: echo "{{.ITEM.OS}}/{{.ITEM.ARCH}}"
|
||||
```
|
||||
|
||||
`task targets` prints `linux/amd64`, `linux/arm64`, `darwin/amd64`, and
|
||||
`darwin/arm64`. These are ordinary iteration values; they do not change the
|
||||
platform on which Task runs.
|
||||
|
||||
Use `ref` to reuse lists defined elsewhere:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
vars:
|
||||
SYSTEMS: [linux, darwin]
|
||||
ARCHITECTURES: [amd64, arm64]
|
||||
|
||||
tasks:
|
||||
targets:
|
||||
cmds:
|
||||
- for:
|
||||
matrix:
|
||||
OS: { ref: .SYSTEMS }
|
||||
ARCH: { ref: .ARCHITECTURES }
|
||||
cmd: echo "{{.ITEM.OS}}/{{.ITEM.ARCH}}"
|
||||
```
|
||||
|
||||
## Loop over files {#looping-over-your-task-s-sources-or-generated-files}
|
||||
|
||||
Use `for: sources` or `for: generates` to reuse the task's file declarations.
|
||||
Globs are expanded before iteration:
|
||||
|
||||
::: code-group
|
||||
|
||||
```yaml [Sources]
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
show:
|
||||
sources: ['src/*.txt']
|
||||
cmds:
|
||||
- for: sources
|
||||
cmd: cat '{{.ITEM}}'
|
||||
```
|
||||
|
||||
```yaml [Generates]
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
show:
|
||||
generates: ['output/*.txt']
|
||||
cmds:
|
||||
- for: generates
|
||||
cmd: cat '{{.ITEM}}'
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
Run `task show` with matching files present. Paths are relative to the task's
|
||||
working directory. Source declarations also enable
|
||||
[up-to-date checks](./up-to-date.md); use `method: none` if this task should
|
||||
print the files every time.
|
||||
|
||||
To build an absolute path, combine a directory with the item using the
|
||||
`joinPath` template function, for example
|
||||
<span v-pre>`{{joinPath .TASK_DIR .ITEM}}`</span>. See the
|
||||
[file-path variables](../reference/templating.md#file-paths) for the available
|
||||
directory values.
|
||||
214
website/src/latest/docs/guide/output.md
Normal file
214
website/src/latest/docs/guide/output.md
Normal file
@@ -0,0 +1,214 @@
|
||||
---
|
||||
title: Output and logging
|
||||
description:
|
||||
Choose an output mode, hide command echoes, and display colors and failure
|
||||
annotations in CI.
|
||||
section: Guide
|
||||
docType: guide
|
||||
outline: deep
|
||||
---
|
||||
|
||||
# Output and logging
|
||||
|
||||
When several tasks run together, their output can be hard to follow. Choose an
|
||||
output mode to identify the source of each line or keep each command's output
|
||||
together. Use `silent` separately to hide the command text Task logs.
|
||||
|
||||
## Choose an output mode {#output-syntax}
|
||||
|
||||
| What do you need? | Mode |
|
||||
| ------------------------------------ | ----------------------- |
|
||||
| Live output without extra formatting | `interleaved` (default) |
|
||||
| Live output labeled by task | `prefixed` |
|
||||
| Each command's output in one block | `group` |
|
||||
|
||||
### Identify parallel output
|
||||
|
||||
Set `output: prefixed` at the root of the Taskfile:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
output: prefixed
|
||||
|
||||
tasks:
|
||||
check:
|
||||
deps: [lint, test]
|
||||
|
||||
lint:
|
||||
cmds:
|
||||
- echo 'Lint passed'
|
||||
|
||||
test:
|
||||
cmds:
|
||||
- echo 'Tests passed'
|
||||
```
|
||||
|
||||
Run `task --silent check`. The command output identifies each task:
|
||||
|
||||
```text
|
||||
[lint] Lint passed
|
||||
[test] Tests passed
|
||||
```
|
||||
|
||||
The lines may appear in either order because the tasks run concurrently. You can
|
||||
override the output mode for one invocation with `task --output group check` (or
|
||||
`task -o group check`).
|
||||
|
||||
Use a task's `prefix` to distinguish repeated calls with different inputs:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
output: prefixed
|
||||
|
||||
tasks:
|
||||
default:
|
||||
deps:
|
||||
- task: check
|
||||
vars: { SERVICE: api }
|
||||
- task: check
|
||||
vars: { SERVICE: worker }
|
||||
|
||||
check:
|
||||
prefix: 'check-{{.SERVICE}}'
|
||||
silent: true
|
||||
cmds:
|
||||
- echo 'Passed'
|
||||
```
|
||||
|
||||
The output uses `[check-api]` and `[check-worker]` prefixes.
|
||||
|
||||
### Group command output
|
||||
|
||||
Set `output: group` to buffer each command's stdout and stderr until that
|
||||
command finishes. Long-running commands do not provide live feedback in this
|
||||
mode. Groups are per command, so blocks from different tasks can still alternate
|
||||
between commands.
|
||||
|
||||
To show buffered output only when a command fails:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
silent: true
|
||||
output:
|
||||
group:
|
||||
error_only: true
|
||||
|
||||
tasks:
|
||||
passes: echo 'Everything passed'
|
||||
fails: echo 'Failure details' && exit 1
|
||||
```
|
||||
|
||||
`task passes` prints nothing. `task fails` prints `Failure details` and the
|
||||
failure message. Hiding successful output does not change exit codes.
|
||||
|
||||
## Hide command echoes {#silent-mode}
|
||||
|
||||
Use `--silent` (or `-s`) to hide the command text Task logs before execution.
|
||||
The command's own output remains visible:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
greet:
|
||||
cmds:
|
||||
- echo 'Hello, World!'
|
||||
```
|
||||
|
||||
`task greet` shows the command and its output. `task --silent greet` prints only
|
||||
`Hello, World!`.
|
||||
|
||||
To make this permanent for selected commands:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
greet:
|
||||
cmds:
|
||||
- cmd: echo 'Hello, World!'
|
||||
silent: true
|
||||
```
|
||||
|
||||
You can also set `silent: true` on a task for all its commands, or at the root
|
||||
of the Taskfile for all tasks.
|
||||
|
||||
To suppress a command's stdout, use shell redirection instead:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
quiet:
|
||||
cmds:
|
||||
- echo 'This output is discarded' > /dev/null
|
||||
```
|
||||
|
||||
Stderr remains visible unless you redirect it too. Silent mode is not a
|
||||
substitute for [secret masking](./secret-variables.md).
|
||||
|
||||
## Make CI logs readable {#ci-integration}
|
||||
|
||||
### Fold command logs
|
||||
|
||||
Use `output.group.begin` and `end` to add the markers a CI system uses for
|
||||
collapsible logs. For GitHub Actions:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
output:
|
||||
group:
|
||||
begin: '::group::{{.TASK}}'
|
||||
end: '::endgroup::'
|
||||
|
||||
tasks:
|
||||
default:
|
||||
silent: true
|
||||
cmds:
|
||||
- echo 'Hello, World!'
|
||||
```
|
||||
|
||||
Running `task` produces:
|
||||
|
||||
```text
|
||||
::group::default
|
||||
Hello, World!
|
||||
::endgroup::
|
||||
```
|
||||
|
||||
These markers follow
|
||||
[GitHub Actions' grouping format](https://docs.github.com/en/actions/learn-github-actions/workflow-commands-for-github-actions#grouping-log-lines).
|
||||
Other providers, such as
|
||||
[Azure Pipelines](https://docs.microsoft.com/en-us/azure/devops/pipelines/scripts/logging-commands?expand=1&view=azure-devops&tabs=bash#formatting-commands),
|
||||
use different markers.
|
||||
|
||||
### Control colors {#colored-output}
|
||||
|
||||
Task enables its colored output when `CI=true`, which most CI providers set
|
||||
automatically. Use `FORCE_COLOR=1` to force colors or `NO_COLOR=1` to disable
|
||||
them. Programs launched by Task may have their own color settings.
|
||||
|
||||
### Surface failures {#error-annotations}
|
||||
|
||||
When `GITHUB_ACTIONS=true`, Task automatically emits an annotation when a task
|
||||
fails, so the workflow can surface the error:
|
||||
|
||||
```text
|
||||
::error title=Task 'build' failed::exit status 1
|
||||
```
|
||||
|
||||
No Taskfile configuration is required for these annotations.
|
||||
|
||||
::: tip Related guide
|
||||
|
||||
<span id="ignore-errors"></span>
|
||||
|
||||
To continue after a selected failure, use `ignore_error`. See
|
||||
[Errors and cleanup](./errors-and-cleanup.md#ignoring-command-errors) for its
|
||||
scope and examples.
|
||||
|
||||
:::
|
||||
129
website/src/latest/docs/guide/platforms.md
Normal file
129
website/src/latest/docs/guide/platforms.md
Normal file
@@ -0,0 +1,129 @@
|
||||
---
|
||||
title: Platforms and shells
|
||||
description:
|
||||
Restrict tasks and commands to an operating system or architecture, and set
|
||||
shell options with `set` and `shopt`.
|
||||
section: Guide
|
||||
docType: guide
|
||||
outline: deep
|
||||
---
|
||||
|
||||
# Platforms and shells {#platform-specific-behaviour}
|
||||
|
||||
Task runs on Linux, macOS, and Windows. A portable Taskfile also needs commands
|
||||
and tools that work on the machines where you run it. Use `platforms` to select
|
||||
OS-specific steps, and keep shared work in the same task.
|
||||
|
||||
## Select platform commands {#platform-specific-tasks-and-commands}
|
||||
|
||||
Set `platforms` on an individual command when only part of a task differs by
|
||||
platform:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
setup:
|
||||
cmds:
|
||||
- cmd: echo 'Preparing Windows tools'
|
||||
platforms: [windows]
|
||||
- cmd: echo 'Preparing Unix tools'
|
||||
platforms: [linux, darwin]
|
||||
- echo 'Preparing shared files'
|
||||
```
|
||||
|
||||
Run `task setup`. A command whose platform does not match is skipped without an
|
||||
error; the shared command runs on every platform.
|
||||
|
||||
### Restrict a whole task
|
||||
|
||||
Put `platforms` on the task when none of its commands should run elsewhere:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
setup:windows:
|
||||
platforms: [windows/amd64]
|
||||
cmds:
|
||||
- echo 'Preparing tools for Windows on amd64'
|
||||
```
|
||||
|
||||
| Restriction | Matches |
|
||||
| ------------------------- | ---------------------------------------------- |
|
||||
| `[windows]` | Windows on any architecture |
|
||||
| `[amd64]` | Any supported OS on amd64 |
|
||||
| `[windows/amd64]` | Windows on amd64 |
|
||||
| `[windows/amd64, darwin]` | Windows on amd64, or macOS on any architecture |
|
||||
|
||||
OS and architecture names use Go's `GOOS` and `GOARCH` values. These
|
||||
restrictions check the machine running Task; they do not configure a compiler's
|
||||
target.
|
||||
|
||||
### Share platform values
|
||||
|
||||
The `OS` and `ARCH` template functions expose the current platform. Use them to
|
||||
select [OS-specific Taskfiles](./includes.md#os-specific-taskfiles) or construct
|
||||
arguments. Use `exeExt` for executable names that need `.exe` on Windows:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
build:
|
||||
cmds:
|
||||
- go build -o app{{exeExt}} main.go
|
||||
```
|
||||
|
||||
## Understand command shells
|
||||
|
||||
Task runs commands through its embedded shell interpreter. It does not start
|
||||
your interactive shell or load that shell's startup configuration. Use
|
||||
[Taskfile `env` and `dotenv`](./environment.md) for values commands need.
|
||||
|
||||
Each `cmds` entry gets a separate shell context. A `cd` or `export` in one entry
|
||||
does not carry over to the next. Set `dir` and `env` on the task instead:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
inspect:
|
||||
dir: src
|
||||
env:
|
||||
BUILD_MODE: development
|
||||
cmds:
|
||||
- pwd
|
||||
- echo "$BUILD_MODE"
|
||||
```
|
||||
|
||||
If several commands need to share shell state, put them in one multiline `cmd`
|
||||
or a script. Programs such as `go`, `npm`, or `docker` must still be installed.
|
||||
Invoke `bash`, `pwsh`, or `cmd /c` explicitly when a command needs that
|
||||
particular shell, and restrict it to machines where it is available.
|
||||
|
||||
## Configure shell options {#set-and-shopt}
|
||||
|
||||
Use `set` for POSIX shell options and `shopt` for supported Bash-style options.
|
||||
For example, `pipefail` makes a pipeline fail when an earlier command fails, and
|
||||
`globstar` enables recursive `**` globs in shell commands:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
set: [pipefail]
|
||||
shopt: [globstar]
|
||||
|
||||
tasks:
|
||||
list:
|
||||
cmds:
|
||||
- echo **/*.go
|
||||
```
|
||||
|
||||
These options can be set at the root, task, or command level. The shell
|
||||
interpreter supports a subset of shell options; see the
|
||||
[shell options reference](../reference/schema.md#shell-options).
|
||||
|
||||
`shopt` controls shell expansion inside commands. Globs in `sources` and
|
||||
`generates` use [Task's file matching](./up-to-date.md#track-the-right-files)
|
||||
and do not require `globstar`.
|
||||
170
website/src/latest/docs/guide/required-variables.md
Normal file
170
website/src/latest/docs/guide/required-variables.md
Normal file
@@ -0,0 +1,170 @@
|
||||
---
|
||||
title: Validation and prompts
|
||||
description:
|
||||
Require variables to be set, restrict them to allowed values, and prompt for
|
||||
missing input.
|
||||
section: Guide
|
||||
docType: guide
|
||||
outline: deep
|
||||
---
|
||||
|
||||
# Validation and prompts {#required-variables-and-prompts}
|
||||
|
||||
Use `requires` to catch missing inputs before a task runs. Add `enum` when only
|
||||
certain values are allowed, and enable interactive prompts when users should be
|
||||
able to fill in missing values at the terminal.
|
||||
|
||||
## Require an input {#ensuring-required-variables-are-set}
|
||||
|
||||
Declare inputs in `requires.vars`, then pass them on the command line:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
release:
|
||||
requires:
|
||||
vars: [VERSION]
|
||||
cmds:
|
||||
- echo "Preparing release {{.VERSION}}"
|
||||
```
|
||||
|
||||
Run `task release VERSION=1.2.3` to print the message. Without `VERSION`, Task
|
||||
fails and identifies the missing input. Task variables and values inherited from
|
||||
the process environment can satisfy the requirement.
|
||||
|
||||
A variable set to an empty string counts as present. To reject an empty value,
|
||||
use an enum of nonempty strings or a
|
||||
[precondition](./conditional-execution.md#using-programmatic-checks-to-cancel-the-execution-of-a-task-and-its-dependencies).
|
||||
|
||||
## Restrict allowed values {#ensuring-required-variables-have-allowed-values}
|
||||
|
||||
Use `name` and `enum` to require a string from a fixed list:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
deploy:
|
||||
requires:
|
||||
vars:
|
||||
- name: ENV
|
||||
enum: [dev, staging, prod]
|
||||
cmds:
|
||||
- echo "Deploying to {{.ENV}}"
|
||||
```
|
||||
|
||||
`task deploy ENV=staging` succeeds. `task deploy ENV=preview` fails before
|
||||
running the command. Enum validation applies to string variables, including
|
||||
strings inherited from the environment.
|
||||
|
||||
## Ask for missing input {#prompting-for-missing-variables-interactively}
|
||||
|
||||
Run `task --interactive deploy` with the example above to choose the missing
|
||||
`ENV` from a menu. Required variables without an enum use a text input instead.
|
||||
|
||||
To enable this behavior by default, set it in your
|
||||
[Task configuration](../reference/config.md#interactive):
|
||||
|
||||
```yaml [~/.taskrc.yml]
|
||||
interactive: true
|
||||
```
|
||||
|
||||
For a task with both kinds of input:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
deploy:
|
||||
requires:
|
||||
vars:
|
||||
- name: ENVIRONMENT
|
||||
enum: [dev, staging, prod]
|
||||
- VERSION
|
||||
cmds:
|
||||
- echo "Deploying {{.VERSION}} to {{.ENVIRONMENT}}"
|
||||
```
|
||||
|
||||
`task --interactive deploy` asks for an environment and a version. Values
|
||||
already supplied through the CLI, environment, or Taskfile do not prompt:
|
||||
|
||||
```shell
|
||||
task deploy ENVIRONMENT=prod VERSION=1.0.0
|
||||
```
|
||||
|
||||
Prompts require a terminal. In CI or another non-interactive environment,
|
||||
missing variables cause an error; supply all required values explicitly.
|
||||
|
||||
## Reuse allowed values {#using-variable-references-for-enum-values}
|
||||
|
||||
Define a shared list and reference it from an enum:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
vars:
|
||||
ALLOWED_ENVS: [dev, staging, prod]
|
||||
|
||||
tasks:
|
||||
deploy:
|
||||
requires:
|
||||
vars:
|
||||
- name: ENV
|
||||
enum:
|
||||
ref: .ALLOWED_ENVS
|
||||
cmds:
|
||||
- echo "Deploying to {{.ENV}}"
|
||||
```
|
||||
|
||||
References can also transform values. Given a `config.json` file containing
|
||||
`{"allowed_environments": ["dev", "prod"]}`, this reads the list from it:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
vars:
|
||||
CONFIG:
|
||||
sh: cat config.json
|
||||
|
||||
tasks:
|
||||
deploy:
|
||||
requires:
|
||||
vars:
|
||||
- name: ENV
|
||||
enum:
|
||||
ref: ( .CONFIG | fromJson ).allowed_environments
|
||||
cmds:
|
||||
- echo "Deploying to {{.ENV}}"
|
||||
```
|
||||
|
||||
For newline-separated command output, convert it to a list before using it as an
|
||||
enum. This example uses the entries in an existing `services/` directory:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
vars:
|
||||
AVAILABLE_SERVICES:
|
||||
sh: ls services/
|
||||
|
||||
tasks:
|
||||
deploy:
|
||||
requires:
|
||||
vars:
|
||||
- name: SERVICE
|
||||
enum:
|
||||
ref: .AVAILABLE_SERVICES | splitLines | compact
|
||||
cmds:
|
||||
- echo "Deploying {{.SERVICE}}"
|
||||
```
|
||||
|
||||
::: tip Related guide
|
||||
|
||||
<span id="warning-prompts"></span>
|
||||
|
||||
A prompt for input fills in a value. A
|
||||
[confirmation prompt](./conditional-execution.md#confirmation-prompts) asks
|
||||
whether execution should proceed, even if all input values are already present.
|
||||
|
||||
:::
|
||||
150
website/src/latest/docs/guide/running-tasks.md
Normal file
150
website/src/latest/docs/guide/running-tasks.md
Normal file
@@ -0,0 +1,150 @@
|
||||
---
|
||||
title: Running tasks
|
||||
description:
|
||||
How Task finds a Taskfile, and how to run one from a subdirectory, from your
|
||||
home directory, from standard input or as a dry run.
|
||||
section: Guide
|
||||
docType: guide
|
||||
outline: deep
|
||||
---
|
||||
|
||||
# Running tasks
|
||||
|
||||
Run `task <name>` from your project to execute a task. With no name, Task runs
|
||||
the `default` task. Start by listing tasks, then run one:
|
||||
|
||||
```shell
|
||||
task --list
|
||||
task build
|
||||
```
|
||||
|
||||
`--list` shows tasks with descriptions. Use `--list-all` to include tasks
|
||||
without descriptions; [internal tasks](./defining-tasks.md#internal-tasks)
|
||||
remain hidden. See [Defining tasks](./defining-tasks.md) to create these
|
||||
entries.
|
||||
|
||||
Pass several names, such as `task lint test`, to run them in order. Use
|
||||
[`--parallel`](./dependencies.md#limiting-how-much-runs-at-once) for independent
|
||||
tasks that can run concurrently. To pass values or command arguments, see
|
||||
[Command-line arguments](./arguments.md).
|
||||
|
||||
## Preview commands {#dry-run-mode}
|
||||
|
||||
Use `--dry` (or `-n`) to print the commands Task would run:
|
||||
|
||||
```shell
|
||||
task --dry build
|
||||
```
|
||||
|
||||
Task still resolves templates and dynamic variables while preparing the
|
||||
commands. A variable declared with `sh` can therefore execute its shell command
|
||||
during a dry run. See [Variables](./variables.md#when-values-are-computed).
|
||||
|
||||
## Run from a subdirectory {#running-a-taskfile-from-a-subdirectory}
|
||||
|
||||
If Task cannot find a Taskfile in the current directory, it searches parent
|
||||
directories. Tasks run from the directory containing that Taskfile unless
|
||||
[their `dir` setting](./defining-tasks.md#task-directory) changes it.
|
||||
|
||||
Use <span v-pre>`{{.USER_WORKING_DIR}}`</span> when the task should act on the
|
||||
directory where you invoked it. In a monorepo, this lets each service use the
|
||||
same task to start its Docker Compose services:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
up:
|
||||
dir: '{{.USER_WORKING_DIR}}'
|
||||
preconditions:
|
||||
- test -f docker-compose.yml
|
||||
cmds:
|
||||
- docker compose up -d
|
||||
```
|
||||
|
||||
From a service directory containing `docker-compose.yml`, run `task up`. The
|
||||
root Taskfile supplies the task; the service directory supplies its files.
|
||||
|
||||
## Use a personal Taskfile {#running-a-global-taskfile}
|
||||
|
||||
Store a Taskfile in your home directory and use `--global` (or `-g`) to call it
|
||||
from anywhere:
|
||||
|
||||
```shell
|
||||
task --global from-working-directory
|
||||
```
|
||||
|
||||
Global tasks run in your home directory by default. Set `dir` to
|
||||
<span v-pre>`{{.USER_WORKING_DIR}}`</span> when a personal utility should work
|
||||
on the current project:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
from-home:
|
||||
cmds:
|
||||
- pwd
|
||||
|
||||
from-working-directory:
|
||||
dir: '{{.USER_WORKING_DIR}}'
|
||||
cmds:
|
||||
- pwd
|
||||
```
|
||||
|
||||
## Read a Taskfile from stdin {#running-a-taskfile-from-stdin}
|
||||
|
||||
Use `--taskfile -` (or `-t -`) to read a generated Taskfile from standard input.
|
||||
For example, to read an existing file through stdin:
|
||||
|
||||
```shell
|
||||
task --taskfile - < ./Taskfile.yml
|
||||
```
|
||||
|
||||
You can also pipe the output of a Taskfile generator into `task --taskfile -`.
|
||||
With no task name, these commands run the generated file's `default` task.
|
||||
|
||||
## Run a terminal app {#interactive-cli-application}
|
||||
|
||||
Set `interactive: true` on a task that launches a terminal application:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
edit:
|
||||
interactive: true
|
||||
cmds:
|
||||
- vim my-file.txt
|
||||
```
|
||||
|
||||
Run `task edit` to open the editor. Interactive applications need direct access
|
||||
to the terminal; buffered or prefixed [output modes](./output.md#output-syntax)
|
||||
and other tasks running concurrently can interfere with their input and display.
|
||||
|
||||
This task setting is distinct from the CLI `--interactive` option, which
|
||||
[prompts for missing variables](./required-variables.md#prompting-for-missing-variables-interactively).
|
||||
|
||||
## Choose a file name {#supported-file-names}
|
||||
|
||||
Use `--taskfile` to choose a specific file or `--dir` to run in another project:
|
||||
|
||||
```shell
|
||||
task --taskfile Taskfile.ci.yml build
|
||||
task --dir ./backend build
|
||||
```
|
||||
|
||||
Task looks for these names in order of priority:
|
||||
|
||||
- `Taskfile.yml`
|
||||
- `taskfile.yml`
|
||||
- `Taskfile.yaml`
|
||||
- `taskfile.yaml`
|
||||
- `Taskfile.dist.yml`
|
||||
- `taskfile.dist.yml`
|
||||
- `Taskfile.dist.yaml`
|
||||
- `taskfile.dist.yaml`
|
||||
|
||||
Commit a `.dist` variant if users need to supply their own `Taskfile.yml`
|
||||
override. The local file takes priority; add it to `.gitignore` if it should
|
||||
remain personal.
|
||||
104
website/src/latest/docs/guide/secret-variables.md
Normal file
104
website/src/latest/docs/guide/secret-variables.md
Normal file
@@ -0,0 +1,104 @@
|
||||
---
|
||||
title: Secret variables
|
||||
description:
|
||||
Mask sensitive variable values in Task's command logs, load secrets from
|
||||
external sources, and understand what masking does not protect.
|
||||
section: Guide
|
||||
docType: guide
|
||||
outline: deep
|
||||
---
|
||||
|
||||
# Secret variables
|
||||
|
||||
Set `secret: true` on a variable to replace its value with `*****` in Task's own
|
||||
command logs. The command still receives the original value.
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
vars:
|
||||
API_TOKEN:
|
||||
sh: echo "$MY_API_TOKEN"
|
||||
secret: true
|
||||
|
||||
tasks:
|
||||
request:
|
||||
cmds:
|
||||
- 'curl -H "Authorization: Bearer {{.API_TOKEN}}" https://api.example.com'
|
||||
# Logged as: curl -H "Authorization: Bearer *****" https://api.example.com
|
||||
```
|
||||
|
||||
Set `MY_API_TOKEN` in the environment before running `task request`. Task's log
|
||||
masks the token, while `curl` receives the real value. The example URL is a
|
||||
placeholder; replace it with your API endpoint.
|
||||
|
||||
Secret variables can be declared globally or on a task. Use `value` instead of
|
||||
`sh` for a literal or template value, and keep real credentials out of committed
|
||||
Taskfiles.
|
||||
|
||||
## Load from a secret store {#loading-secrets}
|
||||
|
||||
Use a dynamic variable to read a secret from an external source:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
vars:
|
||||
API_TOKEN:
|
||||
sh: vault kv get -field=api_key secret/myapp
|
||||
secret: true
|
||||
|
||||
tasks:
|
||||
request:
|
||||
cmds:
|
||||
- 'curl -H "Authorization: Bearer {{.API_TOKEN}}" https://api.example.com'
|
||||
```
|
||||
|
||||
To read an existing environment variable, replace the `sh` command with
|
||||
`echo "$MY_API_TOKEN"`. Keep local credential files, such as `.env.local`, out
|
||||
of version control.
|
||||
|
||||
For dynamic variable evaluation and caching, see
|
||||
[When values are computed](./variables.md#when-values-are-computed).
|
||||
|
||||
## Mark derived secrets {#derived-values}
|
||||
|
||||
The `secret` flag does not propagate to variables that reference a secret. Mark
|
||||
every variable carrying the sensitive value as secret:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
vars:
|
||||
API_TOKEN:
|
||||
sh: echo "$MY_API_TOKEN"
|
||||
secret: true
|
||||
AUTH_HEADER:
|
||||
value: 'Bearer {{.API_TOKEN}}'
|
||||
secret: true
|
||||
|
||||
tasks:
|
||||
request:
|
||||
cmds:
|
||||
- 'curl -H "Authorization: {{.AUTH_HEADER}}" https://api.example.com'
|
||||
# Logged as: curl -H "Authorization: *****" https://api.example.com
|
||||
```
|
||||
|
||||
Without `secret: true` on `AUTH_HEADER`, Task's command log would expose the
|
||||
derived value.
|
||||
|
||||
## Understand masking limits {#limits-of-masking}
|
||||
|
||||
Masking applies to Task's own command logs, including when those logs are
|
||||
collected by a CI system. It does not redact:
|
||||
|
||||
- stdout or stderr produced by commands;
|
||||
- process arguments visible to tools such as `ps`;
|
||||
- values stored in shell history or committed files;
|
||||
- derived variables that are not themselves marked as secret.
|
||||
|
||||
For example, a command that echoes a secret still prints its real value, even
|
||||
though Task masks the command text it logs before execution.
|
||||
|
||||
The `secret` flag applies to `vars`, not `env`. Use your command's supported
|
||||
credential mechanism to control how it receives secrets.
|
||||
236
website/src/latest/docs/guide/up-to-date.md
Normal file
236
website/src/latest/docs/guide/up-to-date.md
Normal file
@@ -0,0 +1,236 @@
|
||||
---
|
||||
title: Up-to-date checks
|
||||
description:
|
||||
Skip unchanged builds, check whether work is already done, and choose between
|
||||
source fingerprints and status commands.
|
||||
section: Guide
|
||||
docType: guide
|
||||
outline: deep
|
||||
---
|
||||
|
||||
# Up-to-date checks {#skipping-work-that-is-up-to-date}
|
||||
|
||||
A build should run when its inputs change or its output is missing. Declare
|
||||
those files with `sources` and `generates`, and Task can skip the commands on
|
||||
your next run. For other kinds of work, use `status` to check whether the result
|
||||
is already available.
|
||||
|
||||
## Skip unchanged builds {#by-fingerprinting-locally-generated-files-and-their-sources}
|
||||
|
||||
For a Go application in `main.go`, declare the source file and the executable
|
||||
that the build produces:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
build:
|
||||
sources: [main.go]
|
||||
generates: ['app{{exeExt}}']
|
||||
cmds:
|
||||
- go build -o app{{exeExt}} main.go
|
||||
```
|
||||
|
||||
Run `task build` to create the executable. Run it again without changing
|
||||
`main.go`, and Task reports that `build` is up to date. Edit `main.go` or delete
|
||||
the executable, and the next call builds it again.
|
||||
|
||||
The default method, `checksum`, compares the content of source files with a
|
||||
saved fingerprint. It checks that declared outputs exist; it does not compare
|
||||
their contents. Editing the executable alone will not trigger a rebuild.
|
||||
|
||||
These checks skip the task's commands. Its [dependencies](./dependencies.md)
|
||||
still run first and perform their own up-to-date checks.
|
||||
|
||||
### Track the right files
|
||||
|
||||
`sources` and `generates` accept files and glob patterns, relative to the task's
|
||||
[working directory](./defining-tasks.md#task-directory). Include every file that
|
||||
affects the result, such as source code, configuration, and dependency
|
||||
lockfiles.
|
||||
|
||||
For a Go module with several source files, replace `sources` and `cmds` in the
|
||||
example above with:
|
||||
|
||||
```yaml
|
||||
sources:
|
||||
- '**/*.go'
|
||||
- go.mod
|
||||
- go.sum
|
||||
- exclude: '**/*_test.go'
|
||||
cmds:
|
||||
- go build -o app{{exeExt}} .
|
||||
```
|
||||
|
||||
Patterns are evaluated in order. Put each `exclude` after the positive glob it
|
||||
narrows. Here, test files are excluded because this task builds the application;
|
||||
a test task should track them.
|
||||
|
||||
Set `use_gitignore: true` at the root of the Taskfile to filter glob matches
|
||||
using `.gitignore` rules. A task can override that setting. Keep it disabled for
|
||||
tasks that need to track ignored files as inputs.
|
||||
|
||||
`generates` is optional. A task such as a test suite can use `sources` alone to
|
||||
skip work when its inputs have not changed. `generates` alone does not provide a
|
||||
file fingerprint; use `status` if you only need to check that a result exists.
|
||||
|
||||
### Choose a check method
|
||||
|
||||
| Method | How it checks sources |
|
||||
| -------------------- | -------------------------------------------------------------------- |
|
||||
| `checksum` (default) | Compares file contents with a saved fingerprint. |
|
||||
| `timestamp` | Compares modification times with outputs and Task's saved timestamp. |
|
||||
| `none` | Disables file-based skipping. |
|
||||
|
||||
To use modification times for the build above, add `method: timestamp` to the
|
||||
task:
|
||||
|
||||
```yaml
|
||||
tasks:
|
||||
build:
|
||||
method: timestamp
|
||||
sources: [main.go]
|
||||
generates: ['app{{exeExt}}']
|
||||
cmds:
|
||||
- go build -o app{{exeExt}} main.go
|
||||
```
|
||||
|
||||
You can also set `method` at the root of the Taskfile to change the default for
|
||||
all tasks. A task's own setting takes precedence.
|
||||
|
||||
With `timestamp`, touching a source can cause a rerun even if its content has
|
||||
not changed. Without `generates`, Task uses its saved timestamp for the
|
||||
comparison. Use `method: none` when `sources` should drive
|
||||
[watch mode](./watch.md) without making the task up to date.
|
||||
|
||||
## Check existing work {#using-programmatic-checks-to-indicate-a-task-is-up-to-date}
|
||||
|
||||
Use `status` when a command can determine whether work is needed. Every check
|
||||
must exit with code `0` for Task to skip the commands. If any check fails, Task
|
||||
runs the commands:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
prepare:
|
||||
status:
|
||||
- test -d directory
|
||||
- test -f directory/file1.txt
|
||||
- test -f directory/file2.txt
|
||||
cmds:
|
||||
- mkdir -p directory
|
||||
- touch directory/file1.txt directory/file2.txt
|
||||
```
|
||||
|
||||
Run `task prepare` twice: the first call creates the files, and the second skips
|
||||
the commands. Delete either file, and Task runs the commands again.
|
||||
|
||||
Keep status checks fast and read-only: they may run each time the task is
|
||||
called. They can inspect files, installed tools, services, or remote artifacts.
|
||||
A failed check means "do the work", so the commands should handle partially
|
||||
completed work, as `mkdir -p` does above.
|
||||
|
||||
If a failed check should stop execution with an error, use
|
||||
[preconditions](./conditional-execution.md#using-programmatic-checks-to-cancel-the-execution-of-a-task-and-its-dependencies).
|
||||
|
||||
### Combine files and status
|
||||
|
||||
Use both `sources` and `status` when the result depends on local files but
|
||||
cannot be checked with `generates`. This Docker example tags the image with a
|
||||
checksum of its build inputs:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
image:
|
||||
sources:
|
||||
- Dockerfile
|
||||
- src/**/*
|
||||
status:
|
||||
- docker image inspect example/app:{{.CHECKSUM}} > /dev/null 2>&1
|
||||
cmds:
|
||||
- docker build -t example/app:{{.CHECKSUM}} .
|
||||
```
|
||||
|
||||
Task skips the build only when the sources are unchanged **and** the status
|
||||
check succeeds. A changed source produces a new tag; a missing image makes the
|
||||
check fail. Include any other files used by your Dockerfile in `sources`.
|
||||
|
||||
You can also combine `sources`, `generates`, and `status`: every configured
|
||||
check must pass for Task to consider the work up to date.
|
||||
|
||||
### Use source values
|
||||
|
||||
With `method: checksum`, <span v-pre>`{{.CHECKSUM}}`</span> contains the source
|
||||
fingerprint. With `method: timestamp`, <span v-pre>`{{.TIMESTAMP}}`</span>
|
||||
contains the latest source modification time. Both can be used in `cmds` and
|
||||
`status`; they describe the sources, not the generated files.
|
||||
|
||||
`.TIMESTAMP` is a Go `time.Time` value. For example,
|
||||
<span v-pre>`{{.TIMESTAMP.Unix}}`</span> produces a Unix timestamp, and
|
||||
<span v-pre>`{{.TIMESTAMP.Format "2006-01-02"}}`</span> formats a date.
|
||||
|
||||
## Check or force a run
|
||||
|
||||
To check whether tasks are up to date without running their commands:
|
||||
|
||||
```shell
|
||||
task --status build
|
||||
```
|
||||
|
||||
You can pass multiple task names. The command exits with a non-zero
|
||||
[exit code](../reference/cli.md#exit-codes) if any task is not up to date.
|
||||
|
||||
To run a task even when its checks say the work is already done:
|
||||
|
||||
```shell
|
||||
task --force build
|
||||
```
|
||||
|
||||
`-f` is the short form of `--force`. To rerun automatically when files change,
|
||||
use [Watch mode](./watch.md).
|
||||
|
||||
## Track different inputs
|
||||
|
||||
With the checksum method, Task stores one source fingerprint per task label. If
|
||||
build variables affect the result, include them in the label and use separate
|
||||
output paths. For example, to build with different Go build tags:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
build:
|
||||
label: 'build-{{.MODE}}'
|
||||
sources: [main.go]
|
||||
generates: ['app-{{.MODE}}{{exeExt}}']
|
||||
cmds:
|
||||
- go build -tags '{{.MODE}}' -o app-{{.MODE}}{{exeExt}} main.go
|
||||
```
|
||||
|
||||
Run `task build MODE=debug`, then `task build MODE=release`. Each mode has its
|
||||
own executable and saved checksum, so a later `task build MODE=debug` can skip
|
||||
the build. A change to `main.go` makes both modes need a rebuild when next
|
||||
called.
|
||||
|
||||
These saved checks apply across invocations. To limit repeated task calls within
|
||||
a single invocation, use
|
||||
[`run: once` or `run: when_changed`](./dependencies.md#repeated-calls).
|
||||
|
||||
## Store fingerprints
|
||||
|
||||
Task stores its file fingerprints in `.task/` under the project directory.
|
||||
Usually, add this directory to `.gitignore`. For generated code committed to
|
||||
version control, you may choose to commit the corresponding checksum too.
|
||||
|
||||
Set `TASK_TEMP_DIR` to store fingerprints elsewhere:
|
||||
|
||||
```shell
|
||||
export TASK_TEMP_DIR='~/.task'
|
||||
```
|
||||
|
||||
Relative paths, such as `tmp/task`, are resolved from the project directory.
|
||||
Absolute paths and paths starting with `~` use a separate subdirectory for each
|
||||
project.
|
||||
343
website/src/latest/docs/guide/variables.md
Normal file
343
website/src/latest/docs/guide/variables.md
Normal file
@@ -0,0 +1,343 @@
|
||||
---
|
||||
title: Variables
|
||||
description:
|
||||
Declare variables, compute values with shell commands, preserve types with
|
||||
references, and understand resolution order.
|
||||
section: Guide
|
||||
docType: guide
|
||||
outline: deep
|
||||
---
|
||||
|
||||
# Variables
|
||||
|
||||
Declare variables with `vars`, then read them in a command with a template:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
vars:
|
||||
NAME: World
|
||||
|
||||
tasks:
|
||||
greet:
|
||||
cmds:
|
||||
- echo "Hello, {{.NAME}}!"
|
||||
```
|
||||
|
||||
Run `task greet` to print `Hello, World!`, or `task greet NAME=Bob` to print
|
||||
`Hello, Bob!`. This example puts the default at the root of the Taskfile so
|
||||
callers can override it.
|
||||
|
||||
Use a literal for a fixed value, `sh` to compute text with a command, and `ref`
|
||||
to preserve arrays and maps. The examples come first;
|
||||
[resolution order](#resolution-order) explains how values from different places
|
||||
interact.
|
||||
|
||||
<span id="command-line-values"></span>
|
||||
|
||||
Pass `NAME=value` on the command line to supply variables to Task. See
|
||||
[Command-line arguments](./arguments.md#variable-assignments) for quoting,
|
||||
multiple tasks and the difference from arguments after `--`.
|
||||
|
||||
::: tip
|
||||
|
||||
The special variable `.TASK` contains the name of the task being run.
|
||||
|
||||
:::
|
||||
|
||||
## Choose a value type {#variable-types}
|
||||
|
||||
Variables support the following types:
|
||||
|
||||
- `string`
|
||||
- `bool`
|
||||
- `int`
|
||||
- `float`
|
||||
- `array`
|
||||
- `map`
|
||||
|
||||
::: info
|
||||
|
||||
Defining a map requires that you use a special `map` subkey (see example below).
|
||||
|
||||
:::
|
||||
|
||||
```yaml
|
||||
version: 3
|
||||
|
||||
tasks:
|
||||
foo:
|
||||
vars:
|
||||
STRING: 'Hello, World!'
|
||||
BOOL: true
|
||||
INT: 42
|
||||
FLOAT: 3.14
|
||||
ARRAY: [1, 2, 3]
|
||||
MAP:
|
||||
map: { A: 1, B: 2, C: 3 }
|
||||
cmds:
|
||||
- 'echo {{.STRING}}' # Hello, World!
|
||||
- 'echo {{.BOOL}}' # true
|
||||
- 'echo {{.INT}}' # 42
|
||||
- 'echo {{.FLOAT}}' # 3.14
|
||||
- 'echo {{.ARRAY}}' # [1 2 3]
|
||||
- 'echo {{index .ARRAY 0}}' # 1
|
||||
- 'echo {{.MAP}}' # map[A:1 B:2 C:3]
|
||||
- 'echo {{.MAP.A}}' # 1
|
||||
```
|
||||
|
||||
## Compute a value {#dynamic-variables}
|
||||
|
||||
Use `sh` to compute a variable from a shell command. Task captures its output
|
||||
and trims the final trailing newline, if present.
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
build:
|
||||
cmds:
|
||||
- go build -ldflags="-X main.Version={{.GIT_COMMIT}}" main.go
|
||||
vars:
|
||||
GIT_COMMIT:
|
||||
sh: git log -n 1 --format=%h
|
||||
```
|
||||
|
||||
The result is text. To convert JSON or YAML output into structured data, use
|
||||
[parsing functions with `ref`](#parsing-json-yaml-into-map-variables).
|
||||
|
||||
## Pass lists and maps {#referencing-other-variables}
|
||||
|
||||
Use `ref` to pass an array or map to another task without converting it to text.
|
||||
In this example, `show` receives the original list:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
default:
|
||||
vars:
|
||||
SERVICES: [api, worker]
|
||||
cmds:
|
||||
- task: show
|
||||
vars:
|
||||
SERVICES:
|
||||
ref: .SERVICES
|
||||
|
||||
show:
|
||||
cmds:
|
||||
- echo '{{index .SERVICES 0}}'
|
||||
```
|
||||
|
||||
Run `task` to print `api`. Replacing the reference with
|
||||
<span v-pre>`SERVICES: '{{.SERVICES}}'`</span> would pass the string
|
||||
`[api worker]`. Indexing that string returns a byte, not a list element.
|
||||
|
||||
References also work in dependency calls and variable definitions:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
default:
|
||||
vars:
|
||||
SERVICES: [api, worker]
|
||||
SELECTED:
|
||||
ref: .SERVICES
|
||||
deps:
|
||||
- task: show
|
||||
vars:
|
||||
SERVICE:
|
||||
ref: index .SELECTED 0
|
||||
|
||||
show:
|
||||
cmds:
|
||||
- echo '{{.SERVICE}}'
|
||||
```
|
||||
|
||||
Use subkeys, indexes, and functions inside `ref`, without the template braces.
|
||||
See the [Templating reference][templating-reference] for available functions.
|
||||
|
||||
## Parse JSON or YAML {#parsing-json-yaml-into-map-variables}
|
||||
|
||||
If you have a raw JSON or YAML string that you want to process in Task, you can
|
||||
use a combination of the `ref` keyword and the `fromJson` or `fromYaml`
|
||||
templating functions to parse the string into a map variable. For example:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
task-with-map:
|
||||
vars:
|
||||
JSON: '{"a": 1, "b": 2, "c": 3}'
|
||||
FOO:
|
||||
ref: 'fromJson .JSON'
|
||||
cmds:
|
||||
- echo {{.FOO}}
|
||||
```
|
||||
|
||||
```txt
|
||||
map[a:1 b:2 c:3]
|
||||
```
|
||||
|
||||
## Understand precedence {#resolution-order}
|
||||
|
||||
Applied first to last. Later wins.
|
||||
|
||||
| # | Source | Set by |
|
||||
| --- | ----------------------------------- | ----------------------------------------------------------------------------- |
|
||||
| 1 | The process environment | the shell that ran `task` |
|
||||
| 2 | Special variables | Task itself (`TASK`, `ROOT_DIR`, `CLI_ARGS`, …) |
|
||||
| 3 | Taskfile `env:` | the `env:` block; `dotenv:` files fill only names `env:` does not already set |
|
||||
| 4 | Global `vars:` | the `vars:` block of every Taskfile in the run |
|
||||
| 5 | Include `vars:` | the `vars:` given on an `includes:` entry |
|
||||
| 6 | The included Taskfile's own `vars:` | the `vars:` block of the file being included |
|
||||
| 7 | Call variables | `task foo BAR=1`, or `vars:` on a `task:` command |
|
||||
| 8 | The task's `vars:` | the `vars:` block of the task being run |
|
||||
|
||||
## Apply precedence rules {#what-this-means-in-practice}
|
||||
|
||||
### Let callers override {#a-task-s-own-variables-cannot-be-overridden-from-the-command-line}
|
||||
|
||||
Step 8 comes after step 7, so a variable declared on the task always wins:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
greet:
|
||||
vars:
|
||||
NAME: from-task
|
||||
cmds:
|
||||
- echo "{{.NAME}}"
|
||||
```
|
||||
|
||||
```shell
|
||||
$ task greet NAME=from-cli
|
||||
from-task
|
||||
```
|
||||
|
||||
To let a caller supply a value, give the default somewhere earlier, in global
|
||||
`vars:`, or use a template default:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
vars:
|
||||
NAME: from-global
|
||||
|
||||
tasks:
|
||||
greet:
|
||||
cmds:
|
||||
- echo "{{.NAME}}"
|
||||
```
|
||||
|
||||
```shell
|
||||
$ task greet NAME=from-cli
|
||||
from-cli
|
||||
```
|
||||
|
||||
To keep the default on the task itself, read the caller's value in a template:
|
||||
|
||||
```yaml
|
||||
vars:
|
||||
NAME: '{{.NAME | default "World"}}'
|
||||
```
|
||||
|
||||
### Configure include defaults {#let-callers-configure-an-included-taskfile}
|
||||
|
||||
Step 6 comes after step 5, so a constant declared in the included Taskfile's
|
||||
`vars:` overrides the value supplied by `includes.vars`.
|
||||
|
||||
To keep a configurable default in the included Taskfile, use a template that
|
||||
reads the previously resolved value:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
vars:
|
||||
DOCKER_IMAGE: '{{.DOCKER_IMAGE | default "app"}}'
|
||||
|
||||
tasks:
|
||||
build:
|
||||
cmds:
|
||||
- echo "building {{.DOCKER_IMAGE}}"
|
||||
```
|
||||
|
||||
An inclusion that supplies `DOCKER_IMAGE: backend_image` now prints
|
||||
`building backend_image`; without a supplied value, it prints `building app`.
|
||||
The default stays in one place and applies to every task in the included file.
|
||||
|
||||
### Avoid global collisions {#global-variable-names-are-shared-across-every-taskfile-in-the-run}
|
||||
|
||||
Global `vars:` are merged into one set before any task runs, so a name declared
|
||||
in both the entrypoint and an included Taskfile resolves to the included one,
|
||||
including for tasks defined in the entrypoint.
|
||||
|
||||
Give globals that belong to an included Taskfile a distinctive name, or move
|
||||
them onto the tasks that use them, where step 8 keeps them local.
|
||||
|
||||
### Choose vars or env {#env-and-vars-are-not-the-same-thing}
|
||||
|
||||
A `vars:` entry is not exported to commands in `cmds`, whichever level it was
|
||||
declared at. Read it with a template instead of `$FOO`. Dynamic variables
|
||||
(`sh:`) have a different environment, described below.
|
||||
|
||||
`env:` is exported to the environment of the commands Task runs, so `$FOO`
|
||||
works. Whether a template also sees it depends on where it was declared:
|
||||
|
||||
| Declared at | <span v-pre>`{{.FOO}}`</span> | `$FOO` |
|
||||
| ------------------------ | ------------------------------------------ | ------ |
|
||||
| the root of the Taskfile | yes, it is step 3 above | yes |
|
||||
| on a task | keeps the value from other sources, if any | yes |
|
||||
|
||||
A task's `env:` is assembled after the variable set has been resolved, so it
|
||||
never takes part in the order on this page. If global `env:` sets `FOO: root`
|
||||
and a task's `env:` sets `FOO: task`, the template <span v-pre>`{{.FOO}}`</span>
|
||||
renders `root`, while `$FOO` in a command reads `task` (assuming the process
|
||||
environment does not already set `FOO`). The template only renders empty if no
|
||||
other source defines the variable. Read a task-level environment value with
|
||||
`$FOO`, or declare it in `vars:` if a template needs it.
|
||||
|
||||
## Understand evaluation {#when-values-are-computed}
|
||||
|
||||
Dynamic variables (`sh:`) are executed while the set is being built, in the
|
||||
order above. Within a block, variables are resolved in declaration order, so a
|
||||
`sh:` command can also reference variables declared earlier in the same block:
|
||||
|
||||
```yaml
|
||||
vars:
|
||||
INPUT: hello
|
||||
OUTPUT:
|
||||
sh: echo {{.INPUT}}
|
||||
```
|
||||
|
||||
Here `OUTPUT` resolves to `hello`. Variables from later declarations or later
|
||||
steps are not available yet.
|
||||
|
||||
The shell used by `sh:` also receives previously resolved scalar variables, so
|
||||
`sh: echo $INPUT` works in this example too. The process environment takes
|
||||
precedence for shell lookups unless the
|
||||
[Env Precedence experiment](../experiments/env-precedence.md) is enabled.
|
||||
Commands in `cmds` only receive the process environment and Task's `env:` and
|
||||
`dotenv:` values; they do not inherit `vars:` this way.
|
||||
|
||||
Results are cached for the run, keyed on the command string, so the same `sh:`
|
||||
command appearing twice runs once.
|
||||
|
||||
To pass a variable without flattening it to text, an array or a map, use `ref:`
|
||||
instead of <span v-pre>`{{ }}`</span>. A template renders a string; `ref:`
|
||||
preserves the type.
|
||||
|
||||
::: tip Related guide
|
||||
|
||||
<span id="secret-variables"></span>
|
||||
|
||||
Mark sensitive values with `secret: true` to mask them in Task's own command
|
||||
logs. See [Secret variables](./secret-variables.md) for examples, loading values
|
||||
from external sources and the limits of masking.
|
||||
|
||||
:::
|
||||
|
||||
[templating-reference]: ../reference/templating.md
|
||||
80
website/src/latest/docs/guide/watch.md
Normal file
80
website/src/latest/docs/guide/watch.md
Normal file
@@ -0,0 +1,80 @@
|
||||
---
|
||||
title: Watch mode
|
||||
description: Re-run a task automatically whenever its sources change.
|
||||
section: Guide
|
||||
docType: guide
|
||||
outline: deep
|
||||
---
|
||||
|
||||
# Watch mode
|
||||
|
||||
Use `--watch` (or `-w`) to keep a task running and rerun it when its source
|
||||
files change. For a Go project:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
build:
|
||||
sources:
|
||||
- '**/*.go'
|
||||
- go.mod
|
||||
- go.sum
|
||||
cmds:
|
||||
- go build ./...
|
||||
```
|
||||
|
||||
Run `task --watch build`, edit a Go file, and save it to trigger another build.
|
||||
Press Ctrl+C to stop watching.
|
||||
|
||||
Watch mode detects changes; [up-to-date checks](./up-to-date.md) decide whether
|
||||
the task's commands need to run. Both use the same `sources`.
|
||||
|
||||
## Enable watching by default
|
||||
|
||||
Set `watch: true` on a task if its normal CLI use should start a watcher:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
build:
|
||||
watch: true
|
||||
sources: ['**/*.go']
|
||||
cmds:
|
||||
- go build ./...
|
||||
```
|
||||
|
||||
Now `task build` starts watch mode. The `watch` setting applies when the task is
|
||||
called from the CLI; calls from another task through `cmds` or `deps` do not
|
||||
start a watcher.
|
||||
|
||||
## Combine rapid changes
|
||||
|
||||
The default watch interval is 100 milliseconds. Increase it if saving several
|
||||
files produces duplicate events:
|
||||
|
||||
```shell
|
||||
task --watch --interval=500ms build
|
||||
```
|
||||
|
||||
You can also set `interval: '500ms'` at the root of the Taskfile. The interval
|
||||
groups events close together so that Task reruns the task once for the batch.
|
||||
|
||||
## Watch long-running apps
|
||||
|
||||
Builds and checks finish after each run. Servers keep running and need to stop
|
||||
before a replacement can take over their port.
|
||||
|
||||
::: warning
|
||||
|
||||
There is a [known issue](https://github.com/go-task/task/issues/160) where watch
|
||||
mode may leave child processes running. Prefer building and running the
|
||||
executable directly over `go run`, which starts another process.
|
||||
|
||||
:::
|
||||
|
||||
For applications that need dedicated live-reload behavior, consider tools such
|
||||
as [Air](https://github.com/air-verse/air/). Report Task-specific problems with
|
||||
a small reproducer in the
|
||||
[issue tracker](https://github.com/go-task/task/issues/new?template=bug_report.yml).
|
||||
69
website/src/latest/docs/index.md
Normal file
69
website/src/latest/docs/index.md
Normal file
@@ -0,0 +1,69 @@
|
||||
---
|
||||
title: Documentation
|
||||
description:
|
||||
Task is a task runner and build tool that aims to be simpler and easier to use
|
||||
than GNU Make. Start here to install it, learn it, or look something up.
|
||||
section: Overview
|
||||
docType: overview
|
||||
aside: false
|
||||
outline: false
|
||||
pageClass: docs-overview
|
||||
---
|
||||
|
||||
# Documentation
|
||||
|
||||
Install Task, learn the basics, or look up syntax for your `Taskfile.yml`.
|
||||
|
||||
<div class="docs-start">
|
||||
<div class="docs-card">
|
||||
|
||||
## Start with Task {#new-to-task}
|
||||
|
||||
Install Task and run your first Taskfile.
|
||||
|
||||
- [Installation](./installation.md)
|
||||
- [Quick Start](./getting-started.md)
|
||||
|
||||
</div>
|
||||
<div class="docs-card">
|
||||
|
||||
## Use Task {#using-task}
|
||||
|
||||
Find a guide for your everyday workflows.
|
||||
|
||||
- [Browse the guide](./guide/index.md)
|
||||
- [Variables](./guide/variables.md)
|
||||
- [Dependencies and task calls](./guide/dependencies.md)
|
||||
|
||||
</div>
|
||||
<div class="docs-card">
|
||||
|
||||
## Reference {#looking-something-up}
|
||||
|
||||
Look up syntax, flags and functions.
|
||||
|
||||
- [Taskfile Schema](./reference/schema.md)
|
||||
- [CLI](./reference/cli.md)
|
||||
- [Templating](./reference/templating.md)
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
For settings outside the Taskfile, see [Configuration](./reference/config.md)
|
||||
and [Environment](./reference/environment.md).
|
||||
|
||||
## Keeping up
|
||||
|
||||
- [Changelog](./changelog.md): what shipped, and when.
|
||||
- [Experiments](./experiments/index.md) and
|
||||
[Deprecations](./deprecations/index.md): what is coming, and what is going
|
||||
away.
|
||||
- [FAQ](./faq.md): the questions that come up most often.
|
||||
- [Community](./community.md): integrations and tools built by other people.
|
||||
|
||||
## Using an AI coding assistant
|
||||
|
||||
[Task documentation for coding agents](../agents.md) is a compact map of these
|
||||
pages plus the semantics that are easiest to get wrong. Every page is also
|
||||
available as raw Markdown by appending `.md` to its URL, and the whole corpus is
|
||||
at [/llms.txt](/llms.txt).
|
||||
@@ -1,244 +1,444 @@
|
||||
---
|
||||
title: Installation
|
||||
description: Installation methods for Task
|
||||
section: Getting Started
|
||||
docType: guide
|
||||
outline: deep
|
||||
pageClass: installation-page
|
||||
---
|
||||
|
||||
<script setup>
|
||||
import InstallationMethod from '../../../.vitepress/components/InstallationMethod.vue';
|
||||
import InstallationMethods from '../../../.vitepress/components/InstallationMethods.vue';
|
||||
</script>
|
||||
|
||||
# Installation
|
||||
|
||||
Task offers many installation methods. Check out the available methods below.
|
||||
Choose a package manager for your system, or install Task from a binary.
|
||||
|
||||
## Official Package Managers
|
||||
<InstallationMethods>
|
||||
|
||||
These installation methods are maintained by the Task team and are always
|
||||
up-to-date.
|
||||
<nav class="installation-shortcuts" aria-label="Installation shortcuts">
|
||||
<a href="#get-the-binary">Binaries & CI</a>
|
||||
<a href="#verify-installation">Verify installation</a>
|
||||
<a href="#setup-completions">Shell completions</a>
|
||||
</nav>
|
||||
|
||||
:::info Package Repository Hosting
|
||||
## Official packages {#official-package-managers}
|
||||
|
||||
[](https://cloudsmith.com)
|
||||
Maintained by the Task team and kept up-to-date.
|
||||
|
||||
Package repository hosting for deb/rpm/apk is graciously provided by [Cloudsmith](https://cloudsmith.com).
|
||||
Cloudsmith is the only fully hosted, cloud-native, universal package management solution, that
|
||||
enables your organization to create, store and share packages in any format, to any place, with total
|
||||
confidence.
|
||||
<InstallationMethod platforms="macos" platform-label="macOS">
|
||||
|
||||
:::
|
||||
<template v-slot:heading>
|
||||
|
||||
### [dnf](https://docs.fedoraproject.org/en-US/quick-docs/dnf)    {#dnf}
|
||||
### [Homebrew](https://brew.sh) {#homebrew}
|
||||
|
||||
[[package](https://cloudsmith.io/~task/repos/task/packages/?sort=-format&q=format%3Arpm)]
|
||||
</template>
|
||||
|
||||
If you Set up the repository by running :
|
||||
<template v-slot:links>
|
||||
|
||||
```shell
|
||||
curl -1sLf 'https://dl.cloudsmith.io/public/task/task/setup.rpm.sh' | sudo -E bash
|
||||
```
|
||||
[Tap source](https://github.com/go-task/homebrew-tap/blob/main/Casks/go-task.rb)
|
||||
[Homebrew package](https://formulae.brew.sh/formula/go-task)
|
||||
[Formula source](https://github.com/Homebrew/homebrew-core/blob/master/Formula/g/go-task.rb)
|
||||
|
||||
Then you can install Task with:
|
||||
|
||||
```shell
|
||||
dnf install task
|
||||
```
|
||||
|
||||
### [apt](https://doc.ubuntu-fr.org/apt)    {#apt}
|
||||
|
||||
[[package](https://cloudsmith.io/~task/repos/task/packages/?sort=-format&q=format%3Adeb)]
|
||||
|
||||
If you Set up the repository by running:
|
||||
|
||||
```shell
|
||||
curl -1sLf 'https://dl.cloudsmith.io/public/task/task/setup.deb.sh' | sudo -E bash
|
||||
```
|
||||
|
||||
Then you can install Task with:
|
||||
|
||||
```shell
|
||||
apt install task
|
||||
```
|
||||
|
||||
### [apk](https://wiki.alpinelinux.org/wiki/Alpine_Package_Keeper)  {#apk}
|
||||
|
||||
[[package](https://cloudsmith.io/~task/repos/task/packages/?sort=-format&q=format%3Aalpine)]
|
||||
|
||||
Set up the repository by running:
|
||||
|
||||
```shell
|
||||
curl -1sLf 'https://dl.cloudsmith.io/public/task/task/setup.alpine.sh' | sudo -E bash
|
||||
```
|
||||
|
||||
Then you can install Task with:
|
||||
|
||||
```shell
|
||||
apk add task
|
||||
```
|
||||
|
||||
### [Homebrew](https://brew.sh)  {#homebrew}
|
||||
|
||||
Task is available via our official Homebrew tap
|
||||
[[source](https://github.com/go-task/homebrew-tap/blob/main/Casks/go-task.rb)]:
|
||||
</template>
|
||||
|
||||
```shell
|
||||
brew install go-task/tap/go-task
|
||||
```
|
||||
|
||||
Alternatively it can be installed from the official Homebrew repository
|
||||
[[package](https://formulae.brew.sh/formula/go-task)]
|
||||
[[source](https://github.com/Homebrew/homebrew-core/blob/master/Formula/g/go-task.rb)]
|
||||
by running:
|
||||
Or use the Homebrew core formula:
|
||||
|
||||
```shell
|
||||
brew install go-task
|
||||
```
|
||||
|
||||
### [Snap](https://snapcraft.io/task)   {#snap}
|
||||
</InstallationMethod>
|
||||
|
||||
Task is available on [Snapcraft](https://snapcraft.io/task)
|
||||
[[source](https://github.com/go-task/snap/blob/main/snap/snapcraft.yaml)], but
|
||||
keep in mind that your Linux distribution should allow classic confinement for
|
||||
Snaps to Task work correctly:
|
||||
<InstallationMethod platforms="linux" platform-label="Fedora · CentOS · Red Hat">
|
||||
|
||||
<template v-slot:heading>
|
||||
|
||||
### [dnf](https://docs.fedoraproject.org/en-US/quick-docs/dnf) {#dnf}
|
||||
|
||||
</template>
|
||||
|
||||
<template v-slot:links>
|
||||
|
||||
[View package](https://cloudsmith.io/~task/repos/task/packages/?sort=-format&q=format%3Arpm)
|
||||
|
||||
</template>
|
||||
|
||||
Set up the repository:
|
||||
|
||||
```shell
|
||||
curl -1sLf 'https://dl.cloudsmith.io/public/task/task/setup.rpm.sh' | sudo -E bash
|
||||
```
|
||||
|
||||
Install Task:
|
||||
|
||||
```shell
|
||||
dnf install task
|
||||
```
|
||||
|
||||
</InstallationMethod>
|
||||
|
||||
<InstallationMethod platforms="linux" platform-label="Ubuntu · Debian · Linux Mint">
|
||||
|
||||
<template v-slot:heading>
|
||||
|
||||
### [apt](https://doc.ubuntu-fr.org/apt) {#apt}
|
||||
|
||||
</template>
|
||||
|
||||
<template v-slot:links>
|
||||
|
||||
[View package](https://cloudsmith.io/~task/repos/task/packages/?sort=-format&q=format%3Adeb)
|
||||
|
||||
</template>
|
||||
|
||||
Set up the repository:
|
||||
|
||||
```shell
|
||||
curl -1sLf 'https://dl.cloudsmith.io/public/task/task/setup.deb.sh' | sudo -E bash
|
||||
```
|
||||
|
||||
Install Task:
|
||||
|
||||
```shell
|
||||
apt install task
|
||||
```
|
||||
|
||||
</InstallationMethod>
|
||||
|
||||
<InstallationMethod platforms="linux" platform-label="Alpine Linux">
|
||||
|
||||
<template v-slot:heading>
|
||||
|
||||
### [apk](https://wiki.alpinelinux.org/wiki/Alpine_Package_Keeper) {#apk}
|
||||
|
||||
</template>
|
||||
|
||||
<template v-slot:links>
|
||||
|
||||
[View package](https://cloudsmith.io/~task/repos/task/packages/?sort=-format&q=format%3Aalpine)
|
||||
|
||||
</template>
|
||||
|
||||
Set up the repository:
|
||||
|
||||
```shell
|
||||
curl -1sLf 'https://dl.cloudsmith.io/public/task/task/setup.alpine.sh' | sudo -E bash
|
||||
```
|
||||
|
||||
Install Task:
|
||||
|
||||
```shell
|
||||
apk add task
|
||||
```
|
||||
|
||||
</InstallationMethod>
|
||||
|
||||
<InstallationMethod platforms="linux" platform-label="Linux">
|
||||
|
||||
<template v-slot:heading>
|
||||
|
||||
### [Snap](https://snapcraft.io/task) {#snap}
|
||||
|
||||
</template>
|
||||
|
||||
<template v-slot:links>
|
||||
|
||||
[Source](https://github.com/go-task/snap/blob/main/snap/snapcraft.yaml)
|
||||
|
||||
</template>
|
||||
|
||||
```shell
|
||||
sudo snap install task --classic
|
||||
```
|
||||
|
||||
### [npm](https://www.npmjs.com)    {#npm}
|
||||
Requires a Linux distribution with classic confinement support.
|
||||
|
||||
Npm can be used as cross-platform way to install Task globally or as a
|
||||
dependency of your project
|
||||
[[package](https://www.npmjs.com/package/@go-task/cli)]
|
||||
[[source](https://github.com/go-task/task/blob/main/package.json)]:
|
||||
</InstallationMethod>
|
||||
|
||||
<InstallationMethod platforms="macos linux windows" platform-label="macOS · Linux · Windows">
|
||||
|
||||
<template v-slot:heading>
|
||||
|
||||
### [npm](https://www.npmjs.com) {#npm}
|
||||
|
||||
</template>
|
||||
|
||||
<template v-slot:links>
|
||||
|
||||
[View package](https://www.npmjs.com/package/@go-task/cli)
|
||||
[Source](https://github.com/go-task/task/blob/main/package.json)
|
||||
|
||||
</template>
|
||||
|
||||
```shell
|
||||
npm install -g @go-task/cli
|
||||
```
|
||||
|
||||
### [WinGet](https://github.com/microsoft/winget-cli)  {#winget}
|
||||
Task is also available as a project dependency.
|
||||
|
||||
Task is available via the
|
||||
[community repository](https://github.com/microsoft/winget-pkgs)
|
||||
[[source](https://github.com/microsoft/winget-pkgs/tree/master/manifests/t/Task/Task)]:
|
||||
</InstallationMethod>
|
||||
|
||||
<InstallationMethod platforms="windows" platform-label="Windows">
|
||||
|
||||
<template v-slot:heading>
|
||||
|
||||
### [WinGet](https://github.com/microsoft/winget-cli) {#winget}
|
||||
|
||||
</template>
|
||||
|
||||
<template v-slot:links>
|
||||
|
||||
[Source](https://github.com/microsoft/winget-pkgs/tree/master/manifests/t/Task/Task)
|
||||
|
||||
</template>
|
||||
|
||||
```shell
|
||||
winget install Task.Task
|
||||
```
|
||||
|
||||
## Community-Maintained Package Managers
|
||||
Available through the
|
||||
[WinGet community repository](https://github.com/microsoft/winget-pkgs).
|
||||
|
||||
::: warning Community Maintained
|
||||
</InstallationMethod>
|
||||
|
||||
These installation methods are maintained by the community and may not always be
|
||||
up-to-date with the latest Task version. The Task team does not directly control
|
||||
these packages.
|
||||
<p class="install-hosting">Package repository hosting for deb/rpm/apk is graciously provided by <a href="https://cloudsmith.com">Cloudsmith</a>.</p>
|
||||
|
||||
:::
|
||||
## Community packages {#community-maintained-package-managers}
|
||||
|
||||
### [Mise](https://mise.jdx.dev/)    {#mise}
|
||||
Maintained by the community, outside the Task team's control. These packages may
|
||||
lag behind the latest release.
|
||||
|
||||
Mise is a cross-platform package manager that acts as a "frontend" to a variety
|
||||
of other package managers "backends" such as `asdf`, `aqua` and `ubi`.
|
||||
<InstallationMethod platforms="macos linux windows" platform-label="macOS · Linux · Windows">
|
||||
|
||||
If using Mise, we recommend using the `aqua` or `ubi` backends to install Task
|
||||
as these install directly from our GitHub releases.
|
||||
<template v-slot:heading>
|
||||
|
||||
::: code-group
|
||||
### [Mise](https://mise.jdx.dev/) {#mise}
|
||||
|
||||
```shell [aqua]
|
||||
mise use -g aqua:go-task/task@latest
|
||||
mise install
|
||||
</template>
|
||||
|
||||
<template v-slot:links>
|
||||
|
||||
[View package](https://mise-tools.jdx.dev/tools/task)
|
||||
|
||||
</template>
|
||||
|
||||
```shell
|
||||
mise use -g task
|
||||
```
|
||||
|
||||
```shell [ubi]
|
||||
mise use -g ubi:go-task/task
|
||||
mise install
|
||||
```
|
||||
For a project-local installation, use `mise use task` instead. This adds Task to
|
||||
your project's `mise.toml`.
|
||||
|
||||
:::
|
||||
</InstallationMethod>
|
||||
|
||||
### [Macports](https://macports.org)  {#macports}
|
||||
<InstallationMethod platforms="macos" platform-label="macOS">
|
||||
|
||||
Task repository is tracked by Macports
|
||||
[[package](https://ports.macports.org/port/go-task/details/)]
|
||||
[[source](https://github.com/macports/macports-ports/blob/master/devel/go-task/Portfile)]:
|
||||
<template v-slot:heading>
|
||||
|
||||
### [Macports](https://macports.org) {#macports}
|
||||
|
||||
</template>
|
||||
|
||||
<template v-slot:links>
|
||||
|
||||
[View package](https://ports.macports.org/port/go-task/details/)
|
||||
[Source](https://github.com/macports/macports-ports/blob/master/devel/go-task/Portfile)
|
||||
|
||||
</template>
|
||||
|
||||
```shell
|
||||
port install go-task
|
||||
```
|
||||
|
||||
### [pip](https://pip.pypa.io)    {#pip}
|
||||
</InstallationMethod>
|
||||
|
||||
Like npm, pip can be used as a cross-platform way to install Task
|
||||
[[package](https://pypi.org/project/go-task-bin)]
|
||||
[[source](https://github.com/Bing-su/pip-binary-factory/tree/main/task)]:
|
||||
<InstallationMethod platforms="macos linux windows" platform-label="macOS · Linux · Windows">
|
||||
|
||||
<template v-slot:heading>
|
||||
|
||||
### [pip](https://pip.pypa.io) {#pip}
|
||||
|
||||
</template>
|
||||
|
||||
<template v-slot:links>
|
||||
|
||||
[View package](https://pypi.org/project/go-task-bin)
|
||||
[Source](https://github.com/Bing-su/pip-binary-factory/tree/main/task)
|
||||
|
||||
</template>
|
||||
|
||||
```shell
|
||||
pip install go-task-bin
|
||||
```
|
||||
|
||||
### [Chocolatey](https://chocolatey.org)  {#chocolatey}
|
||||
</InstallationMethod>
|
||||
|
||||
[[package](https://community.chocolatey.org/packages/go-task)]
|
||||
[[source](https://github.com/Starz0r/ChocolateyPackagingScripts/blob/master/src/go-task_gh_build.py)]
|
||||
<InstallationMethod platforms="windows" platform-label="Windows">
|
||||
|
||||
<template v-slot:heading>
|
||||
|
||||
### [Chocolatey](https://chocolatey.org) {#chocolatey}
|
||||
|
||||
</template>
|
||||
|
||||
<template v-slot:links>
|
||||
|
||||
[View package](https://community.chocolatey.org/packages/go-task)
|
||||
[Source](https://github.com/Starz0r/ChocolateyPackagingScripts/blob/master/src/go-task_gh_build.py)
|
||||
|
||||
</template>
|
||||
|
||||
```shell
|
||||
choco install go-task
|
||||
```
|
||||
|
||||
### [Scoop](https://scoop.sh)  {#scoop}
|
||||
</InstallationMethod>
|
||||
|
||||
[[source](https://github.com/ScoopInstaller/Main/blob/master/bucket/task.json)]
|
||||
<InstallationMethod platforms="windows" platform-label="Windows">
|
||||
|
||||
<template v-slot:heading>
|
||||
|
||||
### [Scoop](https://scoop.sh) {#scoop}
|
||||
|
||||
</template>
|
||||
|
||||
<template v-slot:links>
|
||||
|
||||
[Source](https://github.com/ScoopInstaller/Main/blob/master/bucket/task.json)
|
||||
|
||||
</template>
|
||||
|
||||
```shell
|
||||
scoop install task
|
||||
```
|
||||
|
||||
### Arch ([pacman](https://wiki.archlinux.org/title/Pacman))  {#arch}
|
||||
</InstallationMethod>
|
||||
|
||||
[[package](https://archlinux.org/packages/extra/x86_64/go-task/)]
|
||||
[[source](https://gitlab.archlinux.org/archlinux/packaging/packages/go-task)]
|
||||
<InstallationMethod platforms="linux" platform-label="Arch Linux">
|
||||
|
||||
<template v-slot:heading>
|
||||
|
||||
### Arch ([pacman](https://wiki.archlinux.org/title/Pacman)) {#arch}
|
||||
|
||||
</template>
|
||||
|
||||
<template v-slot:links>
|
||||
|
||||
[View package](https://archlinux.org/packages/extra/x86_64/go-task/)
|
||||
[Source](https://gitlab.archlinux.org/archlinux/packaging/packages/go-task)
|
||||
|
||||
</template>
|
||||
|
||||
```shell
|
||||
pacman -S go-task
|
||||
```
|
||||
|
||||
### Fedora ([dnf](https://docs.fedoraproject.org/en-US/quick-docs/dnf))  {#fedora-community}
|
||||
</InstallationMethod>
|
||||
|
||||
[[package](https://packages.fedoraproject.org/pkgs/golang-github-task/go-task/)]
|
||||
[[source](https://src.fedoraproject.org/rpms/golang-github-task)]
|
||||
<InstallationMethod platforms="linux" platform-label="Fedora">
|
||||
|
||||
<template v-slot:heading>
|
||||
|
||||
### Fedora ([dnf](https://docs.fedoraproject.org/en-US/quick-docs/dnf)) {#fedora-community}
|
||||
|
||||
</template>
|
||||
|
||||
<template v-slot:links>
|
||||
|
||||
[View package](https://packages.fedoraproject.org/pkgs/golang-github-task/go-task/)
|
||||
[Source](https://src.fedoraproject.org/rpms/golang-github-task)
|
||||
|
||||
</template>
|
||||
|
||||
```shell
|
||||
dnf install go-task
|
||||
```
|
||||
|
||||
### FreeBSD ([Ports](https://ports.freebsd.org/cgi/ports.cgi))  {#freebsd}
|
||||
</InstallationMethod>
|
||||
|
||||
[[package](https://cgit.freebsd.org/ports/tree/devel/task)]
|
||||
[[source](https://cgit.freebsd.org/ports/tree/devel/task/Makefile)]
|
||||
<InstallationMethod platforms="freebsd" platform-label="FreeBSD">
|
||||
|
||||
<template v-slot:heading>
|
||||
|
||||
### FreeBSD ([Ports](https://ports.freebsd.org/cgi/ports.cgi)) {#freebsd}
|
||||
|
||||
</template>
|
||||
|
||||
<template v-slot:links>
|
||||
|
||||
[View package](https://cgit.freebsd.org/ports/tree/devel/task)
|
||||
[Source](https://cgit.freebsd.org/ports/tree/devel/task/Makefile)
|
||||
|
||||
</template>
|
||||
|
||||
```shell
|
||||
pkg install task
|
||||
```
|
||||
|
||||
### [Nix](https://nixos.org)     {#nix}
|
||||
</InstallationMethod>
|
||||
|
||||
[[source](https://github.com/NixOS/nixpkgs/blob/master/pkgs/by-name/go/go-task/package.nix)]
|
||||
<InstallationMethod platforms="linux macos" platform-label="Nix · NixOS · Linux · macOS">
|
||||
|
||||
<template v-slot:heading>
|
||||
|
||||
### [Nix](https://nixos.org) {#nix}
|
||||
|
||||
</template>
|
||||
|
||||
<template v-slot:links>
|
||||
|
||||
[Source](https://github.com/NixOS/nixpkgs/blob/master/pkgs/by-name/go/go-task/package.nix)
|
||||
|
||||
</template>
|
||||
|
||||
```shell
|
||||
nix-env -iA nixpkgs.go-task
|
||||
```
|
||||
|
||||
### [pacstall](https://github.com/pacstall/pacstall)   {#pacstall}
|
||||
</InstallationMethod>
|
||||
|
||||
[[package](https://pacstall.dev/packages/go-task-deb)]
|
||||
[[source](https://github.com/pacstall/pacstall-programs/blob/master/packages/go-task-deb/go-task-deb.pacscript)]
|
||||
<InstallationMethod platforms="linux" platform-label="Debian · Ubuntu">
|
||||
|
||||
<template v-slot:heading>
|
||||
|
||||
### [pacstall](https://github.com/pacstall/pacstall) {#pacstall}
|
||||
|
||||
</template>
|
||||
|
||||
<template v-slot:links>
|
||||
|
||||
[View package](https://pacstall.dev/packages/go-task-deb)
|
||||
[Source](https://github.com/pacstall/pacstall-programs/blob/master/packages/go-task-deb/go-task-deb.pacscript)
|
||||
|
||||
</template>
|
||||
|
||||
```shell
|
||||
pacstall -I go-task-deb
|
||||
```
|
||||
|
||||
### [pkgx](https://pkgx.sh)   {#pkgx}
|
||||
</InstallationMethod>
|
||||
|
||||
[[package](https://pkgx.dev/pkgs/taskfile.dev)]
|
||||
[[source](https://github.com/pkgxdev/pantry/blob/main/projects/taskfile.dev/package.yml)]
|
||||
<InstallationMethod platforms="macos linux" platform-label="macOS · Linux">
|
||||
|
||||
<template v-slot:heading>
|
||||
|
||||
### [pkgx](https://pkgx.sh) {#pkgx}
|
||||
|
||||
</template>
|
||||
|
||||
<template v-slot:links>
|
||||
|
||||
[View package](https://pkgx.dev/pkgs/taskfile.dev)
|
||||
[Source](https://github.com/pkgxdev/pantry/blob/main/projects/taskfile.dev/package.yml)
|
||||
|
||||
</template>
|
||||
|
||||
```shell
|
||||
pkgx task
|
||||
@@ -250,75 +450,88 @@ or, if you have pkgx integration enabled:
|
||||
task
|
||||
```
|
||||
|
||||
## Get The Binary
|
||||
</InstallationMethod>
|
||||
|
||||
### Binary
|
||||
</InstallationMethods>
|
||||
|
||||
You can download the binary from the
|
||||
[releases page on GitHub](https://github.com/go-task/task/releases) and add to
|
||||
your `$PATH`.
|
||||
## Binaries & CI {#get-the-binary}
|
||||
|
||||
DEB, RPM and APK packages are also available.
|
||||
Install Task without a package manager: download a binary, use the install
|
||||
script, or add the setup action to your GitHub workflow.
|
||||
|
||||
The `task_checksums.txt` file contains the SHA-256 checksum for each file.
|
||||
### Download a binary {#binary}
|
||||
|
||||
### Install Script
|
||||
1. Open the [GitHub releases](https://github.com/go-task/task/releases) and
|
||||
download the archive for your operating system and architecture.
|
||||
2. Extract `task` (`task.exe` on Windows).
|
||||
3. Move the executable to a directory on your `PATH`.
|
||||
|
||||
We also have an
|
||||
[install script](https://github.com/go-task/task/blob/main/install-task.sh)
|
||||
which is very useful in scenarios like CI. Many thanks to
|
||||
[GoDownloader](https://github.com/goreleaser/godownloader) for enabling the easy
|
||||
generation of this script.
|
||||
Each release also includes DEB, RPM and APK packages, plus `task_checksums.txt`
|
||||
with SHA-256 checksums for the release files.
|
||||
|
||||
By default, it installs on the `./bin` directory relative to the working
|
||||
directory:
|
||||
### Install with a script {#install-script}
|
||||
|
||||
```shell
|
||||
Use the
|
||||
[install script](https://github.com/go-task/task/blob/main/install-task.sh) for
|
||||
a shell-based installation, including CI environments. It downloads a prebuilt
|
||||
binary and verifies its checksum; no Go installation is needed.
|
||||
|
||||
By default, the script installs the latest release into `./bin`, relative to
|
||||
your current directory. Choose a different directory or pin a release:
|
||||
|
||||
::: code-group
|
||||
|
||||
```shell [Latest release]
|
||||
sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d
|
||||
```
|
||||
|
||||
It is possible to override the installation directory with the `-b` parameter.
|
||||
On Linux, common choices are `~/.local/bin` and `~/bin` to install for the
|
||||
current user or `/usr/local/bin` to install for all users:
|
||||
|
||||
```shell
|
||||
```shell [Custom directory]
|
||||
sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b ~/.local/bin
|
||||
```
|
||||
|
||||
::: warning
|
||||
|
||||
On macOS and Windows, `~/.local/bin` and `~/bin` are not added to `$PATH` by
|
||||
default.
|
||||
|
||||
:::
|
||||
|
||||
By default, it installs the latest version available. You can also specify a tag
|
||||
(available in [releases](https://github.com/go-task/task/releases)) to install a
|
||||
specific version:
|
||||
|
||||
```shell
|
||||
sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d v3.36.0
|
||||
```shell [Pinned version]
|
||||
sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d v3.42.1
|
||||
```
|
||||
|
||||
Parameters are order specific, to set both installation directory and version:
|
||||
|
||||
```shell
|
||||
```shell [Directory + version]
|
||||
sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b ~/.local/bin v3.42.1
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
When combining options, keep the
|
||||
[release tag](https://github.com/go-task/task/releases) last.
|
||||
|
||||
::: tip Make Task available in your shell
|
||||
|
||||
Add the installation directory to your `PATH` to run `task` from anywhere. With
|
||||
the default location, you can also run `./bin/task` directly.
|
||||
|
||||
On Linux, `~/.local/bin` and `~/bin` are common per-user locations;
|
||||
`/usr/local/bin` is a system-wide location and may require elevated permissions.
|
||||
Do not assume these directories are already on your `PATH`, especially on macOS
|
||||
and Windows.
|
||||
|
||||
:::
|
||||
|
||||
### GitHub Actions
|
||||
|
||||
We have an [official GitHub Action](https://github.com/go-task/setup-task) to
|
||||
install Task in your GitHub workflows. This repository is forked from the
|
||||
fantastic project by the Arduino team. Check out the repository for more
|
||||
examples and configuration.
|
||||
Add the [official setup action](https://github.com/go-task/setup-task) to your
|
||||
job's `steps` before running Task:
|
||||
|
||||
```yaml
|
||||
- name: Install Task
|
||||
uses: go-task/setup-task@v1
|
||||
uses: go-task/setup-task@v2
|
||||
|
||||
- name: Verify Task
|
||||
run: task --version
|
||||
```
|
||||
|
||||
## Build From Source
|
||||
Use the action's `version` input to pin a Task release. See the
|
||||
[action documentation](https://github.com/go-task/setup-task#usage) for examples
|
||||
and configuration.
|
||||
|
||||
## Build from source
|
||||
|
||||
Ensure that you have a supported version of [Go](https://golang.org) properly
|
||||
installed and setup. You can find the minimum required version of Go in the
|
||||
@@ -364,20 +577,39 @@ demand before calling it.
|
||||
go tool task {arguments...}
|
||||
```
|
||||
|
||||
## Setup completions
|
||||
## Verify installation
|
||||
|
||||
After installing, open a terminal and check that Task is available:
|
||||
|
||||
```shell
|
||||
task --version
|
||||
```
|
||||
|
||||
If you installed Task with `go tool`, run `go tool task --version` instead.
|
||||
|
||||
You're ready to [create your first Taskfile](./getting-started.md). You can also
|
||||
enable shell completions below.
|
||||
|
||||
## Shell completions {#setup-completions}
|
||||
|
||||
Some installation methods will automatically install completions too, but if
|
||||
this isn't working for you or your chosen method doesn't include them, you can
|
||||
run `task --completion <shell>` to output a completion script for any supported
|
||||
shell. There are a couple of ways these completions can be added to your shell
|
||||
config:
|
||||
shell.
|
||||
|
||||
Every shell shares a single source of truth: the script is a thin wrapper that
|
||||
asks the `task` binary itself what to suggest, so Bash, Zsh, Fish, Nushell and
|
||||
PowerShell all offer the same task names, aliases, flags, flag values and
|
||||
`requires` vars.
|
||||
|
||||
There are a couple of ways these completions can be added to your shell config:
|
||||
|
||||
### Option 1. Load the completions in your shell's startup config (Recommended)
|
||||
|
||||
This method loads the completion script from the currently installed version of
|
||||
task every time you create a new shell. This ensures that your completions are
|
||||
always up-to-date.
|
||||
If your executable isn’t named task, set the `TASK_EXE` environment variable before running eval.
|
||||
always up-to-date. If your executable isn’t named task, set the `TASK_EXE`
|
||||
environment variable before running eval.
|
||||
|
||||
::: code-group
|
||||
|
||||
@@ -446,9 +678,10 @@ task --completion nu | save --force ($nu.data-dir | path join "vendor/autoload/t
|
||||
|
||||
### Zsh customization
|
||||
|
||||
The Zsh completion supports the standard `verbose` zstyle to control whether task
|
||||
descriptions are shown. By default, descriptions are displayed. To show only task
|
||||
names without descriptions, add this to your `~/.zshrc` (after the completion is loaded):
|
||||
The Zsh completion supports the standard `verbose` zstyle to control whether
|
||||
task descriptions are shown. By default, descriptions are displayed. To show
|
||||
only task names without descriptions, add this to your `~/.zshrc` (after the
|
||||
completion is loaded):
|
||||
|
||||
```shell
|
||||
zstyle ':completion:*:*:task:*' verbose false
|
||||
@@ -465,24 +698,25 @@ zstyle ':completion:*:*:task:*' show-aliases false
|
||||
|
||||
Nushell cannot source a script from stdin, so both options above write the script
|
||||
to an autoload directory. Option 1 rewrites it at every startup, which keeps it
|
||||
in sync with the installed version of Task — the refreshed completions are picked
|
||||
up by the next shell. With option 2, re-run the command after upgrading Task.
|
||||
in sync with the installed version of Task, and the refreshed completions are
|
||||
picked up by the next shell. With option 2, re-run the command after upgrading
|
||||
Task.
|
||||
|
||||
The completions are attached to an `extern "task"` declaration, which Nushell
|
||||
requires to be static. Three consequences are worth knowing:
|
||||
|
||||
- The experimental flags (`--force-all`, `--download`, `--offline`, …) are always
|
||||
offered, even when the corresponding experiment is disabled. Their description
|
||||
is prefixed with the experiment name, and `task --experiments` lists the ones
|
||||
that are enabled.
|
||||
- Passing a value to a boolean flag with `=` does not work: Nushell forwards
|
||||
`--color=false` as two arguments, so Task reads `false` as a task name. Use
|
||||
`NO_COLOR=1`, or bypass the declaration with `^task --color=false`.
|
||||
- `TASK_EXE` selects the executable that is run, but not the command name the
|
||||
completions are attached to, which is always `task`. For a renamed executable,
|
||||
alias it instead:
|
||||
Nushell shares a single external completer between every command, so the script
|
||||
chains to the one already configured — carapace and friends keep working. Load it
|
||||
from an autoload directory as shown above rather than from `config.nu`, so that
|
||||
your own completer is the one being chained to. If you would rather wire it
|
||||
yourself, the script also exposes a `task-external-completer` command:
|
||||
|
||||
```nu
|
||||
use ($nu.data-dir | path join "vendor/autoload/task-completions.nu") *
|
||||
alias go-task = task
|
||||
$env.config.completions.external.completer = {|spans|
|
||||
match ($spans | first) {
|
||||
task => (task-external-completer $spans)
|
||||
_ => (do $my_other_completer $spans)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Two engine directives behave differently under Nushell by design: it never
|
||||
appends a space after an external completion (so `NoSpace` is a no-op) and never
|
||||
re-sorts the results (so `KeepOrder` is always honoured).
|
||||
|
||||
@@ -3,6 +3,8 @@ title: Integrations
|
||||
description:
|
||||
Official and community integrations for Task, including VS Code, JSON schemas,
|
||||
and other tools
|
||||
section: Getting Started
|
||||
docType: guide
|
||||
outline: deep
|
||||
---
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
title: Command Line Interface Reference
|
||||
description: Complete reference for Task CLI commands, flags, and exit codes
|
||||
permalink: /reference/cli/
|
||||
section: Reference
|
||||
docType: reference
|
||||
outline: deep
|
||||
---
|
||||
|
||||
@@ -457,6 +459,10 @@ Task uses specific exit codes to indicate different types of errors:
|
||||
- **105** - Remote Taskfile fetch not secure
|
||||
- **106** - No cache for remote Taskfile in offline mode
|
||||
- **107** - No schema version defined in Taskfile
|
||||
- **108** - Remote Taskfile network timeout
|
||||
- **109** - Invalid Taskfile
|
||||
- **110** - Taskfile cycle detected
|
||||
- **111** - Taskfile does not match checksum
|
||||
|
||||
### Task Errors (200-255)
|
||||
|
||||
@@ -468,6 +474,7 @@ Task uses specific exit codes to indicate different types of errors:
|
||||
- **205** - Task cancelled by user
|
||||
- **206** - Missing required variables
|
||||
- **207** - Variable has incorrect value
|
||||
- **208** - Task timed out
|
||||
|
||||
::: info
|
||||
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
title: Configuration Reference
|
||||
description: Complete reference for the Task config files and env vars
|
||||
permalink: /reference/config/
|
||||
section: Reference
|
||||
docType: reference
|
||||
outline: deep
|
||||
---
|
||||
|
||||
@@ -85,7 +87,7 @@ experiments:
|
||||
- **Type**: `boolean`
|
||||
- **Default**: `false`
|
||||
- **Description**: Enable verbose output for all tasks
|
||||
- **CLI equivalent**: [`-v, --verbose`](./cli.md#-v---verbose)
|
||||
- **CLI equivalent**: [`-v, --verbose`](./cli.md#v-verbose)
|
||||
- **Environment variable**: [`TASK_VERBOSE`](./environment.md#task-verbose)
|
||||
|
||||
```yaml
|
||||
@@ -97,7 +99,7 @@ verbose: true
|
||||
- **Type**: `boolean`
|
||||
- **Default**: `false`
|
||||
- **Description**: Disables echoing of commands
|
||||
- **CLI equivalent**: [`-s, --silent`](./cli.md#-s---silent)
|
||||
- **CLI equivalent**: [`-s, --silent`](./cli.md#s-silent)
|
||||
- **Environment variable**: [`TASK_SILENT`](./environment.md#task-silent)
|
||||
|
||||
```yaml
|
||||
@@ -110,7 +112,7 @@ silent: true
|
||||
- **Default**: `true`
|
||||
- **Description**: Enable colored output. Colors are automatically enabled in CI
|
||||
environments (`CI=true`).
|
||||
- **CLI equivalent**: [`-c, --color`](./cli.md#-c---color)
|
||||
- **CLI equivalent**: [`-c, --color`](./cli.md#c-color)
|
||||
- **Environment variable**: [`TASK_COLOR`](./environment.md#task-color)
|
||||
|
||||
```yaml
|
||||
@@ -123,7 +125,7 @@ color: false
|
||||
- **Default**: `false`
|
||||
- **Description**: Disable fuzzy matching for task names. When enabled, Task
|
||||
will not suggest similar task names when you mistype a task name.
|
||||
- **CLI equivalent**: [`--disable-fuzzy`](./cli.md#--disable-fuzzy)
|
||||
- **CLI equivalent**: [`--disable-fuzzy`](./cli.md#disable-fuzzy)
|
||||
- **Environment variable**:
|
||||
[`TASK_DISABLE_FUZZY`](./environment.md#task-disable-fuzzy)
|
||||
|
||||
@@ -136,7 +138,7 @@ disable-fuzzy: true
|
||||
- **Type**: `integer`
|
||||
- **Minimum**: `1`
|
||||
- **Description**: Number of concurrent tasks to run
|
||||
- **CLI equivalent**: [`-C, --concurrency`](./cli.md#-c---concurrency-number)
|
||||
- **CLI equivalent**: [`-C, --concurrency`](./cli.md#c-concurrency-number)
|
||||
- **Environment variable**:
|
||||
[`TASK_CONCURRENCY`](./environment.md#task-concurrency)
|
||||
|
||||
@@ -149,7 +151,7 @@ concurrency: 4
|
||||
- **Type**: `boolean`
|
||||
- **Default**: `false`
|
||||
- **Description**: Stop executing dependencies as soon as one of them fail
|
||||
- **CLI equivalent**: [`-F, --failfast`](./cli.md#-f---failfast)
|
||||
- **CLI equivalent**: [`-F, --failfast`](./cli.md#f-failfast)
|
||||
- **Environment variable**: [`TASK_FAILFAST`](./environment.md#task-failfast)
|
||||
|
||||
```yaml
|
||||
@@ -164,7 +166,7 @@ failfast: true
|
||||
When enabled, Task will display an interactive prompt for any missing required
|
||||
variable. Requires a TTY. Task automatically detects non-TTY environments (CI
|
||||
pipelines, etc.) and skips prompts.
|
||||
- **CLI equivalent**: [`--interactive`](./cli.md#--interactive)
|
||||
- **CLI equivalent**: [`--interactive`](./cli.md#interactive)
|
||||
|
||||
```yaml
|
||||
interactive: true
|
||||
@@ -300,6 +302,81 @@ task --trusted-hosts github.com,gitlab.com -t https://github.com/user/repo.git//
|
||||
task --trusted-hosts example.com:8080 -t https://example.com:8080/Taskfile.yml
|
||||
```
|
||||
|
||||
#### `remote.headers`
|
||||
|
||||
- **Type**: `array of objects`
|
||||
- **Default**: `[]` (empty list)
|
||||
- **Description**: HTTP headers to send when downloading a remote Taskfile from
|
||||
a given host, including authentication and custom headers
|
||||
|
||||
```yaml
|
||||
remote:
|
||||
headers:
|
||||
- host: gitlab.com
|
||||
headers:
|
||||
PRIVATE-TOKEN: '{{env "GITLAB_TOKEN"}}'
|
||||
- host: artifacts.example.com:8443
|
||||
headers:
|
||||
Authorization: 'Bearer {{env "ARTIFACTS_TOKEN"}}'
|
||||
Accept: application/yaml
|
||||
X-Custom-Header: custom-value
|
||||
```
|
||||
|
||||
Use this option for authentication, content negotiation or other headers your
|
||||
server expects. For authentication, this is the recommended way to access a
|
||||
remote Taskfile. Unlike a credential placed in the URL, the header never appears
|
||||
in your Taskfile, in the confirmation prompt or in an error message, so the
|
||||
include URL stays safe to commit.
|
||||
|
||||
Each entry applies to a single host, matched exactly and including the port if
|
||||
the URL has one — the same rule as
|
||||
[`remote.trusted-hosts`](#remote-trusted-hosts). Header values may reference
|
||||
[templating functions](./templating.md), evaluated when Task contacts the host.
|
||||
Values starting with <span v-pre>`{{`</span> must be quoted, as YAML would
|
||||
otherwise read them as a mapping. An undefined environment variable expands to
|
||||
nothing, so the header is sent empty. For an authentication header, this may
|
||||
cause the server to reject the request with a `401`.
|
||||
|
||||
Functions compose, so an `Authorization` header needs no manual encoding:
|
||||
|
||||
```yaml
|
||||
remote:
|
||||
headers:
|
||||
- host: artifacts.example.com
|
||||
headers:
|
||||
Authorization: 'Basic {{ printf "%s:%s" (env "USER") (env "PASS") | b64enc }}'
|
||||
```
|
||||
|
||||
::: warning
|
||||
|
||||
Only functions are available here — <span v-pre>`{{.GITLAB_TOKEN}}`</span> and
|
||||
other variable references resolve to nothing. The configuration file is read
|
||||
before any Taskfile, so no variable exists yet. Use
|
||||
<span v-pre>`{{env "GITLAB_TOKEN"}}`</span> instead.
|
||||
|
||||
:::
|
||||
|
||||
The header your server expects depends on the service:
|
||||
|
||||
| Service | Header |
|
||||
| ----------- | -------------------------------------- |
|
||||
| GitLab API | `PRIVATE-TOKEN` (or `JOB-TOKEN` in CI) |
|
||||
| GitHub API | `Authorization: Bearer <token>` |
|
||||
| Artifactory | `X-JFrog-Art-Api` |
|
||||
|
||||
There is no CLI flag or environment variable for this option: a token given on
|
||||
the command line would be visible to any process listing it.
|
||||
|
||||
::: warning
|
||||
|
||||
Headers are only sent to the host they are configured for. If that host answers
|
||||
with a redirect to another one, the request follows the redirect **without**
|
||||
them, and will likely fail — point the URL at the final host instead. Headers
|
||||
are also HTTP-only: a Taskfile fetched over `git` should authenticate with SSH
|
||||
or a git credential helper.
|
||||
|
||||
:::
|
||||
|
||||
#### `remote.cacert`
|
||||
|
||||
- **Type**: `string`
|
||||
@@ -354,6 +431,10 @@ remote:
|
||||
trusted-hosts:
|
||||
- github.com
|
||||
- gitlab.com
|
||||
headers:
|
||||
- host: gitlab.com
|
||||
headers:
|
||||
PRIVATE-TOKEN: '{{env "GITLAB_TOKEN"}}'
|
||||
cacert: ''
|
||||
cert: ''
|
||||
cert-key: ''
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
---
|
||||
title: Environment Reference
|
||||
description: A reference for the Taskfile environment variables
|
||||
section: Reference
|
||||
docType: reference
|
||||
outline: deep
|
||||
---
|
||||
|
||||
@@ -87,7 +89,7 @@ files > defaults.
|
||||
|
||||
- **Type**: `string` (`interleaved`, `group`, `prefixed`)
|
||||
- **Description**: Sets the output style
|
||||
- **CLI equivalent**: [`--output`](./cli.md#--output-string)
|
||||
- **CLI equivalent**: [`--output`](./cli.md#o-output-mode)
|
||||
|
||||
### `TASK_OUTPUT_GROUP_BEGIN`
|
||||
|
||||
@@ -95,7 +97,7 @@ files > defaults.
|
||||
- **Description**: Message template to print before a task's grouped output.
|
||||
Only applies when the output style is `group`.
|
||||
- **CLI equivalent**:
|
||||
[`--output-group-begin`](./cli.md#--output-group-begin-template)
|
||||
[`--output-group-begin`](./cli.md#output-group-begin-template)
|
||||
|
||||
### `TASK_OUTPUT_GROUP_END`
|
||||
|
||||
@@ -103,7 +105,7 @@ files > defaults.
|
||||
- **Description**: Message template to print after a task's grouped output. Only
|
||||
applies when the output style is `group`.
|
||||
- **CLI equivalent**:
|
||||
[`--output-group-end`](./cli.md#--output-group-end-template)
|
||||
[`--output-group-end`](./cli.md#output-group-end-template)
|
||||
|
||||
### `TASK_OUTPUT_GROUP_ERROR_ONLY`
|
||||
|
||||
@@ -112,7 +114,7 @@ files > defaults.
|
||||
- **Description**: Swallow output from successful tasks. Only applies when the
|
||||
output style is `group`.
|
||||
- **CLI equivalent**:
|
||||
[`--output-group-error-only`](./cli.md#--output-group-error-only)
|
||||
[`--output-group-error-only`](./cli.md#output-group-error-only)
|
||||
|
||||
### `TASK_TEMP_DIR`
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
---
|
||||
title: Package API Reference
|
||||
description: A reference for Task's Golang package API
|
||||
section: Reference
|
||||
docType: reference
|
||||
---
|
||||
|
||||
# Package API Reference
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
---
|
||||
title: Taskfile Schema Reference
|
||||
description: A reference for the Taskfile schema
|
||||
section: Reference
|
||||
docType: reference
|
||||
outline: deep
|
||||
---
|
||||
|
||||
@@ -420,7 +422,7 @@ value.
|
||||
|
||||
For complete documentation on secret variables, including security
|
||||
considerations and best practices, see the
|
||||
[Secret variables](/docs/guide#secret-variables) section in the Guide.
|
||||
[Secret variables](../guide/secret-variables.md) section in the Guide.
|
||||
|
||||
:::
|
||||
|
||||
@@ -786,7 +788,8 @@ tasks:
|
||||
# …
|
||||
```
|
||||
|
||||
See [Prompting for missing variables interactively](/docs/guide#prompting-for-missing-variables-interactively)
|
||||
See
|
||||
[Prompting for missing variables interactively](../guide/required-variables.md#prompting-for-missing-variables-interactively)
|
||||
for information on enabling interactive prompts for missing required variables.
|
||||
|
||||
#### `watch`
|
||||
@@ -983,7 +986,7 @@ When a command exceeds its timeout, it is terminated and the task fails with an
|
||||
error, preventing commands from hanging indefinitely in a pipeline. The timeout
|
||||
bounds the whole step, so an [`if`](#command) condition that hangs is cut short
|
||||
too, and [`ignore_error`](#command) covers a timeout like any other failure. A
|
||||
timed-out command reports [`EXIT_CODE`](/docs/reference/templating#exit_code)
|
||||
timed-out command reports [`EXIT_CODE`](./templating.md#exit-code)
|
||||
`124`, following the convention of `timeout(1)`.
|
||||
|
||||
A dependency takes the same key:
|
||||
|
||||
@@ -3,6 +3,8 @@ title: Templating Reference
|
||||
description:
|
||||
Comprehensive guide to Task's templating system with Go text/template, special
|
||||
variables, and available functions
|
||||
section: Reference
|
||||
docType: reference
|
||||
outline: deep
|
||||
---
|
||||
|
||||
@@ -334,7 +336,7 @@ tasks:
|
||||
|
||||
- **Type**: `int`
|
||||
- **Description**: Failed command exit code (only in `defer`, only when
|
||||
non-zero). A command killed by its [`timeout`](/docs/reference/schema#command)
|
||||
non-zero). A command killed by its [`timeout`](./schema.md#command)
|
||||
is reported as `124`, following the convention of `timeout(1)`.
|
||||
|
||||
```yaml
|
||||
|
||||
@@ -3,6 +3,8 @@ title: Releasing
|
||||
description:
|
||||
Task release process including GoReleaser, Homebrew, npm, Snapcraft, winget,
|
||||
and other package managers
|
||||
section: Contributing
|
||||
docType: contributing
|
||||
outline: deep
|
||||
---
|
||||
|
||||
@@ -16,20 +18,38 @@ of the Taskfile.
|
||||
artifacts automatically when a new Git tag is pushed to `main` branch (raw
|
||||
executables and DEB and RPM packages).
|
||||
|
||||
Raw executables can also be reproduced and verified locally by
|
||||
checking out a specific tag and calling `goreleaser build`, using the Go version
|
||||
defined in the above GitHub Actions.
|
||||
The body of the GitHub release is the section of the `CHANGELOG.md` matching the
|
||||
version being released, extracted by `go run ./cmd/release --notes`. A version
|
||||
without changelog entries is released with an empty body.
|
||||
|
||||
Raw executables can also be reproduced and verified locally by checking out a
|
||||
specific tag and calling `goreleaser build`, using the Go version defined in the
|
||||
above GitHub Actions.
|
||||
|
||||
## Website
|
||||
|
||||
`task release:<version>` promotes the documentation before tagging: the docs in
|
||||
`website/src/next/docs`, their sidebar and the `next-*` JSON schemas are copied over
|
||||
their published counterparts, so the released tag carries the docs of the
|
||||
`website/src/next/docs`, their sidebar and the `next-*` JSON schemas are copied
|
||||
over their published counterparts, so the released tag carries the docs of the
|
||||
version it ships. The release workflow then runs `task website:deploy:prod`.
|
||||
|
||||
A new blog post is a Markdown file in `website/src/next/blog` with no file at
|
||||
the same relative path in `website/src/latest/blog`, excluding `index.md`.
|
||||
Renaming a post therefore makes it new. On the `next` site, new posts display
|
||||
the build date in UTC (`YYYY-MM-DD`) and are sorted using that date, without
|
||||
changing the source files. The `latest` site uses only the stored dates.
|
||||
|
||||
During release preparation, `cmd/release` replaces or adds the `date` in each
|
||||
new post's frontmatter with the same local date used for the changelog. It
|
||||
validates all new posts' frontmatter before writing; an error identifies the
|
||||
file to fix. It then copies the blog to `latest`, so both copies carry the same
|
||||
date in the release commit. This is the preparation date, even if publication on
|
||||
GitHub happens later. Already published posts keep their dates, including when
|
||||
their content changes. The `--version` and `--notes` flags do not write files.
|
||||
|
||||
Because taskfile.dev is built from the latest copy, it can be redeployed at any
|
||||
time between releases - to publish a blog post or a documentation fix -
|
||||
without exposing the docs of unreleased features:
|
||||
time between releases - to publish a blog post or a documentation fix - without
|
||||
exposing the docs of unreleased features:
|
||||
|
||||
```shell
|
||||
git checkout main && git pull
|
||||
@@ -40,24 +60,19 @@ task website:deploy:prod
|
||||
|
||||
GoReleaser will automatically publish the release to most package managers:
|
||||
|
||||
* Cloudsmith (DEB and RPM repositories)
|
||||
* Homebrew
|
||||
* npm
|
||||
* winget
|
||||
- Cloudsmith (DEB and RPM repositories)
|
||||
- Homebrew
|
||||
- npm
|
||||
- Snapcraft
|
||||
- winget
|
||||
|
||||
A single package manager still require manual steps:
|
||||
|
||||
* Snapcraft:
|
||||
* Update the `version:` field on [snapcraft.yaml][snapcraftyaml]
|
||||
* Trigger a new build on [Snapcraft -> Builds][snapcraftbuilds]
|
||||
* Once finished, move the new build to "stable" on [Snapcraft -> Releases][snapcraftreleases]
|
||||
Once the release is published, GoReleaser announces it on the
|
||||
[Discord server](https://discord.gg/6TY36E39UK). Nightly releases are not
|
||||
announced.
|
||||
|
||||
These package managers are updated automatically by the community:
|
||||
|
||||
* [Scoop](https://github.com/ScoopInstaller/Main/blob/master/bucket/task.json)
|
||||
* [Nix](https://github.com/NixOS/nixpkgs/blob/master/pkgs/by-name/go/go-task/package.nix)
|
||||
- [Scoop](https://github.com/ScoopInstaller/Main/blob/master/bucket/task.json)
|
||||
- [Nix](https://github.com/NixOS/nixpkgs/blob/master/pkgs/by-name/go/go-task/package.nix)
|
||||
|
||||
[goreleaser]: https://goreleaser.com/
|
||||
[snapcraftyaml]: https://github.com/go-task/snap/blob/main/snap/snapcraft.yaml#L2
|
||||
[snapcraftbuilds]: https://snapcraft.io/task/builds
|
||||
[snapcraftreleases]: https://snapcraft.io/task/releases
|
||||
|
||||
@@ -1,57 +1,129 @@
|
||||
---
|
||||
title: Remote Taskfiles
|
||||
description:
|
||||
Guide to loading and securely using Taskfiles from HTTP and Git sources
|
||||
section: Guide
|
||||
docType: guide
|
||||
outline: deep
|
||||
---
|
||||
|
||||
# Remote Taskfiles
|
||||
|
||||
Use a remote Taskfile to share tasks across projects without copying the file
|
||||
into each repository. You can call it directly or include it under a namespace.
|
||||
|
||||
::: danger
|
||||
|
||||
Never run remote Taskfiles from sources that you do not trust.
|
||||
Only run remote Taskfiles from sources you trust. Their commands execute on your
|
||||
machine, just like commands from a local Taskfile.
|
||||
|
||||
:::
|
||||
|
||||
Task allows you to use Taskfiles which are stored in remote locations. This
|
||||
applies to both the root Taskfile (aka. Entrypoint) and also when including
|
||||
Taskfiles.
|
||||
The examples use Task's public sample, whose `hello` task prints `Hello Task!`.
|
||||
On first use, Task asks you to trust the downloaded file. Review it before
|
||||
accepting; see [trust and checksums](#security) for subsequent changes and CI.
|
||||
|
||||
Task uses "nodes" to reference remote Taskfiles. There are a few different types
|
||||
of node which you can use:
|
||||
## Run a remote Taskfile {#specifying-a-remote-entrypoint}
|
||||
|
||||
Pass the remote location to `--taskfile` (or `-t`). With no task name, Task runs
|
||||
the remote file's `default` task. Choose a transport below:
|
||||
|
||||
::: code-group
|
||||
|
||||
```text [HTTP/HTTPS]
|
||||
https://raw.githubusercontent.com/go-task/task/main/website/src/public/Taskfile.yml
|
||||
```shell [HTTP/HTTPS]
|
||||
$ task --taskfile https://raw.githubusercontent.com/go-task/task/main/website/src/public/Taskfile.yml
|
||||
task: [hello] echo "Hello Task!"
|
||||
Hello Task!
|
||||
```
|
||||
|
||||
```text [Git over HTTP]
|
||||
https://github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=main
|
||||
```shell [Git over HTTP]
|
||||
$ task --taskfile 'https://github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=main'
|
||||
task: [hello] echo "Hello Task!"
|
||||
Hello Task!
|
||||
```
|
||||
|
||||
```text [Git over SSH]
|
||||
git@github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=main
|
||||
```shell [Git over SSH]
|
||||
$ task --taskfile 'git@github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=main'
|
||||
task: [hello] echo "Hello Task!"
|
||||
Hello Task!
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
## Node Types
|
||||
## Include shared tasks {#including-remote-taskfiles}
|
||||
|
||||
Set the include location to a remote URL instead of a local path. The tasks
|
||||
become available under the namespace you choose, just like
|
||||
[local includes](./guide/includes.md):
|
||||
|
||||
::: code-group
|
||||
|
||||
```yaml [HTTP/HTTPS]
|
||||
version: '3'
|
||||
|
||||
includes:
|
||||
shared: https://raw.githubusercontent.com/go-task/task/main/website/src/public/Taskfile.yml
|
||||
```
|
||||
|
||||
```yaml [Git over HTTP]
|
||||
version: '3'
|
||||
|
||||
includes:
|
||||
shared: https://github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=main
|
||||
```
|
||||
|
||||
```yaml [Git over SSH]
|
||||
version: '3'
|
||||
|
||||
includes:
|
||||
shared: git@github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=main
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
```shell
|
||||
$ task shared:hello
|
||||
task: [hello] echo "Hello Task!"
|
||||
Hello Task!
|
||||
```
|
||||
|
||||
### Supply authentication {#authenticating-using-environment-variables}
|
||||
|
||||
The Taskfile location is processed by the templating system, so you can
|
||||
reference environment variables in your URL if you need to add authentication.
|
||||
For example:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
includes:
|
||||
shared: https://{{.TOKEN}}@raw.githubusercontent.com/my-org/my-repo/main/Taskfile.yml
|
||||
```
|
||||
|
||||
Prefer the [`remote.headers`](./reference/config.md#remote-headers) configuration
|
||||
option when the server accepts a header. A credential in the URL ends up in
|
||||
error messages and in the confirmation prompt, and the include can no longer be
|
||||
committed as-is.
|
||||
|
||||
## Choose a source {#node-types}
|
||||
|
||||
### HTTP/HTTPS
|
||||
|
||||
`https://raw.githubusercontent.com/go-task/task/main/website/src/public/Taskfile.yml`
|
||||
|
||||
This is the most basic type of remote node and works by downloading the file
|
||||
from the specified URL. The file must be a valid Taskfile and can be of any
|
||||
name. If a file is not found at the specified URL, Task will append each of the
|
||||
supported file names in turn until it finds a valid file. If it still does not
|
||||
find a valid Taskfile, an error is returned.
|
||||
Use a direct URL when the server exposes the Taskfile as plain text. Task
|
||||
downloads the file from that URL. The file must be a valid Taskfile and can be
|
||||
of any name. If a file is not found at the specified URL, Task will append each
|
||||
of the supported file names in turn until it finds a valid file. If it still
|
||||
does not find a valid Taskfile, an error is returned.
|
||||
|
||||
### Git over HTTP
|
||||
|
||||
`https://github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=main`
|
||||
|
||||
This type of node works by downloading the file from a Git repository over
|
||||
HTTP/HTTPS. The first part of the URL is the base URL of the Git repository.
|
||||
This is the same URL that you would use to clone the repo over HTTP.
|
||||
Use a Git URL to select a file from a repository over HTTP/HTTPS. The first part
|
||||
of the URL is the base URL of the Git repository. This is the same URL that you
|
||||
would use to clone the repo over HTTP.
|
||||
|
||||
- You can optionally add the path to the Taskfile in the repository by appending
|
||||
`//<path>` to the URL.
|
||||
@@ -63,9 +135,9 @@ This is the same URL that you would use to clone the repo over HTTP.
|
||||
|
||||
`git@github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=main`
|
||||
|
||||
This type of node works by downloading the file from a Git repository over SSH.
|
||||
The first part of the URL is the user and base URL of the Git repository. This
|
||||
is the same URL that you would use to clone the repo over SSH.
|
||||
Use an SSH Git URL when repository access depends on your SSH credentials. The
|
||||
first part of the URL is the user and base URL of the Git repository. This is
|
||||
the same URL that you would use to clone the repo over SSH.
|
||||
|
||||
To use Git over SSH, you need to make sure that your SSH agent has your private
|
||||
SSH keys added so that they can be used during authentication.
|
||||
@@ -76,119 +148,24 @@ SSH keys added so that they can be used during authentication.
|
||||
`?ref=<ref>` to the end of the URL. If you omit a reference, the default
|
||||
branch will be used.
|
||||
|
||||
Task has an example remote Taskfile in our repository that you can use for
|
||||
testing and that we will use throughout this document:
|
||||
## Locate files and directories {#special-variables}
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
default:
|
||||
cmds:
|
||||
- task: hello
|
||||
|
||||
hello:
|
||||
cmds:
|
||||
- echo "Hello Task!"
|
||||
```
|
||||
|
||||
## Specifying a remote entrypoint
|
||||
|
||||
By default, Task will look for one of the supported file names on your local
|
||||
filesystem. If you want to use a remote file instead, you can pass its URI into
|
||||
the `--taskfile`/`-t` flag just like you would to specify a different local
|
||||
file. For example:
|
||||
|
||||
::: code-group
|
||||
|
||||
```shell [HTTP/HTTPS]
|
||||
$ task --taskfile https://raw.githubusercontent.com/go-task/task/main/website/src/public/Taskfile.yml
|
||||
task: [hello] echo "Hello Task!"
|
||||
Hello Task!
|
||||
```
|
||||
|
||||
```shell [Git over HTTP]
|
||||
$ task --taskfile https://github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=main
|
||||
task: [hello] echo "Hello Task!"
|
||||
Hello Task!
|
||||
```
|
||||
|
||||
```shell [Git over SSH]
|
||||
$ task --taskfile git@github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=main
|
||||
task: [hello] echo "Hello Task!"
|
||||
Hello Task!
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
## Including remote Taskfiles
|
||||
|
||||
Including a remote file works exactly the same way that including a local file
|
||||
does. You just need to replace the local path with a remote URI. Any tasks in
|
||||
the remote Taskfile will be available to run from your main Taskfile.
|
||||
|
||||
::: code-group
|
||||
|
||||
```yaml [HTTP/HTTPS]
|
||||
version: '3'
|
||||
|
||||
includes:
|
||||
my-remote-namespace: https://raw.githubusercontent.com/go-task/task/main/website/src/public/Taskfile.yml
|
||||
```
|
||||
|
||||
```yaml [Git over HTTP]
|
||||
version: '3'
|
||||
|
||||
includes:
|
||||
my-remote-namespace: https://github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=main
|
||||
```
|
||||
|
||||
```yaml [Git over SSH]
|
||||
version: '3'
|
||||
|
||||
includes:
|
||||
my-remote-namespace: git@github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=main
|
||||
```
|
||||
|
||||
:::
|
||||
|
||||
```shell
|
||||
$ task my-remote-namespace:hello
|
||||
task: [hello] echo "Hello Task!"
|
||||
Hello Task!
|
||||
```
|
||||
|
||||
### Authenticating using environment variables
|
||||
|
||||
The Taskfile location is processed by the templating system, so you can
|
||||
reference environment variables in your URL if you need to add authentication.
|
||||
For example:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
includes:
|
||||
my-remote-namespace: https://{{.TOKEN}}@raw.githubusercontent.com/my-org/my-repo/main/Taskfile.yml
|
||||
```
|
||||
|
||||
## Special Variables
|
||||
|
||||
The file-path [special variables](../docs/reference/templating.md#file-paths)
|
||||
behave differently when a Taskfile is loaded from a remote source, because there
|
||||
is no local file or directory that corresponds 1:1 to the Taskfile:
|
||||
The file-path [special variables](./reference/templating.md#file-paths) behave
|
||||
differently when a Taskfile is loaded from a remote source, because there is no
|
||||
local file or directory that corresponds 1:1 to the Taskfile:
|
||||
|
||||
| Variable | Value when loaded remotely |
|
||||
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `TASKFILE` / `ROOT_TASKFILE` | The original URL, unchanged |
|
||||
| `TASKFILE_DIR` / `ROOT_DIR` | Empty string — a directory variable cannot point to a URL |
|
||||
| `TASKFILE_DIR` / `ROOT_DIR` | Empty string, a directory variable cannot point to a URL |
|
||||
| `TASK_DIR` | Resolved against `USER_WORKING_DIR` (relative `dir:` → joined with `USER_WORKING_DIR`, empty `dir:` → `USER_WORKING_DIR`, absolute `dir:` → kept as-is) |
|
||||
|
||||
If a remote Taskfile includes a local Taskfile (or vice-versa), each variable
|
||||
reflects the source of the Taskfile it refers to.
|
||||
|
||||
## Security
|
||||
## Review trust and changes {#security}
|
||||
|
||||
### Automatic checksums
|
||||
### Review changed files {#automatic-checksums}
|
||||
|
||||
Running commands from sources that you do not control is always a potential
|
||||
security risk. For this reason, we have added some automatic checks when using
|
||||
@@ -221,7 +198,7 @@ in Task. You can also configure trusted hosts in your
|
||||
containing a commit hash) to prevent Task from automatically accepting a
|
||||
prompt that says a remote Taskfile has changed.
|
||||
|
||||
### Manual checksum pinning
|
||||
### Pin reviewed contents {#manual-checksum-pinning}
|
||||
|
||||
Alternatively, if you expect the contents of your remote files to be a constant
|
||||
value, you can pin the checksum of the included file instead:
|
||||
@@ -231,14 +208,15 @@ version: '3'
|
||||
|
||||
includes:
|
||||
included:
|
||||
taskfile: https://taskfile.dev
|
||||
checksum: c153e97e0b3a998a7ed2e61064c6ddaddd0de0c525feefd6bba8569827d8efe9
|
||||
taskfile: https://raw.githubusercontent.com/go-task/task/main/website/src/public/Taskfile.yml
|
||||
checksum: '<sha256-of-reviewed-file>'
|
||||
```
|
||||
|
||||
This will disable the automatic checksum prompts discussed above. However, if
|
||||
the checksums do not match, Task will exit immediately with an error. When
|
||||
setting this up for the first time, you may not know the correct value of the
|
||||
checksum. There are a couple of ways you can obtain this:
|
||||
Replace the placeholder with the SHA-256 checksum of the file you reviewed. A
|
||||
pinned checksum disables the automatic checksum prompts discussed above.
|
||||
However, if the checksums do not match, Task will exit immediately with an
|
||||
error. When setting this up for the first time, you may not know the correct
|
||||
value of the checksum. There are a couple of ways you can obtain this:
|
||||
|
||||
1. Add the include normally without the `checksum` key. The first time you run
|
||||
the included Taskfile, a `.task/remote` temporary directory is created. Find
|
||||
@@ -251,7 +229,7 @@ checksum. There are a couple of ways you can obtain this:
|
||||
will report the incorrect expected checksum and the actual checksum. You can
|
||||
copy the actual checksum and replace your temporary random value.
|
||||
|
||||
### TLS
|
||||
### Use TLS {#tls}
|
||||
|
||||
Task currently supports both `http` and `https` URLs. However, the `http`
|
||||
requests will not execute by default unless you run the task with the
|
||||
@@ -260,7 +238,7 @@ Taskfile that is downloaded via an unencrypted connection. Sources that are not
|
||||
protected by TLS are vulnerable to man-in-the-middle attacks and should be
|
||||
avoided unless you know what you are doing.
|
||||
|
||||
#### Custom Certificates
|
||||
#### Add certificates {#custom-certificates}
|
||||
|
||||
If your remote Taskfiles are hosted on a server that uses a custom CA
|
||||
certificate (e.g., a corporate internal server), you can specify the CA
|
||||
@@ -293,7 +271,17 @@ openssl rsa -in encrypted.key -out decrypted.key
|
||||
These options can also be configured in the
|
||||
[configuration file](#configuration).
|
||||
|
||||
## Caching & Running Offline
|
||||
## Reuse cached files {#caching-running-offline}
|
||||
|
||||
| What do you need? | Option |
|
||||
| -------------------------------------------- | --------------- |
|
||||
| Reuse a downloaded copy for one hour | `--expiry 1h` |
|
||||
| Use an existing cache without network access | `--offline` |
|
||||
| Fetch a fresh copy now | `--download` |
|
||||
| Remove cached remote files | `--clear-cache` |
|
||||
|
||||
For example, run `task --offline shared:hello` after downloading and trusting
|
||||
the include above. Offline mode needs an existing cached copy.
|
||||
|
||||
Whenever you run a remote Taskfile, the latest copy will be downloaded from the
|
||||
internet and cached locally. This cached file will be used for all future
|
||||
@@ -306,8 +294,7 @@ version. However, the cache expiry duration can be modified by setting the
|
||||
If for any reason you lose access to the internet or you are running Task in
|
||||
offline mode (via the `--offline` flag or `TASK_REMOTE_OFFLINE` environment
|
||||
variable), Task will run any available cached files _even if they are expired_.
|
||||
This means that you should never be stuck without the ability to run your tasks
|
||||
as long as you have downloaded a remote Taskfile at least once.
|
||||
An uncached remote file cannot run offline.
|
||||
|
||||
By default, Task will timeout requests to download remote files after 10 seconds
|
||||
and look for a cached copy instead. This timeout can be configured by setting
|
||||
@@ -326,7 +313,7 @@ the `--download` flag.
|
||||
|
||||
You can use the `--clear-cache` flag to clear all cached remote files.
|
||||
|
||||
## Configuration
|
||||
## Set remote defaults {#configuration}
|
||||
|
||||
It is possible to configure the default behavior of remote Taskfiles using
|
||||
configuration. Check out the following references for more information on how to
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
---
|
||||
title: Incident Response Plan
|
||||
description:
|
||||
Task's process for detecting, triaging, mitigating, and disclosing security
|
||||
incidents
|
||||
section: Project
|
||||
docType: project
|
||||
outline: deep
|
||||
---
|
||||
|
||||
@@ -88,4 +93,4 @@ a "best-effort" attempt to help resolve the issue.
|
||||
- Make and document any changes that can be made to prevent similar issues from
|
||||
arising in the future.
|
||||
|
||||
[security-docs]: ../security/
|
||||
[security-docs]: ./index.md
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
---
|
||||
title: Security
|
||||
description:
|
||||
How to report Task security vulnerabilities and how the project responds to
|
||||
them
|
||||
section: Project
|
||||
docType: project
|
||||
outline: deep
|
||||
---
|
||||
|
||||
@@ -18,5 +23,5 @@ You can read more about how we handle security-related issues in our [Incident
|
||||
Response Plan][irp] and [Threat Model][tm].
|
||||
|
||||
[pvr]: https://github.com/go-task/task/security/advisories/new
|
||||
[irp]: ./incident-response-plan
|
||||
[tm]: ./threat-model
|
||||
[irp]: ./incident-response-plan.md
|
||||
[tm]: ./threat-model.md
|
||||
|
||||
@@ -1,5 +1,10 @@
|
||||
---
|
||||
title: Threat Model
|
||||
description:
|
||||
Threats, assets, trust boundaries, and mitigations for the Task project and
|
||||
its release infrastructure
|
||||
section: Project
|
||||
docType: project
|
||||
outline: deep
|
||||
---
|
||||
|
||||
@@ -13,8 +18,8 @@ of our commitment to transparency.
|
||||
|
||||
### Critical Assets
|
||||
|
||||
- **Source Code:** The Task CLI, build scripts, and configuration files
|
||||
(e.g., `Taskfile.yml`, `.goreleaser.yml`).
|
||||
- **Source Code:** The Task CLI, build scripts, and configuration files (e.g.,
|
||||
`Taskfile.yml`, `.goreleaser.yml`).
|
||||
- **Build Artifacts:** Compiled binaries, packages, and containers distributed
|
||||
to users.
|
||||
- **Secrets:** API tokens, signing keys, and repository credentials used in
|
||||
@@ -75,8 +80,8 @@ of our commitment to transparency.
|
||||
|
||||
#### Secrets Leakage
|
||||
|
||||
- Exposure of tokens, credentials, or signing keys in logs, error messages,
|
||||
or artifacts
|
||||
- Exposure of tokens, credentials, or signing keys in logs, error messages, or
|
||||
artifacts
|
||||
- Hardcoded secrets in code or configuration
|
||||
- Improper secret management in CI/CD environments
|
||||
|
||||
@@ -168,7 +173,7 @@ of our commitment to transparency.
|
||||
## References
|
||||
|
||||
- [Task Documentation](https://taskfile.dev/)
|
||||
- [Incident Response Plan](./incident-response-plan)
|
||||
- [Incident Response Plan](./incident-response-plan.md)
|
||||
- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
|
||||
- [Supply Chain Security](https://slsa.dev/)
|
||||
- [GitHub Security Best Practices](https://docs.github.com/en/code-security)
|
||||
|
||||
@@ -3,6 +3,8 @@ title: Style Guide
|
||||
description:
|
||||
Official style guide for Taskfile.yml files with best practices and
|
||||
recommended conventions
|
||||
section: Contributing
|
||||
docType: contributing
|
||||
outline: deep
|
||||
---
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@ title: Taskfile Versions
|
||||
description:
|
||||
How to use the Taskfile schema version to ensure users are using the correct
|
||||
versions of Task
|
||||
section: Project
|
||||
docType: project
|
||||
outline: deep
|
||||
---
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ description:
|
||||
A new completion engine that gives every shell the same suggestions, and that
|
||||
can finally complete your required variables.
|
||||
author: vmaerten
|
||||
date: 2026-09-29
|
||||
date: 2026-10-01
|
||||
tags: ['new-features', 'completion']
|
||||
outline: deep
|
||||
editLink: false
|
||||
|
||||
@@ -13,7 +13,54 @@ editLink: false
|
||||
|
||||
::: v-pre
|
||||
|
||||
## v3.53.0 - 2026-08-18
|
||||
## v3.54.0 - 2026-10-01
|
||||
|
||||
### 🚀 Features
|
||||
|
||||
- Added versioned Homebrew casks (`go-task@<major>.<minor>`) to install a
|
||||
specific minor version of Task (#3023 by @vmaerten).
|
||||
- Added a `remote.headers` config option to send HTTP headers when downloading a
|
||||
remote Taskfile, configured per host. Header values support templating
|
||||
functions, e.g. `{{env "GITLAB_TOKEN"}}`. This keeps the credential out of the
|
||||
include URL, where it would leak into error messages and the confirmation
|
||||
prompt (#2329 by @vmaerten).
|
||||
|
||||
### 🐛 Fixes
|
||||
|
||||
- Fixed remote Git Taskfile cache poisoning on shared hosts (GHSA-679p-658w-m3wr,
|
||||
reported by @danielcadev, fixed by @vmaerten).
|
||||
- Fixed tasks cancelled by the user returning exit code `201` instead of `205`
|
||||
(#3040, #3041 by @r3wretrhy).
|
||||
- Fixed a bug on Windows where watching source paths did not work as expected
|
||||
(#2863, #3028 by @pd93).
|
||||
- Fixed a remote Taskfile whose server refuses the credentials being reported as
|
||||
a missing Taskfile. A `401` now stops the search and reports the status code,
|
||||
instead of retrying every default Taskfile name and concluding that no
|
||||
Taskfile exists (#2329 by @vmaerten).
|
||||
|
||||
- `task --completion <shell>` now serves a new completion engine that unifies
|
||||
Bash, Fish, Zsh, Nushell and PowerShell behind a single `task __complete`
|
||||
command, so every shell offers the same suggestions: task names, aliases,
|
||||
flags, flag values and per-task CLI variables. The Zsh `show-aliases` and
|
||||
`verbose` zstyles keep working, now backed by the `--no-aliases` and
|
||||
`--no-descriptions` completion flags (#2897 by @vmaerten).
|
||||
|
||||
### 📦 Package API
|
||||
|
||||
- Bumped the minimum Go version to 1.26. Task follows Go's two-latest support
|
||||
window, and is now tested against 1.26 and 1.27. This only affects projects
|
||||
importing Task as a Go module (#2920 by @vmaerten).
|
||||
|
||||
### Other
|
||||
|
||||
- Refactored some functional options to always return a concrete type instead of
|
||||
an interface and moved options into their own file (#3037 by @pd93).
|
||||
- Refactored the execext package to use mvdan/sh's new BashOpts API (#3035 by
|
||||
@pd93).
|
||||
|
||||
## v3.53.1 - 2026-08-18
|
||||
|
||||
### 🚀 Features
|
||||
|
||||
- **Remote Taskfiles are now generally available!** This has been an
|
||||
experimental feature for 3 years, but is now enabled by default. Massive
|
||||
@@ -21,21 +68,37 @@ editLink: false
|
||||
here). We've also given the
|
||||
[Remote Taskfiles documentation](https://taskfile.dev/docs/remote-taskfiles) a
|
||||
bit of a polish (#1317, #2906 by @pd93).
|
||||
- Added a per-command `timeout` that terminates a command once it exceeds the
|
||||
given duration (Go duration syntax). It covers shell commands, task calls,
|
||||
deferred commands, `deps` and the `if` condition, obeys `ignore_error`, and
|
||||
reports exit code `124`. Callers that join a `run: once` or `when_changed`
|
||||
task already running now honor their own `timeout`, and inherit that task's
|
||||
failure instead of being told it succeeded (#1569, #2898 by @vmaerten).
|
||||
- Considerably improve performance of fingerprinting on large repositories
|
||||
(monorepos). Fingerprinting is up to 86% faster and make up to 70% fewer
|
||||
memory allocations on the more advanced scenarios. Benchmarks were added as
|
||||
well. We're basically skipping work when not needed. (#2853, #2883 by
|
||||
@Napolitain, #2884 by @Napolitain).
|
||||
- Updated taskfile versions doc to mention when version checks were introduced
|
||||
(#2184 by @jubr).
|
||||
- Fixed `joinUrl` collapsing the `//` in a URL scheme (e.g. producing
|
||||
`http:/localhost` instead of `http://localhost`) (#2915 by @vsaraikin).
|
||||
- Added support for `enum.ref` in `--interactive` prompts. Required vars using
|
||||
`enum.ref` now show the selection list like static enums, instead of falling
|
||||
back to free-form input (#2817 by @vmaerten).
|
||||
- Further improved fingerprinting performance on large repositories: hashing
|
||||
source files now reuses a single buffer, reducing memory allocations by ~98%
|
||||
and wall-clock time by ~7% (#2925 by @vmaerten).
|
||||
- `includes.excludes` can now exclude a whole namespace: append `:*` to the
|
||||
namespace name, e.g. `excludes: ['debug:*']`. Bare entries still match a
|
||||
single task name exactly (#2300, #2959 by @xmxxc).
|
||||
- Added support for `enum.ref` in `--interactive` prompts. Required vars using
|
||||
`enum.ref` now show the selection list like static enums, instead of falling
|
||||
back to free-form input (#2817 by @vmaerten).
|
||||
- Added Nushell completions, available via `task --completion nu`. They complete
|
||||
task names and aliases, every flag with its description, and the values of
|
||||
`--completion`, `--output` and `--sort` (#2966 by @vmaerten).
|
||||
- Added a verbose log line for failed tasks. In `--verbose` mode, a task whose
|
||||
command exits non-zero now reports `task: "<name>" failed: <error>` instead of
|
||||
stopping without a trace (#2240 by @Drino).
|
||||
|
||||
### 🐛 Fixes
|
||||
|
||||
- Fixed a pinned `checksum:` not being verified when a remote Taskfile came from
|
||||
the cache (#2980 by @vmaerten).
|
||||
- Fixed the fingerprint variable (`{{.CHECKSUM}}`/`{{.TIMESTAMP}}`) ignoring a
|
||||
`method:` set at the Taskfile level: the variable now follows the same method
|
||||
resolution as the up-to-date check. Only the variable matching the effective
|
||||
@@ -43,37 +106,31 @@ editLink: false
|
||||
gets `{{.TIMESTAMP}}` and no longer a `{{.CHECKSUM}}` (which now renders as an
|
||||
empty string), and neither variable is injected when the effective method is
|
||||
`none` (#2924 by @vmaerten).
|
||||
- `includes.excludes` can now exclude a whole namespace: append `:*` to the
|
||||
namespace name, e.g. `excludes: ['debug:*']`. Bare entries still match a
|
||||
single task name exactly (#2300, #2959 by @xmxxc).
|
||||
- Fixed `ref:` in `for: matrix:` and `enum:` only accepting literal lists. Refs
|
||||
computed with template functions like `keys` or `splitList` no longer fail
|
||||
with "must resolve to a list" (#2544, #2956 by @no-hup).
|
||||
- Fixed pressing `Esc` at an interactive variable prompt not cancelling the run
|
||||
(#2942 by @anilnatha).
|
||||
- Fixed `joinUrl` collapsing the `//` in a URL scheme (e.g. producing
|
||||
`http:/localhost` instead of `http://localhost`) (#2915 by @vsaraikin).
|
||||
- Fixed the JSON schema rejecting `ignore_error` on a command inside a `for`
|
||||
loop. Editors no longer flag a Taskfile that Task runs perfectly fine (#2044
|
||||
by @gokeefe-atb).
|
||||
- Fixed the JSON schema rejecting more keys the Taskfile parser accepts:
|
||||
`ignore_error` on a `task:` call, and `if`, `set` and `shopt` on a command
|
||||
inside a `for` loop (#2967 by @vmaerten).
|
||||
- Added a verbose log line for failed tasks. In `--verbose` mode, a task whose
|
||||
command exits non-zero now reports `task: "<name>" failed: <error>` instead of
|
||||
stopping without a trace (#2240 by @Drino).
|
||||
- Fixed pressing `Esc` at an interactive variable prompt not cancelling the run
|
||||
(#2942 by @anilnatha).
|
||||
- Added Nushell completions, available via `task --completion nu`. They complete
|
||||
task names and aliases, every flag with its description, and the values of
|
||||
`--completion`, `--output` and `--sort` (#2966 by @vmaerten).
|
||||
- Added a per-command `timeout` that terminates a command once it exceeds the
|
||||
given duration (Go duration syntax). It covers shell commands, task calls,
|
||||
deferred commands, `deps` and the `if` condition, obeys `ignore_error`, and
|
||||
reports exit code `124`. Callers that join a `run: once` or `when_changed`
|
||||
task already running now honor their own `timeout`, and inherit that task's
|
||||
failure instead of being told it succeeded (#1569, #2898 by @vmaerten).
|
||||
- Fixed a pinned `checksum:` not being verified when a remote Taskfile came from
|
||||
the cache (#2980 by @vmaerten).
|
||||
|
||||
### 📚 Documentation & Website
|
||||
|
||||
- Updated taskfile versions doc to mention when version checks were introduced
|
||||
(#2184 by @jubr).
|
||||
- Load the sidebar data and titles/excerpts from the blog post markdown document
|
||||
and its frontmatter on the website (#2981 by @pd93).
|
||||
|
||||
## v3.53.0 - 2026-08-18
|
||||
|
||||
- Failed due to an issue with our release process.
|
||||
|
||||
## v3.52.0 - 2026-07-02
|
||||
|
||||
- Fixed --interactive prompts for required vars sometimes appearing in a random
|
||||
@@ -1638,4 +1695,4 @@ document, since it describes in depth what changed for this version.
|
||||
|
||||
- Add LICENSE file
|
||||
|
||||
:::
|
||||
:::
|
||||
@@ -49,6 +49,28 @@
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"headers": {
|
||||
"type": "array",
|
||||
"description": "HTTP headers to send when downloading remote Taskfiles, per host, including authentication and custom headers.",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"host": {
|
||||
"type": "string",
|
||||
"description": "Host the headers apply to, including the port if the URL has one (e.g., 'gitlab.com', 'example.com:8080')."
|
||||
},
|
||||
"headers": {
|
||||
"type": "object",
|
||||
"description": "Headers to send. Values support templating functions, e.g. {{env \"GITLAB_TOKEN\"}}.",
|
||||
"additionalProperties": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": ["host", "headers"],
|
||||
"additionalProperties": false
|
||||
}
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
|
||||
Reference in New Issue
Block a user