Skip to content

远程 Taskfile (#1317)

WARNING

所有实验性功能都可能随时发生破坏性变更和/或移除。我们强烈推荐不要在生产环境中使用这些功能。它们仅用于测试和反馈。

INFO

要启用此实验,请设置环境变量: TASK_X_REMOTE_TASKFILES=1。请查看 我们的实验启用指南 以获取更多信息。

DANGER

切勿从不信任的来源运行远程 Taskfile。

此实验允许您使用存储在远程位置的 Taskfile。这适用于根 Taskfile(也称为入口点)以及包含 Taskfile 的情况。

Task 使用“节点”来引用远程 Taskfile。您可以使用几种不同类型的节点:

text
https://raw.githubusercontent.com/go-task/task/main/website/src/public/Taskfile.yml
text
https://github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=main
text
git@github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=main

节点类型

HTTP/HTTPS

https://raw.githubusercontent.com/go-task/task/main/website/src/public/Taskfile.yml

这是最基本的远程节点类型,通过从指定的 URL 下载文件来工作。该文件必须是一个有效的 Taskfile,并且可以是任何名称。如果在指定 URL 未找到文件,Task 将依次附加每个支持的文件名,直到找到有效文件。如果仍然未找到有效的 Taskfile,则返回错误。

Git over HTTP

https://github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=main

这种节点类型通过 HTTP/HTTPS 从 Git 仓库下载文件。URL 的第一部分是 Git 仓库的基本 URL。这是您用于通过 HTTP 克隆仓库的相同 URL。

  • 您可以选择通过将 //<path> 附加到 URL 来添加仓库中 Taskfile 的路径。
  • 您也可以选择通过将 ?ref=<ref> 附加到 URL 末尾来指定要使用的分支或标签。如果省略引用,将使用默认分支。

Git over SSH

git@github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=main

这种节点类型通过 SSH 从 Git 仓库下载文件。URL 的第一部分是 Git 仓库的用户和基本 URL。这是您用于通过 SSH 克隆仓库的相同 URL。

要使用 Git over SSH,您需要确保您的 SSH 代理已添加您的私钥,以便在身份验证期间使用。

  • 您可以选择通过将 //<path> 附加到 URL 来添加仓库中 Taskfile 的路径。
  • 您也可以选择通过将 ?ref=<ref> 附加到 URL 末尾来指定要使用的分支或标签。如果省略引用,将使用默认分支。

Task 在我们的仓库中有一个示例远程 Taskfile,您可以用于测试,并且我们将在本文档中使用它:

yaml
version: '3'

tasks:
  default:
    cmds:
      - task: hello

  hello:
    cmds:
      - echo "Hello Task!"

指定远程入口点

默认情况下,Task 将在本地文件系统上查找支持的文件名之一。如果您想改用远程文件,可以将其 URI 传递给 --taskfile/-t 标志,就像指定不同的本地文件一样。例如:

shell
$ task --taskfile https://raw.githubusercontent.com/go-task/task/main/website/src/public/Taskfile.yml
task: [hello] echo "Hello Task!"
Hello Task!
shell
$ task --taskfile https://github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=main
task: [hello] echo "Hello Task!"
Hello Task!
shell
$ task --taskfile git@github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=main
task: [hello] echo "Hello Task!"
Hello Task!

包含远程 Taskfile

包含远程文件的工作方式与包含本地文件完全相同。您只需将本地路径替换为远程 URI。远程 Taskfile 中的任何任务都将可从您的主 Taskfile 运行。

yaml
version: '3'

includes:
  my-remote-namespace: https://raw.githubusercontent.com/go-task/task/main/website/src/public/Taskfile.yml
yaml
version: '3'

includes:
  my-remote-namespace: https://github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=main
yaml
version: '3'

includes:
  my-remote-namespace: git@github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=main
shell
$ task my-remote-namespace:hello
task: [hello] echo "Hello Task!"
Hello Task!

使用环境变量进行身份验证

Taskfile 位置由模板系统处理,因此如果需要添加身份验证,您可以在 URL 中引用环境变量。例如:

yaml
version: '3'

includes:
  my-remote-namespace: https://{{.TOKEN}}@raw.githubusercontent.com/my-org/my-repo/main/Taskfile.yml

安全性

自动校验和

从您不控制的来源运行命令始终是潜在的安全风险。因此,在使用远程 Taskfile 时,我们添加了一些自动检查:

  1. 首次从远程 Taskfile 运行任务时,Task 将在控制台打印警告,要求您检查您是否信任 Taskfile 的来源。如果您不接受提示,则 Task 将以代码 104(不受信任)退出,并且不会运行任何内容。如果您接受提示,远程 Taskfile 将运行,并且对远程 Taskfile 的后续调用将不再提示。
  2. 每次运行远程 Taskfile 时,Task 都会创建并存储您正在运行的文件校验和。如果校验和发生变化,则 Task 将在控制台打印另一个警告,以通知您远程文件的内容已更改。如果您不接受提示,则 Task 将以代码 104(不受信任)退出,并且不会运行任何内容。如果您接受提示,校验和将被更新,并且远程 Taskfile 将运行。

有时您需要在没有交互式终端的环境中运行 Task,因此无法接受提示。在这些情况下,您可以通过使用 --yes 标志告诉 Task 自动接受这些提示。在启用此标志之前,您应该:

  1. 确保您信任远程 Taskfile 的来源和内容。
  2. 考虑使用远程 Taskfile 的固定版本(例如,包含提交哈希的链接),以防止 Task 自动接受提示,该提示表示远程 Taskfile 已更改。

手动校验和固定

或者,如果您预计远程文件的内容是常量值,您可以固定包含文件的校验和:

yaml
version: '3'

includes:
  included:
    taskfile: https://taskfile.dev
    checksum: c153e97e0b3a998a7ed2e61064c6ddaddd0de0c525feefd6bba8569827d8efe9

这将禁用上述自动校验和提示。但是,如果校验和不匹配,Task 将立即以错误退出。首次设置此功能时,您可能不知道正确的校验和值。您可以通过以下几种方式获取:

  1. 正常添加 include,而不添加 checksum 键。首次运行包含的 Taskfile 时,将创建一个 .task/remote 临时目录。找到包含 Taskfile 的正确文件集,并打开以 .checksum 结尾的文件。您可以复制此文件的内容并粘贴到 include 的 checksum 键中。此方法最安全,因为它允许您在固定之前检查下载的 Taskfile。
  2. 或者,使用临时随机值添加 include 到 checksum 键中。当您尝试运行 Taskfile 时,您将收到错误,该错误将报告不正确的预期校验和和实际校验和。您可以复制实际校验和并替换您的临时随机值。

TLS

Task 当前支持 httphttps URL。但是,除非您使用 --insecure 标志运行任务,否则 http 请求默认不会执行。这是为了保护您免于意外运行通过未加密连接下载的远程 Taskfile。没有 TLS 保护的来源容易受到中间人攻击的风险,除非您知道自己在做什么,否则应避免使用。

缓存和离线运行

每次运行远程 Taskfile 时,都将从互联网下载最新副本并本地缓存。此缓存文件将用于 Taskfile 的所有未来调用,直到缓存过期。一旦过期,Task 将下载文件的最新副本并更新缓存。默认情况下,缓存设置为立即过期。这意味着 Task 将始终获取最新版本。但是,可以通过设置 --expiry 标志来修改缓存过期持续时间。

如果由于任何原因您丢失了对互联网的访问,或者您通过 --offline 标志或 TASK_OFFLINE 环境变量在离线模式下运行 Task,Task 将运行任何可用的缓存文件_即使它们已过期_。这意味着只要您至少下载过一次远程 Taskfile,您就永远不会陷入无法运行任务的情况。

默认情况下,Task 将在 10 秒后超时下载远程文件的请求,并转而查找缓存副本。此超时可以通过设置 --timeout 标志并指定持续时间来配置。例如,--timeout 5s 将超时设置为 5 秒。

默认情况下,缓存存储在 Task 临时目录中,由 TASK_TEMP_DIR 环境变量表示。您可以通过设置 TASK_REMOTE_DIR 环境变量来覆盖缓存位置。这样,您可以在不同项目之间共享缓存。

您可以使用 --download 标志强制 Task 忽略缓存并下载最新版本。

您可以使用 --clear-cache 标志清除所有缓存的远程文件。

配置

此实验在 配置文件 中添加了一个新的 remote 部分。

  • Type: object
  • Description: 处理远程 Taskfile 的远程配置设置
yaml
remote:
  insecure: false
  offline: false
  timeout: "30s"
  cache-expiry: "24h"

insecure

  • Type: boolean
  • Default: false
  • Description: 允许在获取远程 Taskfile 时使用不安全的连接
yaml
remote:
  insecure: true

offline

  • Type: boolean
  • Default: false
  • Description: 以离线模式工作,防止获取远程 Taskfile
yaml
remote:
  offline: true

timeout

  • Type: string
  • Default: 10s
  • Pattern: ^[0-9]+(ns|us|µs|ms|s|m|h)$
  • Description: 远程操作的超时持续时间(例如,'30s'、'5m')
yaml
remote:
  timeout: "1m"

cache-expiry

  • Type: string
  • Default: 0s (no cache)
  • Pattern: ^[0-9]+(ns|us|µs|ms|s|m|h)$
  • Description: 远程 Taskfile 的缓存过期持续时间(例如,'1h'、 '24h')
yaml
remote:
  cache-expiry: "6h"