Technical Documentation: go-task/task
βΉοΈ Provenance: Multi-Tier Ingestion Β· CodeWiki Reference
Overview (`README.md`)
Website Src Latest Docs Getting Started (`website/src/latest/docs/getting-started.md`)
title: Quick Start section: Getting Started docType: guide outline: deep
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.
Creating your first Taskfile
Once Task is installed, you can create your first Taskfile by running:
task --initThis will create a file called Taskfile.yml in the current directory. If you
want to create the file in another directory, you can pass an absolute or
relative path to the directory into the command:
task --init ./subdirectoryOr if you want the Taskfile to have a specific name, you can pass in the name of
the file:
task --init Custom.ymlThis will create a Taskfile that looks something like this:
version: '3'
vars:
GREETING: Hello, World!
tasks:
default:
desc: Print a greeting message
cmds:
- echo "{{.GREETING}}"
silent: trueAs you can see, all Taskfiles are written in YAML format.
The version attribute specifies the minimum version of Task that can be used
to run this file. The vars attribute is used to define variables that can be
used in tasks. In this case, we are creating a string variable called GREETING
with a value of Hello, World!.
Finally, the tasks attribute is used to define the tasks that can be run. In
this case, we have a task called default that echoes the value of theGREETING variable. The silent attribute is set to true, which means that
the task metadata will not be printed when the task is run - only the output of
the commands.
Calling a task
To call the task, invoke task followed by the name of the task you want to
run. In this case, the name of the task is default, so you should run:
task defaultNote 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) 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
flag:
task --dir ./subdirectoryOr if you created a Taskfile with a different name, you can run it by passing
the name of the Taskfile as an argument using the --taskfile flag:
task --taskfile Custom.ymlAdding a build task
Let's create a task to build a program in Go. Start by adding a new task calledbuild below the existing default task. We can then add a cmds attribute
with a single command to build the program.
Task uses mvdan/sh, a native Go sh interpreter.
So you can write sh/bash-like commands - even in environments where sh orbash are usually not available (like Windows). Just remember any executables
called must be available as a built-in or in the system's PATH.
When you're done, it should look something like this:
version: '3'
vars:
GREETING: Hello, World!
tasks:
default:
desc: Print a greeting message
cmds:
- echo "{{.GREETING}}"
silent: true
build:
cmds:
- go build ./cmd/main.goCall the task by running:
task buildThat'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 next. Alternatively, you can check out our
reference docs for the Taskfile schema and
CLI.
Website Src Latest Docs Index (`website/src/latest/docs/index.md`)
title: Documentation 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.
Start with Task {#new-to-task}
Install Task and run your first Taskfile.
Use Task {#using-task}
Find a guide for your everyday workflows.
Reference {#looking-something-up}
Look up syntax, flags and functions.
For settings outside the Taskfile, see Configuration
and Environment.
Keeping up
- Changelog: what shipped, and when.
- Experiments and
Deprecations: what is coming, and what is going
away. - FAQ: the questions that come up most often.
- Community: integrations and tools built by other people.
Using an AI coding assistant
Task documentation for coding agents 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.
Website Src Next Docs Getting Started (`website/src/next/docs/getting-started.md`)
title: Quick Start section: Getting Started docType: guide outline: deep
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.
Creating your first Taskfile
Once Task is installed, you can create your first Taskfile by running:
task --initThis will create a file called Taskfile.yml in the current directory. If you
want to create the file in another directory, you can pass an absolute or
relative path to the directory into the command:
task --init ./subdirectoryOr if you want the Taskfile to have a specific name, you can pass in the name of
the file:
task --init Custom.ymlThis will create a Taskfile that looks something like this:
version: '3'
vars:
GREETING: Hello, World!
tasks:
default:
desc: Print a greeting message
cmds:
- echo "{{.GREETING}}"
silent: trueAs you can see, all Taskfiles are written in YAML format.
The version attribute specifies the minimum version of Task that can be used
to run this file. The vars attribute is used to define variables that can be
used in tasks. In this case, we are creating a string variable called GREETING
with a value of Hello, World!.
Finally, the tasks attribute is used to define the tasks that can be run. In
this case, we have a task called default that echoes the value of theGREETING variable. The silent attribute is set to true, which means that
the task metadata will not be printed when the task is run - only the output of
the commands.
Calling a task
To call the task, invoke task followed by the name of the task you want to
run. In this case, the name of the task is default, so you should run:
task defaultNote 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) 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
flag:
task --dir ./subdirectoryOr if you created a Taskfile with a different name, you can run it by passing
the name of the Taskfile as an argument using the --taskfile flag:
task --taskfile Custom.ymlAdding a build task
Let's create a task to build a program in Go. Start by adding a new task calledbuild below the existing default task. We can then add a cmds attribute
with a single command to build the program.
Task uses mvdan/sh, a native Go sh interpreter.
So you can write sh/bash-like commands - even in environments where sh orbash are usually not available (like Windows). Just remember any executables
called must be available as a built-in or in the system's PATH.
When you're done, it should look something like this:
version: '3'
vars:
GREETING: Hello, World!
tasks:
default:
desc: Print a greeting message
cmds:
- echo "{{.GREETING}}"
silent: true
build:
cmds:
- go build ./cmd/main.goCall the task by running:
task buildThat'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 next. Alternatively, you can check out our
reference docs for the Taskfile schema and
CLI.
Website Src Next Docs Index (`website/src/next/docs/index.md`)
title: Documentation 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.
Start with Task {#new-to-task}
Install Task and run your first Taskfile.
Use Task {#using-task}
Find a guide for your everyday workflows.
Reference {#looking-something-up}
Look up syntax, flags and functions.
For settings outside the Taskfile, see Configuration
and Environment.
Keeping up
- Changelog: what shipped, and when.
- Experiments and
Deprecations: what is coming, and what is going
away. - FAQ: the questions that come up most often.
- Community: integrations and tools built by other people.
Using an AI coding assistant
Task documentation for coding agents 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.
Website Src Latest Docs Deprecations Index (`website/src/latest/docs/deprecations/index.md`)
title: Deprecations Guide to deprecated features in Task and how to migrate to the new alternatives section: Project docType: project outline: deep
Deprecations
As Task evolves, it occasionally outgrows some of its functionality. This can be
because they are no longer useful, because another feature has replaced it or
because of a change in the way that Task works internally.
When this happens, we mark the functionality as deprecated. This means that it
will be removed in a future version of Task. This functionality will continue to
work until that time, but we strongly recommend that you do not implement this
functionality in new Taskfiles and make a plan to migrate away from it as soon
as possible.
You can view a full list of active deprecations in the "Deprecations" section of
the sidebar.
Website Src Latest Docs Experiments Index (`website/src/latest/docs/experiments/index.md`)
title: Experiments section: Project docType: project outline: deep
Experiments
::: warning
All experimental features are subject to breaking changes and/or removal at any
time. We strongly recommend that you do not use these features in a production
environment. They are intended for testing and feedback only.
:::
In order to allow Task to evolve quickly, we sometimes roll out breaking changes
to minor versions behind experimental flags. This allows us to gather feedback
on breaking changes before committing to a major release. This process can also
be used to gather feedback on important non-breaking features before their
design is completed. This document describes the
experiment workflow and how you can get involved.
You can view the full list of active experiments in the sidebar submenu to the
left of the page and click on each one to find out more about it.
Enabling Experiments
Task uses environment variables to detect whether or not an experiment is
enabled. All of the experiment variables will begin with the same TASK_X_
prefix followed by the name of the experiment. You can find the exact name for
each experiment on their respective pages in the sidebar. If the variable is set=1 then it will be enabled. Some experiments may have multiple proposals, in
which case, you will need to set the variable equal to the number of the
proposal that you want to enable (=2, =3 etc).
There are three main ways to set the environment variables for an experiment.
Which method you use depends on how you intend to use the experiment:
Prefixing your task commands with the relevant environment variable(s). For
example,TASK_X_{FEATURE}=1 task {my-task}. This is intended for one-off
invocations of Task to test out experimental features.Adding the relevant environment variable(s) in your "dotfiles" (e.g.
.bashrc,.zshrcetc.). This will permanently enable experimental features
for your personal environment.shell# ~/.bashrc export TASK_X_FEATURE=1Creating a
.envor a.taskrc.ymlfile in the same directory as your root
Taskfile.
The.envfile should contain the relevant environment variable(s), while
the.taskrc.ymlfile should use a YAML format where each experiment is
defined as a key with a corresponding value.This allows you to enable an experimental feature at a project level. If you
commit this file to source control, then other users of your project will
also have these experiments enabled.If both files are present, the values in the
.taskrc.ymlfile will take
precedence.
::: code-group
experiments:
FEATURE: 1TASK_X_FEATURE=1:::
Workflow
Experiments are a way for us to test out new features in Task before committing
to them in a major release. Because this concept is built around the idea of
feedback from our community, we have built a workflow for the process of
introducing these changes. This ensures that experiments are given the attention
and time that they need and that we are getting the best possible results out of
them.
The sections below describe the various stages that an experiment must go
through from its proposal all the way to being released in a major version of
Task.
1. Proposal
All experimental features start with a proposal in the form of a GitHub issue.
If the maintainers decide that an issue has enough support and is a breaking
change or is complex/controversial enough to require user feedback, then the
issue's experiment status field will be set to proposed. At this point, the
issue becomes a proposal and a period of consultation begins. During this
period, we request that users provide feedback on the proposal and how it might
effect their use of Task. It is up to the discretion of the maintainers to
decide how long this period lasts.
2. Draft
Once a proposal's consultation ends, a contributor may pick up the work and
begin the initial implementation. Once a PR is opened, the maintainers will
ensure that it meets the requirements for an experimental feature (i.e. flags
are in the right format etc) and merge the feature. Once this code is released,
the experiment status field will be updated to draft. This indicates that an
implementation is now available for use in a release and the experiment is open
for feedback.
::: info
During the draft period, major changes to the implementation may be made based
on the feedback received from users. There are no stability guarantees and
experimental features may be abandoned at any time.
:::
3. Candidate
Once an acceptable level of consensus has been reached by the community and
feedback/changes are less frequent/significant, the experiment status field will
be updated to candidate. This indicates that a proposal is likely to
accepted and will enter a period for final comments and minor changes.
4. Stable
Once a suitable amount of time has passed with no changes or feedback, the
experiment status field will be updated to stable. At this point, the
functionality will be treated like any other feature in Task and any changes
must be backward compatible. This allows users to migrate to the new
functionality without having to worry about anything breaking in future
releases. This provides the best experience for users migrating to a new major
version.
5. Released
When an experiment moves to a released status, it becomes the default behavior
and flags or config are no longer required to enable the feature. For
non-breaking changes, this will happen in a minor release. For breaking changes,
this will happen in a major release.
Abandoned / Superseded
If an experiment is unsuccessful at any point then the experiment status field
will be updated to abandoned or superseded depending on which is more
suitable. These experiments will be removed from Task.
Website Src Latest Docs Guide Index (`website/src/latest/docs/guide/index.md`)
title: Guide 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. For accepted keys,
flags and functions, use the Taskfile Schema,
CLI and Templating
references.
Writing and running tasks {#writing-and-running-tasks}
- Defining tasks: command lists, descriptions, aliases
and display labels. - Running tasks: choosing a Taskfile, running from other
directories, previewing commands and using interactive applications.
Variables and arguments {#variables-and-environment}
- Variables: declaring values, computing them with shell
commands, preserving types and understanding resolution order. - Command-line arguments: assigning variables, forwarding
arguments with--and capturing values from task names. - Validation and prompts: requiring inputs,
restricting allowed values and asking for missing values. - Secret variables: loading sensitive values and
masking them in Task's command logs.
Task execution {#controlling-what-runs}
- Dependencies and task calls: running tasks concurrently
or in sequence, limiting concurrency and controlling repeated calls. - Loops: repeating commands or task calls over values, files and
matrices. - Conditional execution: skipping optional work
withif, enforcing requirements withpreconditionsand asking for
confirmation. - Errors and cleanup: continuing after selected
failures and running cleanup withdefer. - Up-to-date checks: skipping unchanged builds, checking for
missing outputs and combining file checks with custom conditions. - Watch mode: rerunning tasks when source files change.
Environment and output {#execution-environment}
- Environment variables: setting the environment for
commands and loading.envfiles. - Platforms and shells: selecting platform-specific commands,
understanding shell context and setting shell options. - Output and logging: streaming, grouping and prefixing output,
hiding command echoes and displaying CI annotations.
Including Taskfiles {#composing-taskfiles}
- Including Taskfiles: sharing tasks with namespaces,
configuring includes and passing variables to them. - Remote Taskfiles: loading Taskfiles over HTTP or Git
and managing trust, checksums and cached copies.
Website Src Latest Docs Security Index (`website/src/latest/docs/security/index.md`)
title: Security How to report Task security vulnerabilities and how the project responds to them section: Project docType: project outline: deep
Security
The Task team takes security seriously and we thank our community for disclosing
issues responsibly. To report security issues, please use GitHub's built-in
Private Vulnerability Reporting or send an email to
[email protected]. Please include as much detail as
possible in your report.
A member of the team will investigate as soon as possible and we will keep you
updated throughout the process.
You can read more about how we handle security-related issues in our Incident
Response Plan and Threat Model.
Website Src Next Docs Deprecations Index (`website/src/next/docs/deprecations/index.md`)
title: Deprecations Guide to deprecated features in Task and how to migrate to the new alternatives section: Project docType: project outline: deep
Deprecations
As Task evolves, it occasionally outgrows some of its functionality. This can be
because they are no longer useful, because another feature has replaced it or
because of a change in the way that Task works internally.
When this happens, we mark the functionality as deprecated. This means that it
will be removed in a future version of Task. This functionality will continue to
work until that time, but we strongly recommend that you do not implement this
functionality in new Taskfiles and make a plan to migrate away from it as soon
as possible.
You can view a full list of active deprecations in the "Deprecations" section of
the sidebar.
Website Src Next Docs Experiments Index (`website/src/next/docs/experiments/index.md`)
title: Experiments section: Project docType: project outline: deep
Experiments
::: warning
All experimental features are subject to breaking changes and/or removal at any
time. We strongly recommend that you do not use these features in a production
environment. They are intended for testing and feedback only.
:::
In order to allow Task to evolve quickly, we sometimes roll out breaking changes
to minor versions behind experimental flags. This allows us to gather feedback
on breaking changes before committing to a major release. This process can also
be used to gather feedback on important non-breaking features before their
design is completed. This document describes the
experiment workflow and how you can get involved.
You can view the full list of active experiments in the sidebar submenu to the
left of the page and click on each one to find out more about it.
Enabling Experiments
Task uses environment variables to detect whether or not an experiment is
enabled. All of the experiment variables will begin with the same TASK_X_
prefix followed by the name of the experiment. You can find the exact name for
each experiment on their respective pages in the sidebar. If the variable is set=1 then it will be enabled. Some experiments may have multiple proposals, in
which case, you will need to set the variable equal to the number of the
proposal that you want to enable (=2, =3 etc).
There are three main ways to set the environment variables for an experiment.
Which method you use depends on how you intend to use the experiment:
Prefixing your task commands with the relevant environment variable(s). For
example,TASK_X_{FEATURE}=1 task {my-task}. This is intended for one-off
invocations of Task to test out experimental features.Adding the relevant environment variable(s) in your "dotfiles" (e.g.
.bashrc,.zshrcetc.). This will permanently enable experimental features
for your personal environment.shell# ~/.bashrc export TASK_X_FEATURE=1Creating a
.envor a.taskrc.ymlfile in the same directory as your root
Taskfile.
The.envfile should contain the relevant environment variable(s), while
the.taskrc.ymlfile should use a YAML format where each experiment is
defined as a key with a corresponding value.This allows you to enable an experimental feature at a project level. If you
commit this file to source control, then other users of your project will
also have these experiments enabled.If both files are present, the values in the
.taskrc.ymlfile will take
precedence.
::: code-group
experiments:
FEATURE: 1TASK_X_FEATURE=1:::
Workflow
Experiments are a way for us to test out new features in Task before committing
to them in a major release. Because this concept is built around the idea of
feedback from our community, we have built a workflow for the process of
introducing these changes. This ensures that experiments are given the attention
and time that they need and that we are getting the best possible results out of
them.
The sections below describe the various stages that an experiment must go
through from its proposal all the way to being released in a major version of
Task.
1. Proposal
All experimental features start with a proposal in the form of a GitHub issue.
If the maintainers decide that an issue has enough support and is a breaking
change or is complex/controversial enough to require user feedback, then the
issue's experiment status field will be set to proposed. At this point, the
issue becomes a proposal and a period of consultation begins. During this
period, we request that users provide feedback on the proposal and how it might
effect their use of Task. It is up to the discretion of the maintainers to
decide how long this period lasts.
2. Draft
Once a proposal's consultation ends, a contributor may pick up the work and
begin the initial implementation. Once a PR is opened, the maintainers will
ensure that it meets the requirements for an experimental feature (i.e. flags
are in the right format etc) and merge the feature. Once this code is released,
the experiment status field will be updated to draft. This indicates that an
implementation is now available for use in a release and the experiment is open
for feedback.
::: info
During the draft period, major changes to the implementation may be made based
on the feedback received from users. There are no stability guarantees and
experimental features may be abandoned at any time.
:::
3. Candidate
Once an acceptable level of consensus has been reached by the community and
feedback/changes are less frequent/significant, the experiment status field will
be updated to candidate. This indicates that a proposal is likely to
accepted and will enter a period for final comments and minor changes.
4. Stable
Once a suitable amount of time has passed with no changes or feedback, the
experiment status field will be updated to stable. At this point, the
functionality will be treated like any other feature in Task and any changes
must be backward compatible. This allows users to migrate to the new
functionality without having to worry about anything breaking in future
releases. This provides the best experience for users migrating to a new major
version.
5. Released
When an experiment moves to a released status, it becomes the default behavior
and flags or config are no longer required to enable the feature. For
non-breaking changes, this will happen in a minor release. For breaking changes,
this will happen in a major release.
Abandoned / Superseded
If an experiment is unsuccessful at any point then the experiment status field
will be updated to abandoned or superseded depending on which is more
suitable. These experiments will be removed from Task.
Website Src Next Docs Guide Index (`website/src/next/docs/guide/index.md`)
title: Guide 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. For accepted keys,
flags and functions, use the Taskfile Schema,
CLI and Templating
references.
Writing and running tasks {#writing-and-running-tasks}
- Defining tasks: command lists, descriptions, aliases
and display labels. - Running tasks: choosing a Taskfile, running from other
directories, previewing commands and using interactive applications.
Variables and arguments {#variables-and-environment}
- Variables: declaring values, computing them with shell
commands, preserving types and understanding resolution order. - Command-line arguments: assigning variables, forwarding
arguments with--and capturing values from task names. - Validation and prompts: requiring inputs,
restricting allowed values and asking for missing values. - Secret variables: loading sensitive values and
masking them in Task's command logs.
Task execution {#controlling-what-runs}
- Dependencies and task calls: running tasks concurrently
or in sequence, limiting concurrency and controlling repeated calls. - Loops: repeating commands or task calls over values, files and
matrices. - Conditional execution: skipping optional work
withif, enforcing requirements withpreconditionsand asking for
confirmation. - Errors and cleanup: continuing after selected
failures and running cleanup withdefer. - Up-to-date checks: skipping unchanged builds, checking for
missing outputs and combining file checks with custom conditions. - Watch mode: rerunning tasks when source files change.
Environment and output {#execution-environment}
- Environment variables: setting the environment for
commands and loading.envfiles. - Platforms and shells: selecting platform-specific commands,
understanding shell context and setting shell options. - Output and logging: streaming, grouping and prefixing output,
hiding command echoes and displaying CI annotations.
Including Taskfiles {#composing-taskfiles}
- Including Taskfiles: sharing tasks with namespaces,
configuring includes and passing variables to them. - Remote Taskfiles: loading Taskfiles over HTTP or Git
and managing trust, checksums and cached copies.
Website Src Next Docs Security Index (`website/src/next/docs/security/index.md`)
title: Security How to report Task security vulnerabilities and how the project responds to them section: Project docType: project outline: deep
Security
The Task team takes security seriously and we thank our community for disclosing
issues responsibly. To report security issues, please use GitHub's built-in
Private Vulnerability Reporting or send an email to
[email protected]. Please include as much detail as
possible in your report.
A member of the team will investigate as soon as possible and we will keep you
updated throughout the process.
You can read more about how we handle security-related issues in our Incident
Response Plan and Threat Model.
Website Src Latest Docs Changelog (`website/src/latest/docs/changelog.md`)
title: Changelog Release history for Task, including new features, improvements, fixes, and breaking changes section: Project docType: project outline: deep editLink: false
Changelog
::: v-pre
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.headersconfig 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
201instead of205
(#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. A401now 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 singletask __complete
command, so every shell offers the same suggestions: task names, aliases,
flags, flag values and per-task CLI variables. The Zshshow-aliasesandverbosezstyles keep working, now backed by the--no-aliasesand--no-descriptionscompletion 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
thanks to all those that contributed and gave feedback (too many to list
here). We've also given the
Remote Taskfiles documentation a
bit of a polish (#1317, #2906 by @pd93). - Added a per-command
timeoutthat terminates a command once it exceeds the
given duration (Go duration syntax). It covers shell commands, task calls,
deferred commands,depsand theifcondition, obeysignore_error, and
reports exit code124. Callers that join arun: onceorwhen_changed
task already running now honor their owntimeout, 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). - 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.excludescan 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.refin--interactiveprompts. Required vars usingenum.refnow 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,--outputand--sort(#2966 by @vmaerten). - Added a verbose log line for failed tasks. In
--verbosemode, a task whose
command exits non-zero now reportstask: "<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 amethod: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
method is injected, so a task inheriting a Taskfile-levelmethod: timestamp
gets{{.TIMESTAMP}}and no longer a{{.CHECKSUM}}(which now renders as an
empty string), and neither variable is injected when the effective method isnone(#2924 by @vmaerten). - Fixed
ref:infor: matrix:andenum:only accepting literal lists. Refs
computed with template functions likekeysorsplitListno longer fail
with "must resolve to a list" (#2544, #2956 by @no-hup). - Fixed pressing
Escat an interactive variable prompt not cancelling the run
(#2942 by @anilnatha). - Fixed
joinUrlcollapsing the//in a URL scheme (e.g. producinghttp:/localhostinstead ofhttp://localhost) (#2915 by @vsaraikin). - Fixed the JSON schema rejecting
ignore_erroron a command inside afor
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_erroron atask:call, andif,setandshopton a command
inside aforloop (#2967 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
order. Prompts now follow the order the vars are declared in the Taskfile.
(#2871 by @caproven) - Fixed Fish completions not being picked up correctly by installing them to
Fish'svendor_completions.ddirectory instead ofcompletions(#2850, #2859
by @Legimity). - PowerShell completions now work with aliases of the
taskcommand, not just
thetaskbinary itself (#2852 by @kojiishi). - Fixed task and namespace aliases not being completed by the Zsh completion. A
show-aliaseszstyle can turn this off (#2865, #2864 by @vmaerten). - Fixed task names containing certain characters (e.g.
\,_,^) leaking
into checksum/timestamp filenames, breakingsources:/generates:up-to-date
detection (#2886 by @s3onghyun). - Fixed
for: matrix:loops usingref:rows producing wrong values when the
same task was run concurrently (e.g. by paralleldeps) with different vars
(#2890, #2894 by @amitmishra11). - Added a
secret: trueflag for variables that masks their value in logs,task --summary, and command output (#2514 by @vmaerten). - Added the
use_gitignoresetting (global or per-task) to skip files matched
by your.gitignorewhen fingerprintingsources/generatesand when
watching (#2773 by @vmaerten). - Added support for configuring output flags (
--output,--output-group-begin,--output-group-end,--output-group-error-only) via
theTASK_OUTPUT*environment variables (#2873 by @liiight). - Added a
--temp-dirflag (withTASK_TEMP_DIRenv var andtemp-dirtaskrc
config) to customise the directory where Task stores temporary files such as
checksums. Relative paths are resolved against the root Taskfile (#2891 by
@kjasn). - Defined environment variable behavior for remote taskfiles (#2267, #2847 by
@vmaerten). - Added support for remote Taskfiles hosted on Azure DevOps, whose git URLs use
a/_git/path segment rather than a.gitsuffix (#2904 by @pd93). - Re-added the example remote taskfile at
taskfile.dev/Taskfile.yml (#2905 by
@pd93). - Fixed malformed
includes:entries (missingtaskfile/dir) reporting a
misleading "include cycle detected" error instead of a clear configuration
error (#1881, #2892 by @Lewin671).
v3.51.1 - 2026-05-16
- A significant performance boost was achieved for large Taskfiles (monorepos)
by skipping templating altogether when the string is static (#2820 by @romnn). - Added
absPathtemplate function that resolves a path to its absolute form,
cleaning..and.components (#2681, #2788 by @mateenanjum). - Added
joinEnvfunction to join paths based on your oprating system:;for
Windows and:elsewhere, andjoinUrlto join URL paths. Also, added two
new special variables:FILE_PATH_SEPARATORwhich returns\on Windows and/elsewhere, andPATH_LIST_SEPARATORwhich returns;on Windows and:
elsewhere (#2406, #2408 by @solvingj). - Update the shell interpreter with a regression fix (#2812, #2832 by
@andreynering). - Fix potential panic with the shell interpreter (#2810 by @trulede).
v3.50.0 - 2026-04-13
- Added
enum.refsupport inrequires: enum constraints can now reference
variables or template pipelines (e.g.,ref: .ALLOWED_ENVS) instead of
duplicating static lists. Combined withsh:variables, this enables fully
dynamic enum validation (#2678 by @vmaerten). - Fixed Fish completion using hardcoded
taskbinary name instead of$GO_TASK_PROGNAMEfor experiments cache (#2730, #2727 by @SergioChan). - Fixed watch mode ignoring SIGHUP signal, causing the watcher to exit instead
of restarting (#2764, #2642). - Fixed a long time bug where the task wouldn't re-run as it should when using
method: timestampand the files listed ongenerates:were deleted. This
makesmethod: timestampbehaves the same asmethod: checksum(#1230, #2716
by @drichardson).
v3.49.1 - 2026-03-08
- Reverted #2632 for now, which caused some regressions. That change will be
reworked (#2720, #2722, #2723).
v3.49.0 - 2026-03-07
- Fixed included Taskfiles with
watch: truenot triggering watch mode when
called from the root Taskfile (#2686, #1763 by @trulede). - Fixed Remote Git Taskfiles failing on Windows due to backslashes in URL paths
(#2656 by @Trim21). - Fixed remote Git Taskfiles timing out when resolving includes after accepting
the trust prompt (#2669, #2668 by @vmaerten). - Fixed unclear error message when Taskfile search stops at a directory
ownership boundary (#2682, #1683 by @trulede). - Fixed global variables from imported Taskfiles not resolving
ref:values
correctly (#2632 by @trulede). - Every
.taskrc.ymloption can now be overridden with aTASK_-prefixed
environment variable, making CI and container configuration easier (#2607,
#1066 by @vmaerten).
v3.48.0 - 2026-01-26
- Fixed
if:conditions when using to check dynamic variables. Also, skip
variable prompt if task would be skipped byif:(#2658, #2660 by @vmaerten). - Fixed
ROOT_TASKFILEvariable pointing to directory instead of the actual
Taskfile path when no explicit-tflag is provided (#2635, #1706 by
@trulede). - Included Taskfiles with
silent: truenow properly propagate silence to their
tasks, while still allowing individual tasks to override withsilent: false
(#2640, #1319 by @trulede). - Added TLS certificate options for Remote Taskfiles: use
--cacertfor
self-signed certificates and--cert/--cert-keyfor mTLS authentication
(#2537, #2242 by @vmaerten).
v3.47.0 - 2026-01-24
- Fixed remote git Taskfiles: cloning now works without explicit ref, and
directory includes are properly resolved (#2602 by @vmaerten). - For
output: prefixed, printprefix:if set instead of task name (#1566,
#2633 by @trulede). - Ensure no ANSI sequences are printed for
--color=false(#2560, #2584 by
@trulede). - Task aliases can now contain wildcards and will match accordingly (e.g.,
s-*
as alias forstart-*) (#1900, #2234 by @vmaerten). - Added conditional execution with the
iffield: skip tasks, commands, or task
calls based on shell exit codes or template expressions like{{ eq .ENV "prod" }}(#2564, #608 by @vmaerten). - Task can now interactively prompt for missing required variables when running
in a TTY, with support for enum selection menus. Enable with--interactive
flag orinteractive: truein.taskrc.yml(#2579, #2079 by @vmaerten).
v3.46.4 - 2025-12-24
- Fixed regressions in completion script for Fish (#2591, #2604, #2592 by
@WinkelCode).
v3.46.3 - 2025-12-19
- Fixed regression in completion script for zsh (#2593, #2594 by @vmaerten).
v3.46.2 - 2025-12-18
- Fixed a regression on previous release that affected variables passed via
command line (#2588, #2589 by @vmaerten).
v3.46.1 - 2025-12-18
β¨ Features
- A small behavior change was made to dependencies. Task will now wait for all
dependencies to finish running before continuing, even if any of them fail. To
opt for the previous behavior, setfailfast: trueeither on your.taskrc.ymlor per task, or use the--failfastflag, which will also work
for--parallel(#1246, #2525 by @andreynering). - The
--summaryflag now displaysvars:(both global and task-level),env:, andrequires:sections. Dynamic variables show their shell command
(e.g.,sh: echo "hello") instead of the evaluated value (#2486 ,#2524 by
@vmaerten). - Improved performance of fuzzy task name matching by implementing lazy
initialization. Added--disable-fuzzyflag anddisable-fuzzytaskrc option
to allow disabling fuzzy matching entirely (#2521, #2523 by @vmaerten). - Added LLM-optimized documentation via VitePress plugin, generating
llms.txt
andllms-full.txtfor AI-powered development tools (#2513 by @vmaerten). - Added
--trusted-hostsCLI flag andremote.trusted-hostsconfig option to
skip confirmation prompts for specified hosts when using Remote Taskfiles
(#2491, #2473 by @maciejlech). - When running in GitHub Actions, Task now automatically emits error annotations
on failure, improving visibility in workflow summaries (#2568 by @vmaerten). - The
--yesflag is now accessible in templates via the newCLI_ASSUME_YES
variable (#2577, #2479 by @semihbkgr). - Improved shell completion scripts (Zsh, Fish, PowerShell) by adding missing
flags and dynamic experimental feature detection (#2532 by @vmaerten). - Remote Taskfiles now accept
application/octet-streamContent-Type (#2536,
#1944 by @vmaerten). - Shell completion now works when Task is installed or aliased under a different
binary name via TASK_EXE environment variable (#2495, #2468 by @vmaerten). - Some small fixes and improvements were made to
task --initand to the
default Taskfile it generates (#2433 by @andreynering). - Added
--remote-cache-dirflag andremote.cache-dirtaskrc option to
customize the cache directory for Remote Taskfiles (#2572 by @vmaerten). - Zsh completion now supports zstyle verbose option to show or hide task
descriptions (#2571 by @vmaerten). - Task now automatically enables colored output in CI environments (GitHub
Actions, GitLab CI, etc.) without requiring FORCE_COLOR=1 (#2569 by
@vmaerten). - Added color taskrc option to explicitly enable or disable colored output
globally (#2569 by @vmaerten). - Improved Git Remote Taskfiles by switching to go-getter: SSH authentication
now works out of the box andapplyOfis properly supported (#2512 by
@vmaerten).
π Fixes
- Fix RPM upload to Cloudsmith by including the version in the filename to
ensure unique filenames (#2507 by @vmaerten). - Fix
run: when_changedto work properly for Taskfiles included multiple times
(#2508, #2511 by @trulede). - Fixed Zsh and Fish completions to stop suggesting task names after
--
separator, allowing proper CLI_ARGS completion (#1843, #1844 by
@boiledfroginthewell). - Watch mode (
--watch) now always runs the task, regardless ofrun: onceorrun: when_changedsettings (#2566, #1388 by @trulede). - Fixed global variables (CLI_ARGS, CLI_FORCE, etc.) not being accessible in
root-level vars section (#2403, #2397 by @trulede, @vmaerten). - Fixed a bug where
ignore_errorwas ignored when usingtask:to call
another task (#2552, #363 by @trulede). - Fixed Zsh completion not suggesting global tasks when using
-g/--global
flag (#1574, #2574 by @vmaerten). - Fixed Fish completion failing to parse task descriptions containing colons
(e.g., URLs or namespaced functions) (#2101, #2573 by @vmaerten). - Fixed false positive "property 'for' is not allowed" warnings in IntelliJ when
usingforloops in Taskfiles (#2576 by @vmaerten).
v3.45.5 - 2025-11-11
- Fixed bug that made a generic message, instead of an useful one, appear when a
Taskfile could not be found (#2431 by @andreynering). - Fixed a bug that caused an error when including a Remote Git Taskfile (#2438
by @twelvelabs). - Fixed issue where
.taskrc.ymlwas not returned if reading it failed, and
corrected handling of remote entrypoint Taskfiles (#2460, #2461 by @vmaerten). - Improved performance of
--listand--list-allby introducing a faster
compilation method that skips source globbing and checksum updates (#1322,
#2053 by @vmaerten). - Fixed a concurrency bug with
output: group. This ensures that begin/end
parts won't be mixed up from different tasks (#1208, #2349, #2350 by
@trulede). - Do not re-evaluate variables for
defer:(#2244, #2418 by @trulede). - Improve error message when a Taskfile is not found (#2441, #2494 by
@vmaerten). - Fixed generic error message
exit status 1when a dependency task failed
(#2286 by @GrahamDennis). - Fixed YAML library from the unmaintained
gopkg.in/yaml.v3to the new fork
maintained by the official YAML org (#2171, #2434 by @andreynering). - On Windows, the built-in version of the
rmcore utils contains a fix related
to the-fflag (#2426,
u-root/u-root#3464,
mvdan/sh#1199, #2506 by
@andreynering).
v3.45.4 - 2025-09-17
- Fixed a bug where
cache-expirycould not be defined in.taskrc.yml(#2423
by @vmaerten). - Fixed a bug where
.taskrc.ymlfiles in parent folders were not read
correctly (#2424 by @vmaerten). - Fixed a bug where autocomplete in subfolders did not work with zsh (#2425 by
@vmaerten).
v3.45.3 - 2025-09-15
- Task now includes built-in core utilities to greatly improve compatibility on
Windows. This means that your commands that usescp,mv,mkdiror any
other common core utility will now work by default on Windows, without extra
setup. This is something we wanted to address for many many years, and it's
finally being shipped!
Read our blog post this the topic.
(#197, #2360 by @andreynering). - :sparkles: Built and deployed a brand new website
using VitePress (#2359, #2369, #2371, #2375, #2378 by
@vmaerten, @andreynering, @pd93). - Began releasing
nightly builds. This
will allow people to test our changes before they are fully released and
without having to install Go to build them (#2358 by @vmaerten). - Added support for global config files in
$XDG_CONFIG_HOME/task/taskrc.ymlor$HOME/.taskrc.yml. Check out our new
configuration guide for more
details (#2247, #2380, #2390, #2391 by @vmaerten, @pd93). - Added experiments to the taskrc schema to clarify the expected keys and values
(#2235 by @vmaerten). - Added support for new properties in
.taskrc.yml: insecure, verbose,
concurrency, remote offline, remote timeout, and remote expiry. :warning:
Note: setting offline via environment variable is no longer supported. (#2389
by @vmaerten) - Added a
--nestedflag when outputting tasks using--list --json. This will
output tasks in a nested structure when tasks are namespaced (#2415 by @pd93). - Enhanced support for tasks with wildcards: they are now logged correctly, and
wildcard parameters are fully considered during fingerprinting (#1808, #1795
by @vmaerten). - Fixed panic when a variable was declared as an empty hash (
{}) (#2416, #2417
by @trulede).
Package API
- Bumped the minimum version of Go to 1.24 (#2358 by @vmaerten).
Other news
We recently released our
official GitHub Action. This is based
on the fantastic work by the Arduino team who created and maintained the
community version. Now that this is officially adopted, fixes/updates should be
more timely. We have already merged a couple of longstanding PRs in our
first release (by
@pd93, @shrink, @trim21 and all the previous contributors to
arduino/setup-task).
v3.45.0-v3.45.2 - 2025-09-15
Failed due to an issue with our release process.
v3.44.1 - 2025-07-23
- Internal tasks will no longer be shown as suggestions since they cannot be
called (#2309, #2323 by @maxmzkrcensys) - Fixed install script for some ARM platforms (#1516, #2291 by @trulede).
- Fixed a regression where fingerprinting was not working correctly if the path
to you Taskfile contained a space (#2321, #2322 by @pd93). - Reverted a breaking change to
randInt(#2312, #2316 by @pd93). - Made new variables
TEST_NAMEandTEST_DIRavailable in fixture tests
(#2265 by @pd93).
v3.44.0 - 2025-06-08
- Added
uuid,randIntandrandIntNtemplate functions (#1346, #2225 by
@pd93). - Added new
CLI_ARGS_LISTarray variable which contains the arguments passed
to Task after the--(the same asCLI_ARGS, but an array instead of a
string). (#2138, #2139, #2140 by @pd93). - Added
toYamlandfromYamltemplating functions (#2217, #2219 by @pd93). - Added
taskfield the--list --jsonoutput (#2256 by @aleksandersh). - Added the ability to
pin included taskfiles
by specifying a checksum. This works with both local and remote Taskfiles
(#2222, #2223 by @pd93). - When using the
Remote Taskfiles experiment,
any credentials used in the URL will now be redacted in Task's output (#2100,
#2220 by @pd93). - Fixed fuzzy suggestions not working when misspelling a task name (#2192, #2200
by @vmaerten). - Fixed a bug where taskfiles in directories containing spaces created
directories in the wrong location (#2208, #2216 by @pd93). - Added support for dual JSON schema files, allowing changes without affecting
the current schema. The current schemas will only be updated during releases.
(#2211 by @vmaerten). - Improved fingerprint documentation by specifying that the method can be set at
the root level to apply to all tasks (#2233 by @vmaerten). - Fixed some watcher regressions after #2048 (#2199, #2202, #2241, #2196 by
@wazazaby, #2271 by @andreynering).
v3.43.3 - 2025-04-27
Reverted the changes made in #2113 and #2186 that affected theUSER_WORKING_DIR and built-in variables. This fixes #2206, #2195, #2207 and
#2208.
v3.43.2 - 2025-04-21
- Fixed regresion of
CLI_ARGSbeing exposed as the wrong type (#2190, #2191 by
@vmaerten).
v3.43.1 - 2025-04-21
- Significant improvements were made to the watcher. We migrated from
watcher to
fsnotify. The former library used
polling, which means Task had a high CPU usage when watching too many files.fsnotifyuses proper the APIs from each operating system to watch files,
which means a much better performance. The default interval changed from 5
seconds to 100 milliseconds, because now it configures the wait time for
duplicated events, instead of the polling time (#2048 by @andreynering, #1508,
#985, #1179). - The Map Variables experiment
was made generally available so you can now
define map variables in your Taskfiles!
(#1585, #1547, #2081 by @pd93). - Wildcards can now
match multiple tasks (#2072,
#2121 by @pd93). - Added the ability to
loop over the files specified by thegenerateskeyword.
This works the same way as looping over sources (#2151 by @sedyh). - Added the ability to resolve variables when defining an include variable
(#2108, #2113 by @pd93). - A few changes have been made to the
Remote Taskfiles experiment
(#1402, #2176 by @pd93):- Cached files are now prioritized over remote ones.
- Added an
--expiryflag which sets the TTL for a remote file cache. By
default the value will be 0 (caching disabled). If Task is running in
offline mode or fails to make a connection, it will fallback on the cache.
.taskrcfiles can now be used from subdirectories and will be searched for
recursively up the file tree in the same way that Taskfiles are (#2159, #2166
by @pd93).- The default taskfile (output when using the
--initflag) is now an embedded
file in the binary instead of being stored in the code (#2112 by @pd93). - Improved the way we report the Task version when using the
--versionflag or{{.TASK_VERSION}}variable. This should now be more consistent and easier
for package maintainers to use (#2131 by @pd93). - Fixed a bug where globstar (
**) matching insourcesonly resolved the
first result (#2073, #2075 by @pd93). - Fixed a bug where sorting tasks by "none" would use the default sorting
instead of leaving tasks in the order they were defined (#2124, #2125 by
@trulede). - Fixed Fish completion on newer Fish versions (#2130 by @atusy).
- Fixed a bug where undefined/null variables resolved to an empty string instead
ofnil(#1911, #2144 by @pd93). - The
USER_WORKING_DIRspecial now will now properly account for the--dir
(-d) flag, if given (#2102, #2103 by @jaynis, #2186 by @andreynering). - Fix Fish completions when
--global(-g) is given (#2134 by @atusy). - Fixed variables not available when using
defer:(#1909, #2173 by @vmaerten).
Package API
- The
Executornow
uses the functional options pattern (#2085, #2147, #2148 by @pd93). - The functional options for the
taskfile.Reader
andtaskfile.Snippet
types no longer have theReader/Snippetrespective prefixes (#2148 by
@pd93). taskfile.Reader
no longer accepts ataskfile.Node.
Instead nodes are passed directly into theReader.Read
method (#2169 by @pd93).Reader.Read
also now accepts acontext.Context
(#2176 by @pd93).
v3.42.1 - 2025-03-10
- Fixed a bug where some special variables caused a type error when used global
variables (#2106, #2107 by @pd93).
v3.42.0 - 2025-03-08
- Made
--initless verbose by default and respect--silentand--verbose
flags (#2009, #2011 by @HeCorr). --initnow accepts a file name or directory as an argument (#2008, #2018 by
@HeCorr).- Fix a bug where an HTTP node's location was being mutated incorrectly (#2007
by @jeongukjae). - Fixed a bug where allowed values didn't work with dynamic var (#2032, #2033 by
@vmaerten). - Use only the relevant checker (timestamp or checksum) to improve performance
(#2029, #2031 by @vmaerten). - Print warnings when attempting to enable an inactive experiment or an active
experiment with an invalid value (#1979, #2049 by @pd93). - Refactored the experiments package and added tests (#2049 by @pd93).
- Show allowed values when a variable with an enum is missing (#2027, #2052 by
@vmaerten). - Refactored how snippets in error work and added tests (#2068 by @pd93).
- Fixed a bug where errors decoding commands were sometimes unhelpful (#2068 by
@pd93). - Fixed a bug in the Taskfile schema where
deferstatements in the shorthandcmdssyntax were not considered valid (#2068 by @pd93). - Refactored how task sorting functions work (#1798 by @pd93).
- Added a new
.taskrc.yml(or.taskrc.yaml) file to let users enable
experiments (similar to.env) (#1982 by @vmaerten). - Added new Getting Started docs (#2086
by @pd93). - Allow
matrixto use references to other variables (#2065, #2069 by @pd93). - Fixed a bug where, when a dynamic variable is provided, even if it is not
used, all other variables become unavailable in the templating system within
the include (#2092 by @vmaerten).
Package API
Unlike our CLI tool,
Task's package API is not currently stable.
In an effort to ease the pain of breaking changes for our users, we will be
providing changelogs for our package API going forwards. The hope is that these
changes will provide a better long-term experience for our users and allow to
stabilize the API in the future. #121 now tracks this piece of work.
- Bumped the minimum required Go version to 1.23 (#2059 by @pd93).
task.InitTaskfile
(#2011, ff8c913 by @HeCorr and @pd93)- No longer accepts an
io.Writer(output is now the caller's
responsibility). - The path argument can now be a filename OR a directory.
- The function now returns the full path of the generated file.
- No longer accepts an
TaskfileDecodeError.WithFileInfo
now accepts a string instead of the arguments required to generate a snippet
(#2068 by @pd93).- The caller is now expected to create the snippet themselves (see below).
TaskfileSnippet
and related code moved from theerrorspackage to thetaskfilepackage
(#2068 by @pd93).- Renamed
TaskMissingRequiredVarstoTaskMissingRequiredVarsError
(#2052 by @vmaerten). - Renamed
TaskNotAllowedVarstoTaskNotAllowedVarsError
(#2052 by @vmaerten). - The
taskfile.Reader
is now constructed using the functional options pattern (#2082 by @pd93). - Removed our internal
logger.Loggerfrom the entiretaskfilepackage (#2082
by @pd93).- Users are now expected to pass a custom debug/prompt functions into
taskfile.Reader
if they want this functionality by using the newWithDebugFunc
andWithPromptFunc
functional options.
- Users are now expected to pass a custom debug/prompt functions into
- Remove
Rangefunctions in thetaskfile/astpackage in favour of new
iterator functions (#1798 by @pd93). ast.Callwas moved from thetaskfile/astpackage to the maintask
package (#2084 by @pd93).ast.Tasks.FindMatchingTaskswas moved from thetaskfile/astpackage to thetask.Executor.FindMatchingTasksin the maintaskpackage (#2084 by @pd93).- The
Compilerand itsGetVariablesandFastGetVariablesmethods were
moved from theinternal/compilerpackage to the maintaskpackage (#2084
by @pd93).
v3.41.0 - 2025-01-18
- Fixed an issue where dynamic variables were not properly logged in verbose
mode (#1920, #1921 by @mgbowman). - Support
silentfor defer statements (#1877, #1879 by @danilobuerger). - Added an option to exclude some tasks from being included (#1859 by
@vmaerten). - Fixed an issue where a required variable was incorrectly handled in a template
function (#1950, #1962 by @vmaerten). - Expose a new
TASK_DIRspecial variable, which will contain the absolute path
of task directory. (#1959, #1961 by @vmaerten). - Fixed fatal bugs that caused concurrent map writes (#1605, #1972, #1974 by
@pd93, @GrahamDennis and @trim21). - Refactored internal ordered map implementation to use
github.com/elliotchance/orderedmap
(#1797 by @pd93). - Fixed a bug where variables defined at the task level were being ignored in
therequiressection. (#1960, #1955, #1768 by @vmaerten and @mokeko) - The
CHECKSUMandTIMESTAMPvariables are now accessible withincmds
(#1872 by @niklasr22). - Updated installation docs and added pip
installation method (#935, #1989 by @pd93). - Fixed a bug where dynamic variables could not access environment variables
(#630, #1869 by @rohm1 and @pd93). - Disable version check for use as an external library (#1938 by @leaanthony).
v3.40.1 - 2024-12-06
- Fixed a security issue in
git-urlsby switching to the maintained forkchainguard-dev/git-urls(#1917 by @AlekSi). - Added missing
platformsproperty tocmdsthat usefor(#1915 by
@dkarter). - Added misspell linter to check for misspelled English words (#1883 by
@christiandins).
v3.40.0 - 2024-11-05
- Fixed output of some functions (e.g.
splitArgs/splitLines) not working in
for loops (#1822, #1823 by @stawii). - Added a new
TASK_OFFLINEenvironment variable to configure the--offline
flag and expose it as a special variable in the templating system (#1470,
#1716 by @vmaerten and @pd93). - Fixed a bug where multiple remote includes caused all prompts to display
without waiting for user input (#1832, #1833 by @vmaerten and @pd93). - When using the
"Remote Taskfiles".
experiment, you can now include Taskfiles from Git repositories (#1652 by
@vmaerten). - Improved the error message when a dotenv file cannot be parsed (#1842 by
@pbitty). - Fix issue with directory when using the remote experiment (#1757 by @pbitty).
- Fixed an issue where a special variable was used in combination with a dotenv
file (#1232, #1810 by @vmaerten). - Refactor the way Task reads Taskfiles to improve readability (#1771 by
@pbitty). - Added a new option to ensure variable is within the list of values (#1827 by
@vmaerten). - Allow multiple prompts to be specified for a task (#1861, #1866 by @mfbmina).
- Added new template function:
numCPU, which returns the number of logical
CPUs usable (#1890, #1887 by @Amoghrd). - Fixed a bug where non-nil, empty dynamic variables are returned as an empty
interface (#1903, #1904 by @pd93).
v3.39.2 - 2024-09-19
- Fix dynamic variables not working properly for a defer: statement (#1803,
#1818 by @vmaerten).
v3.39.1 - 2024-09-18
- Added Renovate configuration to automatically create PRs to keep dependencies
up to date (#1783 by @vmaerten). - Fixed a bug where the help was displayed twice (#1805, #1806 by @vmaerten).
- Fixed a bug where ZSH and PowerShell completions did not work when using the
recommended method. (#1813, #1809 by @vmaerten and @shirayu) - Fix variables not working properly for a
defer:statement (#1803, #1814 by
@vmaerten and @andreynering).
v3.39.0 - 2024-09-07
- Added
Env Precedence Experiment
(#1038, #1633 by @vmaerten). - Added a CI lint job to ensure that the docs are updated correctly (#1719 by
@vmaerten). - Updated minimum required Go version to 1.22 (#1758 by @pd93).
- Expose a new
EXIT_CODEspecial variable ondefer:when a command finishes
with a non-zero exit code (#1484, #1762 by @dorimon-1 and @andreynering). - Expose a new
ALIASspecial variable, which will contain the alias used to
call the current task. Falls back to the task name. (#1764 by @DanStory). - Fixed
TASK_REMOTE_DIRenvironment variable not working when the path was
absolute. (#1715 by @vmaerten). - Added an option to declare an included Taskfile as flattened (#1704 by
@vmaerten). - Added a new
--completionflag to
output completion scripts for various shells (#293, #1157 by @pd93).- This is now the preferred way to install completions.
- The completion scripts in the
completiondirectory
are now deprecated.
- Added the ability to
loop over a matrix of values
(#1766, #1767, #1784 by @pd93). - Fixed a bug in fish completion where aliases were not displayed (#1781, #1782
by @vmaerten). - Fixed panic when having a flattened included Taskfile that contains a
defaulttask (#1777, #1778 by @vmaerten). - Optimized file existence checks for remote Taskfiles (#1713 by @vmaerten).
v3.38.0 - 2024-06-30
- Added
TASK_EXEspecial variable (#1616, #1624 by @pd93 and @andreynering). - Some YAML parsing errors will now show in a more user friendly way (#1619 by
@pd93). - Prefixed outputs will now be colorized by default (#1572 by
@AlexanderArvidsson) - References are now
generally available (no experiments required) (#1654 by @pd93). - Templating functions can now be used in references (#1645, #1654 by @pd93).
- Added a new
templating reference page to the
documentation (#1614, #1653 by @pd93). - If using the
Map Variables experiment (1),
references are available by
prefixing a string with a#
(#1654 by @pd93). - If using the
Map Variables experiment (2),
theyamlandjsonkeys are no longer available (#1654 by @pd93). - Added a new
TASK_REMOTE_DIRenvironment variable to configure where cached
remote Taskfiles are stored (#1661 by @vmaerten). - Added a new
--clear-cacheflag to clear the cache of remote Taskfiles (#1639
by @vmaerten). - Improved the readability of cached remote Taskfile filenames (#1636 by
@vmaerten). - Starting releasing a binary for the
riscv64architecture on Linux (#1699 by
@mengzhuo). - Added
CLI_SILENTandCLI_VERBOSEvariables (#1480, #1669 by @Vince-Smith). - Fixed a couple of bugs with the
prompt:feature (#1657 by @pd93). - Fixed JSON Schema to disallow invalid properties (#1657 by @pd93).
- Fixed version checks not working as intended (#872, #1663 by @vmaerten).
- Fixed a bug where included tasks were run multiple times even if
run: once
was set (#852, #1655 by @pd93). - Fixed some bugs related to column formatting in the terminal (#1350, #1637,
#1656 by @vmaerten).
v3.37.2 - 2024-05-12
- Fixed a bug where an empty Taskfile would cause a panic (#1648 by @pd93).
- Fixed a bug where includes Taskfile variable were not being merged correctly
(#1643, #1649 by @pd93).
v3.37.1 - 2024-05-09
- Fix bug where non-string values (numbers, bools) added to
env:weren't been
correctly exported (#1640, #1641 by @vmaerten and @andreynering).
v3.37.0 - 2024-05-08
- Released the
Any Variables experiment, but
without support for maps
(#1415, #1547 by @pd93). - Refactored how Task reads, parses and merges Taskfiles using a DAG (#1563,
#1607 by @pd93). - Fix a bug which stopped tasks from using
stdinas input (#1593, #1623 by
@pd93). - Fix error when a file or directory in the project contained a special char
like&,(or)(#1551, #1584 by @andreynering). - Added alias
qfor template functionshellQuote(#1601, #1603 by @vergenzt) - Added support for
~on ZSH completions (#1613 by @jwater7). - Added the ability to pass variables by reference using Go template syntax when
the
Map Variables experiment is
enabled (#1612 by @pd93). - Added support for environment variables in the templating engine in
includes
(#1610 by @vmaerten).
v3.36.0 - 2024-04-08
- Added support for
looping over dependencies
(#1299, #1541 by @pd93). - When using the
"Remote Taskfiles"
experiment, you are now able to use
remote Taskfiles as your entrypoint.includesin remote Taskfiles will now also resolve correctly (#1347 by
@pd93).
- When using the
"Any Variables"
experiments, templating is now supported in collection-type variables (#1477,
#1511, #1526 by @pd93). - Fixed a bug where variables being passed to an included Taskfile were not
available when defining global variables (#1503, #1533 by @pd93). - Improved support to customized colors by allowing 8-bit colors and multiple
ANSI attributes (#1576 by @pd93).
v3.35.1 - 2024-03-04
- Fixed a bug where the
TASKFILE_DIRvariable was sometimes incorrect (#1522,
#1523 by @pd93). - Added a new
TASKFILEspecial variable that holds the root Taskfile path
(#1523 by @pd93). - Fixed various issues related to running a Taskfile from a subdirectory (#1529,
#1530 by @pd93).
v3.35.0 - 2024-02-28
- Added support for
wildcards in task names
(#836, #1489 by @pd93). - Added the ability to
run Taskfiles via stdin
(#655, #1483 by @pd93). - Bumped minimum Go version to 1.21 (#1500 by @pd93).
- Fixed bug related to the
--listflag (#1509, #1512 by @pd93, #1514, #1520 by
@pd93). - Add mention on the documentation to the fact that the variable declaration
order is respected (#1510 by @kirkrodrigues). - Improved style guide docs (#1495 by @iwittkau).
- Removed duplicated entry for
requireson the API docs (#1491 by
@teatimeguest).
v3.34.1 - 2024-01-27
- Fixed prompt regression on
Remote Taskfiles experiment
(#1486, #1487 by @pd93).
v3.34.0 - 2024-01-25
- Removed support for
version: 2schemas. See the
deprecation notice on our website
(#1197, #1447 by @pd93). - Fixed a couple of issues in the JSON Schema + added a CI step to ensure it's
correct (#1471, #1474, #1476 by @sirosen). - Added
Any Variables experiment proposal 2
(#1415, #1444 by @pd93). - Updated the experiments and deprecations documentation format (#1445 by
@pd93). - Added new template function:
spew, which can be used to print variables for
debugging purposes (#1452 by @pd93). - Added new template function:
merge, which can be used to merge any number of
map variables (#1438, #1464 by @pd93). - Small change on the API when using as a library:
call.Directbecamecall.Indirect(#1459 by @pd93). - Refactored the public
readandtaskfilepackages and introducedtaskfile/ast(#1450 by @pd93). ast.IncludedTaskfilesrenamed toast.Includesandorderedmappackage
renamed toomapplus some internal refactor work (#1456 by @pd93).- Fix zsh completion script to allow lowercase
taskfilefile names (#1482 by
@xontab). - Improvements on how we check the Taskfile version (#1465 by @pd93).
- Added a new
ROOT_TASKFILEspecial variable (#1468, #1469 by @pd93). - Fix experiment flags in
.envwhen the--diror--taskfileflags were
used (#1478 by @pd93).
v3.33.1 - 2023-12-21
- Added support for looping over map variables with the
Any Variables experiment
enabled (#1435, #1437 by @pd93). - Fixed a bug where dynamic variables were causing errors during fast
compilation (#1435, #1437 by @pd93)
v3.33.0 - 2023-12-20
- Added
Any Variables experiment
(#1415, #1421 by @pd93). - Updated Docusaurus to v3 (#1432 by @pd93).
- Added
aliasesto--jsonflag output (#1430, #1431 by @pd93). - Added new
CLI_FORCEspecial variable containing whether the--forceor--force-allflags were set (#1412, #1434 by @pd93).
v3.32.0 - 2023-11-29
- Added ability to exclude some files from
sources:by usingexclude:(#225,
#1324 by @pd93 and @andreynering). - The
Remote Taskfiles experiment
now prefers remote files over cached ones by default (#1317, #1345 by @pd93). - Added
--timeoutflag to the
Remote Taskfiles experiment
(#1317, #1345 by @pd93). - Fix bug where dynamic
vars:andenv:were being executed when they should
actually be skipped byplatforms:(#1273, #1377 by @andreynering). - Fix
schema.jsonto makesilentvalid incmdsthat usefor(#1385,
#1386 by @iainvm). - Add new
--no-statusflag to skip expensive status checks when runningtask --list --json(#1348, #1368 by @amancevice).
v3.31.0 - 2023-10-07
- Enabled the
--yesflag for the
Remote Taskfiles experiment
(#1317, #1344 by @pd93). - Add ability to set
watch: truein a task to automatically run it in watch
mode (#231, #1361 by @andreynering). - Fixed a bug on the watch mode where paths that contained
.git(like.github), for example, were also being ignored (#1356 by @butuzov). - Fixed a nil pointer error when running a Taskfile with no contents (#1341,
#1342 by @pd93). - Added a new exit code (107) for when a
Taskfile does not contain a schema version (#1342 by @pd93). - Increased limit of maximum task calls from 100 to 1000 for now, as some people
have been reaching this limit organically now that we have loops. This check
exists to detect recursive calls, but will be removed in favor of a better
algorithm soon (#1321, #1332). - Fixed templating on descriptions on
task --list(#1343 by @blackjid). - Fixed a bug where precondition errors were incorrectly being printed when task
execution was aborted (#1337, #1338 by @sylv-io).
v3.30.1 - 2023-09-14
- Fixed a regression where some special variables weren't being set correctly
(#1331, #1334 by @pd93).
v3.30.0 - 2023-09-13
- Prep work for Remote Taskfiles (#1316 by @pd93).
- Added the
Remote Taskfiles experiment
as a draft (#1152, #1317 by @pd93). - Improve performance of content checksumming on
sources:by replacing md5
with XXH3 which is much faster. This is a soft breaking
change because checksums will be invalidated when upgrading to this release
(#1325 by @ReillyBrogan).
v3.29.1 - 2023-08-26
- Update to Go 1.21 (bump minimum version to 1.20) (#1302 by @pd93)
- Fix a missing a line break on log when using
--watchmode (#1285, #1297 by
@FilipSolich). - Fix
deferon JSON Schema (#1288 by @calvinmclean and @andreynering). - Fix bug in usage of special variables like
{{.USER_WORKING_DIR}}in
combination withincludes(#1046, #1205, #1250, #1293, #1312, #1274 by
@andarto, #1309 by @andreynering). - Fix bug on
--statusflag. Running this flag should not have side-effects: it
should not update the checksum on.task, only report its status (#1305,
#1307 by @visciang, #1313 by @andreynering).
v3.28.0 - 2023-07-24
- Added the ability to
loop over commands and tasks
usingfor(#82, #1220 by @pd93). - Fixed variable propagation in multi-level includes (#778, #996, #1256 by
@hudclark). - Fixed a bug where the
--exit-codecode flag was not returning the correct
exit code when calling commands indirectly (#1266, #1270 by @pd93). - Fixed a
nilpanic when a dependency was commented out or left empty (#1263
by @neomantra).
v3.27.1 - 2023-06-30
- Fix panic when a
.envdirectory (not file) is present on current directory
(#1244, #1245 by @pd93).
v3.27.0 - 2023-06-29
- Allow Taskfiles starting with lowercase characters (#947, #1221 by @pd93).
- e.g.
taskfile.yml,taskfile.yaml,taskfile.dist.yml&taskfile.dist.yaml
- e.g.
- Bug fixes were made to the
npm installation method. (#1190, by
@sounisi5011). - Added the
gentle force experiment as a
draft (#1200, #1216 by @pd93). - Added an
--experimentsflag to allow you to see which experiments are
enabled (#1242 by @pd93). - Added ability to specify which variables are required in a task (#1203, #1204
by @benc-uk).
v3.26.0 - 2023-06-10
- Only rewrite checksum files in
.taskif the checksum has changed (#1185,
#1194 by @deviantintegral). - Added experiments documentation to the
website (#1198 by @pd93). - Deprecated
version: 2schema. This will be removed in the next major release
(#1197, #1198, #1199 by @pd93). - Added a new
prompt:prop to set a warning prompt to be shown before running
a potential dangerous task (#100, #1163 by @MaxCheetham,
Documentation). - Added support for single command task syntax. With this change, it's now
possible to declare justcmd:in a task, avoiding the more complexcmds: []when you have only a single command for that task (#1130, #1131 by
@timdp).
v3.25.0 - 2023-05-22
- Support
silent:when calling another tasks (#680, #1142 by @danquah). - Improve PowerShell completion script (#1168 by @trim21).
- Add more languages to the website menu and show translation progress
percentage (#1173 by @misitebao). - Starting on this release, official binaries for FreeBSD will be available to
download (#1068 by @andreynering). - Fix some errors being unintendedly suppressed (#1134 by @clintmod).
- Fix a nil pointer error when
versionis omitted from a Taskfile (#1148,
#1149 by @pd93). - Fix duplicate error message when a task does not exists (#1141, #1144 by
@pd93).
v3.24.0 - 2023-04-15
- Fix Fish shell completion for tasks with aliases (#1113 by @patricksjackson).
- The default branch was renamed from
mastertomain(#1049, #1048 by
@pd93). - Fix bug where "up-to-date" logs were not being omitted for silent tasks (#546,
#1107 by @danquah). - Add
.hg(Mercurial) to the list of ignored directories when using--watch
(#1098 by @misery). - More improvements to the release tool (#1096 by @pd93).
- Enforce gofumpt linter (#1099 by @pd93)
- Add
--sortflag for use with--listand--list-all(#946, #1105 by
@pd93). - Task now has custom exit codes
depending on the error (#1114 by @pd93).
v3.23.0 - 2023-03-26
Task now has an
official extension for Visual Studio Code
contributed by @pd93! :tada: The extension is maintained in a
new repository under the go-task
organization. We're looking to gather feedback from the community so please give
it a go and let us know what you think via a
discussion,
issue or on our
Discord!
NOTE: The extension requires v3.23.0 to be installed in order to work.
- The website was integrated with
Crowdin to allow the community to
contribute with translations! Chinese is the
first language available (#1057, #1058 by @misitebao). - Added task location data to the
--jsonflag output (#1056 by @pd93) - Change the name of the file generated by
task --initfromTaskfile.yamltoTaskfile.yml(#1062 by @misitebao). - Added new
splitArgstemplate function
({{splitArgs "foo bar 'foo bar baz'"}}) to ensure string is split as
arguments (#1040, #1059 by @dhanusaputra). - Fix the value of
{{.CHECKSUM}}variable in status (#1076, #1080 by @pd93). - Fixed deep copy implementation (#1072 by @pd93)
- Created a tool to assist with releases (#1086 by @pd93).
v3.22.0 - 2023-03-10
- Add a brand new
--global(-g) flag that will run a Taskfile from your$HOMEdirectory. This is useful to have automation that you can run from
anywhere in your system!
(Documentation, #1029
by @andreynering). - Add ability to set
error_only: trueon thegroupoutput mode. This will
instruct Task to only print a command output if it returned with a non-zero
exit code (#664, #1022 by @jaedle). - Fixed bug where
.task/checksumfile was sometimes not being created when
task also declares astatus:(#840, #1035 by @harelwa, #1037 by @pd93). - Refactored and decoupled fingerprinting from the main Task executor (#1039 by
@pd93). - Fixed deadlock issue when using
run: once(#715, #1025 by
@theunrepentantgeek).
v3.21.0 - 2023-02-22
- Added new
TASK_VERSIONspecial variable (#990, #1014 by @ja1code). - Fixed a bug where tasks were sometimes incorrectly marked as internal (#1007
by @pd93). - Update to Go 1.20 (bump minimum version to 1.19) (#1010 by @pd93)
- Added environment variable
FORCE_COLORsupport to force color output. Useful
for environments without TTY (#1003 by @automation-stack)
v3.20.0 - 2023-01-14
- Improve behavior and performance of status checking when using the
timestamp
mode (#976, #977 by @aminya). - Performance optimizations were made for large Taskfiles (#982 by @pd93).
- Add ability to configure options for the
set
andshopt
builtins (#908, #929 by @pd93,
Documentation). - Add new
platforms:attribute totaskandcmd, so it's now possible to
choose in which platforms that given task or command will be run on. Possible
values are operating system (GOOS), architecture (GOARCH) or a combination of
the two. Example:platforms: [linux],platforms: [amd64]orplatforms: [linux/amd64]. Other platforms will be skipped (#978, #980 by
@leaanthony).
v3.19.1 - 2022-12-31
- Small bug fix: closing
Taskfile.ymlonce we're done reading it (#963, #964
by @HeCorr). - Fixes a bug in v2 that caused a panic when using a
Taskfile_{{OS}}.ymlfile
(#961, #971 by @pd93). - Fixed a bug where watch intervals set in the Taskfile were not being respected
(#969, #970 by @pd93) - Add
--jsonflag (alias-j) with the intent to improve support for code
editors and add room to other possible integrations. This is basic for now,
but we plan to add more info in the near future (#936 by @davidalpert, #764).
v3.19.0 - 2022-12-05
- Installation via npm now supports pnpm as well
(go-task/go-npm#2,
go-task/go-npm#3). - It's now possible to run Taskfiles from subdirectories! A new
USER_WORKING_DIRspecial variable was added to add even more flexibility for
monorepos (#289, #920). - Add task-level
dotenvsupport (#389, #904). - It's now possible to use global level variables on
includes(#942, #943). - The website got a brand new
translation to Chinese by
@DeronW. Thanks!
v3.18.0 - 2022-11-12
- Show aliases on
task --list --silent(task --ls). This means that aliases
will be completed by the completion scripts (#919). - Tasks in the root Taskfile will now be displayed first in
--list/--list-alloutput (#806, #890). - It's now possible to call a
defaulttask in an included Taskfile by using
just the namespace. For example:docs:defaultis now automatically aliased
todocs(#661, #815).
v3.17.0 - 2022-10-14
- Add a "Did you mean ...?" suggestion when a task does not exits another one
with a similar name is found (#867, #880). - Now YAML parse errors will print which Taskfile failed to parse (#885, #887).
- Add ability to set
aliasesfor tasks and namespaces (#268, #340, #879). - Improvements to Fish shell completion (#897).
- Added ability to set a different watch interval by setting
interval: '500ms'
or using the--interval=500msflag (#813, #865). - Add colored output to
--list,--list-alland--summaryflags (#845,
#874). - Fix unexpected behavior where
label:was being shown instead of the task
name on--list(#603, #877).
v3.16.0 - 2022-09-29
- Add
npmas new installation method:npm i @go-task/cli(#870, #871,
npm package). - Add support to marking tasks and includes as internal, which will hide them
from--listand--list-all(#818).
v3.15.2 - 2022-09-08
- Fix error when using variable in
env:introduced in the previous release
(#858, #866). - Fix handling of
CLI_ARGS(--) in Bash completion (#863). - On zsh completion, add ability to replace
--list-allwith--listas
already possible on the Bash completion (#861).
v3.15.0 - 2022-09-03
- Add new special variables
ROOT_DIRandTASKFILE_DIR. This was a highly
requested feature (#215, #857,
Documentation). - Follow symlinks on
sources(#826, #831). - Improvements and fixes to Bash completion (#835, #844).
v3.14.1 - 2022-08-03
- Always resolve relative include paths relative to the including Taskfile
(#822, #823). - Fix ZSH and PowerShell completions to consider all tasks instead of just the
public ones (those with descriptions) (#803).
v3.14.0 - 2022-07-08
- Add ability to override the
.taskdirectory location with theTASK_TEMP_DIRenvironment variable. - Allow to override Task colors using environment variables:
TASK_COLOR_RESET,TASK_COLOR_BLUE,TASK_COLOR_GREEN,TASK_COLOR_CYAN,TASK_COLOR_YELLOW,TASK_COLOR_MAGENTAandTASK_COLOR_RED(#568, #792). - Fixed bug when using the
output: groupmode where STDOUT and STDERR were
being print in separated blocks instead of in the right order (#779). - Starting on this release, ARM architecture binaries are been released to Snap
as well (#795). - i386 binaries won't be available anymore on Snap because Ubuntu removed the
support for this architecture. - Upgrade mvdan.cc/sh, which fixes a bug with associative arrays (#785,
mvdan/sh#884,
mvdan/sh#893).
v3.13.0 - 2022-06-13
- Added
-nas an alias to--dry(#776, #777). - Fix behavior of interrupt (SIGINT, SIGTERM) signals. Task will now give time
for the processes running to do cleanup work (#458, #479, #728, #769). - Add new
--exit-code(-x) flag that will pass-through the exit form the
command being ran (#755).
v3.12.1 - 2022-05-10
- Fixed bug where, on Windows, variables were ending with
\rbecause we were
only removing the final\nbut not\r\n(#717).
v3.12.0 - 2022-03-31
- The
--listand--list-allflags can now be combined with the--silent
flag to print the task names only, without their description (#691). - Added support for multi-level inclusion of Taskfiles. This means that included
Taskfiles can also include other Taskfiles. Before this was limited to one
level (#390, #623, #656). - Add ability to specify vars when including a Taskfile.
Check out the documentation
for more information (#677).
v3.11.0 - 2022-02-19
- Task now supports printing begin and end messages when using the
group
output mode, useful for grouping tasks in CI systems.
Check out the documentation
for more information (#647, #651). - Add
Taskfile.dist.ymlandTaskfile.dist.yamlto the supported file name
list.
Check out the documentation
for more information (#498, #666).
v3.10.0 - 2022-01-04
- A new
--list-all(alias-a) flag is now available. It's similar to the
exiting--list(-l) but prints all tasks, even those without a description
(#383, #401). - It's now possible to schedule cleanup commands to run once a task finishes
with thedefer:keyword
(Documentation,
#475, #626). - Remove long deprecated and undocumented
$variable prefix and^command
prefix (#642, #644, #645). - Add support for
.yamlextension (as an alternative to.yml). This was
requested multiple times throughout the years. Enjoy! (#183, #184, #369, #584,
#621). - Fixed error when computing a variable when the task directory do not exist yet
(#481, #579).
v3.9.2 - 2021-12-02
- Upgrade mvdan/sh which contains a fix a for a
important regression on Windows (#619,
mvdan/sh#768,
mvdan/sh#769).
v3.9.1 - 2021-11-28
- Add logging in verbose mode for when a task starts and finishes (#533, #588).
- Fix an issue with preconditions and context errors (#597, #598).
- Quote each
{{.CLI_ARGS}}argument to prevent one with spaces to become many
(#613). - Fix nil pointer when
cmd:was left empty (#612, #614). - Upgrade mvdan/sh which contains two relevant
fixes:- Fix quote of empty strings in
shellQuote(#609,
mvdan/sh#763). - Fix issue of wrong environment variable being picked when there's another
very similar one (#586,
mvdan/sh#745).
- Fix quote of empty strings in
- Install shell completions automatically when installing via Homebrew (#264,
#592,
go-task/homebrew-tap#2).
v3.9.0 - 2021-10-02
- A new
shellQuotefunction was added to the template system
({{shellQuote "a string"}}) to ensure a string is safe for use in shell
(mvdan/sh#727,
mvdan/sh#737,
Documentation) - In this version mvdan.cc/sh was upgraded with
some small fixes and features- The
read -pflag is now supported (#314,
mvdan/sh#551,
mvdan/sh#772) - The
pwd -Pandpwd -Lflags are now supported (#553,
mvdan/sh#724,
mvdan/sh#728) - The
$GIDenvironment variable is now correctly being set (#561,
mvdan/sh#723)
- The
v3.8.0 - 2021-09-26
- Add
interactive: truesetting to improve support for interactive CLI apps
(#217, #563). - Fix some
nilerrors (#534, #573). - Add ability to declare an included Taskfile as optional (#519, #552).
- Add support for including Taskfiles in the home directory by using
~(#539,
#557).
v3.7.3 - 2021-09-04
- Add official support to Apple M1 (#564, #567).
- Our official Homebrew tap will
support more platforms, including Apple M1
v3.7.0 - 2021-07-31
- Add
run:setting to control if tasks should run multiple times or not.
Available options arealways(the default),when_changed(if a variable
modified the task) andonce(run only once no matter what). This is a long
time requested feature. Enjoy! (#53, #359).
v3.6.0 - 2021-07-10
- Allow using both
sources:andstatus:in the same task (#411, #427, #477). - Small optimization and bug fix: don't compute variables if not needed for
dotenv:(#517).
v3.5.0 - 2021-07-04
- Add support for interpolation in
dotenv:(#433, #434, #453).
v3.4.3 - 2021-05-30
- Add support for the
NO_COLORenvironment variable. (#459,
fatih/color#137). - Fix bug where sources were not considering the right directory in
--watch
mode (#484, #485).
v3.4.2 - 2021-04-23
- On watch, report which file failed to read (#472).
- Do not try to catch SIGKILL signal, which are not actually possible (#476).
- Improve version reporting when building Task from source using Go Modules
(#462, #473).
v3.4.1 - 2021-04-17
- Improve error reporting when parsing YAML: in some situations where you would
just see an generic error, you'll now see the actual error with more detail:
the YAML line the failed to parse, for example (#467). - A JSON Schema was published here
and is automatically being used by some editors like Visual Studio Code
(#135). - Print task name before the command in the log output (#398).
v3.3.0 - 2021-03-20
- Add support for delegating CLI arguments to commands with
--and a specialCLI_ARGSvariable (#327). - Add a
--concurrency(alias-C) flag, to limit the number of tasks that run
concurrently. This is useful for heavy workloads. (#345).
v3.2.2 - 2021-01-12
- Improve performance of
--listand--summaryby skipping running shell
variables for these flags (#332). - Fixed a bug where an environment in a Taskfile was not always overridable by
the system environment (#425). - Fixed environment from .env files not being available as variables (#379).
- The install script is now working for ARM platforms (#428).
v3.2.1 - 2021-01-09
- Fixed some bugs and regressions regarding dynamic variables and directories
(#426). - The slim-sprig package was updated
with the upstream sprig.
v3.2.0 - 2021-01-07
- Fix the
.taskdirectory being created in the task directory instead of the
Taskfile directory (#247). - Fix a bug where dynamic variables (those declared with
sh:) were not running
in the task directory when the task has a custom dir or it was in an included
Taskfile (#384). - The watch feature (via the
--watchflag) got a few different bug fixes and
should be more stable now (#423, #365).
v3.1.0 - 2021-01-03
- Fix a bug when the checksum up-to-date resolution is used by a task with a
customlabel:attribute (#412). - Starting from this release, we're releasing official ARMv6 and ARM64 binaries
for Linux (#375, #418). - Task now respects the order of declaration of included Taskfiles when
evaluating variables declaring by them (#393). set -eis now automatically set on every command. This was done to fix an
issue where multiline string commands wouldn't really fail unless the sentence
was in the last line (#403).
v3.0.1 - 2020-12-26
- Allow use as a library by moving the required packages out of the
internal
directory (#358). - Do not error if a specified dotenv file does not exist (#378, #385).
- Fix panic when you have empty tasks in your Taskfile (#338, #362).
v3.0.0 - 2020-08-16
- On
v3, all CLI variables will be considered global variables (#336, #341) - Add support to
.envlike files (#324, #356). - Add
label:to task so you can override the task name in the logs (#321,
#337). - Refactor how variables work on version 3 (#311).
- Disallow
expansionson v3 since it has no effect. Taskvars.ymlis not automatically included anymore.Taskfile_{{OS}}.ymlis not automatically included anymore.- Allow interpolation on
includes, so you can manually include a Taskfile
based on operation system, for example. - Expose
.TASKvariable in templates with the task name (#252). - Implement short task syntax (#194, #240).
- Added option to make included Taskfile run commands on its own directory
(#260, #144) - Taskfiles in version 1 are not supported anymore (#237).
- Added global
method:option. With this option, you can set a default method
to all tasks in a Taskfile (#246). - Changed default method from
timestamptochecksum(#246). - New magic variables are now available when using
status::.TIMESTAMPwhich
contains the greatest modification date from the files listed insources:,
and.CHECKSUM, which contains a checksum of all files listed instatus:.
This is useful for manual checking when using external, or even remote,
artifacts when usingstatus:(#216). - We're now using slim-sprig instead of
sprig, which allowed a file size
reduction of about 22% (#219). - We now use some colors on Task output to better distinguish message types -
commands are green, errors are red, etc (#207).
v2.8.1 - 2020-05-20
- Fix error code for the
--helpflag (#300, #330). - Print version to stdout instead of stderr (#299, #329).
- Suppress
contexterrors when using the--watchflag (#313, #317). - Support templating on description (#276, #283).
v2.8.0 - 2019-12-07
- Add
--parallelflag (alias-p) to run tasks given by the command line in
parallel (#266). - Fixed bug where calling the
taskCLI only informing global vars would not
execute thedefaulttask. - Add ability to silent all tasks by adding
silent: truea the root of the
Taskfile.
v2.7.1 - 2019-11-10
- Fix error being raised when
exit 0was called (#251).
v2.7.0 - 2019-09-22
- Fixed panic bug when assigning a global variable (#229, #243).
- A task with
method: checksumwill now re-run if generated files are deleted
(#228, #238).
v2.6.0 - 2019-07-21
- Fixed some bugs regarding minor version checks on
version:. - Add
preconditions:to task (#205). - Create directory informed on
dir:if it doesn't exist (#209, #211). - We now have a
--taskfileflag (alias-t), which can be used to run another
Taskfile (other than the defaultTaskfile.yml) (#221). - It's now possible to install Task using Homebrew on Linux
(go-task/homebrew-tap#1).
v2.5.2 - 2019-05-11
- Reverted YAML upgrade due issues with CRLF on Windows (#201,
go-yaml/yaml#450). - Allow setting global variables through the CLI (#192).
2.5.1 - 2019-04-27
- Fixed some issues with interactive command line tools, where sometimes the
output were not being shown, and similar issues (#114, #190, #200). - Upgraded go-yaml/yaml from v2 to v3.
v2.5.0 - 2019-03-16
- We moved from the taskfile.org domain to the new fancy taskfile.dev domain.
While stuff is being redirected, we strongly recommend to everyone that use
this install script
to use the new taskfile.dev domain on scripts from now on. - Fixed to the ZSH completion (#182).
- Add
--summaryflag along withsummary:task attribute
(#180).
v2.4.0 - 2019-02-21
- Allow calling a task of the root Taskfile from an included Taskfile by
prefixing it with:(#161, #172). - Add flag to override the
outputoption (#173). - Fix bug where Task was persisting the new checksum on the disk when the Dry
Mode is enabled (#166). - Fix file timestamp issue when the file name has spaces (#176).
- Mitigating path expanding issues on Windows (#170).
v2.3.0 - 2019-01-02
- On Windows, Task can now be installed using Scoop (#152).
- Fixed issue with file/directory globing (#153).
- Added ability to globally set environment variables (#138, #159).
v2.2.1 - 2018-12-09
- This repository now uses Go Modules (#143). We'll still keep the
vendor
directory in sync for some time, though; - Fixing a bug when the Taskfile has no tasks but includes another Taskfile
(#150); - Fix a bug when calling another task or a dependency in an included Taskfile
(#151).
v2.2.0 - 2018-10-25
- Added support for
including other Taskfiles
(#98)- This should be considered experimental. For now, only including local files
is supported, but support for including remote Taskfiles is being discussed.
If you have any feedback, please comment on #98.
- This should be considered experimental. For now, only including local files
- Task now have a dedicated documentation site: https://taskfile.org
v2.1.1 - 2018-09-17
- Fix suggestion to use
task --initnot being shown anymore (when aTaskfile.ymlis not found) - Fix error when using checksum method and no file exists for a source glob
(#131) - Fix signal handling when the
--watchflag is given (#132)
v2.1.0 - 2018-08-19
- Add a
ignore_erroroption to task and command (#123) - Add a dry run mode (
--dryflag) (#126)
v2.0.3 - 2018-06-24
- Expand environment variables on "dir", "sources" and "generates" (#116)
- Fix YAML merging syntax (#112)
- Add ZSH completion (#111)
- Implement new
outputoption. Please check out the
documentation
v2.0.2 - 2018-05-01
- Fix merging of YAML anchors (#112)
v2.0.1 - 2018-03-11
- Fixes panic on
task --list
v2.0.0 - 2018-03-08
Version 2.0.0 is here, with a new Taskfile format.
Please, make sure to read the
Taskfile versions
document, since it describes in depth what changed for this version.
- New Taskfile version 2 (#77)
- Possibility to have global variables in the
Taskfile.ymlinstead ofTaskvars.yml(#66) - Small improvements and fixes
v1.4.4 - 2017-11-19
- Handle SIGINT and SIGTERM (#75);
- List: print message with there's no task with description;
- Expand home dir ("~" symbol) on paths (#74);
- Add Snap as an installation method;
- Move examples to its own repo;
- Watch: also walk on tasks called on on "cmds", and not only on "deps";
- Print logs to stderr instead of stdout (#68);
- Remove deprecated
setkeyword; - Add checksum based status check, alternative to timestamp based.
v1.4.3 - 2017-09-07
- Allow assigning variables to tasks at run time via CLI (#33)
- Added support for multiline variables from sh (#64)
- Fixes env: remove square braces and evaluate shell (#62)
- Watch: change watch library and few fixes and improvements
- When use watching, cancel and restart long running process on file change (#59
and #60)
v1.4.2 - 2017-07-30
- Flag to set directory of execution
- Always echo command if is verbose mode
- Add silent mode to disable echoing of commands
- Fixes and improvements of variables (#56)
v1.4.1 - 2017-07-15
- Allow use of YAML for dynamic variables instead of $ prefix
VAR: {sh: echo Hello}instead ofVAR: $echo Hello
- Add
--list(or-l) flag to print existing tasks - OS specific Taskvars file (e.g.
Taskvars_windows.yml,Taskvars_linux.yml,
etc) - Consider task up-to-date on equal timestamps (#49)
- Allow absolute path in generates section (#48)
- Bugfix: allow templating when calling deps (#42)
- Fix panic for invalid task in cyclic dep detection
- Better error output for dynamic variables in Taskvars.yml (#41)
- Allow template evaluation in parameters
v1.4.0 - 2017-07-06
- Cache dynamic variables
- Add verbose mode (
-vflag) - Support to task parameters (overriding vars) (#31) (#32)
- Print command, also when "set:" is specified (#35)
- Improve task command help text (#35)
v1.3.1 - 2017-06-14
- Fix glob not working on commands (#28)
- Add ExeExt template function
- Add
--initflag to create a new Taskfile - Add status option to prevent task from running (#27)
- Allow interpolation on
generatesandsourcesattributes (#26)
v1.3.0 - 2017-04-24
- Migrate from os/exec.Cmd to a native Go sh/bash interpreter
- This is a potentially breaking change if you use Windows.
- Now,
cmdis not used anymore on Windows. Always use Bash-like syntax for
your commands, even on Windows.
- Add "ToSlash" and "FromSlash" to template functions
- Use functions defined on github.com/Masterminds/sprig
- Do not redirect stdin while running variables commands
- Using
contextanderrgrouppackages (this will make other tasks to be
cancelled, if one returned an error)
v1.2.0 - 2017-04-02
- More tests and Travis integration
- Watch a task (experimental)
- Possibility to call another task
- Fix "=" not being recognized in variables/environment variables
- Tasks can now have a description, and help will print them (#10)
- Task dependencies now run concurrently
- Support for a default task (#16)
v1.1.0 - 2017-03-08
- Support for YAML, TOML and JSON (#1)
- Support running command in another directory (#4)
--forceor-fflag to force execution of task even when it's up-to-date- Detection of cyclic dependencies (#5)
- Support for variables (#6, #9, #14)
- Operation System specific commands and variables (#13)
v1.0.0 - 2017-02-28
- Add LICENSE file
:::
Website Src Latest Docs Community (`website/src/latest/docs/community.md`)
title: Community Task community contributions, installation methods, and integrations maintained by third parties section: Project docType: project outline: deep
Community
Some of the work to improve the Task ecosystem is done by the community, be it
installation methods or integrations with code editor. I (the author) am
thankful for everyone that helps me to improve the overall experience.
Integrations
Many of our integrations are contributed and maintained by the community. You
can view the full list of community integrations
here.
Installation methods
Some installation methods are maintained by third party:
More
Also, thanks for all the
code contributors,
financial contributors, all those who
reported bugs and
answered questions.
If you know something that is missing in this document, please submit a pull
request.
Website Src Latest Docs Contributing (`website/src/latest/docs/contributing.md`)
title: Contributing Comprehensive guide for contributing to the Task project, including setup, development, testing, and submitting PRs section: Contributing docType: contributing outline: deep
Contributing
Thank you for your interest in contributing to Task! We welcome and appreciate
all forms of contributions, but we kindly ask that you read this document first.
If you have any questions that were not answered by this document, you can reach
out on our Discord or by opening a discussion
on GitHub. If you want to help, but you're not sure where to start, you can
check out our list of
good first issues.
::: info
This document applies to the core Task repository and Task for Visual
Studio Code.
:::
AI Usage Policy
When using AI tools (including LLMs like ChatGPT, Claude, Copilot, etc.) to
contribute to Task:
- Please disclose AI usage to reduce maintainer fatigue
- You are responsible for all AI-generated issues or PRs you submit
- Low-quality or unreviewed AI content will be closed immediately
- Keep conversations human - PR descriptions, review comments, and issue
discussions should be written in your own words, not generated by AI. Code
review is a discussion between people, not bots.
We encourage the use of AI tools to assist with development, but all
contributions must be thoroughly reviewed and tested by the contributor before
submission. AI-generated code should be understood, validated, and adapted to
meet Task's standards.
Before you start
- Check existing work - Is there an existing PR? Are there issues discussing
the feature/change you want to make? Please make sure you consider/address
these discussions in your work. - Backwards compatibility - Will your change break existing Taskfiles? It is
much more likely that your change will merged if it backwards compatible. Is
there an approach you can take that maintains this compatibility? If not,
consider opening an issue first so that API changes can be discussed before
you invest your time into a PR. - Experiments - If there is no way to make your change backward compatible
then there is a procedure to introduce breaking changes into minor versions.
We call these "experiments". If you're intending to work on an
experiment, then please read the experiments workflow
document carefully and submit a proposal first.
1. Setup
The easiest way to install everything you need to work on Task is mise.
From the repository root, run:
mise installThis installs the pinned versions of Go, Node.js, pnpm and the dev tools
(golangci-lint, mockery, gotestsum, goreleaser and gorelease) declared
in the mise.toml file.
If you'd rather install things manually, you'll need:
- Go - Task is written in Go. We always support the latest two major
Go versions, so make sure your version is recent enough. - Node.js - Node.js is used to host Task's documentation server
and is required if you want to run this server locally. It is also required if
you want to contribute to the Visual Studio Code extension. - Pnpm - Pnpm is the Node.js package manager used by Task.
2. Making changes
- Code style - Try to maintain the existing code style where possible. Go
code should be formatted and linted bygolangci-lint. This
wraps thegofumptandgciformatters and a number of
linters. We recommend that you take a look at the golangci-lint
docs for a guide on how to setup your editor to
auto-format your code. Any Markdown or TypeScript files should be formatted
and linted by Prettier. This style is enforced by our CI to ensure
that we have a consistent style across the project. You can use thetask lintcommand to lint the code locally and thetask lint:fixcommand
to try to automatically fix any issues that are found. You can also use thetask fmtcommand to auto-format the files if your editor doesn't do it for
you. - Documentation - Ensure that you add/update any relevant documentation. See
the updating documentation section below. - Tests - Ensure that you add/update any relevant tests and that all tests
are passing before submitting the PR. See the writing tests
section below.
Running your changes
To run Task with working changes, you can use go run ./cmd/task. To run a
development build of task against a test Taskfile in testdata, you can usego run ./cmd/task --dir ./testdata/<my_test_dir> <task_name>.
To run Task for Visual Studio Code, you can open the project in VSCode and hit
F5 (or whatever you debug keybind is set to). This will open a new VSCode window
with the extension running. Debugging this way is recommended as it will allow
you to set breakpoints and step through the code. Otherwise, you can runtask package which will generate a .vsix file that can be used to manually
install the extension.
Updating documentation
Task uses Vitepress to host a documentation server. The code for
this is located in the core Task repository. This can be setup and run locally
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 inwebsite/patches/ to resolve links before it moves directory indexes such asdocs/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 is necessary. This document contains descriptions and
examples of how to use Task features. If you're adding a new feature, try to
find an appropriate place to add a new section. If you're updating an existing
feature, ensure that the documentation and any examples are up-to-date. Ensure
that any examples follow the Taskfile Styleguide.
If you added a new command or flag, ensure that you add it to the CLI
Reference. New fields also need to be added to the Schema
Reference and JSON Schema. The descriptions
for fields in the docs and the schema should match.
Documentation channels
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 andsrc/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.
Write in website/src/next. It holds the upcoming release, andcmd/release copies it over website/src/latest at every release. The same
split applies to the JSON schemas: edit next-schema.json andnext-schema-taskrc.json, never schema.json or schema-taskrc.json.
Where you put a blog post decides when it goes out. A post that announces a
feature belongs in website/src/next/blog alone: it ships with the release that
carries the feature. A post that stands on its own - an announcement, a write-up
about an already released feature - can be added to website/src/latest/blog as
well, and it goes live at the next deploy. Its sidebar entry comes from the
post's own frontmatter, so there is nothing else to update.
Never edit an existing file under website/src/latest: cmd/release overwrites
that directory at every release, so the change would be silently lost. The same
goes for .vitepress/sidebar/latest.ts, which is promoted from next.ts. CI
fails a pull request that modifies either. Adding a file underwebsite/src/latest is fine - that is how a blog post gets published early.
To preview what taskfile.dev will look like, run task website:start:latest. It
serves the latest channel on port 3002, so it can run next to task website
and the version selector switches between the two.
Writing tests
A lot of Task's tests are held in the task_test.go file in the project root
and this is where you'll most likely want to add new ones too. Most of these
tests also have a subdirectory in the testdata directory where any
Taskfiles/data required to run the tests are stored.
When making a changes, consider whether new tests are required. These tests
should ensure that the functionality you are adding will continue to work in the
future. Existing tests may also need updating if you have changed Task's
behavior.
You may also consider adding unit tests for any new functions you have added.
The unit tests should follow the Go convention of being location in a file named*_test.go in the same package as the code being tested.
3. Committing your code
Try to write meaningful commit messages and avoid having too many commits on the
PR. Most PRs should likely have a single commit (although for bigger PRs it may
be reasonable to split it in a few). Git squash and rebase is your friend!
If you're not sure how to format your commit message, check out Conventional
Commits. This style is not enforced, but it is a good way
to make your commit messages more readable and consistent.
4. Submitting a PR
- Describe your changes - Ensure that you provide a comprehensive
description of your changes. - Issue/PR links - Link any previous work such as related issues or PRs.
Please describe how your changes differ to/extend this work. - Examples - Add any examples or screenshots that you think are useful to
demonstrate the effect of your changes. - Draft PRs - If your changes are incomplete, but you would like to discuss
them, open the PR as a draft and add a comment to start a discussion. Using
comments rather than the PR description allows the description to be updated
later while preserving any discussions.
FAQ
I want to contribute, where do I start?
Take a look at the list of open issues for Task or Task for
Visual Studio Code. We have a good first
issue label for simpler issues that are ideal for first time
contributions.
All kinds of contributions are welcome, whether its a typo fix or a shiny new
feature. You can also contribute by upvoting/commenting on issues, helping to
answer questions or contributing to other community projects.
I'm stuck, where can I get help?
If you have questions, feel free to ask them in the #help forum channel on our
Discord server or open a Discussion on GitHub.
Website Src Latest Docs Faq (`website/src/latest/docs/faq.md`)
title: FAQ Frequently asked questions about Task, including ETAs, shell limitations, and Windows compatibility section: Project docType: project outline: deep
FAQ
This page contains a list of frequently asked questions about Task.
When will \ be released? / ETAs
Task is free and open source project maintained by a small group of
volunteers with full time jobs and lives outside of the project. Because of
this, it is difficult to predict how much time we will be able to dedicate to
the project in advance and we don't want to make any promises that we can't
keep. For this reason, we are unable to provide ETAs for new features or
releases. We make a "best effort" to provide regular releases and fix bugs in a
timely fashion, but sometimes our personal lives must take priority.
ETAs are probably the number one question we (and maintainers of other open
source projects) get asked. We understand that you are passionate about the
project, but it can be overwhelming to be asked this question so often. Please
be patient and avoid asking for ETAs.
The best way to speed things up is to contribute to the project yourself. We
always appreciate new contributors. If you are interested in contributing, check
out the contributing guide.
Why won't my task update my shell environment?
This is a limitation of how shells work. Task runs as a subprocess of your
current shell, so it can't change the environment of the shell that started it.
This limitation is shared by other task runners and build tools too.
A common way to work around this is to create a task that will generate output
that can be parsed by your shell. For example, to set an environment variable on
your shell you can write a task like this:
my-shell-env:
cmds:
- echo "export FOO=foo"
- echo "export BAR=bar"Now run eval $(task my-shell-env) and the variables $FOO and $BAR will be
available in your shell.
I can't reuse my shell in a task's commands
Task runs each command as a separate shell process, so something you do in one
command won't effect any future commands. For example, this won't work:
version: '3'
tasks:
foo:
cmds:
- a=foo
- echo $a
# outputs ""To work around this you can either use a multiline command:
version: '3'
tasks:
foo:
cmds:
- |
a=foo
echo $a
# outputs "foo"Or for more complex multi-line commands it is recommended to move your code into
a separate file and call that instead:
version: '3'
tasks:
foo:
cmds:
- ./foo-printer.bash#!/bin/bash
a=foo
echo $aAre shell core utilities available on Windows?
The most common ones, yes. And we might add more in the future.
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
environment variable:
# Enable, even on non-Windows platforms
env TASK_CORE_UTILS=1 task ...
# Disable, even on Windows
env TASK_CORE_UTILS=0 task ...This is the list of core utils that are currently available:
base64catchmodcpfindgziplsmkdirmktempmvrmshasumtartouchxargs- (more might be added in the future)
Website Src Latest Docs Installation (`website/src/latest/docs/installation.md`)
title: Installation section: Getting Started docType: guide outline: deep pageClass: installation-page
Installation
Choose a package manager for your system, or install Task from a binary.
Official packages {#official-package-managers}
Maintained by the Task team and kept up-to-date.
[Homebrew](https://brew.sh) {#homebrew}
Tap source
Homebrew package
Formula source
brew install go-task/tap/go-taskOr use the Homebrew core formula:
brew install go-task[dnf](https://docs.fedoraproject.org/en-US/quick-docs/dnf) {#dnf}
Set up the repository:
curl -1sLf 'https://dl.cloudsmith.io/public/task/task/setup.rpm.sh' | sudo -E bashInstall Task:
dnf install task[apt](https://doc.ubuntu-fr.org/apt) {#apt}
Set up the repository:
curl -1sLf 'https://dl.cloudsmith.io/public/task/task/setup.deb.sh' | sudo -E bashInstall Task:
apt install task[apk](https://wiki.alpinelinux.org/wiki/Alpine_Package_Keeper) {#apk}
Set up the repository:
curl -1sLf 'https://dl.cloudsmith.io/public/task/task/setup.alpine.sh' | sudo -E bashInstall Task:
apk add task[Snap](https://snapcraft.io/task) {#snap}
sudo snap install task --classicRequires a Linux distribution with classic confinement support.
[npm](https://www.npmjs.com) {#npm}
npm install @go-task/cliTask is also available as a project dependency.
[WinGet](https://github.com/microsoft/winget-cli) {#winget}
winget install Task.TaskAvailable through the
WinGet community repository.
Package repository hosting for deb/rpm/apk is graciously provided by Cloudsmith.
Community packages {#community-maintained-package-managers}
Maintained by the community, outside the Task team's control. These packages may
lag behind the latest release.
[Mise](https://mise.jdx.dev/) {#mise}
mise use -g taskFor a project-local installation, use mise use task instead. This adds Task to
your project's mise.toml.
[Macports](https://macports.org) {#macports}
port install go-task[pip](https://pip.pypa.io) {#pip}
pip install go-task-bin[Chocolatey](https://chocolatey.org) {#chocolatey}
choco install go-task[Scoop](https://scoop.sh) {#scoop}
scoop install taskArch ([pacman](https://wiki.archlinux.org/title/Pacman)) {#arch}
pacman -S go-taskFedora ([dnf](https://docs.fedoraproject.org/en-US/quick-docs/dnf)) {#fedora-community}
dnf install go-taskFreeBSD ([Ports](https://ports.freebsd.org/cgi/ports.cgi)) {#freebsd}
pkg install task[Nix](https://nixos.org) {#nix}
nix-env -iA nixpkgs.go-task[pacstall](https://github.com/pacstall/pacstall) {#pacstall}
pacstall -I go-task-deb[pkgx](https://pkgx.sh) {#pkgx}
pkgx taskor, if you have pkgx integration enabled:
taskBinaries & CI {#get-the-binary}
Install Task without a package manager: download a binary, use the install
script, or add the setup action to your GitHub workflow.
Download a binary {#binary}
- Open the GitHub releases and
download the archive for your operating system and architecture. - Extract
task(task.exeon Windows). - Move the executable to a directory on your
PATH.
Each release also includes DEB, RPM and APK packages, plus task_checksums.txt
with SHA-256 checksums for the release files.
Install with a script {#install-script}
Use the
install script 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
sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -dsh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b ~/.local/binsh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d v3.42.1sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b ~/.local/bin v3.42.1:::
When combining options, keep the
release tag 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
Add the official setup action to your
job's steps before running Task:
- name: Install Task
uses: go-task/setup-task@v2
- name: Verify Task
run: task --versionUse the action's version input to pin a Task release. See the
action documentation for examples
and configuration.
Build from source
Ensure that you have a supported version of Go properly
installed and setup. You can find the minimum required version of Go in the
go.mod file.
You can then install the latest release globally by running:
go install github.com/go-task/task/v3/cmd/task@latestOr you can install into another directory:
env GOBIN=/bin go install github.com/go-task/task/v3/cmd/task@latest::: tip
For CI environments we recommend using the install script
instead, which is faster and more stable, since it'll just download the latest
released binary.
:::
Go Tool
If you're working in a Go project, a nice possibility is using go tool.go tool makes it easy to run Task without needing to install the binary
manually. This works well on CI.
To do that, just run the following to add Task as a tool in your Go project.
Task will be added to your go.mod.
go get -tool github.com/go-task/task/v3/cmd/task@latestThen, prefix go tool when calling Task like below. Go will compile Task on
demand before calling it.
go tool task {arguments...}Verify installation
After installing, open a terminal and check that Task is available:
task --versionIf you installed Task with go tool, run go tool task --version instead.
You're ready to create your first Taskfile. 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.
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 andrequires 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.
::: code-group
# ~/.bashrc
# export TASK_EXE='go-task' if needed
eval "$(task --completion bash)"# ~/.zshrc
# export TASK_EXE='go-task' if needed
eval "$(task --completion zsh)"# ~/.config/fish/config.fish
# export TASK_EXE='go-task' if needed
task --completion fish | source# $PROFILE\Microsoft.PowerShell_profile.ps1
Invoke-Expression (&task --completion powershell | Out-String)# ~/.config/nushell/config.nu
#
# Nushell cannot source a script from stdin, so the script is saved where
# Nushell auto-loads it at startup. Autoload directories are read after
# config.nu, so the completions become available 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"):::
Option 2. Copy the script to your shell's completions directory
This method requires you to manually update the completions whenever Task is
updated. However, it is useful if you want to modify the completions yourself.
::: code-group
task --completion bash > /etc/bash_completion.d/tasktask --completion zsh > /usr/local/share/zsh/site-functions/_tasktask --completion fish > ~/.config/fish/completions/task.fishtask --completion nu | save --force ($nu.data-dir | path join "vendor/autoload/task-completions.nu"):::
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):
zstyle ':completion:*:*:task:*' verbose falseBy default, task aliases are also offered as completions. To complete only the
canonical task names, add the show-aliases zstyle:
zstyle ':completion:*:*:task:*' show-aliases falseNushell caveats
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, and the refreshed completions are
picked up by the next shell. With option 2, re-run the command after upgrading
Task.
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:
$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).
Website Src Latest Docs Integrations (`website/src/latest/docs/integrations.md`)
title: Integrations Official and community integrations for Task, including VS Code, JSON schemas, and other tools section: Getting Started docType: guide outline: deep
Integrations
Visual Studio Code Extension
Task has an
official extension for Visual Studio Code.
The code for this project can be found in
our GitHub repository. To use this
extension, you must have Task v3.45.3+ installed on your system.
This extension provides the following features (and more):
- View tasks in the sidebar.
- Run tasks from the sidebar and command palette.
- Go to definition from the sidebar and command palette.
- Run last task command.
- Multi-root workspace support.
- Initialize a Taskfile in the current workspace.
To get autocompletion and validation for your Taskfile, see the
Schema section below.
Configuration namespace change
In v1.0.0 of the extension, the configuration namespace was changed from task
to taskfile in order to fix
an issue.
If you receive a warning like the one above, you will need to update your
settings to use the new taskfile namespace instead:
Schema
This was initially created by @KROSF in
this Gist and
is now officially maintained in
this file
and made available at https://taskfile.dev/schema.json. This schema can be used
to validate Taskfiles and provide autocompletion in many code editors:
Visual Studio Code
To integrate the schema into VS Code, you need to install the
YAML extension
by Red Hat. Any Taskfile.yml in your project should automatically be detected
and validation/autocompletion should work. If this doesn't work or you want to
manually configure it for files with a different name, you can add the following
to your settings.json:
// settings.json
{
"yaml.schemas": {
"https://taskfile.dev/schema.json": [
"**/Taskfile.yml",
"./path/to/any/other/taskfile.yml"
]
}
}You can also configure the schema directly inside of a Taskfile by adding the
following comment to the top of the file:
# yaml-language-server: $schema=https://taskfile.dev/schema.json
version: '3'You can find more information on this in the
YAML language server project.
AI/LLM Assistants
Task documentation is optimized for AI assistants like Claude Code, Cursor, and
other LLM-powered development tools through the
VitePress LLMs plugin.
This integration provides:
- Structured documentation in LLM-friendly formats
- Context-optimized content for AI assistants
- Automatic generation of
llms.txtandllms-full.txtfiles - Enhanced discoverability of Task features for AI tools
AI assistants can access Task documentation through:
- llms.txt: Lightweight overview of Task documentation
- llms-full.txt: Complete documentation with all content
These files are automatically generated and kept in sync with the documentation,
ensuring AI assistants always have access to the latest Task features and usage
patterns.
Community Integrations
In addition to our official integrations, there is an amazing community of
developers who have created their own integrations for Task:
- Sublime Text Plugin
[source] by @biozz - IntelliJ Plugin
[source] by @lechuckroh - Zed Extension
[source] by @nickalie - mk command line tool recognizes Taskfiles
natively. - fzf-make fuzzy finder with preview window
for make, pnpm, yarn, just & task.
If you have made something that integrates with Task, please feel free to open a
PR to add it to this list.
Website Src Latest Docs Releasing (`website/src/latest/docs/releasing.md`)
title: Releasing Task release process including GoReleaser, Homebrew, npm, Snapcraft, winget, and other package managers section: Contributing docType: contributing outline: deep
Releasing
The release process of Task is done with the help of GoReleaser.
You can test the release process locally by calling the goreleaser:test task
of the Taskfile.
GitHub Actions should release
artifacts automatically when a new Git tag is pushed to main branch (raw
executables and DEB and RPM packages).
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 inwebsite/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:
git checkout main && git pull
task website:deploy:prodPackage managers
GoReleaser will automatically publish the release to most package managers:
- Cloudsmith (DEB and RPM repositories)
- Homebrew
- npm
- Snapcraft
- winget
Once the release is published, GoReleaser announces it on the
Discord server. Nightly releases are not
announced.
These package managers are updated automatically by the community:
Website Src Latest Docs Remote Taskfiles (`website/src/latest/docs/remote-taskfiles.md`)
title: Remote Taskfiles 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
Only run remote Taskfiles from sources you trust. Their commands execute on your
machine, just like commands from a local Taskfile.
:::
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 for subsequent changes and CI.
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
$ task --taskfile https://raw.githubusercontent.com/go-task/task/main/website/src/public/Taskfile.yml
task: [hello] echo "Hello Task!"
Hello Task!$ task --taskfile 'https://github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=main'
task: [hello] echo "Hello Task!"
Hello Task!$ task --taskfile '[email protected]/go-task/task.git//website/src/public/Taskfile.yml?ref=main'
task: [hello] echo "Hello Task!"
Hello Task!:::
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:
::: code-group
version: '3'
includes:
shared: https://raw.githubusercontent.com/go-task/task/main/website/src/public/Taskfile.ymlversion: '3'
includes:
shared: https://github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=mainversion: '3'
includes:
shared: [email protected]/go-task/task.git//website/src/public/Taskfile.yml?ref=main:::
$ 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:
version: '3'
includes:
shared: https://{{.TOKEN}}@raw.githubusercontent.com/my-org/my-repo/main/Taskfile.ymlPrefer the 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
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
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
//to the URL. - You can also optionally specify a branch or tag to use by appending
?ref=<ref>to the end of the URL. If you omit a reference, the default
branch will be used.
Git over SSH
[email protected]/go-task/task.git//website/src/public/Taskfile.yml?ref=main
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.
- You can optionally add the path to the Taskfile in the repository by appending
//to the URL. - You can also optionally specify a branch or tag to use by appending
?ref=<ref>to the end of the URL. If you omit a reference, the default
branch will be used.
Locate files and directories {#special-variables}
The file-path special variables 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 |
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.
Review trust and changes {#security}
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
remote Taskfiles:
- When running a task from a remote Taskfile for the first time, Task will
print a warning to the console asking you to check that you are sure that you
trust the source of the Taskfile. If you do not accept the prompt, then Task
will exit with code104(not trusted) and nothing will run. If you accept
the prompt, the remote Taskfile will run and further calls to the remote
Taskfile will not prompt you again. - Whenever you run a remote Taskfile, Task will create and store a checksum of
the file that you are running. If the checksum changes, then Task will print
another warning to the console to inform you that the contents of the remote
file has changed. If you do not accept the prompt, then Task will exit with
code104(not trusted) and nothing will run. If you accept the prompt, the
checksum will be updated and the remote Taskfile will run.
Sometimes you need to run Task in an environment that does not have an
interactive terminal, so you are not able to accept a prompt. In these cases you
are able to tell task to accept these prompts automatically by using the --yes
flag or the --trusted-hosts flag. The --trusted-hosts flag allows you to
specify trusted hosts for remote Taskfiles, while --yes applies to all prompts
in Task. You can also configure trusted hosts in your
taskrc configuration usingremote.trusted-hosts. Before enabling automatic trust, you should:
- Be sure that you trust the source and contents of the remote Taskfile.
- Consider using a pinned version of the remote Taskfile (e.g. A link
containing a commit hash) to prevent Task from automatically accepting a
prompt that says a remote Taskfile has changed.
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:
version: '3'
includes:
included:
taskfile: https://raw.githubusercontent.com/go-task/task/main/website/src/public/Taskfile.yml
checksum: '<sha256-of-reviewed-file>'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:
- Add the include normally without the
checksumkey. The first time you run
the included Taskfile, a.task/remotetemporary directory is created. Find
the correct set of files for your included Taskfile and open the file that
ends with.checksum. You can copy the contents of this file and paste it
into thechecksumkey of your include. This method is safest as it allows
you to inspect the downloaded Taskfile before you pin it. - Alternatively, add the include with a temporary random value in the
checksumkey. When you try to run the Taskfile, you will get an error that
will report the incorrect expected checksum and the actual checksum. You can
copy the actual checksum and replace your temporary random value.
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--insecure flag. This is to protect you from accidentally running a remote
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.
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
certificate using the --cacert flag:
task --taskfile https://internal.example.com/Taskfile.yml --cacert /path/to/ca.crtFor servers that require client certificate authentication (mTLS), you can
provide a client certificate and key:
task --taskfile https://secure.example.com/Taskfile.yml \
--cert /path/to/client.crt \
--cert-key /path/to/client.key::: warning
Encrypted private keys are not currently supported. If your key is encrypted,
you must decrypt it first:
openssl rsa -in encrypted.key -out decrypted.key:::
These options can also be configured in the
configuration file.
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
invocations of the Taskfile until the cache expires. Once it expires, Task will
download the latest copy of the file and update the cache. By default, the cache
is set to expire immediately. This means that Task will always fetch the latest
version. However, the cache expiry duration can be modified by setting the--expiry flag.
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.
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
the --timeout flag and specifying a duration. For example, --timeout 5s will
set the timeout to 5 seconds.
By default, the cache is stored in the Task temp directory (.task). You can
override the location of the cache by using the --remote-cache-dir flag, theremote.cache-dir option in your
configuration file, or theTASK_REMOTE_CACHE_DIR environment variable. This way, you can share the cache
between different projects.
You can force Task to ignore the cache and download the latest version by using
the --download flag.
You can use the --clear-cache flag to clear all cached remote files.
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
set up this configuration using flags, environment variables or a configuration
file:
Website Src Latest Docs Styleguide (`website/src/latest/docs/styleguide.md`)
title: Style Guide Official style guide for Taskfile.yml files with best practices and recommended conventions section: Contributing docType: contributing outline: deep
Style Guide
This is the official style guide for Taskfile.yml files. It provides basic
instructions for keeping your Taskfiles clean and familiar to other users.
This guide contains general guidelines, but they do not necessarily need to be
followed strictly. Feel free to disagree and do things differently if you need
or want to. Any improvements to this guide are welcome! Please open an issue or
create a pull request to contribute.
Use the suggested ordering of the main sections
version:
includes:
# optional configurations (output, silent, method, run, etc.)
vars:
env: # followed or replaced by dotenv
tasks:Use two spaces for indentation
This is the most common convention for YAML files, and Task follows it.
# bad
tasks:
foo:
cmds:
- echo 'foo'
# good
tasks:
foo:
cmds:
- echo 'foo'Separate the main sections with empty lines
# bad
version: '3'
includes:
docker: ./docker/Taskfile.yml
output: prefixed
vars:
FOO: bar
env:
BAR: baz
tasks:
# ...
# good
version: '3'
includes:
docker: ./docker/Taskfile.yml
output: prefixed
vars:
FOO: bar
env:
BAR: baz
tasks:
# ...Separate tasks with empty lines
# bad
version: '3'
tasks:
foo:
cmds:
- echo 'foo'
bar:
cmds:
- echo 'bar'
baz:
cmds:
- echo 'baz'
# good
version: '3'
tasks:
foo:
cmds:
- echo 'foo'
bar:
cmds:
- echo 'bar'
baz:
cmds:
- echo 'baz'Use only uppercase letters for variable names
# bad
version: '3'
vars:
binary_name: myapp
tasks:
build:
cmds:
- go build -o {{.binary_name}} .
# good
version: '3'
vars:
BINARY_NAME: myapp
tasks:
build:
cmds:
- go build -o {{.BINARY_NAME}} .Avoid using whitespace when templating variables
# bad
version: '3'
tasks:
greet:
cmds:
- echo '{{ .MESSAGE }}'
# good
version: '3'
tasks:
greet:
cmds:
- echo '{{.MESSAGE}}'This convention is also commonly used in templates for the Go programming
language.
Use kebab case for task names
# bad
version: '3'
tasks:
do_something_fancy:
cmds:
- echo 'Do something'
# good
version: '3'
tasks:
do-something-fancy:
cmds:
- echo 'Do something'Use a colon to separate the task namespace and name
# good
version: '3'
tasks:
docker:build:
cmds:
- docker ...
docker:run:
cmds:
- docker-compose ...This is also done automatically when using included Taskfiles.
Prefer using external scripts instead of multi-line commands
# bad
version: '3'
tasks:
build:
cmds:
- |
for i in $(seq 1 10); do
echo $i
echo "some other complex logic"
done'
# good
version: '3'
tasks:
build:
cmds:
- ./scripts/my_complex_script.shWebsite Src Latest Docs Taskfile Versions (`website/src/latest/docs/taskfile-versions.md`)
title: Taskfile Versions How to use the Taskfile schema version to ensure users are using the correct versions of Task section: Project docType: project outline: deep
Taskfile Versions
The Taskfile schema slowly changes as new features are added and old ones are
removed. This document explains how to use a Taskfile's schema version to ensure
that the users of your Taskfile are using the correct versions of Task.
What the Taskfile version means
The schema version at the top of every Taskfile corresponds to a version of the
Task CLI, and by extension, the features that are provided by that version. When
creating a Taskfile, you should specify the minimum version of Task that
supports the features you require. If you try to run a Taskfile with a version
of Task that does not meet this minimum required version, it will exit with an
error. For example, given a Taskfile that starts with:
version: '3.2.1'When executed with Task v3.2.0, it will exit with an error. Running with
version v3.2.1 or higher will work as expected.
Task accepts any SemVer compatible string including versions which
omit the minor or patch numbers. For example, 3, 3.0, and 3.0.0 all mean
the same thing and are all valid. Most Taskfiles only specify the major version
number. However it can be useful to be more specific when you intend to share a
Taskfile with others.
For example, the Taskfile below makes use of aliases:
version: '3'
tasks:
hello:
aliases:
- hi
- hey
cmds:
- echo "Hello, world!"Aliases were introduced in Task v3.17.0, but the Taskfile only specifies 3
as the version. This means that a user who has v3.16.0 or lower installed will
get a potentially confusing error message when trying to run the Task as the
Taskfile specifies that any version greater or equal to v3.0.0 is fine.
Instead, we should start the file like this:
version: '3.17'Now when someone tries to run the Taskfile with an older version of Task, they
will receive an error prompting them to upgrade their version of Task tov3.17.0 or greater.
:::info
Note that this functionality was introduced in
v3.34.0, so older
versions are not able to give you this warning.
:::
Versions 1 & 2
Version 1 and 2 of Task are no longer officially supported and anyone still
using them is strongly encouraged to upgrade to the latest version of Task.
While version: 2 of Task did support schema versions, the behavior did not
work in quite the same way and cannot be relied upon for the purposes discussed
above.
Website Src Next Docs Changelog (`website/src/next/docs/changelog.md`)
title: Changelog Release history for Task, including new features, improvements, fixes, and breaking changes section: Project docType: project outline: deep editLink: false
Changelog
::: v-pre
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.headersconfig 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
201instead of205
(#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. A401now 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 singletask __complete
command, so every shell offers the same suggestions: task names, aliases,
flags, flag values and per-task CLI variables. The Zshshow-aliasesandverbosezstyles keep working, now backed by the--no-aliasesand--no-descriptionscompletion 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
thanks to all those that contributed and gave feedback (too many to list
here). We've also given the
Remote Taskfiles documentation a
bit of a polish (#1317, #2906 by @pd93). - Added a per-command
timeoutthat terminates a command once it exceeds the
given duration (Go duration syntax). It covers shell commands, task calls,
deferred commands,depsand theifcondition, obeysignore_error, and
reports exit code124. Callers that join arun: onceorwhen_changed
task already running now honor their owntimeout, 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). - 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.excludescan 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.refin--interactiveprompts. Required vars usingenum.refnow 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,--outputand--sort(#2966 by @vmaerten). - Added a verbose log line for failed tasks. In
--verbosemode, a task whose
command exits non-zero now reportstask: "<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 amethod: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
method is injected, so a task inheriting a Taskfile-levelmethod: timestamp
gets{{.TIMESTAMP}}and no longer a{{.CHECKSUM}}(which now renders as an
empty string), and neither variable is injected when the effective method isnone(#2924 by @vmaerten). - Fixed
ref:infor: matrix:andenum:only accepting literal lists. Refs
computed with template functions likekeysorsplitListno longer fail
with "must resolve to a list" (#2544, #2956 by @no-hup). - Fixed pressing
Escat an interactive variable prompt not cancelling the run
(#2942 by @anilnatha). - Fixed
joinUrlcollapsing the//in a URL scheme (e.g. producinghttp:/localhostinstead ofhttp://localhost) (#2915 by @vsaraikin). - Fixed the JSON schema rejecting
ignore_erroron a command inside afor
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_erroron atask:call, andif,setandshopton a command
inside aforloop (#2967 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
order. Prompts now follow the order the vars are declared in the Taskfile.
(#2871 by @caproven) - Fixed Fish completions not being picked up correctly by installing them to
Fish'svendor_completions.ddirectory instead ofcompletions(#2850, #2859
by @Legimity). - PowerShell completions now work with aliases of the
taskcommand, not just
thetaskbinary itself (#2852 by @kojiishi). - Fixed task and namespace aliases not being completed by the Zsh completion. A
show-aliaseszstyle can turn this off (#2865, #2864 by @vmaerten). - Fixed task names containing certain characters (e.g.
\,_,^) leaking
into checksum/timestamp filenames, breakingsources:/generates:up-to-date
detection (#2886 by @s3onghyun). - Fixed
for: matrix:loops usingref:rows producing wrong values when the
same task was run concurrently (e.g. by paralleldeps) with different vars
(#2890, #2894 by @amitmishra11). - Added a
secret: trueflag for variables that masks their value in logs,task --summary, and command output (#2514 by @vmaerten). - Added the
use_gitignoresetting (global or per-task) to skip files matched
by your.gitignorewhen fingerprintingsources/generatesand when
watching (#2773 by @vmaerten). - Added support for configuring output flags (
--output,--output-group-begin,--output-group-end,--output-group-error-only) via
theTASK_OUTPUT*environment variables (#2873 by @liiight). - Added a
--temp-dirflag (withTASK_TEMP_DIRenv var andtemp-dirtaskrc
config) to customise the directory where Task stores temporary files such as
checksums. Relative paths are resolved against the root Taskfile (#2891 by
@kjasn). - Defined environment variable behavior for remote taskfiles (#2267, #2847 by
@vmaerten). - Added support for remote Taskfiles hosted on Azure DevOps, whose git URLs use
a/_git/path segment rather than a.gitsuffix (#2904 by @pd93). - Re-added the example remote taskfile at
taskfile.dev/Taskfile.yml (#2905 by
@pd93). - Fixed malformed
includes:entries (missingtaskfile/dir) reporting a
misleading "include cycle detected" error instead of a clear configuration
error (#1881, #2892 by @Lewin671).
v3.51.1 - 2026-05-16
- A significant performance boost was achieved for large Taskfiles (monorepos)
by skipping templating altogether when the string is static (#2820 by @romnn). - Added
absPathtemplate function that resolves a path to its absolute form,
cleaning..and.components (#2681, #2788 by @mateenanjum). - Added
joinEnvfunction to join paths based on your oprating system:;for
Windows and:elsewhere, andjoinUrlto join URL paths. Also, added two
new special variables:FILE_PATH_SEPARATORwhich returns\on Windows and/elsewhere, andPATH_LIST_SEPARATORwhich returns;on Windows and:
elsewhere (#2406, #2408 by @solvingj). - Update the shell interpreter with a regression fix (#2812, #2832 by
@andreynering). - Fix potential panic with the shell interpreter (#2810 by @trulede).
v3.50.0 - 2026-04-13
- Added
enum.refsupport inrequires: enum constraints can now reference
variables or template pipelines (e.g.,ref: .ALLOWED_ENVS) instead of
duplicating static lists. Combined withsh:variables, this enables fully
dynamic enum validation (#2678 by @vmaerten). - Fixed Fish completion using hardcoded
taskbinary name instead of$GO_TASK_PROGNAMEfor experiments cache (#2730, #2727 by @SergioChan). - Fixed watch mode ignoring SIGHUP signal, causing the watcher to exit instead
of restarting (#2764, #2642). - Fixed a long time bug where the task wouldn't re-run as it should when using
method: timestampand the files listed ongenerates:were deleted. This
makesmethod: timestampbehaves the same asmethod: checksum(#1230, #2716
by @drichardson).
v3.49.1 - 2026-03-08
- Reverted #2632 for now, which caused some regressions. That change will be
reworked (#2720, #2722, #2723).
v3.49.0 - 2026-03-07
- Fixed included Taskfiles with
watch: truenot triggering watch mode when
called from the root Taskfile (#2686, #1763 by @trulede). - Fixed Remote Git Taskfiles failing on Windows due to backslashes in URL paths
(#2656 by @Trim21). - Fixed remote Git Taskfiles timing out when resolving includes after accepting
the trust prompt (#2669, #2668 by @vmaerten). - Fixed unclear error message when Taskfile search stops at a directory
ownership boundary (#2682, #1683 by @trulede). - Fixed global variables from imported Taskfiles not resolving
ref:values
correctly (#2632 by @trulede). - Every
.taskrc.ymloption can now be overridden with aTASK_-prefixed
environment variable, making CI and container configuration easier (#2607,
#1066 by @vmaerten).
v3.48.0 - 2026-01-26
- Fixed
if:conditions when using to check dynamic variables. Also, skip
variable prompt if task would be skipped byif:(#2658, #2660 by @vmaerten). - Fixed
ROOT_TASKFILEvariable pointing to directory instead of the actual
Taskfile path when no explicit-tflag is provided (#2635, #1706 by
@trulede). - Included Taskfiles with
silent: truenow properly propagate silence to their
tasks, while still allowing individual tasks to override withsilent: false
(#2640, #1319 by @trulede). - Added TLS certificate options for Remote Taskfiles: use
--cacertfor
self-signed certificates and--cert/--cert-keyfor mTLS authentication
(#2537, #2242 by @vmaerten).
v3.47.0 - 2026-01-24
- Fixed remote git Taskfiles: cloning now works without explicit ref, and
directory includes are properly resolved (#2602 by @vmaerten). - For
output: prefixed, printprefix:if set instead of task name (#1566,
#2633 by @trulede). - Ensure no ANSI sequences are printed for
--color=false(#2560, #2584 by
@trulede). - Task aliases can now contain wildcards and will match accordingly (e.g.,
s-*
as alias forstart-*) (#1900, #2234 by @vmaerten). - Added conditional execution with the
iffield: skip tasks, commands, or task
calls based on shell exit codes or template expressions like{{ eq .ENV "prod" }}(#2564, #608 by @vmaerten). - Task can now interactively prompt for missing required variables when running
in a TTY, with support for enum selection menus. Enable with--interactive
flag orinteractive: truein.taskrc.yml(#2579, #2079 by @vmaerten).
v3.46.4 - 2025-12-24
- Fixed regressions in completion script for Fish (#2591, #2604, #2592 by
@WinkelCode).
v3.46.3 - 2025-12-19
- Fixed regression in completion script for zsh (#2593, #2594 by @vmaerten).
v3.46.2 - 2025-12-18
- Fixed a regression on previous release that affected variables passed via
command line (#2588, #2589 by @vmaerten).
v3.46.1 - 2025-12-18
β¨ Features
- A small behavior change was made to dependencies. Task will now wait for all
dependencies to finish running before continuing, even if any of them fail. To
opt for the previous behavior, setfailfast: trueeither on your.taskrc.ymlor per task, or use the--failfastflag, which will also work
for--parallel(#1246, #2525 by @andreynering). - The
--summaryflag now displaysvars:(both global and task-level),env:, andrequires:sections. Dynamic variables show their shell command
(e.g.,sh: echo "hello") instead of the evaluated value (#2486 ,#2524 by
@vmaerten). - Improved performance of fuzzy task name matching by implementing lazy
initialization. Added--disable-fuzzyflag anddisable-fuzzytaskrc option
to allow disabling fuzzy matching entirely (#2521, #2523 by @vmaerten). - Added LLM-optimized documentation via VitePress plugin, generating
llms.txt
andllms-full.txtfor AI-powered development tools (#2513 by @vmaerten). - Added
--trusted-hostsCLI flag andremote.trusted-hostsconfig option to
skip confirmation prompts for specified hosts when using Remote Taskfiles
(#2491, #2473 by @maciejlech). - When running in GitHub Actions, Task now automatically emits error annotations
on failure, improving visibility in workflow summaries (#2568 by @vmaerten). - The
--yesflag is now accessible in templates via the newCLI_ASSUME_YES
variable (#2577, #2479 by @semihbkgr). - Improved shell completion scripts (Zsh, Fish, PowerShell) by adding missing
flags and dynamic experimental feature detection (#2532 by @vmaerten). - Remote Taskfiles now accept
application/octet-streamContent-Type (#2536,
#1944 by @vmaerten). - Shell completion now works when Task is installed or aliased under a different
binary name via TASK_EXE environment variable (#2495, #2468 by @vmaerten). - Some small fixes and improvements were made to
task --initand to the
default Taskfile it generates (#2433 by @andreynering). - Added
--remote-cache-dirflag andremote.cache-dirtaskrc option to
customize the cache directory for Remote Taskfiles (#2572 by @vmaerten). - Zsh completion now supports zstyle verbose option to show or hide task
descriptions (#2571 by @vmaerten). - Task now automatically enables colored output in CI environments (GitHub
Actions, GitLab CI, etc.) without requiring FORCE_COLOR=1 (#2569 by
@vmaerten). - Added color taskrc option to explicitly enable or disable colored output
globally (#2569 by @vmaerten). - Improved Git Remote Taskfiles by switching to go-getter: SSH authentication
now works out of the box andapplyOfis properly supported (#2512 by
@vmaerten).
π Fixes
- Fix RPM upload to Cloudsmith by including the version in the filename to
ensure unique filenames (#2507 by @vmaerten). - Fix
run: when_changedto work properly for Taskfiles included multiple times
(#2508, #2511 by @trulede). - Fixed Zsh and Fish completions to stop suggesting task names after
--
separator, allowing proper CLI_ARGS completion (#1843, #1844 by
@boiledfroginthewell). - Watch mode (
--watch) now always runs the task, regardless ofrun: onceorrun: when_changedsettings (#2566, #1388 by @trulede). - Fixed global variables (CLI_ARGS, CLI_FORCE, etc.) not being accessible in
root-level vars section (#2403, #2397 by @trulede, @vmaerten). - Fixed a bug where
ignore_errorwas ignored when usingtask:to call
another task (#2552, #363 by @trulede). - Fixed Zsh completion not suggesting global tasks when using
-g/--global
flag (#1574, #2574 by @vmaerten). - Fixed Fish completion failing to parse task descriptions containing colons
(e.g., URLs or namespaced functions) (#2101, #2573 by @vmaerten). - Fixed false positive "property 'for' is not allowed" warnings in IntelliJ when
usingforloops in Taskfiles (#2576 by @vmaerten).
v3.45.5 - 2025-11-11
- Fixed bug that made a generic message, instead of an useful one, appear when a
Taskfile could not be found (#2431 by @andreynering). - Fixed a bug that caused an error when including a Remote Git Taskfile (#2438
by @twelvelabs). - Fixed issue where
.taskrc.ymlwas not returned if reading it failed, and
corrected handling of remote entrypoint Taskfiles (#2460, #2461 by @vmaerten). - Improved performance of
--listand--list-allby introducing a faster
compilation method that skips source globbing and checksum updates (#1322,
#2053 by @vmaerten). - Fixed a concurrency bug with
output: group. This ensures that begin/end
parts won't be mixed up from different tasks (#1208, #2349, #2350 by
@trulede). - Do not re-evaluate variables for
defer:(#2244, #2418 by @trulede). - Improve error message when a Taskfile is not found (#2441, #2494 by
@vmaerten). - Fixed generic error message
exit status 1when a dependency task failed
(#2286 by @GrahamDennis). - Fixed YAML library from the unmaintained
gopkg.in/yaml.v3to the new fork
maintained by the official YAML org (#2171, #2434 by @andreynering). - On Windows, the built-in version of the
rmcore utils contains a fix related
to the-fflag (#2426,
u-root/u-root#3464,
mvdan/sh#1199, #2506 by
@andreynering).
v3.45.4 - 2025-09-17
- Fixed a bug where
cache-expirycould not be defined in.taskrc.yml(#2423
by @vmaerten). - Fixed a bug where
.taskrc.ymlfiles in parent folders were not read
correctly (#2424 by @vmaerten). - Fixed a bug where autocomplete in subfolders did not work with zsh (#2425 by
@vmaerten).
v3.45.3 - 2025-09-15
- Task now includes built-in core utilities to greatly improve compatibility on
Windows. This means that your commands that usescp,mv,mkdiror any
other common core utility will now work by default on Windows, without extra
setup. This is something we wanted to address for many many years, and it's
finally being shipped!
Read our blog post this the topic.
(#197, #2360 by @andreynering). - :sparkles: Built and deployed a brand new website
using VitePress (#2359, #2369, #2371, #2375, #2378 by
@vmaerten, @andreynering, @pd93). - Began releasing
nightly builds. This
will allow people to test our changes before they are fully released and
without having to install Go to build them (#2358 by @vmaerten). - Added support for global config files in
$XDG_CONFIG_HOME/task/taskrc.ymlor$HOME/.taskrc.yml. Check out our new
configuration guide for more
details (#2247, #2380, #2390, #2391 by @vmaerten, @pd93). - Added experiments to the taskrc schema to clarify the expected keys and values
(#2235 by @vmaerten). - Added support for new properties in
.taskrc.yml: insecure, verbose,
concurrency, remote offline, remote timeout, and remote expiry. :warning:
Note: setting offline via environment variable is no longer supported. (#2389
by @vmaerten) - Added a
--nestedflag when outputting tasks using--list --json. This will
output tasks in a nested structure when tasks are namespaced (#2415 by @pd93). - Enhanced support for tasks with wildcards: they are now logged correctly, and
wildcard parameters are fully considered during fingerprinting (#1808, #1795
by @vmaerten). - Fixed panic when a variable was declared as an empty hash (
{}) (#2416, #2417
by @trulede).
Package API
- Bumped the minimum version of Go to 1.24 (#2358 by @vmaerten).
Other news
We recently released our
official GitHub Action. This is based
on the fantastic work by the Arduino team who created and maintained the
community version. Now that this is officially adopted, fixes/updates should be
more timely. We have already merged a couple of longstanding PRs in our
first release (by
@pd93, @shrink, @trim21 and all the previous contributors to
arduino/setup-task).
v3.45.0-v3.45.2 - 2025-09-15
Failed due to an issue with our release process.
v3.44.1 - 2025-07-23
- Internal tasks will no longer be shown as suggestions since they cannot be
called (#2309, #2323 by @maxmzkrcensys) - Fixed install script for some ARM platforms (#1516, #2291 by @trulede).
- Fixed a regression where fingerprinting was not working correctly if the path
to you Taskfile contained a space (#2321, #2322 by @pd93). - Reverted a breaking change to
randInt(#2312, #2316 by @pd93). - Made new variables
TEST_NAMEandTEST_DIRavailable in fixture tests
(#2265 by @pd93).
v3.44.0 - 2025-06-08
- Added
uuid,randIntandrandIntNtemplate functions (#1346, #2225 by
@pd93). - Added new
CLI_ARGS_LISTarray variable which contains the arguments passed
to Task after the--(the same asCLI_ARGS, but an array instead of a
string). (#2138, #2139, #2140 by @pd93). - Added
toYamlandfromYamltemplating functions (#2217, #2219 by @pd93). - Added
taskfield the--list --jsonoutput (#2256 by @aleksandersh). - Added the ability to
pin included taskfiles
by specifying a checksum. This works with both local and remote Taskfiles
(#2222, #2223 by @pd93). - When using the
Remote Taskfiles experiment,
any credentials used in the URL will now be redacted in Task's output (#2100,
#2220 by @pd93). - Fixed fuzzy suggestions not working when misspelling a task name (#2192, #2200
by @vmaerten). - Fixed a bug where taskfiles in directories containing spaces created
directories in the wrong location (#2208, #2216 by @pd93). - Added support for dual JSON schema files, allowing changes without affecting
the current schema. The current schemas will only be updated during releases.
(#2211 by @vmaerten). - Improved fingerprint documentation by specifying that the method can be set at
the root level to apply to all tasks (#2233 by @vmaerten). - Fixed some watcher regressions after #2048 (#2199, #2202, #2241, #2196 by
@wazazaby, #2271 by @andreynering).
v3.43.3 - 2025-04-27
Reverted the changes made in #2113 and #2186 that affected theUSER_WORKING_DIR and built-in variables. This fixes #2206, #2195, #2207 and
#2208.
v3.43.2 - 2025-04-21
- Fixed regresion of
CLI_ARGSbeing exposed as the wrong type (#2190, #2191 by
@vmaerten).
v3.43.1 - 2025-04-21
- Significant improvements were made to the watcher. We migrated from
watcher to
fsnotify. The former library used
polling, which means Task had a high CPU usage when watching too many files.fsnotifyuses proper the APIs from each operating system to watch files,
which means a much better performance. The default interval changed from 5
seconds to 100 milliseconds, because now it configures the wait time for
duplicated events, instead of the polling time (#2048 by @andreynering, #1508,
#985, #1179). - The Map Variables experiment
was made generally available so you can now
define map variables in your Taskfiles!
(#1585, #1547, #2081 by @pd93). - Wildcards can now
match multiple tasks (#2072,
#2121 by @pd93). - Added the ability to
loop over the files specified by thegenerateskeyword.
This works the same way as looping over sources (#2151 by @sedyh). - Added the ability to resolve variables when defining an include variable
(#2108, #2113 by @pd93). - A few changes have been made to the
Remote Taskfiles experiment
(#1402, #2176 by @pd93):- Cached files are now prioritized over remote ones.
- Added an
--expiryflag which sets the TTL for a remote file cache. By
default the value will be 0 (caching disabled). If Task is running in
offline mode or fails to make a connection, it will fallback on the cache.
.taskrcfiles can now be used from subdirectories and will be searched for
recursively up the file tree in the same way that Taskfiles are (#2159, #2166
by @pd93).- The default taskfile (output when using the
--initflag) is now an embedded
file in the binary instead of being stored in the code (#2112 by @pd93). - Improved the way we report the Task version when using the
--versionflag or{{.TASK_VERSION}}variable. This should now be more consistent and easier
for package maintainers to use (#2131 by @pd93). - Fixed a bug where globstar (
**) matching insourcesonly resolved the
first result (#2073, #2075 by @pd93). - Fixed a bug where sorting tasks by "none" would use the default sorting
instead of leaving tasks in the order they were defined (#2124, #2125 by
@trulede). - Fixed Fish completion on newer Fish versions (#2130 by @atusy).
- Fixed a bug where undefined/null variables resolved to an empty string instead
ofnil(#1911, #2144 by @pd93). - The
USER_WORKING_DIRspecial now will now properly account for the--dir
(-d) flag, if given (#2102, #2103 by @jaynis, #2186 by @andreynering). - Fix Fish completions when
--global(-g) is given (#2134 by @atusy). - Fixed variables not available when using
defer:(#1909, #2173 by @vmaerten).
Package API
- The
Executornow
uses the functional options pattern (#2085, #2147, #2148 by @pd93). - The functional options for the
taskfile.Reader
andtaskfile.Snippet
types no longer have theReader/Snippetrespective prefixes (#2148 by
@pd93). taskfile.Reader
no longer accepts ataskfile.Node.
Instead nodes are passed directly into theReader.Read
method (#2169 by @pd93).Reader.Read
also now accepts acontext.Context
(#2176 by @pd93).
v3.42.1 - 2025-03-10
- Fixed a bug where some special variables caused a type error when used global
variables (#2106, #2107 by @pd93).
v3.42.0 - 2025-03-08
- Made
--initless verbose by default and respect--silentand--verbose
flags (#2009, #2011 by @HeCorr). --initnow accepts a file name or directory as an argument (#2008, #2018 by
@HeCorr).- Fix a bug where an HTTP node's location was being mutated incorrectly (#2007
by @jeongukjae). - Fixed a bug where allowed values didn't work with dynamic var (#2032, #2033 by
@vmaerten). - Use only the relevant checker (timestamp or checksum) to improve performance
(#2029, #2031 by @vmaerten). - Print warnings when attempting to enable an inactive experiment or an active
experiment with an invalid value (#1979, #2049 by @pd93). - Refactored the experiments package and added tests (#2049 by @pd93).
- Show allowed values when a variable with an enum is missing (#2027, #2052 by
@vmaerten). - Refactored how snippets in error work and added tests (#2068 by @pd93).
- Fixed a bug where errors decoding commands were sometimes unhelpful (#2068 by
@pd93). - Fixed a bug in the Taskfile schema where
deferstatements in the shorthandcmdssyntax were not considered valid (#2068 by @pd93). - Refactored how task sorting functions work (#1798 by @pd93).
- Added a new
.taskrc.yml(or.taskrc.yaml) file to let users enable
experiments (similar to.env) (#1982 by @vmaerten). - Added new Getting Started docs (#2086
by @pd93). - Allow
matrixto use references to other variables (#2065, #2069 by @pd93). - Fixed a bug where, when a dynamic variable is provided, even if it is not
used, all other variables become unavailable in the templating system within
the include (#2092 by @vmaerten).
Package API
Unlike our CLI tool,
Task's package API is not currently stable.
In an effort to ease the pain of breaking changes for our users, we will be
providing changelogs for our package API going forwards. The hope is that these
changes will provide a better long-term experience for our users and allow to
stabilize the API in the future. #121 now tracks this piece of work.
- Bumped the minimum required Go version to 1.23 (#2059 by @pd93).
task.InitTaskfile
(#2011, ff8c913 by @HeCorr and @pd93)- No longer accepts an
io.Writer(output is now the caller's
responsibility). - The path argument can now be a filename OR a directory.
- The function now returns the full path of the generated file.
- No longer accepts an
TaskfileDecodeError.WithFileInfo
now accepts a string instead of the arguments required to generate a snippet
(#2068 by @pd93).- The caller is now expected to create the snippet themselves (see below).
TaskfileSnippet
and related code moved from theerrorspackage to thetaskfilepackage
(#2068 by @pd93).- Renamed
TaskMissingRequiredVarstoTaskMissingRequiredVarsError
(#2052 by @vmaerten). - Renamed
TaskNotAllowedVarstoTaskNotAllowedVarsError
(#2052 by @vmaerten). - The
taskfile.Reader
is now constructed using the functional options pattern (#2082 by @pd93). - Removed our internal
logger.Loggerfrom the entiretaskfilepackage (#2082
by @pd93).- Users are now expected to pass a custom debug/prompt functions into
taskfile.Reader
if they want this functionality by using the newWithDebugFunc
andWithPromptFunc
functional options.
- Users are now expected to pass a custom debug/prompt functions into
- Remove
Rangefunctions in thetaskfile/astpackage in favour of new
iterator functions (#1798 by @pd93). ast.Callwas moved from thetaskfile/astpackage to the maintask
package (#2084 by @pd93).ast.Tasks.FindMatchingTaskswas moved from thetaskfile/astpackage to thetask.Executor.FindMatchingTasksin the maintaskpackage (#2084 by @pd93).- The
Compilerand itsGetVariablesandFastGetVariablesmethods were
moved from theinternal/compilerpackage to the maintaskpackage (#2084
by @pd93).
v3.41.0 - 2025-01-18
- Fixed an issue where dynamic variables were not properly logged in verbose
mode (#1920, #1921 by @mgbowman). - Support
silentfor defer statements (#1877, #1879 by @danilobuerger). - Added an option to exclude some tasks from being included (#1859 by
@vmaerten). - Fixed an issue where a required variable was incorrectly handled in a template
function (#1950, #1962 by @vmaerten). - Expose a new
TASK_DIRspecial variable, which will contain the absolute path
of task directory. (#1959, #1961 by @vmaerten). - Fixed fatal bugs that caused concurrent map writes (#1605, #1972, #1974 by
@pd93, @GrahamDennis and @trim21). - Refactored internal ordered map implementation to use
github.com/elliotchance/orderedmap
(#1797 by @pd93). - Fixed a bug where variables defined at the task level were being ignored in
therequiressection. (#1960, #1955, #1768 by @vmaerten and @mokeko) - The
CHECKSUMandTIMESTAMPvariables are now accessible withincmds
(#1872 by @niklasr22). - Updated installation docs and added pip
installation method (#935, #1989 by @pd93). - Fixed a bug where dynamic variables could not access environment variables
(#630, #1869 by @rohm1 and @pd93). - Disable version check for use as an external library (#1938 by @leaanthony).
v3.40.1 - 2024-12-06
- Fixed a security issue in
git-urlsby switching to the maintained forkchainguard-dev/git-urls(#1917 by @AlekSi). - Added missing
platformsproperty tocmdsthat usefor(#1915 by
@dkarter). - Added misspell linter to check for misspelled English words (#1883 by
@christiandins).
v3.40.0 - 2024-11-05
- Fixed output of some functions (e.g.
splitArgs/splitLines) not working in
for loops (#1822, #1823 by @stawii). - Added a new
TASK_OFFLINEenvironment variable to configure the--offline
flag and expose it as a special variable in the templating system (#1470,
#1716 by @vmaerten and @pd93). - Fixed a bug where multiple remote includes caused all prompts to display
without waiting for user input (#1832, #1833 by @vmaerten and @pd93). - When using the
"Remote Taskfiles".
experiment, you can now include Taskfiles from Git repositories (#1652 by
@vmaerten). - Improved the error message when a dotenv file cannot be parsed (#1842 by
@pbitty). - Fix issue with directory when using the remote experiment (#1757 by @pbitty).
- Fixed an issue where a special variable was used in combination with a dotenv
file (#1232, #1810 by @vmaerten). - Refactor the way Task reads Taskfiles to improve readability (#1771 by
@pbitty). - Added a new option to ensure variable is within the list of values (#1827 by
@vmaerten). - Allow multiple prompts to be specified for a task (#1861, #1866 by @mfbmina).
- Added new template function:
numCPU, which returns the number of logical
CPUs usable (#1890, #1887 by @Amoghrd). - Fixed a bug where non-nil, empty dynamic variables are returned as an empty
interface (#1903, #1904 by @pd93).
v3.39.2 - 2024-09-19
- Fix dynamic variables not working properly for a defer: statement (#1803,
#1818 by @vmaerten).
v3.39.1 - 2024-09-18
- Added Renovate configuration to automatically create PRs to keep dependencies
up to date (#1783 by @vmaerten). - Fixed a bug where the help was displayed twice (#1805, #1806 by @vmaerten).
- Fixed a bug where ZSH and PowerShell completions did not work when using the
recommended method. (#1813, #1809 by @vmaerten and @shirayu) - Fix variables not working properly for a
defer:statement (#1803, #1814 by
@vmaerten and @andreynering).
v3.39.0 - 2024-09-07
- Added
Env Precedence Experiment
(#1038, #1633 by @vmaerten). - Added a CI lint job to ensure that the docs are updated correctly (#1719 by
@vmaerten). - Updated minimum required Go version to 1.22 (#1758 by @pd93).
- Expose a new
EXIT_CODEspecial variable ondefer:when a command finishes
with a non-zero exit code (#1484, #1762 by @dorimon-1 and @andreynering). - Expose a new
ALIASspecial variable, which will contain the alias used to
call the current task. Falls back to the task name. (#1764 by @DanStory). - Fixed
TASK_REMOTE_DIRenvironment variable not working when the path was
absolute. (#1715 by @vmaerten). - Added an option to declare an included Taskfile as flattened (#1704 by
@vmaerten). - Added a new
--completionflag to
output completion scripts for various shells (#293, #1157 by @pd93).- This is now the preferred way to install completions.
- The completion scripts in the
completiondirectory
are now deprecated.
- Added the ability to
loop over a matrix of values
(#1766, #1767, #1784 by @pd93). - Fixed a bug in fish completion where aliases were not displayed (#1781, #1782
by @vmaerten). - Fixed panic when having a flattened included Taskfile that contains a
defaulttask (#1777, #1778 by @vmaerten). - Optimized file existence checks for remote Taskfiles (#1713 by @vmaerten).
v3.38.0 - 2024-06-30
- Added
TASK_EXEspecial variable (#1616, #1624 by @pd93 and @andreynering). - Some YAML parsing errors will now show in a more user friendly way (#1619 by
@pd93). - Prefixed outputs will now be colorized by default (#1572 by
@AlexanderArvidsson) - References are now
generally available (no experiments required) (#1654 by @pd93). - Templating functions can now be used in references (#1645, #1654 by @pd93).
- Added a new
templating reference page to the
documentation (#1614, #1653 by @pd93). - If using the
Map Variables experiment (1),
references are available by
prefixing a string with a#
(#1654 by @pd93). - If using the
Map Variables experiment (2),
theyamlandjsonkeys are no longer available (#1654 by @pd93). - Added a new
TASK_REMOTE_DIRenvironment variable to configure where cached
remote Taskfiles are stored (#1661 by @vmaerten). - Added a new
--clear-cacheflag to clear the cache of remote Taskfiles (#1639
by @vmaerten). - Improved the readability of cached remote Taskfile filenames (#1636 by
@vmaerten). - Starting releasing a binary for the
riscv64architecture on Linux (#1699 by
@mengzhuo). - Added
CLI_SILENTandCLI_VERBOSEvariables (#1480, #1669 by @Vince-Smith). - Fixed a couple of bugs with the
prompt:feature (#1657 by @pd93). - Fixed JSON Schema to disallow invalid properties (#1657 by @pd93).
- Fixed version checks not working as intended (#872, #1663 by @vmaerten).
- Fixed a bug where included tasks were run multiple times even if
run: once
was set (#852, #1655 by @pd93). - Fixed some bugs related to column formatting in the terminal (#1350, #1637,
#1656 by @vmaerten).
v3.37.2 - 2024-05-12
- Fixed a bug where an empty Taskfile would cause a panic (#1648 by @pd93).
- Fixed a bug where includes Taskfile variable were not being merged correctly
(#1643, #1649 by @pd93).
v3.37.1 - 2024-05-09
- Fix bug where non-string values (numbers, bools) added to
env:weren't been
correctly exported (#1640, #1641 by @vmaerten and @andreynering).
v3.37.0 - 2024-05-08
- Released the
Any Variables experiment, but
without support for maps
(#1415, #1547 by @pd93). - Refactored how Task reads, parses and merges Taskfiles using a DAG (#1563,
#1607 by @pd93). - Fix a bug which stopped tasks from using
stdinas input (#1593, #1623 by
@pd93). - Fix error when a file or directory in the project contained a special char
like&,(or)(#1551, #1584 by @andreynering). - Added alias
qfor template functionshellQuote(#1601, #1603 by @vergenzt) - Added support for
~on ZSH completions (#1613 by @jwater7). - Added the ability to pass variables by reference using Go template syntax when
the
Map Variables experiment is
enabled (#1612 by @pd93). - Added support for environment variables in the templating engine in
includes
(#1610 by @vmaerten).
v3.36.0 - 2024-04-08
- Added support for
looping over dependencies
(#1299, #1541 by @pd93). - When using the
"Remote Taskfiles"
experiment, you are now able to use
remote Taskfiles as your entrypoint.includesin remote Taskfiles will now also resolve correctly (#1347 by
@pd93).
- When using the
"Any Variables"
experiments, templating is now supported in collection-type variables (#1477,
#1511, #1526 by @pd93). - Fixed a bug where variables being passed to an included Taskfile were not
available when defining global variables (#1503, #1533 by @pd93). - Improved support to customized colors by allowing 8-bit colors and multiple
ANSI attributes (#1576 by @pd93).
v3.35.1 - 2024-03-04
- Fixed a bug where the
TASKFILE_DIRvariable was sometimes incorrect (#1522,
#1523 by @pd93). - Added a new
TASKFILEspecial variable that holds the root Taskfile path
(#1523 by @pd93). - Fixed various issues related to running a Taskfile from a subdirectory (#1529,
#1530 by @pd93).
v3.35.0 - 2024-02-28
- Added support for
wildcards in task names
(#836, #1489 by @pd93). - Added the ability to
run Taskfiles via stdin
(#655, #1483 by @pd93). - Bumped minimum Go version to 1.21 (#1500 by @pd93).
- Fixed bug related to the
--listflag (#1509, #1512 by @pd93, #1514, #1520 by
@pd93). - Add mention on the documentation to the fact that the variable declaration
order is respected (#1510 by @kirkrodrigues). - Improved style guide docs (#1495 by @iwittkau).
- Removed duplicated entry for
requireson the API docs (#1491 by
@teatimeguest).
v3.34.1 - 2024-01-27
- Fixed prompt regression on
Remote Taskfiles experiment
(#1486, #1487 by @pd93).
v3.34.0 - 2024-01-25
- Removed support for
version: 2schemas. See the
deprecation notice on our website
(#1197, #1447 by @pd93). - Fixed a couple of issues in the JSON Schema + added a CI step to ensure it's
correct (#1471, #1474, #1476 by @sirosen). - Added
Any Variables experiment proposal 2
(#1415, #1444 by @pd93). - Updated the experiments and deprecations documentation format (#1445 by
@pd93). - Added new template function:
spew, which can be used to print variables for
debugging purposes (#1452 by @pd93). - Added new template function:
merge, which can be used to merge any number of
map variables (#1438, #1464 by @pd93). - Small change on the API when using as a library:
call.Directbecamecall.Indirect(#1459 by @pd93). - Refactored the public
readandtaskfilepackages and introducedtaskfile/ast(#1450 by @pd93). ast.IncludedTaskfilesrenamed toast.Includesandorderedmappackage
renamed toomapplus some internal refactor work (#1456 by @pd93).- Fix zsh completion script to allow lowercase
taskfilefile names (#1482 by
@xontab). - Improvements on how we check the Taskfile version (#1465 by @pd93).
- Added a new
ROOT_TASKFILEspecial variable (#1468, #1469 by @pd93). - Fix experiment flags in
.envwhen the--diror--taskfileflags were
used (#1478 by @pd93).
v3.33.1 - 2023-12-21
- Added support for looping over map variables with the
Any Variables experiment
enabled (#1435, #1437 by @pd93). - Fixed a bug where dynamic variables were causing errors during fast
compilation (#1435, #1437 by @pd93)
v3.33.0 - 2023-12-20
- Added
Any Variables experiment
(#1415, #1421 by @pd93). - Updated Docusaurus to v3 (#1432 by @pd93).
- Added
aliasesto--jsonflag output (#1430, #1431 by @pd93). - Added new
CLI_FORCEspecial variable containing whether the--forceor--force-allflags were set (#1412, #1434 by @pd93).
v3.32.0 - 2023-11-29
- Added ability to exclude some files from
sources:by usingexclude:(#225,
#1324 by @pd93 and @andreynering). - The
Remote Taskfiles experiment
now prefers remote files over cached ones by default (#1317, #1345 by @pd93). - Added
--timeoutflag to the
Remote Taskfiles experiment
(#1317, #1345 by @pd93). - Fix bug where dynamic
vars:andenv:were being executed when they should
actually be skipped byplatforms:(#1273, #1377 by @andreynering). - Fix
schema.jsonto makesilentvalid incmdsthat usefor(#1385,
#1386 by @iainvm). - Add new
--no-statusflag to skip expensive status checks when runningtask --list --json(#1348, #1368 by @amancevice).
v3.31.0 - 2023-10-07
- Enabled the
--yesflag for the
Remote Taskfiles experiment
(#1317, #1344 by @pd93). - Add ability to set
watch: truein a task to automatically run it in watch
mode (#231, #1361 by @andreynering). - Fixed a bug on the watch mode where paths that contained
.git(like.github), for example, were also being ignored (#1356 by @butuzov). - Fixed a nil pointer error when running a Taskfile with no contents (#1341,
#1342 by @pd93). - Added a new exit code (107) for when a
Taskfile does not contain a schema version (#1342 by @pd93). - Increased limit of maximum task calls from 100 to 1000 for now, as some people
have been reaching this limit organically now that we have loops. This check
exists to detect recursive calls, but will be removed in favor of a better
algorithm soon (#1321, #1332). - Fixed templating on descriptions on
task --list(#1343 by @blackjid). - Fixed a bug where precondition errors were incorrectly being printed when task
execution was aborted (#1337, #1338 by @sylv-io).
v3.30.1 - 2023-09-14
- Fixed a regression where some special variables weren't being set correctly
(#1331, #1334 by @pd93).
v3.30.0 - 2023-09-13
- Prep work for Remote Taskfiles (#1316 by @pd93).
- Added the
Remote Taskfiles experiment
as a draft (#1152, #1317 by @pd93). - Improve performance of content checksumming on
sources:by replacing md5
with XXH3 which is much faster. This is a soft breaking
change because checksums will be invalidated when upgrading to this release
(#1325 by @ReillyBrogan).
v3.29.1 - 2023-08-26
- Update to Go 1.21 (bump minimum version to 1.20) (#1302 by @pd93)
- Fix a missing a line break on log when using
--watchmode (#1285, #1297 by
@FilipSolich). - Fix
deferon JSON Schema (#1288 by @calvinmclean and @andreynering). - Fix bug in usage of special variables like
{{.USER_WORKING_DIR}}in
combination withincludes(#1046, #1205, #1250, #1293, #1312, #1274 by
@andarto, #1309 by @andreynering). - Fix bug on
--statusflag. Running this flag should not have side-effects: it
should not update the checksum on.task, only report its status (#1305,
#1307 by @visciang, #1313 by @andreynering).
v3.28.0 - 2023-07-24
- Added the ability to
loop over commands and tasks
usingfor(#82, #1220 by @pd93). - Fixed variable propagation in multi-level includes (#778, #996, #1256 by
@hudclark). - Fixed a bug where the
--exit-codecode flag was not returning the correct
exit code when calling commands indirectly (#1266, #1270 by @pd93). - Fixed a
nilpanic when a dependency was commented out or left empty (#1263
by @neomantra).
v3.27.1 - 2023-06-30
- Fix panic when a
.envdirectory (not file) is present on current directory
(#1244, #1245 by @pd93).
v3.27.0 - 2023-06-29
- Allow Taskfiles starting with lowercase characters (#947, #1221 by @pd93).
- e.g.
taskfile.yml,taskfile.yaml,taskfile.dist.yml&taskfile.dist.yaml
- e.g.
- Bug fixes were made to the
npm installation method. (#1190, by
@sounisi5011). - Added the
gentle force experiment as a
draft (#1200, #1216 by @pd93). - Added an
--experimentsflag to allow you to see which experiments are
enabled (#1242 by @pd93). - Added ability to specify which variables are required in a task (#1203, #1204
by @benc-uk).
v3.26.0 - 2023-06-10
- Only rewrite checksum files in
.taskif the checksum has changed (#1185,
#1194 by @deviantintegral). - Added experiments documentation to the
website (#1198 by @pd93). - Deprecated
version: 2schema. This will be removed in the next major release
(#1197, #1198, #1199 by @pd93). - Added a new
prompt:prop to set a warning prompt to be shown before running
a potential dangerous task (#100, #1163 by @MaxCheetham,
Documentation). - Added support for single command task syntax. With this change, it's now
possible to declare justcmd:in a task, avoiding the more complexcmds: []when you have only a single command for that task (#1130, #1131 by
@timdp).
v3.25.0 - 2023-05-22
- Support
silent:when calling another tasks (#680, #1142 by @danquah). - Improve PowerShell completion script (#1168 by @trim21).
- Add more languages to the website menu and show translation progress
percentage (#1173 by @misitebao). - Starting on this release, official binaries for FreeBSD will be available to
download (#1068 by @andreynering). - Fix some errors being unintendedly suppressed (#1134 by @clintmod).
- Fix a nil pointer error when
versionis omitted from a Taskfile (#1148,
#1149 by @pd93). - Fix duplicate error message when a task does not exists (#1141, #1144 by
@pd93).
v3.24.0 - 2023-04-15
- Fix Fish shell completion for tasks with aliases (#1113 by @patricksjackson).
- The default branch was renamed from
mastertomain(#1049, #1048 by
@pd93). - Fix bug where "up-to-date" logs were not being omitted for silent tasks (#546,
#1107 by @danquah). - Add
.hg(Mercurial) to the list of ignored directories when using--watch
(#1098 by @misery). - More improvements to the release tool (#1096 by @pd93).
- Enforce gofumpt linter (#1099 by @pd93)
- Add
--sortflag for use with--listand--list-all(#946, #1105 by
@pd93). - Task now has custom exit codes
depending on the error (#1114 by @pd93).
v3.23.0 - 2023-03-26
Task now has an
official extension for Visual Studio Code
contributed by @pd93! :tada: The extension is maintained in a
new repository under the go-task
organization. We're looking to gather feedback from the community so please give
it a go and let us know what you think via a
discussion,
issue or on our
Discord!
NOTE: The extension requires v3.23.0 to be installed in order to work.
- The website was integrated with
Crowdin to allow the community to
contribute with translations! Chinese is the
first language available (#1057, #1058 by @misitebao). - Added task location data to the
--jsonflag output (#1056 by @pd93) - Change the name of the file generated by
task --initfromTaskfile.yamltoTaskfile.yml(#1062 by @misitebao). - Added new
splitArgstemplate function
({{splitArgs "foo bar 'foo bar baz'"}}) to ensure string is split as
arguments (#1040, #1059 by @dhanusaputra). - Fix the value of
{{.CHECKSUM}}variable in status (#1076, #1080 by @pd93). - Fixed deep copy implementation (#1072 by @pd93)
- Created a tool to assist with releases (#1086 by @pd93).
v3.22.0 - 2023-03-10
- Add a brand new
--global(-g) flag that will run a Taskfile from your$HOMEdirectory. This is useful to have automation that you can run from
anywhere in your system!
(Documentation, #1029
by @andreynering). - Add ability to set
error_only: trueon thegroupoutput mode. This will
instruct Task to only print a command output if it returned with a non-zero
exit code (#664, #1022 by @jaedle). - Fixed bug where
.task/checksumfile was sometimes not being created when
task also declares astatus:(#840, #1035 by @harelwa, #1037 by @pd93). - Refactored and decoupled fingerprinting from the main Task executor (#1039 by
@pd93). - Fixed deadlock issue when using
run: once(#715, #1025 by
@theunrepentantgeek).
v3.21.0 - 2023-02-22
- Added new
TASK_VERSIONspecial variable (#990, #1014 by @ja1code). - Fixed a bug where tasks were sometimes incorrectly marked as internal (#1007
by @pd93). - Update to Go 1.20 (bump minimum version to 1.19) (#1010 by @pd93)
- Added environment variable
FORCE_COLORsupport to force color output. Useful
for environments without TTY (#1003 by @automation-stack)
v3.20.0 - 2023-01-14
- Improve behavior and performance of status checking when using the
timestamp
mode (#976, #977 by @aminya). - Performance optimizations were made for large Taskfiles (#982 by @pd93).
- Add ability to configure options for the
set
andshopt
builtins (#908, #929 by @pd93,
Documentation). - Add new
platforms:attribute totaskandcmd, so it's now possible to
choose in which platforms that given task or command will be run on. Possible
values are operating system (GOOS), architecture (GOARCH) or a combination of
the two. Example:platforms: [linux],platforms: [amd64]orplatforms: [linux/amd64]. Other platforms will be skipped (#978, #980 by
@leaanthony).
v3.19.1 - 2022-12-31
- Small bug fix: closing
Taskfile.ymlonce we're done reading it (#963, #964
by @HeCorr). - Fixes a bug in v2 that caused a panic when using a
Taskfile_{{OS}}.ymlfile
(#961, #971 by @pd93). - Fixed a bug where watch intervals set in the Taskfile were not being respected
(#969, #970 by @pd93) - Add
--jsonflag (alias-j) with the intent to improve support for code
editors and add room to other possible integrations. This is basic for now,
but we plan to add more info in the near future (#936 by @davidalpert, #764).
v3.19.0 - 2022-12-05
- Installation via npm now supports pnpm as well
(go-task/go-npm#2,
go-task/go-npm#3). - It's now possible to run Taskfiles from subdirectories! A new
USER_WORKING_DIRspecial variable was added to add even more flexibility for
monorepos (#289, #920). - Add task-level
dotenvsupport (#389, #904). - It's now possible to use global level variables on
includes(#942, #943). - The website got a brand new
translation to Chinese by
@DeronW. Thanks!
v3.18.0 - 2022-11-12
- Show aliases on
task --list --silent(task --ls). This means that aliases
will be completed by the completion scripts (#919). - Tasks in the root Taskfile will now be displayed first in
--list/--list-alloutput (#806, #890). - It's now possible to call a
defaulttask in an included Taskfile by using
just the namespace. For example:docs:defaultis now automatically aliased
todocs(#661, #815).
v3.17.0 - 2022-10-14
- Add a "Did you mean ...?" suggestion when a task does not exits another one
with a similar name is found (#867, #880). - Now YAML parse errors will print which Taskfile failed to parse (#885, #887).
- Add ability to set
aliasesfor tasks and namespaces (#268, #340, #879). - Improvements to Fish shell completion (#897).
- Added ability to set a different watch interval by setting
interval: '500ms'
or using the--interval=500msflag (#813, #865). - Add colored output to
--list,--list-alland--summaryflags (#845,
#874). - Fix unexpected behavior where
label:was being shown instead of the task
name on--list(#603, #877).
v3.16.0 - 2022-09-29
- Add
npmas new installation method:npm i @go-task/cli(#870, #871,
npm package). - Add support to marking tasks and includes as internal, which will hide them
from--listand--list-all(#818).
v3.15.2 - 2022-09-08
- Fix error when using variable in
env:introduced in the previous release
(#858, #866). - Fix handling of
CLI_ARGS(--) in Bash completion (#863). - On zsh completion, add ability to replace
--list-allwith--listas
already possible on the Bash completion (#861).
v3.15.0 - 2022-09-03
- Add new special variables
ROOT_DIRandTASKFILE_DIR. This was a highly
requested feature (#215, #857,
Documentation). - Follow symlinks on
sources(#826, #831). - Improvements and fixes to Bash completion (#835, #844).
v3.14.1 - 2022-08-03
- Always resolve relative include paths relative to the including Taskfile
(#822, #823). - Fix ZSH and PowerShell completions to consider all tasks instead of just the
public ones (those with descriptions) (#803).
v3.14.0 - 2022-07-08
- Add ability to override the
.taskdirectory location with theTASK_TEMP_DIRenvironment variable. - Allow to override Task colors using environment variables:
TASK_COLOR_RESET,TASK_COLOR_BLUE,TASK_COLOR_GREEN,TASK_COLOR_CYAN,TASK_COLOR_YELLOW,TASK_COLOR_MAGENTAandTASK_COLOR_RED(#568, #792). - Fixed bug when using the
output: groupmode where STDOUT and STDERR were
being print in separated blocks instead of in the right order (#779). - Starting on this release, ARM architecture binaries are been released to Snap
as well (#795). - i386 binaries won't be available anymore on Snap because Ubuntu removed the
support for this architecture. - Upgrade mvdan.cc/sh, which fixes a bug with associative arrays (#785,
mvdan/sh#884,
mvdan/sh#893).
v3.13.0 - 2022-06-13
- Added
-nas an alias to--dry(#776, #777). - Fix behavior of interrupt (SIGINT, SIGTERM) signals. Task will now give time
for the processes running to do cleanup work (#458, #479, #728, #769). - Add new
--exit-code(-x) flag that will pass-through the exit form the
command being ran (#755).
v3.12.1 - 2022-05-10
- Fixed bug where, on Windows, variables were ending with
\rbecause we were
only removing the final\nbut not\r\n(#717).
v3.12.0 - 2022-03-31
- The
--listand--list-allflags can now be combined with the--silent
flag to print the task names only, without their description (#691). - Added support for multi-level inclusion of Taskfiles. This means that included
Taskfiles can also include other Taskfiles. Before this was limited to one
level (#390, #623, #656). - Add ability to specify vars when including a Taskfile.
Check out the documentation
for more information (#677).
v3.11.0 - 2022-02-19
- Task now supports printing begin and end messages when using the
group
output mode, useful for grouping tasks in CI systems.
Check out the documentation
for more information (#647, #651). - Add
Taskfile.dist.ymlandTaskfile.dist.yamlto the supported file name
list.
Check out the documentation
for more information (#498, #666).
v3.10.0 - 2022-01-04
- A new
--list-all(alias-a) flag is now available. It's similar to the
exiting--list(-l) but prints all tasks, even those without a description
(#383, #401). - It's now possible to schedule cleanup commands to run once a task finishes
with thedefer:keyword
(Documentation,
#475, #626). - Remove long deprecated and undocumented
$variable prefix and^command
prefix (#642, #644, #645). - Add support for
.yamlextension (as an alternative to.yml). This was
requested multiple times throughout the years. Enjoy! (#183, #184, #369, #584,
#621). - Fixed error when computing a variable when the task directory do not exist yet
(#481, #579).
v3.9.2 - 2021-12-02
- Upgrade mvdan/sh which contains a fix a for a
important regression on Windows (#619,
mvdan/sh#768,
mvdan/sh#769).
v3.9.1 - 2021-11-28
- Add logging in verbose mode for when a task starts and finishes (#533, #588).
- Fix an issue with preconditions and context errors (#597, #598).
- Quote each
{{.CLI_ARGS}}argument to prevent one with spaces to become many
(#613). - Fix nil pointer when
cmd:was left empty (#612, #614). - Upgrade mvdan/sh which contains two relevant
fixes:- Fix quote of empty strings in
shellQuote(#609,
mvdan/sh#763). - Fix issue of wrong environment variable being picked when there's another
very similar one (#586,
mvdan/sh#745).
- Fix quote of empty strings in
- Install shell completions automatically when installing via Homebrew (#264,
#592,
go-task/homebrew-tap#2).
v3.9.0 - 2021-10-02
- A new
shellQuotefunction was added to the template system
({{shellQuote "a string"}}) to ensure a string is safe for use in shell
(mvdan/sh#727,
mvdan/sh#737,
Documentation) - In this version mvdan.cc/sh was upgraded with
some small fixes and features- The
read -pflag is now supported (#314,
mvdan/sh#551,
mvdan/sh#772) - The
pwd -Pandpwd -Lflags are now supported (#553,
mvdan/sh#724,
mvdan/sh#728) - The
$GIDenvironment variable is now correctly being set (#561,
mvdan/sh#723)
- The
v3.8.0 - 2021-09-26
- Add
interactive: truesetting to improve support for interactive CLI apps
(#217, #563). - Fix some
nilerrors (#534, #573). - Add ability to declare an included Taskfile as optional (#519, #552).
- Add support for including Taskfiles in the home directory by using
~(#539,
#557).
v3.7.3 - 2021-09-04
- Add official support to Apple M1 (#564, #567).
- Our official Homebrew tap will
support more platforms, including Apple M1
v3.7.0 - 2021-07-31
- Add
run:setting to control if tasks should run multiple times or not.
Available options arealways(the default),when_changed(if a variable
modified the task) andonce(run only once no matter what). This is a long
time requested feature. Enjoy! (#53, #359).
v3.6.0 - 2021-07-10
- Allow using both
sources:andstatus:in the same task (#411, #427, #477). - Small optimization and bug fix: don't compute variables if not needed for
dotenv:(#517).
v3.5.0 - 2021-07-04
- Add support for interpolation in
dotenv:(#433, #434, #453).
v3.4.3 - 2021-05-30
- Add support for the
NO_COLORenvironment variable. (#459,
fatih/color#137). - Fix bug where sources were not considering the right directory in
--watch
mode (#484, #485).
v3.4.2 - 2021-04-23
- On watch, report which file failed to read (#472).
- Do not try to catch SIGKILL signal, which are not actually possible (#476).
- Improve version reporting when building Task from source using Go Modules
(#462, #473).
v3.4.1 - 2021-04-17
- Improve error reporting when parsing YAML: in some situations where you would
just see an generic error, you'll now see the actual error with more detail:
the YAML line the failed to parse, for example (#467). - A JSON Schema was published here
and is automatically being used by some editors like Visual Studio Code
(#135). - Print task name before the command in the log output (#398).
v3.3.0 - 2021-03-20
- Add support for delegating CLI arguments to commands with
--and a specialCLI_ARGSvariable (#327). - Add a
--concurrency(alias-C) flag, to limit the number of tasks that run
concurrently. This is useful for heavy workloads. (#345).
v3.2.2 - 2021-01-12
- Improve performance of
--listand--summaryby skipping running shell
variables for these flags (#332). - Fixed a bug where an environment in a Taskfile was not always overridable by
the system environment (#425). - Fixed environment from .env files not being available as variables (#379).
- The install script is now working for ARM platforms (#428).
v3.2.1 - 2021-01-09
- Fixed some bugs and regressions regarding dynamic variables and directories
(#426). - The slim-sprig package was updated
with the upstream sprig.
v3.2.0 - 2021-01-07
- Fix the
.taskdirectory being created in the task directory instead of the
Taskfile directory (#247). - Fix a bug where dynamic variables (those declared with
sh:) were not running
in the task directory when the task has a custom dir or it was in an included
Taskfile (#384). - The watch feature (via the
--watchflag) got a few different bug fixes and
should be more stable now (#423, #365).
v3.1.0 - 2021-01-03
- Fix a bug when the checksum up-to-date resolution is used by a task with a
customlabel:attribute (#412). - Starting from this release, we're releasing official ARMv6 and ARM64 binaries
for Linux (#375, #418). - Task now respects the order of declaration of included Taskfiles when
evaluating variables declaring by them (#393). set -eis now automatically set on every command. This was done to fix an
issue where multiline string commands wouldn't really fail unless the sentence
was in the last line (#403).
v3.0.1 - 2020-12-26
- Allow use as a library by moving the required packages out of the
internal
directory (#358). - Do not error if a specified dotenv file does not exist (#378, #385).
- Fix panic when you have empty tasks in your Taskfile (#338, #362).
v3.0.0 - 2020-08-16
- On
v3, all CLI variables will be considered global variables (#336, #341) - Add support to
.envlike files (#324, #356). - Add
label:to task so you can override the task name in the logs (#321,
#337). - Refactor how variables work on version 3 (#311).
- Disallow
expansionson v3 since it has no effect. Taskvars.ymlis not automatically included anymore.Taskfile_{{OS}}.ymlis not automatically included anymore.- Allow interpolation on
includes, so you can manually include a Taskfile
based on operation system, for example. - Expose
.TASKvariable in templates with the task name (#252). - Implement short task syntax (#194, #240).
- Added option to make included Taskfile run commands on its own directory
(#260, #144) - Taskfiles in version 1 are not supported anymore (#237).
- Added global
method:option. With this option, you can set a default method
to all tasks in a Taskfile (#246). - Changed default method from
timestamptochecksum(#246). - New magic variables are now available when using
status::.TIMESTAMPwhich
contains the greatest modification date from the files listed insources:,
and.CHECKSUM, which contains a checksum of all files listed instatus:.
This is useful for manual checking when using external, or even remote,
artifacts when usingstatus:(#216). - We're now using slim-sprig instead of
sprig, which allowed a file size
reduction of about 22% (#219). - We now use some colors on Task output to better distinguish message types -
commands are green, errors are red, etc (#207).
v2.8.1 - 2020-05-20
- Fix error code for the
--helpflag (#300, #330). - Print version to stdout instead of stderr (#299, #329).
- Suppress
contexterrors when using the--watchflag (#313, #317). - Support templating on description (#276, #283).
v2.8.0 - 2019-12-07
- Add
--parallelflag (alias-p) to run tasks given by the command line in
parallel (#266). - Fixed bug where calling the
taskCLI only informing global vars would not
execute thedefaulttask. - Add ability to silent all tasks by adding
silent: truea the root of the
Taskfile.
v2.7.1 - 2019-11-10
- Fix error being raised when
exit 0was called (#251).
v2.7.0 - 2019-09-22
- Fixed panic bug when assigning a global variable (#229, #243).
- A task with
method: checksumwill now re-run if generated files are deleted
(#228, #238).
v2.6.0 - 2019-07-21
- Fixed some bugs regarding minor version checks on
version:. - Add
preconditions:to task (#205). - Create directory informed on
dir:if it doesn't exist (#209, #211). - We now have a
--taskfileflag (alias-t), which can be used to run another
Taskfile (other than the defaultTaskfile.yml) (#221). - It's now possible to install Task using Homebrew on Linux
(go-task/homebrew-tap#1).
v2.5.2 - 2019-05-11
- Reverted YAML upgrade due issues with CRLF on Windows (#201,
go-yaml/yaml#450). - Allow setting global variables through the CLI (#192).
2.5.1 - 2019-04-27
- Fixed some issues with interactive command line tools, where sometimes the
output were not being shown, and similar issues (#114, #190, #200). - Upgraded go-yaml/yaml from v2 to v3.
v2.5.0 - 2019-03-16
- We moved from the taskfile.org domain to the new fancy taskfile.dev domain.
While stuff is being redirected, we strongly recommend to everyone that use
this install script
to use the new taskfile.dev domain on scripts from now on. - Fixed to the ZSH completion (#182).
- Add
--summaryflag along withsummary:task attribute
(#180).
v2.4.0 - 2019-02-21
- Allow calling a task of the root Taskfile from an included Taskfile by
prefixing it with:(#161, #172). - Add flag to override the
outputoption (#173). - Fix bug where Task was persisting the new checksum on the disk when the Dry
Mode is enabled (#166). - Fix file timestamp issue when the file name has spaces (#176).
- Mitigating path expanding issues on Windows (#170).
v2.3.0 - 2019-01-02
- On Windows, Task can now be installed using Scoop (#152).
- Fixed issue with file/directory globing (#153).
- Added ability to globally set environment variables (#138, #159).
v2.2.1 - 2018-12-09
- This repository now uses Go Modules (#143). We'll still keep the
vendor
directory in sync for some time, though; - Fixing a bug when the Taskfile has no tasks but includes another Taskfile
(#150); - Fix a bug when calling another task or a dependency in an included Taskfile
(#151).
v2.2.0 - 2018-10-25
- Added support for
including other Taskfiles
(#98)- This should be considered experimental. For now, only including local files
is supported, but support for including remote Taskfiles is being discussed.
If you have any feedback, please comment on #98.
- This should be considered experimental. For now, only including local files
- Task now have a dedicated documentation site: https://taskfile.org
v2.1.1 - 2018-09-17
- Fix suggestion to use
task --initnot being shown anymore (when aTaskfile.ymlis not found) - Fix error when using checksum method and no file exists for a source glob
(#131) - Fix signal handling when the
--watchflag is given (#132)
v2.1.0 - 2018-08-19
- Add a
ignore_erroroption to task and command (#123) - Add a dry run mode (
--dryflag) (#126)
v2.0.3 - 2018-06-24
- Expand environment variables on "dir", "sources" and "generates" (#116)
- Fix YAML merging syntax (#112)
- Add ZSH completion (#111)
- Implement new
outputoption. Please check out the
documentation
v2.0.2 - 2018-05-01
- Fix merging of YAML anchors (#112)
v2.0.1 - 2018-03-11
- Fixes panic on
task --list
v2.0.0 - 2018-03-08
Version 2.0.0 is here, with a new Taskfile format.
Please, make sure to read the
Taskfile versions
document, since it describes in depth what changed for this version.
- New Taskfile version 2 (#77)
- Possibility to have global variables in the
Taskfile.ymlinstead ofTaskvars.yml(#66) - Small improvements and fixes
v1.4.4 - 2017-11-19
- Handle SIGINT and SIGTERM (#75);
- List: print message with there's no task with description;
- Expand home dir ("~" symbol) on paths (#74);
- Add Snap as an installation method;
- Move examples to its own repo;
- Watch: also walk on tasks called on on "cmds", and not only on "deps";
- Print logs to stderr instead of stdout (#68);
- Remove deprecated
setkeyword; - Add checksum based status check, alternative to timestamp based.
v1.4.3 - 2017-09-07
- Allow assigning variables to tasks at run time via CLI (#33)
- Added support for multiline variables from sh (#64)
- Fixes env: remove square braces and evaluate shell (#62)
- Watch: change watch library and few fixes and improvements
- When use watching, cancel and restart long running process on file change (#59
and #60)
v1.4.2 - 2017-07-30
- Flag to set directory of execution
- Always echo command if is verbose mode
- Add silent mode to disable echoing of commands
- Fixes and improvements of variables (#56)
v1.4.1 - 2017-07-15
- Allow use of YAML for dynamic variables instead of $ prefix
VAR: {sh: echo Hello}instead ofVAR: $echo Hello
- Add
--list(or-l) flag to print existing tasks - OS specific Taskvars file (e.g.
Taskvars_windows.yml,Taskvars_linux.yml,
etc) - Consider task up-to-date on equal timestamps (#49)
- Allow absolute path in generates section (#48)
- Bugfix: allow templating when calling deps (#42)
- Fix panic for invalid task in cyclic dep detection
- Better error output for dynamic variables in Taskvars.yml (#41)
- Allow template evaluation in parameters
v1.4.0 - 2017-07-06
- Cache dynamic variables
- Add verbose mode (
-vflag) - Support to task parameters (overriding vars) (#31) (#32)
- Print command, also when "set:" is specified (#35)
- Improve task command help text (#35)
v1.3.1 - 2017-06-14
- Fix glob not working on commands (#28)
- Add ExeExt template function
- Add
--initflag to create a new Taskfile - Add status option to prevent task from running (#27)
- Allow interpolation on
generatesandsourcesattributes (#26)
v1.3.0 - 2017-04-24
- Migrate from os/exec.Cmd to a native Go sh/bash interpreter
- This is a potentially breaking change if you use Windows.
- Now,
cmdis not used anymore on Windows. Always use Bash-like syntax for
your commands, even on Windows.
- Add "ToSlash" and "FromSlash" to template functions
- Use functions defined on github.com/Masterminds/sprig
- Do not redirect stdin while running variables commands
- Using
contextanderrgrouppackages (this will make other tasks to be
cancelled, if one returned an error)
v1.2.0 - 2017-04-02
- More tests and Travis integration
- Watch a task (experimental)
- Possibility to call another task
- Fix "=" not being recognized in variables/environment variables
- Tasks can now have a description, and help will print them (#10)
- Task dependencies now run concurrently
- Support for a default task (#16)
v1.1.0 - 2017-03-08
- Support for YAML, TOML and JSON (#1)
- Support running command in another directory (#4)
--forceor-fflag to force execution of task even when it's up-to-date- Detection of cyclic dependencies (#5)
- Support for variables (#6, #9, #14)
- Operation System specific commands and variables (#13)
v1.0.0 - 2017-02-28
- Add LICENSE file
:::
Website Src Next Docs Community (`website/src/next/docs/community.md`)
title: Community Task community contributions, installation methods, and integrations maintained by third parties section: Project docType: project outline: deep
Community
Some of the work to improve the Task ecosystem is done by the community, be it
installation methods or integrations with code editor. I (the author) am
thankful for everyone that helps me to improve the overall experience.
Integrations
Many of our integrations are contributed and maintained by the community. You
can view the full list of community integrations
here.
Installation methods
Some installation methods are maintained by third party:
More
Also, thanks for all the
code contributors,
financial contributors, all those who
reported bugs and
answered questions.
If you know something that is missing in this document, please submit a pull
request.
Website Src Next Docs Contributing (`website/src/next/docs/contributing.md`)
title: Contributing Comprehensive guide for contributing to the Task project, including setup, development, testing, and submitting PRs section: Contributing docType: contributing outline: deep
Contributing
Thank you for your interest in contributing to Task! We welcome and appreciate
all forms of contributions, but we kindly ask that you read this document first.
If you have any questions that were not answered by this document, you can reach
out on our Discord or by opening a discussion
on GitHub. If you want to help, but you're not sure where to start, you can
check out our list of
good first issues.
::: info
This document applies to the core Task repository and Task for Visual
Studio Code.
:::
AI Usage Policy
When using AI tools (including LLMs like ChatGPT, Claude, Copilot, etc.) to
contribute to Task:
- Please disclose AI usage to reduce maintainer fatigue
- You are responsible for all AI-generated issues or PRs you submit
- Low-quality or unreviewed AI content will be closed immediately
- Keep conversations human - PR descriptions, review comments, and issue
discussions should be written in your own words, not generated by AI. Code
review is a discussion between people, not bots.
We encourage the use of AI tools to assist with development, but all
contributions must be thoroughly reviewed and tested by the contributor before
submission. AI-generated code should be understood, validated, and adapted to
meet Task's standards.
Before you start
- Check existing work - Is there an existing PR? Are there issues discussing
the feature/change you want to make? Please make sure you consider/address
these discussions in your work. - Backwards compatibility - Will your change break existing Taskfiles? It is
much more likely that your change will merged if it backwards compatible. Is
there an approach you can take that maintains this compatibility? If not,
consider opening an issue first so that API changes can be discussed before
you invest your time into a PR. - Experiments - If there is no way to make your change backward compatible
then there is a procedure to introduce breaking changes into minor versions.
We call these "experiments". If you're intending to work on an
experiment, then please read the experiments workflow
document carefully and submit a proposal first.
1. Setup
The easiest way to install everything you need to work on Task is mise.
From the repository root, run:
mise installThis installs the pinned versions of Go, Node.js, pnpm and the dev tools
(golangci-lint, mockery, gotestsum, goreleaser and gorelease) declared
in the mise.toml file.
If you'd rather install things manually, you'll need:
- Go - Task is written in Go. We always support the latest two major
Go versions, so make sure your version is recent enough. - Node.js - Node.js is used to host Task's documentation server
and is required if you want to run this server locally. It is also required if
you want to contribute to the Visual Studio Code extension. - Pnpm - Pnpm is the Node.js package manager used by Task.
2. Making changes
- Code style - Try to maintain the existing code style where possible. Go
code should be formatted and linted bygolangci-lint. This
wraps thegofumptandgciformatters and a number of
linters. We recommend that you take a look at the golangci-lint
docs for a guide on how to setup your editor to
auto-format your code. Any Markdown or TypeScript files should be formatted
and linted by Prettier. This style is enforced by our CI to ensure
that we have a consistent style across the project. You can use thetask lintcommand to lint the code locally and thetask lint:fixcommand
to try to automatically fix any issues that are found. You can also use thetask fmtcommand to auto-format the files if your editor doesn't do it for
you. - Documentation - Ensure that you add/update any relevant documentation. See
the updating documentation section below. - Tests - Ensure that you add/update any relevant tests and that all tests
are passing before submitting the PR. See the writing tests
section below.
Running your changes
To run Task with working changes, you can use go run ./cmd/task. To run a
development build of task against a test Taskfile in testdata, you can usego run ./cmd/task --dir ./testdata/<my_test_dir> <task_name>.
To run Task for Visual Studio Code, you can open the project in VSCode and hit
F5 (or whatever you debug keybind is set to). This will open a new VSCode window
with the extension running. Debugging this way is recommended as it will allow
you to set breakpoints and step through the code. Otherwise, you can runtask package which will generate a .vsix file that can be used to manually
install the extension.
Updating documentation
Task uses Vitepress to host a documentation server. The code for
this is located in the core Task repository. This can be setup and run locally
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 inwebsite/patches/ to resolve links before it moves directory indexes such asdocs/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 is necessary. This document contains descriptions and
examples of how to use Task features. If you're adding a new feature, try to
find an appropriate place to add a new section. If you're updating an existing
feature, ensure that the documentation and any examples are up-to-date. Ensure
that any examples follow the Taskfile Styleguide.
If you added a new command or flag, ensure that you add it to the CLI
Reference. New fields also need to be added to the Schema
Reference and JSON Schema. The descriptions
for fields in the docs and the schema should match.
Documentation channels
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 andsrc/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.
Write in website/src/next. It holds the upcoming release, andcmd/release copies it over website/src/latest at every release. The same
split applies to the JSON schemas: edit next-schema.json andnext-schema-taskrc.json, never schema.json or schema-taskrc.json.
Where you put a blog post decides when it goes out. A post that announces a
feature belongs in website/src/next/blog alone: it ships with the release that
carries the feature. A post that stands on its own - an announcement, a write-up
about an already released feature - can be added to website/src/latest/blog as
well, and it goes live at the next deploy. Its sidebar entry comes from the
post's own frontmatter, so there is nothing else to update.
Never edit an existing file under website/src/latest: cmd/release overwrites
that directory at every release, so the change would be silently lost. The same
goes for .vitepress/sidebar/latest.ts, which is promoted from next.ts. CI
fails a pull request that modifies either. Adding a file underwebsite/src/latest is fine - that is how a blog post gets published early.
To preview what taskfile.dev will look like, run task website:start:latest. It
serves the latest channel on port 3002, so it can run next to task website
and the version selector switches between the two.
Writing tests
A lot of Task's tests are held in the task_test.go file in the project root
and this is where you'll most likely want to add new ones too. Most of these
tests also have a subdirectory in the testdata directory where any
Taskfiles/data required to run the tests are stored.
When making a changes, consider whether new tests are required. These tests
should ensure that the functionality you are adding will continue to work in the
future. Existing tests may also need updating if you have changed Task's
behavior.
You may also consider adding unit tests for any new functions you have added.
The unit tests should follow the Go convention of being location in a file named*_test.go in the same package as the code being tested.
3. Committing your code
Try to write meaningful commit messages and avoid having too many commits on the
PR. Most PRs should likely have a single commit (although for bigger PRs it may
be reasonable to split it in a few). Git squash and rebase is your friend!
If you're not sure how to format your commit message, check out Conventional
Commits. This style is not enforced, but it is a good way
to make your commit messages more readable and consistent.
4. Submitting a PR
- Describe your changes - Ensure that you provide a comprehensive
description of your changes. - Issue/PR links - Link any previous work such as related issues or PRs.
Please describe how your changes differ to/extend this work. - Examples - Add any examples or screenshots that you think are useful to
demonstrate the effect of your changes. - Draft PRs - If your changes are incomplete, but you would like to discuss
them, open the PR as a draft and add a comment to start a discussion. Using
comments rather than the PR description allows the description to be updated
later while preserving any discussions.
FAQ
I want to contribute, where do I start?
Take a look at the list of open issues for Task or Task for
Visual Studio Code. We have a good first
issue label for simpler issues that are ideal for first time
contributions.
All kinds of contributions are welcome, whether its a typo fix or a shiny new
feature. You can also contribute by upvoting/commenting on issues, helping to
answer questions or contributing to other community projects.
I'm stuck, where can I get help?
If you have questions, feel free to ask them in the #help forum channel on our
Discord server or open a Discussion on GitHub.
Website Src Next Docs Faq (`website/src/next/docs/faq.md`)
title: FAQ Frequently asked questions about Task, including ETAs, shell limitations, and Windows compatibility section: Project docType: project outline: deep
FAQ
This page contains a list of frequently asked questions about Task.
When will \ be released? / ETAs
Task is free and open source project maintained by a small group of
volunteers with full time jobs and lives outside of the project. Because of
this, it is difficult to predict how much time we will be able to dedicate to
the project in advance and we don't want to make any promises that we can't
keep. For this reason, we are unable to provide ETAs for new features or
releases. We make a "best effort" to provide regular releases and fix bugs in a
timely fashion, but sometimes our personal lives must take priority.
ETAs are probably the number one question we (and maintainers of other open
source projects) get asked. We understand that you are passionate about the
project, but it can be overwhelming to be asked this question so often. Please
be patient and avoid asking for ETAs.
The best way to speed things up is to contribute to the project yourself. We
always appreciate new contributors. If you are interested in contributing, check
out the contributing guide.
Why won't my task update my shell environment?
This is a limitation of how shells work. Task runs as a subprocess of your
current shell, so it can't change the environment of the shell that started it.
This limitation is shared by other task runners and build tools too.
A common way to work around this is to create a task that will generate output
that can be parsed by your shell. For example, to set an environment variable on
your shell you can write a task like this:
my-shell-env:
cmds:
- echo "export FOO=foo"
- echo "export BAR=bar"Now run eval $(task my-shell-env) and the variables $FOO and $BAR will be
available in your shell.
I can't reuse my shell in a task's commands
Task runs each command as a separate shell process, so something you do in one
command won't effect any future commands. For example, this won't work:
version: '3'
tasks:
foo:
cmds:
- a=foo
- echo $a
# outputs ""To work around this you can either use a multiline command:
version: '3'
tasks:
foo:
cmds:
- |
a=foo
echo $a
# outputs "foo"Or for more complex multi-line commands it is recommended to move your code into
a separate file and call that instead:
version: '3'
tasks:
foo:
cmds:
- ./foo-printer.bash#!/bin/bash
a=foo
echo $aAre shell core utilities available on Windows?
The most common ones, yes. And we might add more in the future.
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
environment variable:
# Enable, even on non-Windows platforms
env TASK_CORE_UTILS=1 task ...
# Disable, even on Windows
env TASK_CORE_UTILS=0 task ...This is the list of core utils that are currently available:
base64catchmodcpfindgziplsmkdirmktempmvrmshasumtartouchxargs- (more might be added in the future)
Website Src Next Docs Installation (`website/src/next/docs/installation.md`)
title: Installation section: Getting Started docType: guide outline: deep pageClass: installation-page
Installation
Choose a package manager for your system, or install Task from a binary.
Official packages {#official-package-managers}
Maintained by the Task team and kept up-to-date.
[Homebrew](https://brew.sh) {#homebrew}
Tap source
Homebrew package
Formula source
brew install go-task/tap/go-taskOr use the Homebrew core formula:
brew install go-task[dnf](https://docs.fedoraproject.org/en-US/quick-docs/dnf) {#dnf}
Set up the repository:
curl -1sLf 'https://dl.cloudsmith.io/public/task/task/setup.rpm.sh' | sudo -E bashInstall Task:
dnf install task[apt](https://doc.ubuntu-fr.org/apt) {#apt}
Set up the repository:
curl -1sLf 'https://dl.cloudsmith.io/public/task/task/setup.deb.sh' | sudo -E bashInstall Task:
apt install task[apk](https://wiki.alpinelinux.org/wiki/Alpine_Package_Keeper) {#apk}
Set up the repository:
curl -1sLf 'https://dl.cloudsmith.io/public/task/task/setup.alpine.sh' | sudo -E bashInstall Task:
apk add task[Snap](https://snapcraft.io/task) {#snap}
sudo snap install task --classicRequires a Linux distribution with classic confinement support.
[npm](https://www.npmjs.com) {#npm}
npm install @go-task/cliTask is also available as a project dependency.
[WinGet](https://github.com/microsoft/winget-cli) {#winget}
winget install Task.TaskAvailable through the
WinGet community repository.
Package repository hosting for deb/rpm/apk is graciously provided by Cloudsmith.
Community packages {#community-maintained-package-managers}
Maintained by the community, outside the Task team's control. These packages may
lag behind the latest release.
[Mise](https://mise.jdx.dev/) {#mise}
mise use -g taskFor a project-local installation, use mise use task instead. This adds Task to
your project's mise.toml.
[Macports](https://macports.org) {#macports}
port install go-task[pip](https://pip.pypa.io) {#pip}
pip install go-task-bin[Chocolatey](https://chocolatey.org) {#chocolatey}
choco install go-task[Scoop](https://scoop.sh) {#scoop}
scoop install taskArch ([pacman](https://wiki.archlinux.org/title/Pacman)) {#arch}
pacman -S go-taskFedora ([dnf](https://docs.fedoraproject.org/en-US/quick-docs/dnf)) {#fedora-community}
dnf install go-taskFreeBSD ([Ports](https://ports.freebsd.org/cgi/ports.cgi)) {#freebsd}
pkg install task[Nix](https://nixos.org) {#nix}
nix-env -iA nixpkgs.go-task[pacstall](https://github.com/pacstall/pacstall) {#pacstall}
pacstall -I go-task-deb[pkgx](https://pkgx.sh) {#pkgx}
pkgx taskor, if you have pkgx integration enabled:
taskBinaries & CI {#get-the-binary}
Install Task without a package manager: download a binary, use the install
script, or add the setup action to your GitHub workflow.
Download a binary {#binary}
- Open the GitHub releases and
download the archive for your operating system and architecture. - Extract
task(task.exeon Windows). - Move the executable to a directory on your
PATH.
Each release also includes DEB, RPM and APK packages, plus task_checksums.txt
with SHA-256 checksums for the release files.
Install with a script {#install-script}
Use the
install script 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
sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -dsh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b ~/.local/binsh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d v3.42.1sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b ~/.local/bin v3.42.1:::
When combining options, keep the
release tag 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
Add the official setup action to your
job's steps before running Task:
- name: Install Task
uses: go-task/setup-task@v2
- name: Verify Task
run: task --versionUse the action's version input to pin a Task release. See the
action documentation for examples
and configuration.
Build from source
Ensure that you have a supported version of Go properly
installed and setup. You can find the minimum required version of Go in the
go.mod file.
You can then install the latest release globally by running:
go install github.com/go-task/task/v3/cmd/task@latestOr you can install into another directory:
env GOBIN=/bin go install github.com/go-task/task/v3/cmd/task@latest::: tip
For CI environments we recommend using the install script
instead, which is faster and more stable, since it'll just download the latest
released binary.
:::
Go Tool
If you're working in a Go project, a nice possibility is using go tool.go tool makes it easy to run Task without needing to install the binary
manually. This works well on CI.
To do that, just run the following to add Task as a tool in your Go project.
Task will be added to your go.mod.
go get -tool github.com/go-task/task/v3/cmd/task@latestThen, prefix go tool when calling Task like below. Go will compile Task on
demand before calling it.
go tool task {arguments...}Verify installation
After installing, open a terminal and check that Task is available:
task --versionIf you installed Task with go tool, run go tool task --version instead.
You're ready to create your first Taskfile. 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.
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 andrequires 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.
::: code-group
# ~/.bashrc
# export TASK_EXE='go-task' if needed
eval "$(task --completion bash)"# ~/.zshrc
# export TASK_EXE='go-task' if needed
eval "$(task --completion zsh)"# ~/.config/fish/config.fish
# export TASK_EXE='go-task' if needed
task --completion fish | source# $PROFILE\Microsoft.PowerShell_profile.ps1
Invoke-Expression (&task --completion powershell | Out-String)# ~/.config/nushell/config.nu
#
# Nushell cannot source a script from stdin, so the script is saved where
# Nushell auto-loads it at startup. Autoload directories are read after
# config.nu, so the completions become available 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"):::
Option 2. Copy the script to your shell's completions directory
This method requires you to manually update the completions whenever Task is
updated. However, it is useful if you want to modify the completions yourself.
::: code-group
task --completion bash > /etc/bash_completion.d/tasktask --completion zsh > /usr/local/share/zsh/site-functions/_tasktask --completion fish > ~/.config/fish/completions/task.fishtask --completion nu | save --force ($nu.data-dir | path join "vendor/autoload/task-completions.nu"):::
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):
zstyle ':completion:*:*:task:*' verbose falseBy default, task aliases are also offered as completions. To complete only the
canonical task names, add the show-aliases zstyle:
zstyle ':completion:*:*:task:*' show-aliases falseNushell caveats
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, and the refreshed completions are
picked up by the next shell. With option 2, re-run the command after upgrading
Task.
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:
$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).
Website Src Next Docs Integrations (`website/src/next/docs/integrations.md`)
title: Integrations Official and community integrations for Task, including VS Code, JSON schemas, and other tools section: Getting Started docType: guide outline: deep
Integrations
Visual Studio Code Extension
Task has an
official extension for Visual Studio Code.
The code for this project can be found in
our GitHub repository. To use this
extension, you must have Task v3.45.3+ installed on your system.
This extension provides the following features (and more):
- View tasks in the sidebar.
- Run tasks from the sidebar and command palette.
- Go to definition from the sidebar and command palette.
- Run last task command.
- Multi-root workspace support.
- Initialize a Taskfile in the current workspace.
To get autocompletion and validation for your Taskfile, see the
Schema section below.
Configuration namespace change
In v1.0.0 of the extension, the configuration namespace was changed from task
to taskfile in order to fix
an issue.
If you receive a warning like the one above, you will need to update your
settings to use the new taskfile namespace instead:
Schema
This was initially created by @KROSF in
this Gist and
is now officially maintained in
this file
and made available at https://taskfile.dev/schema.json. This schema can be used
to validate Taskfiles and provide autocompletion in many code editors:
Visual Studio Code
To integrate the schema into VS Code, you need to install the
YAML extension
by Red Hat. Any Taskfile.yml in your project should automatically be detected
and validation/autocompletion should work. If this doesn't work or you want to
manually configure it for files with a different name, you can add the following
to your settings.json:
// settings.json
{
"yaml.schemas": {
"https://taskfile.dev/schema.json": [
"**/Taskfile.yml",
"./path/to/any/other/taskfile.yml"
]
}
}You can also configure the schema directly inside of a Taskfile by adding the
following comment to the top of the file:
# yaml-language-server: $schema=https://taskfile.dev/schema.json
version: '3'You can find more information on this in the
YAML language server project.
AI/LLM Assistants
Task documentation is optimized for AI assistants like Claude Code, Cursor, and
other LLM-powered development tools through the
VitePress LLMs plugin.
This integration provides:
- Structured documentation in LLM-friendly formats
- Context-optimized content for AI assistants
- Automatic generation of
llms.txtandllms-full.txtfiles - Enhanced discoverability of Task features for AI tools
AI assistants can access Task documentation through:
- llms.txt: Lightweight overview of Task documentation
- llms-full.txt: Complete documentation with all content
These files are automatically generated and kept in sync with the documentation,
ensuring AI assistants always have access to the latest Task features and usage
patterns.
Community Integrations
In addition to our official integrations, there is an amazing community of
developers who have created their own integrations for Task:
- Sublime Text Plugin
[source] by @biozz - IntelliJ Plugin
[source] by @lechuckroh - Zed Extension
[source] by @nickalie - mk command line tool recognizes Taskfiles
natively. - fzf-make fuzzy finder with preview window
for make, pnpm, yarn, just & task.
If you have made something that integrates with Task, please feel free to open a
PR to add it to this list.
Website Src Next Docs Releasing (`website/src/next/docs/releasing.md`)
title: Releasing Task release process including GoReleaser, Homebrew, npm, Snapcraft, winget, and other package managers section: Contributing docType: contributing outline: deep
Releasing
The release process of Task is done with the help of GoReleaser.
You can test the release process locally by calling the goreleaser:test task
of the Taskfile.
GitHub Actions should release
artifacts automatically when a new Git tag is pushed to main branch (raw
executables and DEB and RPM packages).
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 inwebsite/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:
git checkout main && git pull
task website:deploy:prodPackage managers
GoReleaser will automatically publish the release to most package managers:
- Cloudsmith (DEB and RPM repositories)
- Homebrew
- npm
- Snapcraft
- winget
Once the release is published, GoReleaser announces it on the
Discord server. Nightly releases are not
announced.
These package managers are updated automatically by the community:
Website Src Next Docs Remote Taskfiles (`website/src/next/docs/remote-taskfiles.md`)
title: Remote Taskfiles 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
Only run remote Taskfiles from sources you trust. Their commands execute on your
machine, just like commands from a local Taskfile.
:::
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 for subsequent changes and CI.
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
$ task --taskfile https://raw.githubusercontent.com/go-task/task/main/website/src/public/Taskfile.yml
task: [hello] echo "Hello Task!"
Hello Task!$ task --taskfile 'https://github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=main'
task: [hello] echo "Hello Task!"
Hello Task!$ task --taskfile '[email protected]/go-task/task.git//website/src/public/Taskfile.yml?ref=main'
task: [hello] echo "Hello Task!"
Hello Task!:::
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:
::: code-group
version: '3'
includes:
shared: https://raw.githubusercontent.com/go-task/task/main/website/src/public/Taskfile.ymlversion: '3'
includes:
shared: https://github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=mainversion: '3'
includes:
shared: [email protected]/go-task/task.git//website/src/public/Taskfile.yml?ref=main:::
$ 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:
version: '3'
includes:
shared: https://{{.TOKEN}}@raw.githubusercontent.com/my-org/my-repo/main/Taskfile.ymlPrefer the 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
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
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
//to the URL. - You can also optionally specify a branch or tag to use by appending
?ref=<ref>to the end of the URL. If you omit a reference, the default
branch will be used.
Git over SSH
[email protected]/go-task/task.git//website/src/public/Taskfile.yml?ref=main
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.
- You can optionally add the path to the Taskfile in the repository by appending
//to the URL. - You can also optionally specify a branch or tag to use by appending
?ref=<ref>to the end of the URL. If you omit a reference, the default
branch will be used.
Locate files and directories {#special-variables}
The file-path special variables 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 |
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.
Review trust and changes {#security}
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
remote Taskfiles:
- When running a task from a remote Taskfile for the first time, Task will
print a warning to the console asking you to check that you are sure that you
trust the source of the Taskfile. If you do not accept the prompt, then Task
will exit with code104(not trusted) and nothing will run. If you accept
the prompt, the remote Taskfile will run and further calls to the remote
Taskfile will not prompt you again. - Whenever you run a remote Taskfile, Task will create and store a checksum of
the file that you are running. If the checksum changes, then Task will print
another warning to the console to inform you that the contents of the remote
file has changed. If you do not accept the prompt, then Task will exit with
code104(not trusted) and nothing will run. If you accept the prompt, the
checksum will be updated and the remote Taskfile will run.
Sometimes you need to run Task in an environment that does not have an
interactive terminal, so you are not able to accept a prompt. In these cases you
are able to tell task to accept these prompts automatically by using the --yes
flag or the --trusted-hosts flag. The --trusted-hosts flag allows you to
specify trusted hosts for remote Taskfiles, while --yes applies to all prompts
in Task. You can also configure trusted hosts in your
taskrc configuration usingremote.trusted-hosts. Before enabling automatic trust, you should:
- Be sure that you trust the source and contents of the remote Taskfile.
- Consider using a pinned version of the remote Taskfile (e.g. A link
containing a commit hash) to prevent Task from automatically accepting a
prompt that says a remote Taskfile has changed.
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:
version: '3'
includes:
included:
taskfile: https://raw.githubusercontent.com/go-task/task/main/website/src/public/Taskfile.yml
checksum: '<sha256-of-reviewed-file>'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:
- Add the include normally without the
checksumkey. The first time you run
the included Taskfile, a.task/remotetemporary directory is created. Find
the correct set of files for your included Taskfile and open the file that
ends with.checksum. You can copy the contents of this file and paste it
into thechecksumkey of your include. This method is safest as it allows
you to inspect the downloaded Taskfile before you pin it. - Alternatively, add the include with a temporary random value in the
checksumkey. When you try to run the Taskfile, you will get an error that
will report the incorrect expected checksum and the actual checksum. You can
copy the actual checksum and replace your temporary random value.
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--insecure flag. This is to protect you from accidentally running a remote
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.
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
certificate using the --cacert flag:
task --taskfile https://internal.example.com/Taskfile.yml --cacert /path/to/ca.crtFor servers that require client certificate authentication (mTLS), you can
provide a client certificate and key:
task --taskfile https://secure.example.com/Taskfile.yml \
--cert /path/to/client.crt \
--cert-key /path/to/client.key::: warning
Encrypted private keys are not currently supported. If your key is encrypted,
you must decrypt it first:
openssl rsa -in encrypted.key -out decrypted.key:::
These options can also be configured in the
configuration file.
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
invocations of the Taskfile until the cache expires. Once it expires, Task will
download the latest copy of the file and update the cache. By default, the cache
is set to expire immediately. This means that Task will always fetch the latest
version. However, the cache expiry duration can be modified by setting the--expiry flag.
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.
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
the --timeout flag and specifying a duration. For example, --timeout 5s will
set the timeout to 5 seconds.
By default, the cache is stored in the Task temp directory (.task). You can
override the location of the cache by using the --remote-cache-dir flag, theremote.cache-dir option in your
configuration file, or theTASK_REMOTE_CACHE_DIR environment variable. This way, you can share the cache
between different projects.
You can force Task to ignore the cache and download the latest version by using
the --download flag.
You can use the --clear-cache flag to clear all cached remote files.
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
set up this configuration using flags, environment variables or a configuration
file:
Website Src Next Docs Styleguide (`website/src/next/docs/styleguide.md`)
title: Style Guide Official style guide for Taskfile.yml files with best practices and recommended conventions section: Contributing docType: contributing outline: deep
Style Guide
This is the official style guide for Taskfile.yml files. It provides basic
instructions for keeping your Taskfiles clean and familiar to other users.
This guide contains general guidelines, but they do not necessarily need to be
followed strictly. Feel free to disagree and do things differently if you need
or want to. Any improvements to this guide are welcome! Please open an issue or
create a pull request to contribute.
Use the suggested ordering of the main sections
version:
includes:
# optional configurations (output, silent, method, run, etc.)
vars:
env: # followed or replaced by dotenv
tasks:Use two spaces for indentation
This is the most common convention for YAML files, and Task follows it.
# bad
tasks:
foo:
cmds:
- echo 'foo'
# good
tasks:
foo:
cmds:
- echo 'foo'Separate the main sections with empty lines
# bad
version: '3'
includes:
docker: ./docker/Taskfile.yml
output: prefixed
vars:
FOO: bar
env:
BAR: baz
tasks:
# ...
# good
version: '3'
includes:
docker: ./docker/Taskfile.yml
output: prefixed
vars:
FOO: bar
env:
BAR: baz
tasks:
# ...Separate tasks with empty lines
# bad
version: '3'
tasks:
foo:
cmds:
- echo 'foo'
bar:
cmds:
- echo 'bar'
baz:
cmds:
- echo 'baz'
# good
version: '3'
tasks:
foo:
cmds:
- echo 'foo'
bar:
cmds:
- echo 'bar'
baz:
cmds:
- echo 'baz'Use only uppercase letters for variable names
# bad
version: '3'
vars:
binary_name: myapp
tasks:
build:
cmds:
- go build -o {{.binary_name}} .
# good
version: '3'
vars:
BINARY_NAME: myapp
tasks:
build:
cmds:
- go build -o {{.BINARY_NAME}} .Avoid using whitespace when templating variables
# bad
version: '3'
tasks:
greet:
cmds:
- echo '{{ .MESSAGE }}'
# good
version: '3'
tasks:
greet:
cmds:
- echo '{{.MESSAGE}}'This convention is also commonly used in templates for the Go programming
language.
Use kebab case for task names
# bad
version: '3'
tasks:
do_something_fancy:
cmds:
- echo 'Do something'
# good
version: '3'
tasks:
do-something-fancy:
cmds:
- echo 'Do something'Use a colon to separate the task namespace and name
# good
version: '3'
tasks:
docker:build:
cmds:
- docker ...
docker:run:
cmds:
- docker-compose ...This is also done automatically when using included Taskfiles.
Prefer using external scripts instead of multi-line commands
# bad
version: '3'
tasks:
build:
cmds:
- |
for i in $(seq 1 10); do
echo $i
echo "some other complex logic"
done'
# good
version: '3'
tasks:
build:
cmds:
- ./scripts/my_complex_script.shWebsite Src Next Docs Taskfile Versions (`website/src/next/docs/taskfile-versions.md`)
title: Taskfile Versions How to use the Taskfile schema version to ensure users are using the correct versions of Task section: Project docType: project outline: deep
Taskfile Versions
The Taskfile schema slowly changes as new features are added and old ones are
removed. This document explains how to use a Taskfile's schema version to ensure
that the users of your Taskfile are using the correct versions of Task.
What the Taskfile version means
The schema version at the top of every Taskfile corresponds to a version of the
Task CLI, and by extension, the features that are provided by that version. When
creating a Taskfile, you should specify the minimum version of Task that
supports the features you require. If you try to run a Taskfile with a version
of Task that does not meet this minimum required version, it will exit with an
error. For example, given a Taskfile that starts with:
version: '3.2.1'When executed with Task v3.2.0, it will exit with an error. Running with
version v3.2.1 or higher will work as expected.
Task accepts any SemVer compatible string including versions which
omit the minor or patch numbers. For example, 3, 3.0, and 3.0.0 all mean
the same thing and are all valid. Most Taskfiles only specify the major version
number. However it can be useful to be more specific when you intend to share a
Taskfile with others.
For example, the Taskfile below makes use of aliases:
version: '3'
tasks:
hello:
aliases:
- hi
- hey
cmds:
- echo "Hello, world!"Aliases were introduced in Task v3.17.0, but the Taskfile only specifies 3
as the version. This means that a user who has v3.16.0 or lower installed will
get a potentially confusing error message when trying to run the Task as the
Taskfile specifies that any version greater or equal to v3.0.0 is fine.
Instead, we should start the file like this:
version: '3.17'Now when someone tries to run the Taskfile with an older version of Task, they
will receive an error prompting them to upgrade their version of Task tov3.17.0 or greater.
:::info
Note that this functionality was introduced in
v3.34.0, so older
versions are not able to give you this warning.
:::
Versions 1 & 2
Version 1 and 2 of Task are no longer officially supported and anyone still
using them is strongly encouraged to upgrade to the latest version of Task.
While version: 2 of Task did support schema versions, the behavior did not
work in quite the same way and cannot be relied upon for the purposes discussed
above.
Website Src Latest Docs Deprecations Completion Scripts (`website/src/latest/docs/deprecations/completion-scripts.md`)
title: 'Completion Scripts' section: Project docType: project outline: deep
Completion Scripts
::: danger
This deprecation breaks the following functionality:
- Any direct references to the completion scripts in the Task git repository
:::
Direct use of the completion scripts in the completion/* directory of the
github.com/go-task/task Git repository is deprecated. Any shell
configuration that directly refers to these scripts will potentially break in
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 instead.
Website Src Latest Docs Deprecations Template Functions (`website/src/latest/docs/deprecations/template-functions.md`)
title: 'Template Functions' Deprecation of some templating functions in Task, with guidance on their replacements. section: Project docType: project outline: deep
Template Functions
::: danger
This deprecation breaks the following functionality:
- A small set of templating functions
:::
The following templating functions are deprecated. Any replacement functions are
listed besides the function being removed.
| Deprecated function | Replaced by |
|---|---|
IsSH |
- |
FromSlash |
fromSlash |
ToSlash |
toSlash |
ExeExt |
exeExt |
Website Src Latest Docs Deprecations Template (`website/src/latest/docs/deprecations/template.md`)
This is a template for deprecation documentation
Copy this page and fill in the details as necessary
title: '--- Template ---' draft: true # Hide in production outline: deep
{Name of Deprecated Feature} (#{Issue})
::: danger
This deprecation breaks the following functionality:
- {list any existing functionality that will be broken by this deprecation}
- {if there are no breaking changes, remove this admonition}
:::
{Short description of the feature/behavior and why it is being deprecated}
{Short explanation of any replacement features/behaviors and how users should
migrate to it}
Website Src Latest Docs Deprecations Version 2 Schema (`website/src/latest/docs/deprecations/version-2-schema.md`)
title: 'Version 2 Schema (#1197)' section: Project docType: project outline: deep
Version 2 Schema (#1197)
::: danger
This deprecation breaks the following functionality:
- Any Taskfiles that use the version 2 schema
Taskvar.ymlfiles
:::
The Taskfile version 2 schema was introduced in March 2018 and replaced by
version 3 in August 2019. In May 2023 we published a deprecation
notice for the version 2 schema on the basis that the vast
majority of users had already upgraded to version 3 and removing support for
version 2 would allow us to tidy up the codebase and focus on new functionality
instead.
In December 2023, the final version of Task that supports the version 2 schema
(v3.33.0) was published and all legacy code was removed from Task's
main branch. To use a more recent version of Task, you will need to ensure that
your Taskfile uses the version 3 schema instead. A list of changes between
version 2 and version 3 are available in the Task v3 Release Notes.
Website Src Latest Docs Experiments Env Precedence (`website/src/latest/docs/experiments/env-precedence.md`)
title: 'Env Precedence (#1038)' Experiment to change the precedence of environment variables in Task section: Project docType: project outline: deep
Env Precedence (#1038)
::: warning
All experimental features are subject to breaking changes and/or removal at any
time. We strongly recommend that you do not use these features in a production
environment. They are intended for testing and feedback only.
:::
::: danger
This experiment breaks the following functionality:
- environment variable will take precedence over OS environment variables
:::
::: info
To enable this experiment, set the environment variable:TASK_X_ENV_PRECEDENCE=1. Check out
our guide to enabling experiments for more
information.
:::
Before this experiment, the OS variable took precedence over the task
environment variable. This experiment changes the precedence to make the task
environment variable take precedence over the OS variable.
Consider the following example:
version: '3'
tasks:
default:
env:
KEY: 'other'
cmds:
- echo "$KEY"Running KEY=some task before this experiment, the output would be some, but
after this experiment, the output would be other.
If you still want to get the OS variable, you can use the template function env
like follow : {{env "OS_VAR"}}.
version: '3'
tasks:
default:
env:
KEY: 'other'
cmds:
- echo "$KEY"
- echo {{env "KEY"}}Running KEY=some task, the output would be other and some.
Like other variables/envs, you can also fall back to a given value using the
default template function:
MY_ENV: '{{.MY_ENV | default "fallback"}}'Website Src Latest Docs Experiments Gentle Force (`website/src/latest/docs/experiments/gentle-force.md`)
title: 'Gentle Force (#1200)' section: Project docType: project outline: deep
Gentle Force (#1200)
::: warning
All experimental features are subject to breaking changes and/or removal at any
time. We strongly recommend that you do not use these features in a production
environment. They are intended for testing and feedback only.
:::
::: danger
This experiment breaks the following functionality:
- The
--forceflag
:::
::: info
To enable this experiment, set the environment variable:TASK_X_GENTLE_FORCE=1. Check out
our guide to enabling experiments for more
information.
:::
The --force flag currently forces all tasks to run regardless of the status
checks. This can be useful, but we have found that most of the time users only
expect the direct task they are calling to be forced and not all of its
dependent tasks.
This experiment changes the --force flag to only force the directly called
task. All dependent tasks will have their statuses checked as normal and will
only run if Task considers them to be out of date. A new --force-all flag will
also be added to maintain the current behavior for users that need this
functionality.
If you want to migrate, but continue to force all dependent tasks to run, you
should replace all uses of the --force flag with --force-all. Alternatively,
if you want to adopt the new behavior, you can continue to use the --force
flag as you do now!
Website Src Latest Docs Experiments Remote Taskfiles (`website/src/latest/docs/experiments/remote-taskfiles.md`)
title: Remote Taskfiles (#1317) section: Project docType: project outline: deep
Remote Taskfiles (#1317)
The Remote Taskfiles experiment has now been released :tada:. To
learn more, you can read the remote Taskfile docs or
check out our blog post.
Website Src Latest Docs Experiments Template (`website/src/latest/docs/experiments/template.md`)
title: '--- Template ---'
\{Name of Experiment\} (#\{Issue\})
::: warning
All experimental features are subject to breaking changes and/or removal at any
time. We strongly recommend that you do not use these features in a production
environment. They are intended for testing and feedback only.
:::
::: warning
This experiment breaks the following functionality:
- {list any existing functionality that will be broken by this experiment}
- {if there are no breaking changes, remove this admonition}
:::
:::info
To enable this experiment, set the environment variable: TASK_X_{feature}=1.
Check out our guide to enabling experiments for more
information.
:::
{Short description of the feature}
{Short explanation of how users should migrate to the new behavior}
Website Src Latest Docs Guide Arguments (`website/src/latest/docs/guide/arguments.md`)
title: Command-line arguments 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 |
{{.NAME}} |
| Arguments for a command | task yarn -- install |
{{.CLI_ARGS}} |
| Part of a task name | task start:api |
{{index .MATCH 0}} |
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:
version: '3'
vars:
NAME: World
tasks:
greet:
cmds:
- echo "Hello, {{.NAME}}!"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:
task build test ENV=productionA value declared in a task's own vars can override the command-line value. See
variable resolution for precedence and
configurable defaults. To set values in a command's shell environment, see
Environment variables.
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 runsyarn install:
$ task yarn -- installversion: '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:
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:
$ task start:foo
Starting fooYou can use whitespace in your arguments as long as you quote the task name:
$ task "start:foo bar"
Starting foo barIf 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.
$ task start:foo:3
Starting foo with 3 replicasWildcard task names also work with aliases:
version: '3'
tasks:
start:*:
aliases: [run:*]
vars:
SERVICE: '{{index .MATCH 0}}'
cmds:
- echo "Running {{.SERVICE}}"Call the task through the run:* alias:
$ task run:foo
Running fooWebsite Src Latest Docs Guide Conditional Execution (`website/src/latest/docs/guide/conditional-execution.md`)
title: Conditional execution 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 |
| Stop when a requirement is unmet | preconditions |
| Ask before executing commands | prompt |
| Skip work already completed | Up-to-date checks |
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:
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:
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:
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:
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 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:
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.txttask 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.
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:
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 205.
Unlike
prompts for missing input,
confirmation prompts do not require --interactive. Supplying every required
variable does not bypass them.
For several confirmations, use a list:
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
To control how often a task runs when several tasks call it, userun: once or run: when_changed. These
settings apply within one invocation. Use up-to-date checks
to skip completed work across invocations.
:::
Website Src Latest Docs Guide Defining Tasks (`website/src/latest/docs/guide/defining-tasks.md`)
title: Defining tasks 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 incmds. Add desc to explain what a task does:
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 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 taskdefault 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:
version: '3'
tasks:
build: go build -v -o ./app{{exeExt}} .
run:
- task: build
- ./app{{exeExt}} -h localhost -p 8080Keep 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:
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:
version: '3'
tasks:
serve:
dir: public/www
cmds:
# run http server
- caddyRun 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.
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
in your Taskfile and when including tasks with aliases from
another Taskfile. They can also be used together with
namespace aliases.
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:
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:
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.csswould print the following output:
* 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:
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-tooltask --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-toolIf 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.
Website Src Latest Docs Guide Dependencies (`website/src/latest/docs/guide/dependencies.md`)
title: Dependencies and task calls 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. Usedeps 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:
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 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:
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:
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, add a leading :, for exampletask: :build.
:::
Pass variables to a task
Use the object form of a task call to provide vars. You can also setsilent: true to hide the command being executed for that call:
version: '3'
tasks:
greet:
cmds:
- echo "Hello, {{.RECIPIENT}}!"
greet:all:
cmds:
- task: greet
vars: { RECIPIENT: 'World' }
- task: greet
vars: { RECIPIENT: 'Cruel World' }
silent: truetask greet:all prints both greetings in order. The second call still prints
its greeting: silent mode hides the command, not its
output.
The same task, vars, and silent fields work in deps. Use
references to pass arrays and maps
without turning them into strings. To call a task for each value in a list, see
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:
task --concurrency 2 buildThe 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:
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 or usetask --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, oroutput: 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 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:
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:
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.
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:
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.
Website Src Latest Docs Guide Environment (`website/src/latest/docs/guide/environment.md`)
title: Environment variables 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:
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.
Set values for commands {#task}
Put env on a task to configure its commands, or at the root to provide values
for every task:
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 changes this rule.
env values support templates and dynamic sh commands. For example, an entryBUILD_MODE: '{{.MODE}}' exports a Task variable to a
command's environment. A vars entry alone is not exported to commands incmds.
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
GREETING=Hello from .env!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:
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-levelenv values take precedence over values loaded from dotenv files:
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 '{{.HOME}}/.env'.
The dotenv key is not supported inside included Taskfiles. Load shared values
in the entrypoint Taskfile instead. See Including Taskfiles.
Website Src Latest Docs Guide Errors And Cleanup (`website/src/latest/docs/guide/errors-and-cleanup.md`)
title: Errors and cleanup 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.
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:
version: '3'
tasks:
default:
cmds:
- mkdir -p tmpdir/
- defer: rm -rf tmpdir/
- echo 'Work completed' > tmpdir/result.txtRun task, then check that tmpdir/ was removed. Replace the last command withexit 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:
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. You can check its presence to know
if the task completed successfully or not:
version: '3'
tasks:
default:
cmds:
- defer:
echo '{{if .EXIT_CODE}}Failed with
{{.EXIT_CODE}}!{{else}}Success!{{end}}'
- exit 1Continue after an error {#ignoring-command-errors}
Set ignore_error: true on a command to continue after it fails:
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.
Website Src Latest Docs Guide Includes (`website/src/latest/docs/guide/includes.md`)
title: Including Taskfiles 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
version: '3'
includes:
docs:
taskfile: ./docs/Taskfile.yml
dir: ./docsversion: '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. Thedocs 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.
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
version: '3'
includes:
backend:
taskfile: ./taskfiles/Docker.yml
vars:
DOCKER_IMAGE: backend_image
frontend:
taskfile: ./taskfiles/Docker.yml
vars:
DOCKER_IMAGE: frontend_imageversion: '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 for the full rules.
Shorten namespace names {#namespace-aliases}
Add namespace aliases to shorten frequently used task names:
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.
Allow a missing file {#optional-includes}
Use optional: true when a missing local Taskfile should not prevent the rest
of the project from running:
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:
version: '3'
includes:
docs:
taskfile: ./docs/Taskfile.yml
dir: ./docs
internal: true
tasks:
build:
cmds:
- task: docs:buildWith the docs/Taskfile.yml from the first example, task build works, buttask 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:
version: '3'
includes:
docs:
taskfile: ./docs/Taskfile.yml
dir: ./docs
flatten: trueWith the first example's included file, call task build instead oftask 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
version: '3'
includes:
tools:
taskfile: ./Tools.yml
excludes: [debug, 'internal:*']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:
version: '3'
includes:
build: ./Taskfile_{{OS}}.ymlProvide files such as Taskfile_linux.yml, Taskfile_darwin.yml, andTaskfile_windows.yml for the platforms you support. If only a few commands
differ,
platform restrictions may
be easier to maintain.
::: tip Related guide
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
for a complete example, checksum pinning, and offline use.
:::
Website Src Latest Docs Guide Loops (`website/src/latest/docs/guide/loops.md`)
title: Loops 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:
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 for
iterations that may run concurrently.
For a changing set of files, use
a source glob 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:
version: '3'
tasks:
greet:
vars:
NAMES: Alice Bob
cmds:
- for: { var: NAMES }
cmd: echo "Hello, {{.ITEM}}!"For another separator, set split:
version: '3'
tasks:
greet:
vars:
NAMES: Alice,Bob
cmds:
- for: { var: NAMES, split: ',' }
cmd: echo "Hello, {{.ITEM}}!"Arrays preserve values containing spaces:
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:
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:
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:
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:
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:
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:
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 for concurrency limits and
repeated-call policies.
Try every combination {#looping-over-a-matrix}
Use matrix to visit every combination of several lists:
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, anddarwin/arm64. These are ordinary iteration values; they do not change the
platform on which Task runs.
Use ref to reuse lists defined elsewhere:
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
version: '3'
tasks:
show:
sources: ['src/*.txt']
cmds:
- for: sources
cmd: cat '{{.ITEM}}'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; use method: none if this task should
print the files every time.
To build an absolute path, combine a directory with the item using thejoinPath template function, for example{{joinPath .TASK_DIR .ITEM}}. See the
file-path variables for the available
directory values.
Website Src Latest Docs Guide Output (`website/src/latest/docs/guide/output.md`)
title: Output and logging 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:
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:
[lint] Lint passed
[test] Tests passedThe 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 (ortask -o group check).
Use a task's prefix to distinguish repeated calls with different inputs:
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:
version: '3'
silent: true
output:
group:
error_only: true
tasks:
passes: echo 'Everything passed'
fails: echo 'Failure details' && exit 1task 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:
version: '3'
tasks:
greet:
cmds:
- echo 'Hello, World!'task greet shows the command and its output. task --silent greet prints onlyHello, World!.
To make this permanent for selected commands:
version: '3'
tasks:
greet:
cmds:
- cmd: echo 'Hello, World!'
silent: trueYou 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:
version: '3'
tasks:
quiet:
cmds:
- echo 'This output is discarded' > /dev/nullStderr remains visible unless you redirect it too. Silent mode is not a
substitute for secret masking.
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:
version: '3'
output:
group:
begin: '::group::{{.TASK}}'
end: '::endgroup::'
tasks:
default:
silent: true
cmds:
- echo 'Hello, World!'Running task produces:
::group::default
Hello, World!
::endgroup::These markers follow
GitHub Actions' grouping format.
Other providers, such as
Azure Pipelines,
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:
::error title=Task 'build' failed::exit status 1No Taskfile configuration is required for these annotations.
::: tip Related guide
To continue after a selected failure, use ignore_error. See
Errors and cleanup for its
scope and examples.
:::
Website Src Latest Docs Guide Platforms (`website/src/latest/docs/guide/platforms.md`)
title: Platforms and shells 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:
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:
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 or construct
arguments. Use exeExt for executable names that need .exe on Windows:
version: '3'
tasks:
build:
cmds:
- go build -o app{{exeExt}} main.goUnderstand 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 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:
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, andglobstar enables recursive ** globs in shell commands:
version: '3'
set: [pipefail]
shopt: [globstar]
tasks:
list:
cmds:
- echo **/*.goThese 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.
shopt controls shell expansion inside commands. Globs in sources andgenerates use Task's file matching
and do not require globstar.
Website Src Latest Docs Guide Required Variables (`website/src/latest/docs/guide/required-variables.md`)
title: Validation and prompts 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:
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.
Restrict allowed values {#ensuring-required-variables-have-allowed-values}
Use name and enum to require a string from a fixed list:
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 missingENV 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:
interactive: trueFor a task with both kinds of input:
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:
task deploy ENVIRONMENT=prod VERSION=1.0.0Prompts 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:
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:
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:
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
A prompt for input fills in a value. A
confirmation prompt asks
whether execution should proceed, even if all input values are already present.
:::
Website Src Latest Docs Guide Running Tasks (`website/src/latest/docs/guide/running-tasks.md`)
title: Running tasks 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:
task --list
task build--list shows tasks with descriptions. Use --list-all to include tasks
without descriptions; internal tasks
remain hidden. See Defining tasks to create these
entries.
Pass several names, such as task lint test, to run them in order. Use--parallel for independent
tasks that can run concurrently. To pass values or command arguments, see
Command-line arguments.
Preview commands {#dry-run-mode}
Use --dry (or -n) to print the commands Task would run:
task --dry buildTask 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.
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 changes it.
Use {{.USER_WORKING_DIR}} 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:
version: '3'
tasks:
up:
dir: '{{.USER_WORKING_DIR}}'
preconditions:
- test -f docker-compose.yml
cmds:
- docker compose up -dFrom 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:
task --global from-working-directoryGlobal tasks run in your home directory by default. Set dir to{{.USER_WORKING_DIR}} when a personal utility should work
on the current project:
version: '3'
tasks:
from-home:
cmds:
- pwd
from-working-directory:
dir: '{{.USER_WORKING_DIR}}'
cmds:
- pwdRead 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:
task --taskfile - < ./Taskfile.ymlYou 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:
version: '3'
tasks:
edit:
interactive: true
cmds:
- vim my-file.txtRun task edit to open the editor. Interactive applications need direct access
to the terminal; buffered or prefixed output modes
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.
Choose a file name {#supported-file-names}
Use --taskfile to choose a specific file or --dir to run in another project:
task --taskfile Taskfile.ci.yml build
task --dir ./backend buildTask looks for these names in order of priority:
Taskfile.ymltaskfile.ymlTaskfile.yamltaskfile.yamlTaskfile.dist.ymltaskfile.dist.ymlTaskfile.dist.yamltaskfile.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.
Website Src Latest Docs Guide Secret Variables (`website/src/latest/docs/guide/secret-variables.md`)
title: Secret variables 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.
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.comSet 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 ofsh 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:
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 withecho "$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.
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:
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.comWithout 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.
Website Src Latest Docs Guide Up To Date (`website/src/latest/docs/guide/up-to-date.md`)
title: Up-to-date checks 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:
version: '3'
tasks:
build:
sources: [main.go]
generates: ['app{{exeExt}}']
cmds:
- go build -o app{{exeExt}} main.goRun task build to create the executable. Run it again without changingmain.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
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. 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:
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:
tasks:
build:
method: timestamp
sources: [main.go]
generates: ['app{{exeExt}}']
cmds:
- go build -o app{{exeExt}} main.goYou 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 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:
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.txtRun 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.
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:
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, {{.CHECKSUM}} contains the source
fingerprint. With method: timestamp, {{.TIMESTAMP}}
contains the latest source modification time. Both can be used in cmds andstatus; they describe the sources, not the generated files.
.TIMESTAMP is a Go time.Time value. For example,{{.TIMESTAMP.Unix}} produces a Unix timestamp, and{{.TIMESTAMP.Format "2006-01-02"}} formats a date.
Check or force a run
To check whether tasks are up to date without running their commands:
task --status buildYou can pass multiple task names. The command exits with a non-zero
exit code if any task is not up to date.
To run a task even when its checks say the work is already done:
task --force build-f is the short form of --force. To rerun automatically when files change,
use Watch mode.
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:
version: '3'
tasks:
build:
label: 'build-{{.MODE}}'
sources: [main.go]
generates: ['app-{{.MODE}}{{exeExt}}']
cmds:
- go build -tags '{{.MODE}}' -o app-{{.MODE}}{{exeExt}} main.goRun 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, userun: once or run: when_changed.
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:
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.
Website Src Latest Docs Guide Variables (`website/src/latest/docs/guide/variables.md`)
title: Variables 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:
version: '3'
vars:
NAME: World
tasks:
greet:
cmds:
- echo "Hello, {{.NAME}}!"Run task greet to print Hello, World!, or task greet NAME=Bob to printHello, 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 explains how values from different places
interact.
Pass NAME=value on the command line to supply variables to Task. See
Command-line arguments 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:
stringboolintfloatarraymap
::: info
Defining a map requires that you use a special map subkey (see example below).
:::
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}}' # 1Compute 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.
version: '3'
tasks:
build:
cmds:
- go build -ldflags="-X main.Version={{.GIT_COMMIT}}" main.go
vars:
GIT_COMMIT:
sh: git log -n 1 --format=%hThe result is text. To convert JSON or YAML output into structured data, use
parsing functions with ref.
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:
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 withSERVICES: '{{.SERVICES}}' 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:
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 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:
version: '3'
tasks:
task-with-map:
vars:
JSON: '{"a": 1, "b": 2, "c": 3}'
FOO:
ref: 'fromJson .JSON'
cmds:
- echo {{.FOO}}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:
version: '3'
tasks:
greet:
vars:
NAME: from-task
cmds:
- echo "{{.NAME}}"$ task greet NAME=from-cli
from-taskTo let a caller supply a value, give the default somewhere earlier, in globalvars:, or use a template default:
version: '3'
vars:
NAME: from-global
tasks:
greet:
cmds:
- echo "{{.NAME}}"$ task greet NAME=from-cli
from-cliTo keep the default on the task itself, read the caller's value in a template:
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'svars: 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:
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 printsbuilding 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 | {{.FOO}} |
$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 {{.FOO}}
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 ash: command can also reference variables declared earlier in the same block:
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, sosh: echo $INPUT works in this example too. The process environment takes
precedence for shell lookups unless the
Env Precedence experiment is enabled.
Commands in cmds only receive the process environment and Task's env: anddotenv: 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 {{ }}. A template renders a string; ref:
preserves the type.
::: tip Related guide
Mark sensitive values with secret: true to mask them in Task's own command
logs. See Secret variables for examples, loading values
from external sources and the limits of masking.
:::
Website Src Latest Docs Guide Watch (`website/src/latest/docs/guide/watch.md`)
title: Watch mode 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:
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 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:
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:
task --watch --interval=500ms buildYou 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 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. Report Task-specific problems with
a small reproducer in the
issue tracker.
Website Src Latest Docs Reference Cli (`website/src/latest/docs/reference/cli.md`)
title: Command Line Interface Reference permalink: /reference/cli/ section: Reference docType: reference outline: deep
Command Line Interface Reference
Task has multiple ways of being configured. These methods are parsed, in
sequence, in the following order with the highest priority last:
- Configuration files
- Environment variables
- Command-line flags
In this document, we will look at the last of the three options, command-line
flags. All CLI commands override their configuration file and environment
variable equivalents.
Format
Task commands have the following syntax:
task [options] [tasks...] [-- CLI_ARGS...]::: tip
If -- is given, all remaining arguments will be assigned to a specialCLI_ARGS variable.
:::
Commands
`task [tasks...]`
Run one or more tasks defined in your Taskfile.
task build
task test lint
task deploy --force`task --list`
List all available tasks with their descriptions.
task --list
task -l`task --list-all`
List all tasks, including those without descriptions.
task --list-all
task -a`task --init`
Create a new Taskfile.yml in the current directory.
task --init
task -i::: tip
Combine --list or --list-all with --silent (-ls or -as for shortants)
to list only the task names in each line. Useful for scripting with grep or
similar.
:::
Options
General
`-h, --help`
Show help information.
task --help`--version`
Show Task version.
task --version`-v, --verbose`
Enable verbose mode for detailed output.
- Config equivalent:
verbose - Environment variable:
TASK_VERBOSE
task build --verbose`-s, --silent`
Disable command echoing.
- Config equivalent:
silent - Environment variable:
TASK_SILENT
task deploy --silent`--disable-fuzzy`
Disable fuzzy matching for task names. When enabled, Task will not suggest
similar task names when you mistype a task name.
- Config equivalent:
disable-fuzzy - Environment variable:
TASK_DISABLE_FUZZY
task buidl --disable-fuzzy
# Output: Task "buidl" does not exist
# (without "Did you mean 'build'?" suggestion)Execution Control
`-F, --failfast`
Stop executing dependencies as soon as one of them fails.
- Config equivalent:
failfast - Environment variable:
TASK_FAILFAST
task build --failfast`-f, --force`
Force execution even when the task is up-to-date.
task build --force`-n, --dry`
Compile and print tasks without executing them.
- Environment variable:
TASK_DRY
task deploy --dry`-p, --parallel`
Execute multiple tasks in parallel.
task test lint --parallel`-C, --concurrency `
Limit the number of concurrent tasks. Zero means unlimited.
- Config equivalent:
concurrency - Environment variable:
TASK_CONCURRENCY
task test --concurrency 4`-x, --exit-code`
Pass through the exit code of failed commands.
task test --exit-codeFile and Directory
`-d, --dir `
Set the directory where Task will run and look for Taskfiles.
task build --dir ./backend`-t, --taskfile `
Specify a custom Taskfile path.
task build --taskfile ./custom/Taskfile.yml`-g, --global`
Run the global Taskfile from $HOME/Taskfile.{yml,yaml}.
task backup --global`--temp-dir `
Set the directory used to store Task temporary files, such as checksums.
Relative paths are relative to the root Taskfile.
- Config equivalent:
temp-dir - Environment variable:
TASK_TEMP_DIR
task build --temp-dir .task-cacheOutput Control
`-o, --output `
Set output style. Available modes: interleaved, group, prefixed.
- Environment variable:
TASK_OUTPUT
task test --output group`--output-group-begin `
Message template to print before grouped output.
- Environment variable:
TASK_OUTPUT_GROUP_BEGIN
task test --output group --output-group-begin "::group::{{.TASK}}"`--output-group-end `
Message template to print after grouped output.
- Environment variable:
TASK_OUTPUT_GROUP_END
task test --output group --output-group-end "::endgroup::"`--output-group-error-only`
Only show command output on non-zero exit codes.
- Environment variable:
TASK_OUTPUT_GROUP_ERROR_ONLY
task test --output group --output-group-error-only`-c, --color`
Control colored output. Enabled by default.
- Config equivalent:
color - Environment variable:
TASK_COLOR
task build --color=false
# or use environment variable
NO_COLOR=1 task buildTask Information
`--status`
Check if tasks are up-to-date without running them.
task build --status`--summary`
Show detailed information about a task.
task build --summary`--json`
Output task information in JSON format (use with --list or --list-all).
task --list --json`--sort `
Change task listing order. Available modes:
default- Sorts tasks alphabetically by name, but ensures that root tasks
(tasks without a namespace) are listed before namespaced tasks.alphanumeric- Sort tasks alphabetically by name.none- No sorting. Uses the order as defined in the Taskfile.
task --list --sort alphanumericWatch Mode
`-w, --watch`
Watch for file changes and re-run tasks automatically.
task build --watch`-I, --interval `
Set watch interval (default: 5s). Must be a valid
Go duration.
task build --watch --interval 1sInteractive
`-y, --yes`
Automatically answer "yes" to all prompts.
- Environment variable:
TASK_ASSUME_YES
task deploy --yes`--interactive`
Enable interactive prompts for missing required variables. When a required
variable is not provided, Task will prompt for input instead of failing.
Task automatically detects non-TTY environments (like CI pipelines) and skips
prompts. This flag can also be set in .taskrc.yml to enable prompts by
default.
- Environment variable:
TASK_INTERACTIVE
task deploy --interactiveRemote
The following flags are used to control the behavior of
remote Taskfiles.
`--insecure`
Allow insecure connections when fetching remote Taskfiles.
`--offline`
Work in offline mode, preventing remote Taskfile fetching.
`--download`
Forces task to download remote Taskfiles and ignore any cached versions.
`--timeout`
Timeout duration for remote operations (e.g., '30s', '5m').
`--clear-cache`
Wipe the cache of remote Taskfiles and checksums.
`--expiry`
Cache expiry duration for remote Taskfiles (e.g., '1h', '24h').
`--remote-cache-dir`
Directory where remote Taskfiles are cached. Can be an absolute path (e.g.,/var/cache/task) or relative to the Taskfile directory.
`--trusted-hosts`
List of (comma-separated) trusted hosts for remote Taskfiles. Hosts in this list
will not prompt for confirmation when downloading Taskfiles.
Hosts in the trusted hosts list will automatically be trusted without prompting
for confirmation when they are first downloaded or when their checksums change.
The host matching includes the port if specified in the URL. Use with caution
and only add hosts you fully trust.
`--cacert`
Path to a custom CA certificate file for TLS verification.
`--cert`
Path to a client certificate file for mTLS authentication.
`--cert-key`
Path to the client certificate private key file.
Exit Codes
Task uses specific exit codes to indicate different types of errors:
Success
- 0 - Success
General Errors (1-99)
- 1 - Unknown error occurred
Taskfile Errors (100-199)
- 100 - No Taskfile found
- 101 - Taskfile already exists (when using
--init) - 102 - Invalid or unparseable Taskfile
- 103 - Remote Taskfile download failed
- 104 - Remote Taskfile not trusted
- 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)
- 200 - Task not found
- 201 - Command execution error
- 202 - Attempted to run internal task
- 203 - Multiple tasks with same name/alias
- 204 - Task called too many times (recursion limit)
- 205 - Task cancelled by user
- 206 - Missing required variables
- 207 - Variable has incorrect value
- 208 - Task timed out
::: info
When using -x/--exit-code, failed command exit codes are passed through
instead of the above codes.
:::
::: tip
The complete list of exit codes is available in the repository aterrors/errors.go.
:::
JSON Output Format
When using --json with --list or --list-all:
{
"tasks": [
{
"name": "build",
"task": "build",
"desc": "Build the application",
"summary": "Compiles the source code and generates binaries",
"up_to_date": false,
"location": {
"line": 12,
"column": 3,
"taskfile": "/path/to/Taskfile.yml"
}
}
],
"location": "/path/to/Taskfile.yml"
}Website Src Latest Docs Reference Config (`website/src/latest/docs/reference/config.md`)
title: Configuration Reference permalink: /reference/config/ section: Reference docType: reference outline: deep
Configuration Reference
Task has multiple ways of being configured. These methods are parsed, in
sequence, in the following order with the highest priority last:
- Configuration files
- Environment variables
- Command-line flags
In this document, we will look at the first of the three options, configuration
files.
File Precedence
Task will automatically look for directories containing configuration files in
the following order with the highest priority first:
- Current directory (or the one specified by the
--taskfile/--entrypoint
flags). - Each directory walking up the file tree from the current directory (or the one
specified by the--taskfile/--entrypointflags) until we reach the user's
home directory or the root directory of that drive. - The users
$HOMEdirectory. - The
$XDG_CONFIG_HOME/taskdirectory.
Config files in the current directory, its parent folders or home directory
should be called .taskrc.yml or .taskrc.yaml. Config files in the$XDG_CONFIG_HOME/task directory are named the same way, but should not contain
the . prefix.
All config files will be merged together into a unified config, starting with
the lowest priority file in $XDG_CONFIG_HOME/task with each subsequent file
overwriting the previous one if values are set.
For example, given the following files:
# lowest priority global config
option_1: foo
option_2: foo
option_3: foooption_1: bar
option_2: bar# highest priority project config
option_1: bazYou would end up with the following configuration:
option_1: baz # Taken from $HOME/path/to/project/.taskrc.yml
option_2: bar # Taken from $HOME/.taskrc.yml
option_3: foo # Taken from $XDG_CONFIG_HOME/task/.taskrc.ymlConfiguration Options
`experiments`
The experiments section allows you to enable Task's experimental features. These
options are not enumerated here. Instead, please refer to our
experiments documentation for more information.
experiments:
feature_name: 1
another_feature: 2`verbose`
- Type:
boolean - Default:
false - Description: Enable verbose output for all tasks
- CLI equivalent:
-v, --verbose - Environment variable:
TASK_VERBOSE
verbose: true`silent`
- Type:
boolean - Default:
false - Description: Disables echoing of commands
- CLI equivalent:
-s, --silent - Environment variable:
TASK_SILENT
silent: true`color`
- Type:
boolean - Default:
true - Description: Enable colored output. Colors are automatically enabled in CI
environments (CI=true). - CLI equivalent:
-c, --color - Environment variable:
TASK_COLOR
color: false`disable-fuzzy`
- Type:
boolean - 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 - Environment variable:
TASK_DISABLE_FUZZY
disable-fuzzy: true`concurrency`
- Type:
integer - Minimum:
1 - Description: Number of concurrent tasks to run
- CLI equivalent:
-C, --concurrency - Environment variable:
TASK_CONCURRENCY
concurrency: 4`failfast`
- Type:
boolean - Default:
false - Description: Stop executing dependencies as soon as one of them fail
- CLI equivalent:
-F, --failfast - Environment variable:
TASK_FAILFAST
failfast: true`interactive`
- Type:
boolean - Default:
false - Description: Prompt for missing required variables instead of failing.
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
interactive: true`temp-dir`
- Type:
string - Default:
./.task - Description: Directory to store Task temporary files, such as checksums
and temporary metadata. Relative paths are relative to the root Taskfile. - Environment variable:
TASK_TEMP_DIR
temp-dir: .task`remote`
- Type:
object - Description: Remote configuration settings for handling
remote Taskfiles.
`remote.insecure`
- Type:
boolean - Default:
false - Description: Allow insecure connections when fetching remote Taskfiles
- CLI equivalent:
--insecure - Environment variable:
TASK_REMOTE_INSECURE
remote:
insecure: true`remote.offline`
- Type:
boolean - Default:
false - Description: Work in offline mode, preventing remote Taskfile fetching
- CLI equivalent:
--offline - Environment variable:
TASK_REMOTE_OFFLINE
remote:
offline: true`remote.timeout`
- Type:
string - Default: 10s
- Pattern:
^[0-9]+(ns|us|Β΅s|ms|s|m|h)$ - Description: Timeout duration for remote operations (e.g., '30s', '5m')
- CLI equivalent:
--timeout - Environment variable:
TASK_REMOTE_TIMEOUT
remote:
timeout: '1m'`remote.cache-expiry`
- Type:
string - Default: 0s (no cache)
- Pattern:
^[0-9]+(ns|us|Β΅s|ms|s|m|h)$ - Description: Cache expiry duration for remote Taskfiles (e.g., '1h',
'24h') - CLI equivalent:
--expiry - Environment variable:
TASK_REMOTE_CACHE_EXPIRY
remote:
cache-expiry: '6h'`remote.cache-dir`
- Type:
string - Default:
.task - Description: Directory where remote Taskfiles are cached. Can be an
absolute path (e.g.,/var/cache/task) or relative to the Taskfile directory. - CLI equivalent:
--remote-cache-dir - Environment variable:
TASK_REMOTE_CACHE_DIR
remote:
cache-dir: ~/.task`remote.trusted-hosts`
- Type:
array of strings - Default:
[](empty list) - Description: List of trusted hosts for remote Taskfiles. Hosts in this
list will not prompt for confirmation when downloading Taskfiles - CLI equivalent:
--trusted-hosts - Environment variable:
TASK_REMOTE_TRUSTED_HOSTS
(comma-separated)
remote:
trusted-hosts:
- github.com
- gitlab.com
- raw.githubusercontent.com
- example.com:8080Hosts in the trusted hosts list will automatically be trusted without prompting
for confirmation when they are first downloaded or when their checksums change.
The host matching includes the port if specified in the URL. Use with caution
and only add hosts you fully trust.
You can also specify trusted hosts via the command line:
# Trust specific host for this execution
task --trusted-hosts github.com -t https://github.com/user/repo.git//Taskfile.yml
# Trust multiple hosts (comma-separated)
task --trusted-hosts github.com,gitlab.com -t https://github.com/user/repo.git//Taskfile.yml
# Trust a host with a specific port
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
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-valueUse 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 asremote.trusted-hosts. Header values may reference
templating functions, evaluated when Task contacts the host.
Values starting with {{ 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:
remote:
headers:
- host: artifacts.example.com
headers:
Authorization: 'Basic {{ printf "%s:%s" (env "USER") (env "PASS") | b64enc }}'::: warning
Only functions are available here β {{.GITLAB_TOKEN}} and
other variable references resolve to nothing. The configuration file is read
before any Taskfile, so no variable exists yet. Use{{env "GITLAB_TOKEN"}} 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 - Default:
"" - Description: Path to a custom CA certificate file for TLS verification
remote:
cacert: '/path/to/ca.crt'`remote.cert`
- Type:
string - Default:
"" - Description: Path to a client certificate file for mTLS authentication
remote:
cert: '/path/to/client.crt'`remote.cert-key`
- Type:
string - Default:
"" - Description: Path to the client certificate private key file
remote:
cert-key: '/path/to/client.key'Example Configuration
Here's a complete example of a .taskrc.yml file with all available options:
# Global settings
verbose: true
silent: false
color: true
disable-fuzzy: false
concurrency: 2
temp-dir: .task
remote:
insecure: false
offline: false
timeout: '30s'
cache-expiry: '24h'
cache-dir: ~/.task
trusted-hosts:
- github.com
- gitlab.com
headers:
- host: gitlab.com
headers:
PRIVATE-TOKEN: '{{env "GITLAB_TOKEN"}}'
cacert: ''
cert: ''
cert-key: ''
# Enable experimental features
experiments:
GENTLE_FORCE: 1Website Src Latest Docs Reference Environment (`website/src/latest/docs/reference/environment.md`)
title: Environment Reference section: Reference docType: reference outline: deep
Environment Reference
Task has multiple ways of being configured. These methods are parsed, in
sequence, in the following order with the highest priority last:
- Configuration files
- Environment variables
- Command-line flags
In this document, we will look at the second of the three options, environment
variables. All Task-specific variables are prefixed with TASK_ and override
their configuration file equivalents.
Variables
All configuration file options can also be set via environment
variables. The priority order is: CLI flags > environment variables > config
files > defaults.
`TASK_VERBOSE`
- Type:
boolean(true,false,1,0) - Default:
false - Description: Enable verbose output for all tasks
- Config equivalent:
verbose
`TASK_SILENT`
- Type:
boolean(true,false,1,0) - Default:
false - Description: Disables echoing of commands
- Config equivalent:
silent
`TASK_COLOR`
- Type:
boolean(true,false,1,0) - Default:
true - Description: Enable colored output
- Config equivalent:
color
`TASK_DISABLE_FUZZY`
- Type:
boolean(true,false,1,0) - Default:
false - Description: Disable fuzzy matching for task names
- Config equivalent:
disable-fuzzy
`TASK_CONCURRENCY`
- Type:
integer - Description: Limit number of tasks to run concurrently
- Config equivalent:
concurrency
`TASK_FAILFAST`
- Type:
boolean(true,false,1,0) - Default:
false - Description: When running tasks in parallel, stop all tasks if one fails
- Config equivalent:
failfast
`TASK_DRY`
- Type:
boolean(true,false,1,0) - Default:
false - Description: Compiles and prints tasks in the order that they would be
run, without executing them
`TASK_ASSUME_YES`
- Type:
boolean(true,false,1,0) - Default:
false - Description: Assume "yes" as answer to all prompts
`TASK_INTERACTIVE`
- Type:
boolean(true,false,1,0) - Default:
false - Description: Prompt for missing required variables
`TASK_OUTPUT`
- Type:
string(interleaved,group,prefixed) - Description: Sets the output style
- CLI equivalent:
--output
`TASK_OUTPUT_GROUP_BEGIN`
- Type:
string - Description: Message template to print before a task's grouped output.
Only applies when the output style isgroup. - CLI equivalent:
--output-group-begin
`TASK_OUTPUT_GROUP_END`
- Type:
string - Description: Message template to print after a task's grouped output. Only
applies when the output style isgroup. - CLI equivalent:
--output-group-end
`TASK_OUTPUT_GROUP_ERROR_ONLY`
- Type:
boolean(true,false,1,0) - Default:
false - Description: Swallow output from successful tasks. Only applies when the
output style isgroup. - CLI equivalent:
--output-group-error-only
`TASK_TEMP_DIR`
Defines the location of Task's temporary directory which is used for storing
checksums and temporary metadata. Can be relative like tmp/task or absolute
like /tmp/.task or ~/.task. Relative paths are relative to the root
Taskfile, not the working directory. Defaults to: ./.task.
`TASK_CORE_UTILS`
This env controls whether the Bash interpreter will use its own core utilities
implemented in Go, or the ones available in the system. Valid values are true
(1) or false (0). By default, this is true on Windows and false on
other operating systems. We might consider making this enabled by default on all
platforms in the future.
`FORCE_COLOR`
Force color output usage.
Remote Taskfile Variables
The following variables are used to control the behavior of
remote Taskfiles.
`TASK_REMOTE_INSECURE`
Allow insecure connections when fetching remote Taskfiles.
`TASK_REMOTE_OFFLINE`
Work in offline mode, preventing remote Taskfile fetching.
`TASK_REMOTE_TIMEOUT`
Timeout duration for remote operations (e.g., '30s', '5m').
`TASK_REMOTE_CACHE_EXPIRY`
Cache expiry duration for remote Taskfiles (e.g., '1h', '24h').
`TASK_REMOTE_CACHE_DIR`
Directory where remote Taskfiles are cached. Can be an absolute path (e.g.,/var/cache/task) or relative to the Taskfile directory.
`TASK_REMOTE_TRUSTED_HOSTS`
List of (comma-separated) trusted hosts for remote Taskfiles. Hosts in this list
will not prompt for confirmation when downloading Taskfiles.
Hosts in the trusted hosts list will automatically be trusted without prompting
for confirmation when they are first downloaded or when their checksums change.
The host matching includes the port if specified in the URL. Use with caution
and only add hosts you fully trust.
`TASK_REMOTE_CACERT`
Path to a custom CA certificate file for TLS verification.
`TASK_REMOTE_CERT`
Path to a client certificate file for mTLS authentication.
`TASK_REMOTE_CERT_KEY`
Path to the client certificate private key file.
Custom Colors
All color variables are ANSI color codes. You can specify multiple codes
separated by a semicolon. For example: 31;1 will make the text bold and red.
Task also supports 8-bit color (256 colors). You can specify these colors by
using the sequence 38;2;R:G:B for foreground colors and 48;2;R:G:B for
background colors where R, G and B should be replaced with values between
0 and 255.
For convenience, we allow foreground colors to be specified using shorthand,
comma-separated syntax: R,G,B. For example, 255,0,0 is equivalent to38;2;255:0:0.
A table of variables and their defaults can be found below:
| ENV | Default |
|---|---|
TASK_COLOR_RESET |
0 |
TASK_COLOR_RED |
31 |
TASK_COLOR_GREEN |
32 |
TASK_COLOR_YELLOW |
33 |
TASK_COLOR_BLUE |
34 |
TASK_COLOR_MAGENTA |
35 |
TASK_COLOR_CYAN |
36 |
TASK_COLOR_BRIGHT_RED |
91 |
TASK_COLOR_BRIGHT_GREEN |
92 |
TASK_COLOR_BRIGHT_YELLOW |
93 |
TASK_COLOR_BRIGHT_BLUE |
94 |
TASK_COLOR_BRIGHT_MAGENTA |
95 |
TASK_COLOR_BRIGHT_CYAN |
96 |
Website Src Latest Docs Reference Package (`website/src/latest/docs/reference/package.md`)
title: Package API Reference section: Reference docType: reference
Package API Reference
::: warning
Task's package API is still experimental and subject to breaking changes.
This means that unlike our CLI, we may make breaking changes to the package API
in minor (or even patch) releases. We try to avoid this when possible, but it
may be necessary in order to improve the overall design of the package API.
In the future we may stabilize the package API. However, this is not currently
planned. For now, if you need to use Task as a Go package, we recommend pinning
the version in your go.mod file. Where possible we will try to include a
changelog entry for breaking changes to the package API.
:::
Task is primarily a CLI tool that is agnostic of any programming language.
However, it is written in Go and therefore can also be used as a Go package too.
This can be useful if you are already using Go in your project and you need to
extend Task's functionality in some way. In this document, we describe the
public API surface of Task and how to use it. This may also be useful if you
want to contribute to Task or understand how it works in more detail.
Key packages
The following packages make up the most important parts of Task's package API.
Below we have listed what they are for and some of the key types available:
[`github.com/go-task/task/v3`]
The core task package provides most of the main functionality for Task including
fetching and executing tasks from a Taskfile. At this time, the vast majority of
the this package's functionality is exposed via the task.Executor which
allows the user to fetch and execute tasks from a Taskfile.
::: info
This is the package which is most likely to be the subject of breaking changes
as we refine the API.
:::
[`github.com/go-task/task/v3/taskfile`]
The taskfile package provides utilities for reading Taskfiles from various
sources. These sources can be local files, remote files, or even in-memory
strings (via stdin).
taskfile.Node- A reference to the location of a Taskfile. ANodeis an
interface that has several implementations:taskfile.FileNode- Local filestaskfile.HTTPNode- Remote files via HTTP/HTTPStaskfile.GitNode- Remote files via Gittaskfile.StdinNode- In-memory strings (via stdin)
taskfile.Reader- Accepts aNodeand reads the Taskfile from it.taskfile.Snippet- Mostly used for rendering Taskfile errors. A snippet
stores a small part of a taskfile around a given line number and column. The
output can be syntax highlighted for CLIs and include line/column indicators.
[`github.com/go-task/task/v3/taskfile/ast`]
AST stands for "Abstract Syntax Tree". An AST allows us to easily
represent the Taskfile syntax in Go. This package provides a way to parse
Taskfile YAML into an AST and store them in memory.
ast.TaskfileGraph- Represents a set of Taskfiles and their dependencies
between one another.ast.Taskfile- Represents a single Taskfile or a set of merged Taskfiles.
TheTaskfiletype contains all of the subtypes for the Taskfile syntax, such
astasks,includes,vars, etc. These are not listed here for brevity.
[`github.com/go-task/task/v3/errors`]
Contains all of the error types used in Task. All of these types implement theerrors.TaskError interface which wraps Go's standard error interface.
This allows you to call the Code method on the error to obtain the unique exit
code for any error.
Reading Taskfiles
Start by importing the github.com/go-task/task/v3/taskfile package. This
provides all of the functions you need to read a Taskfile into memory:
import (
"github.com/go-task/task/v3/taskfile"
)Reading Taskfiles is done by using a taskfile.Reader and an implementation
of taskfile.Node. In this example we will read a local file by using thetaskfile.FileNode type. You can create this by calling thetaskfile.NewFileNode function:
node := taskfile.NewFileNode("Taskfile.yml", "./path/to/dir")and then create a your reader by calling the taskfile.NewReader function and
passing any functional options you want to use. For example, you could pass a
debug function to the reader which will be called with debug messages:
reader := taskfile.NewReader(
taskfile.WithDebugFunc(func(s string) {
slog.Debug(s)
}),
)Now that everything is set up, you can read the Taskfile (and any included
Taskfiles) by calling the Read method on the reader and pass the Node as an
argument:
ctx := context.Background()
tfg, err := reader.Read(ctx, node)
// handle errorThis returns an instance of ast.TaskfileGraph which is a "Directed Acyclic
Graph" (DAG) of all the parsed Taskfiles. We use this graph to store and resolve
the includes directives in Taskfiles. However most of the time, you will want
a merged Taskfile. To do this, simply call the Merge method on the Taskfile
graph:
tf, err := tfg.Merge()
// handle errorThis compiles the DAG into a single ast.Taskfile containing all the
namespaces and tasks from all the Taskfiles we read.
::: info
We plan to remove AST merging in the future as it is unnecessarily complex and
causes lots of issues with scoping.
:::
Website Src Latest Docs Reference Schema (`website/src/latest/docs/reference/schema.md`)
title: Taskfile Schema Reference section: Reference docType: reference outline: deep
Taskfile Schema Reference
This page documents all available properties and types for the Taskfile schema
version 3, based on the
official JSON schema.
Root Schema
The root Taskfile schema defines the structure of your main Taskfile.yml.
`version`
- Type:
stringornumber - Required: Yes
- Valid values:
"3",3, or any valid semver string - Description: Version of the Taskfile schema
version: '3'`output`
- Type:
stringorobject - Default:
interleaved - Options:
interleaved,group,prefixed - Description: Controls how task output is displayed
# Simple string format
output: group
# Advanced object format
output:
group:
begin: "::group::{{.TASK}}"
end: "::endgroup::"
error_only: false`method`
- Type:
string - Default:
checksum - Options:
checksum,timestamp,none - Description: Default method for checking if tasks are up-to-date
method: timestamp[`includes`](#include)
- Type:
map[string]Include - Description: Include other Taskfiles
includes:
# Simple string format
docs: ./Taskfile.yml
# Full object format
backend:
taskfile: ./backend
dir: ./backend
optional: false
flatten: false
internal: false
aliases: [api]
excludes: [internal-task]
vars:
SERVICE_NAME: backend
checksum: abc123...[`vars`](#variable)
- Type:
map[string]Variable - Description: Global variables available to all tasks
vars:
# Simple values
APP_NAME: myapp
VERSION: 1.0.0
DEBUG: true
PORT: 8080
FEATURES: [auth, logging]
# Dynamic variables
COMMIT_HASH:
sh: git rev-parse HEAD
# Variable references
BUILD_VERSION:
ref: .VERSION
# Map variables
CONFIG:
map:
database: postgres
cache: redis`env`
- Type:
map[string]Variable - Description: Global environment variables
env:
NODE_ENV: production
DATABASE_URL:
sh: echo $DATABASE_URL[`tasks`](#task)
- Type:
map[string]Task - Description: Task definitions
tasks:
# Simple string format
hello: echo "Hello World"
# Array format
build:
- go mod tidy
- go build ./...
# Full object format
deploy:
desc: Deploy the application
cmds:
- ./scripts/deploy.sh`silent`
- Type:
bool - Default:
false - Description: Suppress task name and command output by default
silent: true`dotenv`
- Type:
[]string - Description: Load environment variables from .env files. When the same
variable is defined in multiple files, the first file in the list takes
precedence.
dotenv:
- .env.local # Highest priority
- .env # Lowest priority`run`
- Type:
string - Default:
always - Options:
always,once,when_changed - Description: Default execution behavior for tasks
run: once`interval`
- Type:
string - Default:
100ms - Pattern:
^[0-9]+(?:m|s|ms)$ - Description: Watch interval for file changes
interval: 1s`set`
- Type:
[]string - Options:
allexport,a,errexit,e,noexec,n,noglob,f,nounset,u,xtrace,x,pipefail - Description: POSIX shell options for all commands
set: [errexit, nounset, pipefail]`shopt`
- Type:
[]string - Options:
expand_aliases,globstar,nullglob - Description: Bash shell options for all commands
shopt: [globstar]`use_gitignore`
- Type:
bool - Default:
false - Description: Exclude files matched by
.gitignorerules when resolvingsourcesandgeneratesglobs for all tasks. Can be overridden per task.
use_gitignore: trueInclude
Configuration for including external Taskfiles.
`taskfile`
- Type:
string - Required: Yes
- Description: Path to the Taskfile or directory to include
includes:
backend: ./backend/Taskfile.yml
# Shorthand for above
frontend: ./frontend`dir`
- Type:
string - Description: Working directory for included tasks
includes:
api:
taskfile: ./api
dir: ./api`optional`
- Type:
bool - Default:
false - Description: Don't error if the included file doesn't exist
includes:
optional-tasks:
taskfile: ./optional.yml
optional: true`flatten`
- Type:
bool - Default:
false - Description: Include tasks without namespace prefix
includes:
common:
taskfile: ./common.yml
flatten: true`internal`
- Type:
bool - Default:
false - Description: Hide included tasks from command line and
--list
includes:
internal:
taskfile: ./internal.yml
internal: true
[...]
tasks:
example:
desc: using an internal task
cmds:
- task: internal:default`aliases`
- Type:
[]string - Description: Alternative names for the namespace
includes:
database:
taskfile: ./db.yml
aliases: [db, data]`excludes`
- Type:
[]string - Description: Task names or namespace patterns ending in
:*to exclude
from inclusion
includes:
shared:
taskfile: ./shared.yml
excludes: [internal-setup, 'debug:*', 'experimental:*']`vars`
- Type:
map[string]Variable - Description: Variables to pass to the included Taskfile
includes:
deploy:
taskfile: ./deploy.yml
vars:
ENVIRONMENT: production`checksum`
- Type:
string - Description: Expected checksum of the included file
includes:
remote:
taskfile: https://example.com/tasks.yml
checksum: c153e97e0b3a998a7ed2e61064c6ddaddd0de0c525feefd6bba8569827d8efe9Variable
Variables support multiple types and can be static values, dynamic commands,
references, or maps.
Static Variables
vars:
# String
APP_NAME: myapp
# Number
PORT: 8080
# Boolean
DEBUG: true
# Array
FEATURES: [auth, logging, metrics]
# Null
OPTIONAL_VAR: nullDynamic Variables (`sh`)
vars:
COMMIT_HASH:
sh: git rev-parse HEAD
BUILD_TIME:
sh: date -u +"%Y-%m-%dT%H:%M:%SZ"Variable References (`ref`)
vars:
BASE_VERSION: 1.0.0
FULL_VERSION:
ref: .BASE_VERSIONMap Variables (`map`)
vars:
CONFIG:
map:
database:
host: localhost
port: 5432
cache:
type: redis
ttl: 3600Secret Variables (`secret`)
Mark variables as secret to mask their values in command logs.
vars:
API_KEY:
value: 'sk-1234567890abcdef'
secret: true # This variable will be masked in logs
DB_PASSWORD:
sh: vault read -field=password secret/db
secret: true # Works with dynamic variables tooWhen a variable is marked as secret: true, Task will replace its value with***** in command logs. The actual command execution still receives the real
value.
::: info
For complete documentation on secret variables, including security
considerations and best practices, see the
Secret variables section in the Guide.
:::
Variable Ordering
Variables can reference previously defined variables:
vars:
GREETING: Hello
TARGET: World
MESSAGE: '{{.GREETING}} {{.TARGET}}!'Task
Individual task configuration with multiple syntax options.
Simple Task Formats
tasks:
# String command
hello: echo "Hello World"
# Array of commands
build:
- go mod tidy
- go build ./...
# Object with cmd shorthand
test:
cmd: go test ./...Task Properties
`cmds`
- Type:
[]Command - Description: Commands to execute
tasks:
build:
cmds:
- go build ./...
- echo "Build complete"`cmd`
- Type:
string - Description: Single command (alternative to
cmds)
tasks:
test:
cmd: go test ./...`deps`
- Type:
[]Dependency - Description: Tasks to run before this task
tasks:
# Simple dependencies
deploy:
deps: [build, test]
cmds:
- ./deploy.sh
# Dependencies with variables
advanced-deploy:
deps:
- task: build
vars:
ENVIRONMENT: production
- task: test
vars:
COVERAGE: true
cmds:
- ./deploy.sh
# Silent dependencies
main:
deps:
- task: setup
silent: true
cmds:
- echo "Main task"
# Loop dependencies
test-all:
deps:
- for: [unit, integration, e2e]
task: test
vars:
TEST_TYPE: '{{.ITEM}}'
cmds:
- echo "All tests completed"`desc`
- Type:
string - Description: Short description shown in
--list
tasks:
test:
desc: Run unit tests
cmds:
- go test ./...`summary`
- Type:
string - Description: Detailed description shown in
--summary
tasks:
deploy:
desc: Deploy to production
summary: |
Deploy the application to production environment.
This includes building, testing, and uploading artifacts.`prompt`
- Type:
stringor[]string - Description: Prompts shown before task execution
tasks:
# Single prompt
deploy:
prompt: "Deploy to production?"
cmds:
- ./deploy.sh
# Multiple prompts
deploy-multi:
prompt:
- "Are you sure?"
- "This will affect live users!"
cmds:
- ./deploy.sh`aliases`
- Type:
[]string - Description: Alternative names for the task
tasks:
build:
aliases: [compile, make]
cmds:
- go build ./...`method`
- Type:
string - Default:
checksum - Options:
checksum,timestamp,none - Description: Method for checking if the task is up-to-date. Refer to the
methodroot property for details.
tasks:
build:
sources:
- go.mod
method: timestamp`sources`
- Type:
[]stringor[]Glob - Description: Source files to monitor for changes
tasks:
build:
sources:
- '**/*.go'
- go.mod
# With exclusions
- exclude: '**/*_test.go'
cmds:
- go build ./...`generates`
- Type:
[]stringor[]Glob - Description: Files generated by this task
tasks:
build:
sources: ['**/*.go']
generates:
- './app'
- exclude: '*.debug'
cmds:
- go build -o app ./cmd`use_gitignore`
- Type:
bool - Default:
false - Description: Exclude files matched by
.gitignorerules when resolving
this task'ssourcesandgeneratesglobs. Overrides the root-leveluse_gitignoresetting.
tasks:
build:
use_gitignore: true
sources:
- '**/*.go'
cmds:
- go build ./...`status`
- Type:
[]string - Description: Commands to check if task should run
tasks:
install-deps:
status:
- test -f node_modules/.installed
cmds:
- npm install
- touch node_modules/.installed`preconditions`
- Type:
[]Precondition - Description: Conditions that must be met before running
tasks:
# Simple precondition (shorthand)
build:
preconditions:
- test -d ./src
cmds:
- go build ./...
# Preconditions with custom messages
deploy:
preconditions:
- sh: test -n "$API_KEY"
msg: 'API_KEY environment variable is required'
- sh: test -f ./app
msg: "Application binary not found. Run 'task build' first."
cmds:
- ./deploy.sh`if`
- Type:
string - Description: Shell command to conditionally execute the task. If the
command exits with a non-zero code, the task is skipped (not failed).
tasks:
# Task only runs in CI environment
deploy:
if: '[ "$CI" = "true" ]'
cmds:
- ./deploy.sh
# Using Go template expressions
build-prod:
if: '{{eq .ENV "production"}}'
cmds:
- go build -ldflags="-s -w" ./...`dir`
- Type:
string - Description: The directory in which this task should run
- Default: If the task is in the root Taskfile, the default
dirisROOT_DIR. For included Taskfiles, the defaultdiris the value specified in
their respectiveincludes.*.dirfield (if any).
tasks:
current-dir:
dir: '{{.USER_WORKING_DIR}}'
cmd: pwd`requires`
- Type:
Requires - Description: Required variables with optional enum validation
tasks:
deploy:
requires:
vars: [API_KEY, ENVIRONMENT]
cmds:
- ./deploy.sh
advanced-deploy:
requires:
vars:
- API_KEY
- name: ENVIRONMENT
enum: [development, staging, production]
- name: LOG_LEVEL
enum: [debug, info, warn, error]
cmds:
- echo "Deploying to {{.ENVIRONMENT}} with log level {{.LOG_LEVEL}}"
- ./deploy.sh
# Requirements with enum from variable reference
reusable-deploy:
requires:
vars:
- name: ENVIRONMENT
enum:
ref: .ALLOWED_ENVS
cmds:
- ./deploy.sh[`vars`](#variable)
- Type:
map[string]Variable - Description: Task level variables available to individual task
tasks:
default:
vars:
# Simple values
APP_NAME: myapp
VERSION: 1.0.0
DEBUG: true
PORT: 8080
FEATURES: [auth, logging]
cmds:
#Β β¦See
Prompting for missing variables interactively
for information on enabling interactive prompts for missing required variables.
`watch`
- Type:
bool - Default:
false - Description: Automatically run task in watch mode
tasks:
dev:
watch: true
cmds:
- npm run dev`platforms`
- Type:
[]string - Description: Platforms where this task should run
tasks:
windows-build:
platforms: [windows]
cmds:
- go build -o app.exe ./cmd
unix-build:
platforms: [linux, darwin]
cmds:
- go build -o app ./cmdCommand
Individual command configuration within a task.
Basic Commands
tasks:
example:
cmds:
- echo "Simple command"
- ls -laCommand Object
tasks:
example:
cmds:
- cmd: echo "Hello World"
silent: true
ignore_error: false
platforms: [linux, darwin]
set: [errexit]
shopt: [globstar]
timeout: 5mTask References
tasks:
example:
cmds:
- task: other-task
vars:
PARAM: value
silent: falseDeferred Commands
tasks:
with-cleanup:
cmds:
- echo "Starting work"
# Deferred command string
- defer: echo "Cleaning up"
# Deferred task reference
- defer:
task: cleanup-task
vars:
CLEANUP_MODE: fullFor Loops
Loop Over List
tasks:
greet-all:
cmds:
- for: [alice, bob, charlie]
cmd: echo "Hello {{.ITEM}}"Loop Over Sources/Generates
tasks:
process-files:
sources: ['*.txt']
cmds:
- for: sources
cmd: wc -l {{.ITEM}}
- for: generates
cmd: gzip {{.ITEM}}Loop Over Variable
tasks:
process-items:
vars:
ITEMS: 'item1,item2,item3'
cmds:
- for:
var: ITEMS
split: ','
as: CURRENT
cmd: echo "Processing {{.CURRENT}}"Loop Over Matrix
tasks:
test-matrix:
cmds:
- for:
matrix:
OS: [linux, windows, darwin]
ARCH: [amd64, arm64]
cmd: echo "Testing {{.ITEM.OS}}/{{.ITEM.ARCH}}"Loop in Dependencies
tasks:
build-all:
deps:
- for: [frontend, backend, worker]
task: build
vars:
SERVICE: '{{.ITEM}}'Conditional Commands
Use if to conditionally execute a command. If the shell command exits with a
non-zero code, the command is skipped.
tasks:
build:
cmds:
# Only run in production
- cmd: echo "Optimizing for production"
if: '[ "$ENV" = "production" ]'
# Using Go templates
- cmd: echo "Feature enabled"
if: '{{eq .ENABLE_FEATURE "true"}}'
# Inside for loops (evaluated per iteration)
- for: [a, b, c]
cmd: echo "processing {{.ITEM}}"
if: '[ "{{.ITEM}}" != "b" ]'Command Timeouts
Use timeout to limit how long a command may run. The value uses Go duration
syntax (e.g. 30s, 5m, 1h30m) and must be greater than zero.
tasks:
deploy:
cmds:
- cmd: npm run build
timeout: 5m
- cmd: ./deploy.sh
timeout: 30mWhen 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 condition that hangs is cut short
too, and ignore_error covers a timeout like any other failure. A
timed-out command reports EXIT_CODE124, following the convention of timeout(1).
A dependency takes the same key:
tasks:
build:
deps:
- task: fetch-assets
timeout: 2mThe key goes next to the command whatever form it takes, including a defer:
tasks:
deploy:
cmds:
- defer:
task: cleanup
timeout: 30s
- defer: ./cleanup.sh
timeout: 30sA timed-out deferred command is logged and ignored, like other deferred errors.
Calling a task that is already running under run: once orrun: when_changed joins that execution instead of starting a second
one. A timeout on such a call bounds how long you wait for it, not the shared
execution itself, which only the caller that started it can bound.
Shell Options
Set Options
Available set options for POSIX shell features:
allexport/a- Export all variableserrexit/e- Exit on errornoexec/n- Read commands but don't executenoglob/f- Disable pathname expansionnounset/u- Error on undefined variablesxtrace/x- Print commands before executionpipefail- Pipe failures propagate
# Global level
set: [errexit, nounset, pipefail]
tasks:
debug:
# Task level
set: [xtrace]
cmds:
- cmd: echo "This will be traced"
# Command level
set: [noexec]Shopt Options
Available shopt options for Bash features:
expand_aliases- Enable alias expansionglobstar- Enable**recursive globbingnullglob- Null glob expansion
# Global level
shopt: [globstar]
tasks:
find-files:
# Task level
shopt: [nullglob]
cmds:
- cmd: ls **/*.go
# Command level
shopt: [globstar]Website Src Latest Docs Reference Templating (`website/src/latest/docs/reference/templating.md`)
title: Templating Reference Comprehensive guide to Task's templating system with Go text/template, special variables, and available functions section: Reference docType: reference outline: deep
Templating Reference
Task's templating engine uses Go's
text/template package to interpolate values.
This reference covers the main features and all available functions for creating
dynamic Taskfiles. Most of the provided functions come from the
slim-sprig library.
Basic Usage
Most string values in Task can be templated using double curly braces{{ and }}. Anything inside the braces is executed as a Go
template.
Simple Variable Interpolation
version: '3'
tasks:
hello:
vars:
MESSAGE: 'Hello, World!'
cmds:
- 'echo {{.MESSAGE}}'Output:
Hello, World!Conditional Logic
version: '3'
tasks:
maybe-happy:
vars:
SMILE: ':\)'
FROWN: ':\('
HAPPY: true
cmds:
- 'echo {{if .HAPPY}}{{.SMILE}}{{else}}{{.FROWN}}{{end}}'Output:
:)Function Calls and Pipes
version: '3'
tasks:
uniq:
vars:
NUMBERS: '0,1,1,1,2,2,3'
cmds:
- 'echo {{splitList "," .NUMBERS | uniq | join ", "}}'Output:
0, 1, 2, 3Control Flow with Loops
version: '3'
tasks:
loop:
vars:
NUMBERS: [0, 1, 1, 1, 2, 2, 3]
cmds:
- |
{{range $index, $num := .NUMBERS}}
{{if gt $num 1}}{{break}}{{end}}
echo {{$index}}: {{$num}}
{{end}}Output:
0: 0
1: 1
2: 1
3: 1Special Variables
Task provides special variables that are always available in templates. These
override any user-defined variables with the same name.
CLI
`CLI_ARGS`
- Type:
string - Description: All extra arguments passed after
--as a string
tasks:
test:
cmds:
- go test {{.CLI_ARGS}}task test -- -v -race
# Runs: go test -v -race`CLI_ARGS_LIST`
- Type:
[]string - Description: All extra arguments passed after
--as a shell parsed list
tasks:
docker-run:
cmds:
- docker run {{range .CLI_ARGS_LIST}}{{.}} {{end}}myapp`CLI_FORCE`
- Type:
bool - Description: Whether
--forceor--force-allflags were set
tasks:
deploy:
cmds:
- |
{{if .CLI_FORCE}}
echo "Force deployment enabled"
{{end}}
./deploy.sh`CLI_SILENT`
- Type:
bool - Description: Whether
--silentflag was set
`CLI_VERBOSE`
- Type:
bool - Description: Whether
--verboseflag was set
`CLI_OFFLINE`
- Type:
bool - Description: Whether
--offlineflag was set
`CLI_ASSUME_YES`
- Type:
bool - Description: Whether
--yesflag was set
Task
`TASK`
- Type:
string - Description: Name of the current task
tasks:
build:
cmds:
- echo "Running task {{.TASK}}"`ALIAS`
- Type:
string - Description: Alias used for the current task, otherwise matches
TASK
`TASK_EXE`
- Type:
string - Description: Task executable name or path
tasks:
self-update:
cmds:
- echo "Updating {{.TASK_EXE}}"File Paths
`ROOT_TASKFILE`
- Type:
string - Description: Absolute path of the root Taskfile
`ROOT_DIR`
- Type:
string - Description: Absolute path of the root Taskfile directory
`TASKFILE`
- Type:
string - Description: Absolute path of the current (included) Taskfile
`TASKFILE_DIR`
- Type:
string - Description: Absolute path of the current Taskfile directory
`TASK_DIR`
- Type:
string - Description: Absolute path where the task is executed
`USER_WORKING_DIR`
- Type:
string - Description: Absolute path where
taskwas called from
tasks:
info:
cmds:
- echo "Root {{.ROOT_DIR}}"
- echo "Current {{.TASKFILE_DIR}}"
- echo "Working {{.USER_WORKING_DIR}}"`FILE_PATH_SEPARATOR`
- Type:
string - Description: OS-specific path separator: Windows =
\, others =/
::: info
See
joinPathin Path Functions for joining filesystem paths for use with
file system operations.
:::
Environment Variables
`PATH_LIST_SEPARATOR`
- Type:
string - Description: OS-specific path separator for environment variables: Windows =
;, others =:
::: info
See
joinEnvin Environment Variable Functions for joining
paths for use in environment variables.
:::
Status
`CHECKSUM`
- Type:
string - Description: Checksum of files in
sources(only instatuswithchecksummethod)
`TIMESTAMP`
- Type:
time.Time - Description: Greatest timestamp of files in
sources(only instatus
withtimestampmethod)
tasks:
build:
method: checksum
sources: ['**/*.go']
status:
- test "{{.CHECKSUM}}" = "$(cat .last-checksum)"
cmds:
- go build ./...
- echo "{{.CHECKSUM}}" > .last-checksumLoop
`ITEM`
- Type:
any - Description: Current iteration value when using
forproperty
tasks:
greet:
cmds:
- for: [alice, bob, charlie]
cmd: echo "Hello {{.ITEM}}"Can be renamed using as:
tasks:
greet:
cmds:
- for:
var: NAMES
as: NAME
cmd: echo "Hello {{.NAME}}"Defer
`EXIT_CODE`
- Type:
int - Description: Failed command exit code (only in
defer, only when
non-zero). A command killed by itstimeout
is reported as124, following the convention oftimeout(1).
tasks:
deploy:
cmds:
- ./deploy.sh
- defer: |
{{if .EXIT_CODE}}
echo "Deployment failed with code {{.EXIT_CODE}}"
./rollback.sh
{{end}}System
`TASK_VERSION`
- Type:
string - Description: Current version of Task
tasks:
version:
cmds:
- echo "Using Task {{.TASK_VERSION}}"Available Functions
Task provides a comprehensive set of functions for templating. Functions can be chained using pipes (|) and combined for powerful templating capabilities.
Logic and Control Flow
`and`, `or`, `not`
Boolean operations for conditional logic
tasks:
conditional:
vars:
DEBUG: true
VERBOSE: false
PRODUCTION: false
cmds:
- echo "{{if and .DEBUG .VERBOSE}}Debug mode with verbose{{end}}"
- echo "{{if or .DEBUG .VERBOSE}}Some kind of debug{{end}}"
- echo "{{if not .PRODUCTION}}Development build{{end}}"`eq`, `ne`, `lt`, `le`, `gt`, `ge`
Comparison operations
tasks:
compare:
vars:
VERSION: 3
cmds:
- echo "{{if gt .VERSION 2}}Version 3 or higher{{end}}"
- echo "{{if eq .VERSION 3}}Exactly version 3{{end}}"Data Access and Manipulation
`index`
Access array/map elements by index or key
tasks:
access:
vars:
SERVICES: [api, web, worker]
CONFIG:
map:
database: postgres
port: 5432
cmds:
- echo "First service {{index .SERVICES 0}}"
- echo "Database {{index .CONFIG "database"}}"`len`
Get length of arrays, maps, or strings
tasks:
length:
vars:
ITEMS: [a, b, c, d]
TEXT: "Hello World"
cmds:
- echo "Found {{len .ITEMS}} items"
- echo "Text has {{len .TEXT}} characters"`slice`
Extract a portion of an array or string
tasks:
slice-demo:
vars:
ITEMS: [a, b, c, d, e]
cmds:
- echo "{{slice .ITEMS 1 3}}" # [b c]String Functions
Basic String Operations
tasks:
string-basic:
vars:
MESSAGE: ' Hello World '
NAME: 'john doe'
TEXT: "Hello World"
cmds:
- echo "{{.MESSAGE | trim}}" # "Hello World"
- echo "{{.NAME | title}}" # "John Doe"
- echo "{{.NAME | upper}}" # "JOHN DOE"
- echo "{{.MESSAGE | lower}}" # "hello world"
- echo "{{.NAME | trunc 4}}" # "john"
- echo "{{"test" | repeat 3}}" # "testtesttest"
- echo "{{.TEXT | substr 0 5}}" # "Hello"String Testing and Searching
tasks:
string-test:
vars:
FILENAME: 'app.tar.gz'
EMAIL: '[email protected]'
cmds:
- echo "{{.FILENAME | hasPrefix "app"}}" # true
- echo "{{.FILENAME | hasSuffix ".gz"}}" # true
- echo "{{.EMAIL | contains "@"}}" # trueString Replacement and Formatting
tasks:
string-format:
vars:
TEXT: 'Hello, World!'
UNSAFE: 'file with spaces.txt'
cmds:
- echo "{{.TEXT | replace "," ""}}" # "Hello World!"
- echo "{{.TEXT | quote}}" # "\"Hello, World!\""
- echo "{{.UNSAFE | shellQuote}}" # Shell-safe quoting
- echo "{{.UNSAFE | q}}" # Short alias for shellQuoteRegular Expressions
tasks:
regex:
vars:
EMAIL: '[email protected]'
TEXT: 'abc123def456'
cmds:
- echo "{{regexMatch "@" .EMAIL}}" # true
- echo "{{regexFind "[0-9]+" .TEXT}}" # "123"
- echo "{{regexFindAll "[0-9]+" .TEXT -1}}" # ["123", "456"]
- echo "{{regexReplaceAll "[0-9]+" .TEXT "X"}}" # "abcXdefX"List Functions
List Access and Basic Operations
tasks:
list-basic:
vars:
ITEMS: ["apple", "banana", "cherry", "date"]
cmds:
- echo "First {{.ITEMS | first}}" # "apple"
- echo "Last {{.ITEMS | last}}" # "date"
- echo "Rest {{.ITEMS | rest}}" # ["banana", "cherry", "date"]
- echo "Initial {{.ITEMS | initial}}" # ["apple", "banana", "cherry"]
- echo "Length {{.ITEMS | len}}" # 4List Manipulation
tasks:
list-manipulate:
vars:
NUMBERS: [3, 1, 4, 1, 5, 9, 1]
FRUITS: ["apple", "banana"]
cmds:
- echo "{{.NUMBERS | uniq}}" # [3, 1, 4, 5, 9]
- echo "{{.NUMBERS | sortAlpha}}" # [1, 1, 1, 3, 4, 5, 9]
- echo"'{{append .FRUITS "cherry"}}"" # ["apple", "banana", "cherry"]
- echo "{{ without .NUMBERS 1}}" # [3, 4, 5, 9]
- echo "{{.NUMBERS | has 5}}" # trueString Lists
tasks:
string-lists:
vars:
CSV: 'apple,banana,cherry'
WORDS: ['hello', 'world', 'from', 'task']
MULTILINE: |
line1
line2
line3
cmds:
- echo "{{.CSV | splitList ","}}" # ["apple", "banana", "cherry"]
- echo "{{.WORDS | join " "}}" # "hello world from task"
- echo "{{.WORDS | sortAlpha}}" # ["from", "hello", "task", "world"]
- echo "{{.MULTILINE | splitLines}}" # Split on newlines (Unix/Windows)
- echo "{{.MULTILINE | catLines}}" # Replace newlines with spacesIn pipeline form, join receives the list from the left-hand side. The
equivalent non-pipeline form is {{join " " .WORDS}}.
Shell Argument Parsing
tasks:
shell-args:
vars:
ARGS: 'file1.txt -v --output="result file.txt"'
cmds:
- |
{{range .ARGS | splitArgs}}
echo "Arg: {{.}}"
{{end}}Math Functions
tasks:
math:
vars:
A: 10
B: 3
NUMBERS: [1, 5, 3, 9, 2]
cmds:
- echo "Addition {{add .A .B}}" # 13
- echo "Subtraction {{sub .A .B}}" # 7
- echo "Multiplication {{mul .A .B}}" # 30
- echo "Division {{div .A .B}}" # 3
- echo "Modulo {{mod .A .B}}" # 1
- echo "Maximum {{.NUMBERS | max}}" # 9
- echo "Minimum {{.NUMBERS | min}}" # 1
- echo "Random 1-99 {{randInt 1 100}}" # Random number
- echo "Random 0-999 {{randIntN 1000}}" # Random number 0-999Date and Time Functions
tasks:
date-time:
vars:
BUILD_DATE: "2023-12-25"
cmds:
- echo "Now {{now | date "2006-01-02 15:04:05"}}"
- echo {{ toDate "2006-01-02" .BUILD_DATE }}
- echo "Build {{.BUILD_DATE | toDate "2006-01-02" | date "Jan 2, 2006"}}"
- echo "Unix timestamp {{now | unixEpoch}}"
- echo "Duration ago {{now | ago}}"System Functions
Platform Information
tasks:
platform:
cmds:
- echo "OS {{OS}}" # linux, darwin, windows, etc.
- echo "Architecture {{ARCH}}" # amd64, arm64, etc.
- echo "CPU cores {{numCPU}}" # Number of CPU cores
- echo "Building for {{OS}}/{{ARCH}}"Path Functions
tasks:
paths:
vars:
WIN_PATH: 'C:\Users\name\file.txt'
OUTPUT_DIR: 'dist'
BINARY_NAME: 'myapp'
cmds:
- echo "{{.WIN_PATH | toSlash}}" # Convert to forward slashes
- echo "{{.WIN_PATH | fromSlash}}" # Convert to OS-specific slashes
- echo "{{joinPath .OUTPUT_DIR .BINARY_NAME}}" # Join path elements
- echo "Relative {{relPath .ROOT_DIR .TASKFILE_DIR}}" # Get relative path
- echo '{{absPath "../sibling"}}' # Resolve to an absolute pathEnvironment Variable Functions
tasks:
paths:
vars:
WIN_PATH1: 'C:\Users\Person\bin'
WIN_PATH2: 'C:\Shared\bin'
cmds:
# Join paths for Windows ENV vars:
# C:\Users\Person\bin;C:\Shared\bin
- echo "{{joinEnv .WIN_PATH1 .WIN_PATH2}}"tasks:
paths:
vars:
POSIX_PATH1: '/users/person/.local/bin'
POSIX_PATH2: '/usr/bin'
cmds:
# Join paths for POSIX ENV vars:
# /users/person/.local/bin:/usr/bin
- echo "{{joinEnv .POSIX_PATH1 .POSIX_PATH2}}"URLs
tasks:
paths:
vars:
SERVER: 'http://localhost'
PATH1: 'path1'
PATH2: 'path2'
cmds:
# Join paths for URL:
# http://localhost/path1/path2
- echo "{{joinUrl .SERVER .PATH1 .PATH2}}"Data Structure Functions
Dictionary Operations
tasks:
dict:
vars:
CONFIG:
map:
database: postgres
port: 5432
ssl: true
cmds:
- echo "Database {{get .CONFIG "database"}}"
- echo "Database {{"database" | get .CONFIG}}"
- echo "Keys {{.CONFIG | keys}}"
- echo "Keys {{keys .CONFIG }}"
- echo "Has SSL {{hasKey .CONFIG "ssl"}}"
- echo "{{dict "env" "prod" "debug" false}}"Merging and Combining
tasks:
merge:
vars:
BASE_CONFIG:
map:
timeout: 30
retries: 3
USER_CONFIG:
map:
timeout: 60
debug: true
cmds:
- echo "{{merge .BASE_CONFIG .USER_CONFIG | toJson}}"Default Values and Coalescing
tasks:
defaults:
vars:
API_URL: ""
DEBUG: false
ITEMS: []
cmds:
- echo "{{.API_URL | default "http://localhost:8080"}}"
- echo "{{.DEBUG | default true}}"
- echo "{{.MISSING_VAR | default "fallback"}}"
- echo "{{coalesce .API_URL .FALLBACK_URL "default"}}"
- echo "Is empty {{empty .ITEMS}}" # trueEncoding and Serialization
JSON
tasks:
json:
vars:
DATA:
map:
name: 'Task'
version: '3.0'
JSON_STRING: '{"key": "value", "number": 42}'
cmds:
- echo "{{.DATA | toJson}}"
- echo "{{.DATA | toPrettyJson}}"
- echo "{{.JSON_STRING | fromJson }}"YAML
tasks:
yaml:
vars:
CONFIG:
map:
database:
host: localhost
port: 5432
YAML_STRING: |
key: value
items:
- one
- two
cmds:
- echo "{{.CONFIG | toYaml}}"
- echo "{{.YAML_STRING | fromYaml}}"Base64
tasks:
base64:
vars:
SECRET: 'my-secret-key'
cmds:
- echo "{{.SECRET | b64enc}}" # Encode to base64
- echo "{{"bXktc2VjcmV0LWtleQ==" | b64dec}}" # Decode from base64Type Conversion
tasks:
convert:
vars:
NUM_STR: '42'
FLOAT_STR: '3.14'
BOOL_STR: 'true'
ITEMS: [1, 2, 3]
cmds:
- echo "{{.NUM_STR | atoi | add 8}}" # String to int: 50
- echo "{{.FLOAT_STR | float64}}" # String to float: 3.14
- echo "{{.ITEMS | toStrings}}" # Convert to strings: ["1", "2", "3"]Utility Functions
UUID Generation
tasks:
generate:
vars:
DEPLOYMENT_ID: "{{uuid}}"
cmds:
- echo "Deployment ID {{.DEPLOYMENT_ID}}"Debugging
tasks:
debug:
vars:
COMPLEX_VAR:
map:
items: [1, 2, 3]
nested:
key: value
cmds:
- echo "{{spew .COMPLEX_VAR}}" # Pretty-print for debuggingOutput Functions
Formatted Output
tasks:
output:
vars:
VERSION: "1.2.3"
BUILD: 42
cmds:
- echo '{{print "Simple output"}}'
- echo '{{printf "Version %s.%d" .VERSION .BUILD}}'
- echo '{{println "With newline"}}'Website Src Latest Docs Security Incident Response Plan (`website/src/latest/docs/security/incident-response-plan.md`)
title: Incident Response Plan Task's process for detecting, triaging, mitigating, and disclosing security incidents section: Project docType: project outline: deep
Incident Response Plan
This document outlines our incident response plan in the event that a
vulnerability is reported to the Task project. This serves as a high-level,
public guide and is published as part of our commitment to transparency.
Below are the security principles that we aim to adhere to as a project:
- Transparency: All incidents and fixes are documented here for the
community. - Stewardship: Take responsibility for protecting users and the project.
- Protection: Act to minimize harm and provide guidance.
Scope
This plan applies to the core Task repository and all official Task projects.
For example, the Visual Studio Code extension and officially supported
installation methods. In the event that a vulnerability is reported with a
community-managed installation method, we will work with the community and make
a "best-effort" attempt to help resolve the issue.
Steps
π 1. Detect
- All security issues should be privately reported as described in our
security documentation. - Maintainers should also regularly monitor and respond to:
- Pull requests from dependency scanners such as Dependabot.
- GitHub notifications and vulnerability alerts.
- Messages in community channels such as Discord.
π©Ί 2. Triage
- Upon first receipt of a security issue, one of our team will immediately
notify the other maintainers via a secure and private channel. This ensures
that all maintainers are able to contribute to the issue where possible. - A maintainer should respond to the reporter in a timely manner in order to
acknowledge receipt of the issue. - The issue must then be triaged into one of the following categories:
- βΌοΈCritical: Has a serious and immediate impact on users or affects
critical infrastructure related to the project. - βHigh: Has the potential to seriously impact users of a distributed
asset. - π°Medium: Has the potential to impact users, but is obscure or low-risk.
- βLow: No direct or immediate impact to users, but requires attention.
- βΌοΈCritical: Has a serious and immediate impact on users or affects
- Open a draft
GitHub Security Advisory (GHSA)
in the Task repository.- Optionally create a CVE. This can be skipped for low/medium impact issues at
the discretion of the maintainers.
- Optionally create a CVE. This can be skipped for low/medium impact issues at
π©Ή 3. Mitigate
- Act calmly and communicate decisions.
- Stop the bleed.
- Before attempting to fix the issue, perform any actions that stop the
problem from becoming worse. For example:- Rotate any affected secrets.
- Rebuild any affected services (website, etc.).
- It may be difficult to do some of this in cases where packages are
maintained by the community if we are not yet ready to disclose the
vulnerability publicly. This should be decided on a case-by-case basis.
- Before attempting to fix the issue, perform any actions that stop the
- Address the root cause.
- Plan and document a fix.
- Patch the issue.
- Test the fix.
- Release new versions.
π’ 4. Disclose
- Publish the GitHub Security Advisory (GHSE). Make sure to include:
- The affected version(s)/services.
- The impact of the issue.
- The root cause.
- The steps taken to resolve.
- Optionally, create a blog post and/or share the information via our socials
and public communication channels.
π§ 5. Learn
- Document the disclosure in a permanent location.
- Make and document any changes that can be made to prevent similar issues from
arising in the future.
Website Src Latest Docs Security Threat Model (`website/src/latest/docs/security/threat-model.md`)
title: Threat Model Threats, assets, trust boundaries, and mitigations for the Task project and its release infrastructure section: Project docType: project outline: deep
Threat Model
This document outlines the security threats, assets, and mitigations for the
Task project. It serves as a high-level, public guide and is published as part
of our commitment to transparency.
Asset Inventory
Critical Assets
- 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
CI/CD and release pipelines. - Release Metadata: Version numbers, changelogs, and checksums.
- CI/CD Pipelines & Runners: GitHub Actions workflows that build, test, and
release the project. - Third-party Dependencies: Go modules and tools used to build and
distribute Task. - Website & Documentation: The taskfile.dev site and installation scripts.
Asset Locations
- Local developer machines
- GitHub Actions runners
- GitHub Releases
- Public package registries (npm, Homebrew, Winget, Cloudsmith)
- Source control platforms (GitHub)
- Netlify (website hosting)
Threat Model
Actors
- Maintainers & Contributors: Trusted users with varying levels of
repository access. - External Attackers: Untrusted users seeking to compromise builds,
releases, or user systems. - Supply Chain Threats: Malicious dependencies or compromised third-party
services. - CI/CD Systems: Automated agents that may be exploited if misconfigured.
Entry Points
- Source code contributions (pull requests, issues)
- Configuration files and build scripts
- CI/CD integration and environment variables
- Third-party dependencies
- Release pipelines and artifact repositories
- Remote Taskfile fetching (HTTP, Git)
- Installation scripts
Trust Boundaries
- Between the project repository and the CI/CD environment
- Between Task and remote Taskfiles fetched over the network
- Between artifact generation and distribution channels
- Between the Task binary and user-defined shell commands
Threats
Supply Chain Attacks
- Compromised Go dependencies or build tools
- Unauthorized changes to source code or configuration
- Exploitation of third-party CI/CD or package registry services
- Compromised installation scripts or distribution channels
Secrets Leakage
- 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
Code Execution / Injection
- Malicious code execution via compromised pull requests or dependencies
- Remote code execution vulnerabilities in Task or its dependencies
- Note: Task intentionally executes user-defined shell commands as part of
its core functionality. Users are responsible for the commands they define in
their Taskfiles.
Unauthorized Access
- Unauthorized users triggering releases or accessing sensitive artifacts
- Insecure permissions on runners, repositories, or artifact stores
- Compromised maintainer accounts
Data Integrity & Tampering
- Tampering with build artifacts, changelogs, or metadata
- Compromise of signing keys, leading to malicious releases
- Man-in-the-middle attacks against remote Taskfile fetching
Denial of Service
- Abuse of CI/CD resources, bandwidth, or artifact storage
- Overloading automated processes or API endpoints
- Malicious Taskfiles designed to exhaust system resources
Mitigations
Supply Chain Security
- Pin dependencies and use trusted sources
- Mandatory code review and CI checks on all incoming pull requests
- Signed commits and release tags
- Enable immutable releases where supported
- Run
govulncheckon every commit and tag - Pin GitHub Actions to specific commit SHAs
Secrets Management
- Secure storage using GitHub Secrets
- Never log or expose secrets in build or release outputs
- Regularly rotate secrets and monitor for suspicious activity
- Use least-privilege tokens scoped to specific repositories
Secure Code Execution
- Validate and sanitize configuration files and user inputs
- Audit dependencies for vulnerabilities
- HTTP is rejected for remote Taskfiles by default (requires
--insecureflag) - TLS certificate verification for remote Git repositories
Access Control
- Enforce least privilege for CI/CD runners, repositories, and artifact stores
- Require multi-factor authentication for maintainers
- Restrict release triggers to tagged releases only
- Lower permissions of less active maintainers
Artifact Integrity
- Generate checksums for all release artifacts
- Distribute artifacts via trusted, access-controlled repositories
- Verify signatures and checksums in installation scripts where possible
Availability Protection
- Implement rate limiting and resource quotas on CI/CD jobs
- Monitor for abnormal activity and automate alerts
- Set timeouts on network operations (e.g., remote Taskfile fetching)
Residual Risks
- Zero-day vulnerabilities in dependencies, CI/CD systems, or Task itself
- Social engineering attacks targeting maintainers
- Unnoticed supply chain compromises
- Human error in configuration or secret management
- Users fetching malicious remote Taskfiles from untrusted sources
Security Best Practices
- Regularly update dependencies and build tools
- Monitor security advisories and patch vulnerabilities promptly
- Educate contributors on secure coding and secrets hygiene
- Document security policies and incident response procedures
References
- Task Documentation
- Incident Response Plan
- OWASP Top 10
- Supply Chain Security
- GitHub Security Best Practices
Website Src Next Docs Deprecations Completion Scripts (`website/src/next/docs/deprecations/completion-scripts.md`)
title: 'Completion Scripts' section: Project docType: project outline: deep
Completion Scripts
::: danger
This deprecation breaks the following functionality:
- Any direct references to the completion scripts in the Task git repository
:::
Direct use of the completion scripts in the completion/* directory of the
github.com/go-task/task Git repository is deprecated. Any shell
configuration that directly refers to these scripts will potentially break in
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 instead.
Website Src Next Docs Deprecations Template Functions (`website/src/next/docs/deprecations/template-functions.md`)
title: 'Template Functions' Deprecation of some templating functions in Task, with guidance on their replacements. section: Project docType: project outline: deep
Template Functions
::: danger
This deprecation breaks the following functionality:
- A small set of templating functions
:::
The following templating functions are deprecated. Any replacement functions are
listed besides the function being removed.
| Deprecated function | Replaced by |
|---|---|
IsSH |
- |
FromSlash |
fromSlash |
ToSlash |
toSlash |
ExeExt |
exeExt |
Website Src Next Docs Deprecations Template (`website/src/next/docs/deprecations/template.md`)
This is a template for deprecation documentation
Copy this page and fill in the details as necessary
title: '--- Template ---' draft: true # Hide in production outline: deep
{Name of Deprecated Feature} (#{Issue})
::: danger
This deprecation breaks the following functionality:
- {list any existing functionality that will be broken by this deprecation}
- {if there are no breaking changes, remove this admonition}
:::
{Short description of the feature/behavior and why it is being deprecated}
{Short explanation of any replacement features/behaviors and how users should
migrate to it}
Website Src Next Docs Deprecations Version 2 Schema (`website/src/next/docs/deprecations/version-2-schema.md`)
title: 'Version 2 Schema (#1197)' section: Project docType: project outline: deep
Version 2 Schema (#1197)
::: danger
This deprecation breaks the following functionality:
- Any Taskfiles that use the version 2 schema
Taskvar.ymlfiles
:::
The Taskfile version 2 schema was introduced in March 2018 and replaced by
version 3 in August 2019. In May 2023 we published a deprecation
notice for the version 2 schema on the basis that the vast
majority of users had already upgraded to version 3 and removing s