mirror of
https://github.com/go-task/task.git
synced 2026-07-01 16:44:34 +00:00
v3.43.0
This commit is contained in:
@@ -1,245 +0,0 @@
|
||||
---
|
||||
slug: /experiments/map-variables/
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# Map Variables (#1585)
|
||||
|
||||
:::caution
|
||||
|
||||
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.
|
||||
|
||||
:::
|
||||
|
||||
Currently, Task supports all variable types except for maps. This experiment
|
||||
adds two different proposals for map variables. Click on the tabs below to
|
||||
switch between them.
|
||||
|
||||
<Tabs defaultValue="1" queryString="proposal"
|
||||
values={[
|
||||
{label: 'Proposal 1', value: '1'},
|
||||
{label: 'Proposal 2', value: '2'}
|
||||
]}>
|
||||
|
||||
<TabItem value="1">
|
||||
|
||||
:::warning
|
||||
|
||||
This experiment proposal breaks the following functionality:
|
||||
|
||||
- Dynamically defined variables (using the `sh` keyword)
|
||||
|
||||
:::
|
||||
|
||||
:::info
|
||||
|
||||
To enable this experiment, set the environment variable:
|
||||
`TASK_X_MAP_VARIABLES=1`. Check out [our guide to enabling experiments
|
||||
][enabling-experiments] for more information.
|
||||
|
||||
:::
|
||||
|
||||
This proposal removes support for the `sh` and `ref` keywords in favour of a new
|
||||
syntax for dynamically defined variables and references. This allows you to
|
||||
define a map directly as you would for any other type:
|
||||
|
||||
```yaml
|
||||
version: 3
|
||||
|
||||
tasks:
|
||||
foo:
|
||||
vars:
|
||||
FOO: {a: 1, b: 2, c: 3} # <-- Directly defined map on the `FOO` key
|
||||
cmds:
|
||||
- 'echo {{.FOO.a}}'
|
||||
```
|
||||
|
||||
## Migration
|
||||
|
||||
Taskfiles with dynamically defined variables via the `sh` subkey or references
|
||||
defined with `ref` will no longer work with this experiment enabled. In order to
|
||||
keep using these features, you will need to migrate your Taskfile to use the new
|
||||
syntax.
|
||||
|
||||
### Dynamic Variables
|
||||
|
||||
Previously, you had to define dynamic variables using the `sh` subkey. With this
|
||||
experiment enabled, you will need to remove the `sh` subkey and define your
|
||||
command as a string that begins with a `$`. This will instruct Task to interpret
|
||||
the string as a command instead of a literal value and the variable will be
|
||||
populated with the output of the command. For example:
|
||||
|
||||
<Tabs defaultValue="2"
|
||||
values={[
|
||||
{label: 'Before', value: '1'},
|
||||
{label: 'After', value: '2'}
|
||||
]}>
|
||||
|
||||
<TabItem value="1">
|
||||
|
||||
```yaml
|
||||
version: 3
|
||||
|
||||
tasks:
|
||||
foo:
|
||||
vars:
|
||||
CALCULATED_VAR:
|
||||
sh: 'echo hello'
|
||||
cmds:
|
||||
- 'echo {{.CALCULATED_VAR}}'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="2">
|
||||
|
||||
```yaml
|
||||
version: 3
|
||||
|
||||
tasks:
|
||||
foo:
|
||||
vars:
|
||||
CALCULATED_VAR: '$echo hello' # <-- Prefix dynamic variable with a `$`
|
||||
cmds:
|
||||
- 'echo {{.CALCULATED_VAR}}'
|
||||
```
|
||||
|
||||
</TabItem></Tabs>
|
||||
|
||||
### References
|
||||
|
||||
<Tabs defaultValue="2"
|
||||
values={[
|
||||
{label: 'Before', value: '1'},
|
||||
{label: 'After', value: '2'}
|
||||
]}>
|
||||
|
||||
<TabItem value="1">
|
||||
|
||||
```yaml
|
||||
version: 3
|
||||
|
||||
tasks:
|
||||
foo:
|
||||
vars:
|
||||
VAR: 42
|
||||
VAR_REF:
|
||||
ref: '.FOO'
|
||||
cmds:
|
||||
- 'echo {{.VAR_REF}}'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="2">
|
||||
|
||||
```yaml
|
||||
version: 3
|
||||
|
||||
tasks:
|
||||
foo:
|
||||
vars:
|
||||
VAR: 42
|
||||
VAR_REF: '#.FOO' # <-- Prefix reference with a `#`
|
||||
cmds:
|
||||
- 'echo {{.VAR_REF}}'
|
||||
```
|
||||
|
||||
</TabItem></Tabs>
|
||||
|
||||
If your current Taskfile contains a string variable that begins with a `$` or a
|
||||
`#`, you will now need to escape it with a backslash (`\`) to stop Task from
|
||||
interpreting it as a command or reference.
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="2">
|
||||
|
||||
:::info
|
||||
|
||||
To enable this experiment, set the environment variable:
|
||||
`TASK_X_MAP_VARIABLES=2`. Check out [our guide to enabling experiments
|
||||
][enabling-experiments] for more information.
|
||||
|
||||
:::
|
||||
|
||||
This proposal maintains backwards-compatibility and the `sh` subkey and adds
|
||||
another new `map` subkey for defining map variables:
|
||||
|
||||
```yaml
|
||||
version: 3
|
||||
|
||||
tasks:
|
||||
foo:
|
||||
vars:
|
||||
FOO:
|
||||
map: {a: 1, b: 2, c: 3} # <-- Defined using the `map' subkey instead of directly on 'FOO'
|
||||
BAR: true # <-- Other types of variables are still defined directly on the key
|
||||
BAZ:
|
||||
sh: 'echo Hello Task' # <-- The `sh` subkey is still supported
|
||||
QUX:
|
||||
ref: '.BAZ' # <-- The `ref` subkey is still supported
|
||||
cmds:
|
||||
- 'echo {{.FOO.a}}'
|
||||
```
|
||||
|
||||
</TabItem></Tabs>
|
||||
|
||||
## Looping over maps
|
||||
|
||||
This experiment also adds support for looping over maps using the `for` keyword,
|
||||
just like arrays. In addition to the `{{.ITEM}}` variable being populated when
|
||||
looping over a map, we also make an additional `{{.KEY}}` variable available
|
||||
that holds the string value of the map key.
|
||||
|
||||
<Tabs defaultValue="1" queryString="proposal"
|
||||
values={[
|
||||
{label: 'Proposal 1', value: '1'},
|
||||
{label: 'Proposal 2', value: '2'}
|
||||
]}>
|
||||
|
||||
<TabItem value="1">
|
||||
|
||||
```yaml
|
||||
version: 3
|
||||
|
||||
tasks:
|
||||
foo:
|
||||
vars:
|
||||
MAP: {a: 1, b: 2, c: 3}
|
||||
cmds:
|
||||
- for:
|
||||
var: MAP
|
||||
cmd: 'echo "{{.KEY}}: {{.ITEM}}"'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="2">
|
||||
|
||||
```yaml
|
||||
version: 3
|
||||
|
||||
tasks:
|
||||
foo:
|
||||
vars:
|
||||
map:
|
||||
MAP: {a: 1, b: 2, c: 3}
|
||||
cmds:
|
||||
- for:
|
||||
var: MAP
|
||||
cmd: 'echo "{{.KEY}}: {{.ITEM}}"'
|
||||
```
|
||||
|
||||
:::note
|
||||
|
||||
Remember that maps are unordered, so
|
||||
the order in which the items are looped over is random.
|
||||
|
||||
:::
|
||||
|
||||
</TabItem></Tabs>
|
||||
|
||||
{/* prettier-ignore-start */}
|
||||
[enabling-experiments]: ./experiments.mdx#enabling-experiments
|
||||
{/* prettier-ignore-end */}
|
||||
@@ -2,6 +2,9 @@
|
||||
slug: /experiments/remote-taskfiles/
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# Remote Taskfiles (#1317)
|
||||
|
||||
:::caution
|
||||
@@ -20,33 +23,151 @@ To enable this experiment, set the environment variable:
|
||||
|
||||
:::
|
||||
|
||||
This experiment allows you to specify a remote Taskfile URL when including a
|
||||
Taskfile. For example:
|
||||
:::danger
|
||||
Never run remote Taskfiles from sources that you do not trust.
|
||||
:::
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
This experiment allows you to use Taskfiles which are stored in remote
|
||||
locations. This applies to both the root Taskfile (aka. Entrypoint) and also
|
||||
when including Taskfiles.
|
||||
|
||||
includes:
|
||||
my-remote-namespace: https://raw.githubusercontent.com/my-org/my-repo/main/Taskfile.yml
|
||||
```
|
||||
Task uses "nodes" to reference remote Taskfiles. There are a few different types
|
||||
of node which you can use:
|
||||
|
||||
This works exactly the same way that including a local file does. Any tasks in
|
||||
the remote Taskfile will be available to run from your main Taskfile via the
|
||||
namespace `my-remote-namespace`. For example, if the remote file contains the
|
||||
following:
|
||||
<Tabs groupId="method" queryString>
|
||||
<TabItem value="http" label="HTTP/HTTPS">
|
||||
|
||||
`https://raw.githubusercontent.com/go-task/task/main/website/static/Taskfile.yml`
|
||||
|
||||
This is the most basic type of remote node and works by downloading the file
|
||||
from the specified URL. The file must be a valid Taskfile and can be of any
|
||||
name. If a file is not found at the specified URL, Task will append each of the
|
||||
[supported file names][supported-file-names] in turn until it finds a valid
|
||||
file. If it still does not find a valid Taskfile, an error is returned.
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="git-http" label="Git over HTTP">
|
||||
|
||||
`https://github.com/go-task/task.git//website/static/Taskfile.yml?ref=main`
|
||||
|
||||
This type of node works by downloading the file from a Git repository over
|
||||
HTTP/HTTPS. The first part of the URL is the base URL of the Git repository.
|
||||
This is the same URL that you would use to clone the repo over HTTP.
|
||||
|
||||
- You can optionally add the path to the Taskfile in the repository by appending
|
||||
`//<path>` 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.
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="git-ssh" label="Git over SSH">
|
||||
|
||||
`git@github.com/go-task/task.git//website/static/Taskfile.yml?ref=main`
|
||||
|
||||
This type of node works by downloading the file from a Git repository over SSH.
|
||||
The first part of the URL is the user and base URL of the Git repository. This
|
||||
is the same URL that you would use to clone the repo over SSH.
|
||||
|
||||
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
|
||||
`//<path>` 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.
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Task has an [example remote Taskfile][example-remote-taskfile] in our repository
|
||||
that you can use for testing and that we will use throughout this document:
|
||||
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
hello:
|
||||
silent: true
|
||||
default:
|
||||
cmds:
|
||||
- echo "Hello from the remote Taskfile!"
|
||||
- task: hello
|
||||
|
||||
hello:
|
||||
cmds:
|
||||
- echo "Hello Task!"
|
||||
```
|
||||
|
||||
and you run `task my-remote-namespace:hello`, it will print the text: "Hello
|
||||
from the remote Taskfile!" to your console.
|
||||
## Specifying a remote entrypoint
|
||||
|
||||
By default, Task will look for one of the [supported file
|
||||
names][supported-file-names] on your local filesystem. If you want to use a
|
||||
remote file instead, you can pass its URI into the `--taskfile`/`-t` flag just
|
||||
like you would to specify a different local file. For example:
|
||||
|
||||
<Tabs groupId="method" queryString>
|
||||
<TabItem value="http" label="HTTP/HTTPS">
|
||||
```shell
|
||||
$ task --taskfile https://raw.githubusercontent.com/go-task/task/main/website/static/Taskfile.yml
|
||||
task: [hello] echo "Hello Task!"
|
||||
Hello Task!
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="git-http" label="Git over HTTP">
|
||||
```shell
|
||||
$ task --taskfile https://github.com/go-task/task.git//website/static/Taskfile.yml?ref=main
|
||||
task: [hello] echo "Hello Task!"
|
||||
Hello Task!
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="git-ssh" label="Git over SSH">
|
||||
```shell
|
||||
$ task --taskfile git@github.com/go-task/task.git//website/static/Taskfile.yml?ref=main
|
||||
task: [hello] echo "Hello Task!"
|
||||
Hello Task!
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Including remote Taskfiles
|
||||
|
||||
Including a remote file works exactly the same way that including a local file
|
||||
does. You just need to replace the local path with a remote URI. Any tasks in
|
||||
the remote Taskfile will be available to run from your main Taskfile.
|
||||
|
||||
<Tabs groupId="method" queryString>
|
||||
<TabItem value="http" label="HTTP/HTTPS">
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
includes:
|
||||
my-remote-namespace: https://raw.githubusercontent.com/go-task/task/main/website/static/Taskfile.yml
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="git-http" label="Git over HTTP">
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
includes:
|
||||
my-remote-namespace: https://github.com/go-task/task.git//website/static/Taskfile.yml?ref=main
|
||||
```
|
||||
</TabItem>
|
||||
<TabItem value="git-ssh" label="Git over SSH">
|
||||
```yaml
|
||||
version: '3'
|
||||
|
||||
includes:
|
||||
my-remote-namespace: git@github.com/go-task/task.git//website/static/Taskfile.yml?ref=main
|
||||
```
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
```shell
|
||||
$ task my-remote-namespace:hello
|
||||
task: [hello] echo "Hello Task!"
|
||||
Hello Task!
|
||||
```
|
||||
|
||||
### Authenticating using environment variables
|
||||
|
||||
The Taskfile location is processed by the templating system, so you can
|
||||
reference environment variables in your URL if you need to add authentication.
|
||||
@@ -59,19 +180,6 @@ includes:
|
||||
my-remote-namespace: https://{{.TOKEN}}@raw.githubusercontent.com/my-org/my-repo/main/Taskfile.yml
|
||||
```
|
||||
|
||||
`TOKEN=my-token task my-remote-namespace:hello` will be resolved by Task to
|
||||
`https://my-token@raw.githubusercontent.com/my-org/my-repo/main/Taskfile.yml`
|
||||
|
||||
## Git nodes
|
||||
|
||||
You can also include a Taskfile from a Git node. We currently support ssh-style and http / https addresses like `git@example.com/foo/bar.git//Taskfiles.yml?ref=v1` and `https://example.com/foo/bar.git//Taskfiles.yml?ref=v1`.
|
||||
|
||||
You need to follow this pattern : `<baseUrl>.git//<path>?ref=<ref>`.
|
||||
The `ref` parameter, optional, can be a branch name or a tag, if not provided it'll pick up the default branch.
|
||||
The `path` is the path to the Taskfile in the repository.
|
||||
|
||||
If you want to use the SSH protocol, you need to make sure that your ssh-agent has your private ssh keys added so that they can be used during authentication.
|
||||
|
||||
## Security
|
||||
|
||||
Running commands from sources that you do not control is always a potential
|
||||
@@ -104,20 +212,26 @@ flag. Before enabling this flag, you should:
|
||||
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 via an unencrypted connection. Sources that are not protected
|
||||
by TLS are vulnerable to [man-in-the-middle attacks][man-in-the-middle-attacks]
|
||||
and should be avoided unless you know what you are doing.
|
||||
Taskfile that is downloaded via an unencrypted connection. Sources that are not
|
||||
protected by TLS are vulnerable to [man-in-the-middle
|
||||
attacks][man-in-the-middle-attacks] and should be avoided unless you know what
|
||||
you are doing.
|
||||
|
||||
## Caching & Running Offline
|
||||
|
||||
Whenever you run a remote Taskfile, the latest copy will be downloaded from the
|
||||
internet and cached locally. If for whatever reason, you lose access to the
|
||||
internet, you will still be able to run your tasks by specifying the `--offline`
|
||||
flag. This will tell Task to use the latest cached version of the file instead
|
||||
of trying to download it. You are able to use the `--download` flag to update
|
||||
the cached version of the remote files without running any tasks. You are able
|
||||
to use the `--clear-cache` flag to clear all cached version of the remote files
|
||||
without running any tasks.
|
||||
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_OFFLINE` environment variable),
|
||||
Task will run the any available cached files _even if they are expired_. This
|
||||
means that you should never be stuck without the ability to run your tasks as
|
||||
long as you have downloaded a remote Taskfile at least once.
|
||||
|
||||
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
|
||||
@@ -129,7 +243,14 @@ By default, the cache is stored in the Task temp directory, represented by the
|
||||
override the location of the cache by setting the `TASK_REMOTE_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.
|
||||
|
||||
{/* prettier-ignore-start */}
|
||||
[enabling-experiments]: ./experiments.mdx#enabling-experiments
|
||||
[man-in-the-middle-attacks]: https://en.wikipedia.org/wiki/Man-in-the-middle_attack
|
||||
[supported-file-names]: https://taskfile.dev/usage/#supported-file-names
|
||||
[example-remote-taskfile]: https://raw.githubusercontent.com/go-task/task/main/website/static/Taskfile.yml
|
||||
{/* prettier-ignore-end */}
|
||||
|
||||
Reference in New Issue
Block a user