diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 35c46d12..0ff31d6d 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -95,7 +95,45 @@ jobs:
run: python -m pip install 'check-jsonschema==0.27.3'
- name: 📋 Validate JSON Schema
- run: check-jsonschema --check-metaschema website/src/public/schema.json
+ run: check-jsonschema --check-metaschema website/src/public/next-schema.json website/src/public/schema.json
+
+ check-latest-content:
+ name: 📚 Check latest content
+ # Pull requests only: the release commit is pushed straight to main and is
+ # the one thing allowed to rewrite these files.
+ if: github.event_name == 'pull_request'
+ runs-on: ubuntu-latest
+ permissions:
+ pull-requests: read
+ steps:
+ - uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
+ with:
+ script: |
+ // Everything cmd/release overwrites. Adding a file is fine -- that
+ // is how a blog post gets published early -- editing one is not.
+ const generated = (name) =>
+ name.startsWith('website/src/latest/') ||
+ name === 'website/src/public/schema.json' ||
+ name === 'website/src/public/schema-taskrc.json' ||
+ name === 'website/.vitepress/sidebar/latest.ts'
+
+ const files = await github.paginate(
+ github.rest.pulls.listFiles, {
+ pull_number: context.issue.number,
+ owner: context.repo.owner,
+ repo: context.repo.repo,
+ per_page: 100,
+ }
+ )
+ const edited = files.filter(
+ (f) => generated(f.filename) && f.status !== 'added'
+ )
+ if (edited.length > 0) {
+ core.setFailed(
+ 'These files are generated by cmd/release and would be overwritten at the next release. Update their website/src counterpart instead:\n' +
+ edited.map((f) => f.filename).join('\n')
+ )
+ }
govulncheck:
name: 🛡️ Vulnerabilities
diff --git a/Taskfile.yml b/Taskfile.yml
index 6b9b69a7..da8b2b44 100644
--- a/Taskfile.yml
+++ b/Taskfile.yml
@@ -197,8 +197,7 @@ tasks:
This task will do the following:
- Update the version and date in the CHANGELOG.md file
- - Update the version in the package.json and package-lock.json files
- - Copy the latest docs to the "current" version on the website
+ - Promote the docs, sidebar and JSON schemas to the released version
- Commit the changes
- Create a new tag
- Push the commit/tag to the repository
diff --git a/cmd/release/main.go b/cmd/release/main.go
index 1406729c..9448f03b 100644
--- a/cmd/release/main.go
+++ b/cmd/release/main.go
@@ -15,10 +15,29 @@ import (
const (
changelogSource = "CHANGELOG.md"
- changelogTarget = "website/src/docs/changelog.md"
+ changelogTarget = "website/src/next/docs/changelog.md"
versionFile = "internal/version/version.txt"
)
+type promotion struct{ source, target string }
+
+// Promoted at release time: the website builds `next` from the sources on the
+// left and `latest` from the targets on the right, so that taskfile.dev only
+// ever documents the version being released. The other half of the mechanism
+// lives in website/.vitepress/config.ts, which picks a side at build time.
+var (
+ promotedDirs = []promotion{
+ {"website/src/next/docs", "website/src/latest/docs"},
+ {"website/src/next/blog", "website/src/latest/blog"},
+ }
+
+ promotedFiles = []promotion{
+ {"website/.vitepress/sidebar/next.ts", "website/.vitepress/sidebar/latest.ts"},
+ {"website/src/public/next-schema.json", "website/src/public/schema.json"},
+ {"website/src/public/next-schema-taskrc.json", "website/src/public/schema-taskrc.json"},
+ }
+)
+
var changelogReleaseRegex = regexp.MustCompile(`## Unreleased`)
// Flags
@@ -61,6 +80,11 @@ func release() error {
return err
}
+ // After the changelog so that the promoted docs carry it.
+ if err := promote(); err != nil {
+ return err
+ }
+
if err := setVersionFile(versionFile, version); err != nil {
return err
}
@@ -68,6 +92,30 @@ func release() error {
return nil
}
+func promote() error {
+ for _, p := range promotedDirs {
+ // CopyFS refuses to overwrite, so the previous release has to go first.
+ if err := os.RemoveAll(p.target); err != nil {
+ return err
+ }
+ if err := os.CopyFS(p.target, os.DirFS(p.source)); err != nil {
+ return err
+ }
+ }
+
+ for _, p := range promotedFiles {
+ b, err := os.ReadFile(p.source)
+ if err != nil {
+ return err
+ }
+ if err := os.WriteFile(p.target, b, 0o644); err != nil { //nolint:gosec
+ return err
+ }
+ }
+
+ return nil
+}
+
func getVersion(filename string) (*semver.Version, error) {
b, err := os.ReadFile(filename)
if err != nil {
diff --git a/website/.vitepress/blog.data.ts b/website/.vitepress/blog.data.ts
index f6db8fc0..b3b43cab 100644
--- a/website/.vitepress/blog.data.ts
+++ b/website/.vitepress/blog.data.ts
@@ -29,10 +29,20 @@ function extractExcerpt(html: string): string | undefined {
.trim();
}
-export default createContentLoader('blog/*.md', {
+// Same channel as .vitepress/config.ts: the posts of the other one are not part
+// of this build.
+const channel = process.env.DOCS_CHANNEL === 'latest' ? 'latest' : 'next';
+
+export default createContentLoader(`${channel}/blog/*.md`, {
render: true,
transform(raw) {
return raw
+ .map((page) => ({
+ ...page,
+ // Content loaders resolve URLs against `srcDir` and know nothing about
+ // `rewrites`, so the channel has to be stripped by hand.
+ url: page.url.replace(`/${channel}/`, '/')
+ }))
.filter(({ url }) => url !== '/blog/')
.map(({ frontmatter, html, url }) => {
const date = new Date(frontmatter.date);
diff --git a/website/.vitepress/config.ts b/website/.vitepress/config.ts
index 16b1ac1b..c17d73ed 100644
--- a/website/.vitepress/config.ts
+++ b/website/.vitepress/config.ts
@@ -14,15 +14,28 @@ import { adopters } from './adopters.ts';
import { taskDescription, taskName, ogUrl, ogImage } from './meta.ts';
import { fileURLToPath, URL } from 'node:url';
import llmstxt from 'vitepress-plugin-llms';
+import { sidebar as nextSidebar } from './sidebar/next.ts';
+import { sidebar as latestSidebar } from './sidebar/latest.ts';
const version = readFileSync(
resolve(__dirname, '../../internal/version/version.txt'),
'utf8'
).trim();
+// Which channel to build. `src/next` is written for the upcoming release and
+// serves next.taskfile.dev; `src/latest` is its copy at the released version
+// and serves taskfile.dev. Both mount at the same URLs, so taskfile.dev never
+// documents or announces a feature that is not in the released binary.
+// cmd/release owns the other half of this: it promotes one over the other.
+const isLatest = process.env.DOCS_CHANNEL === 'latest';
+const channel = isLatest ? 'latest' : 'next';
+const other = isLatest ? 'next' : 'latest';
+
+const docsSidebar = isLatest ? latestSidebar : nextSidebar;
+
// Builds the "/blog/" sidebar from each blog post's frontmatter.
function buildBlogSidebar() {
- const blogDir = resolve(__dirname, '../src/blog');
+ const blogDir = resolve(__dirname, `../src/${channel}/blog`);
const posts = readdirSync(blogDir)
.filter((file) => file.endsWith('.md') && file !== 'index.md')
.map((file) => {
@@ -53,11 +66,15 @@ function buildBlogSidebar() {
}));
}
+// Ports are the ones the dev tasks bind to; keep them in sync with
+// website/Taskfile.yml. DOCS_LOCAL is set by those tasks alone, so a build can
+// never end up shipping localhost URLs.
+const localPorts = { latest: 3002, next: 3001 };
const urlVersion =
- process.env.NODE_ENV === 'development'
+ process.env.DOCS_LOCAL === '1'
? {
- current: 'https://taskfile.dev/',
- next: 'http://localhost:3002/'
+ current: `http://localhost:${localPorts.latest}/`,
+ next: `http://localhost:${localPorts.next}/`
}
: {
current: 'https://taskfile.dev/',
@@ -252,6 +269,8 @@ export default defineConfig({
},
srcDir: 'src',
cleanUrls: true,
+ srcExclude: [`${other}/**`],
+ rewrites: { [`${channel}/:path*`]: ':path*' },
markdown: {
config: (md) => {
md.use(githubLinksPlugin, {
@@ -269,11 +288,12 @@ export default defineConfig({
'index.md',
'team.md',
'donate.md',
- 'docs/styleguide.md',
- 'docs/contributing.md',
- 'docs/releasing.md',
- 'docs/changelog.md',
- 'blog/*'
+ // Matched against source paths, which `rewrites` does not touch.
+ `${channel}/docs/styleguide.md`,
+ `${channel}/docs/contributing.md`,
+ `${channel}/docs/releasing.md`,
+ `${channel}/docs/changelog.md`,
+ `${channel}/blog/*`
]
}),
groupIconVitePlugin({
@@ -326,17 +346,24 @@ export default defineConfig({
{ text: 'Donate', link: '/donate' },
{ text: 'Team', link: '/team' },
{
- text: process.env.NODE_ENV === 'development' ? 'Next' : `v${version}`,
+ text: isLatest ? `v${version}` : 'Next',
items: [
{
items: [
+ // Absolute links, so VitePress would treat them as external and
+ // open them in a new tab. Switching channels is navigation, not a
+ // detour off the site.
{
text: `v${version}`,
- link: urlVersion.current
+ link: urlVersion.current,
+ target: '_self',
+ noIcon: true
},
{
text: 'Next',
- link: urlVersion.next
+ link: urlVersion.next,
+ target: '_self',
+ noIcon: true
}
]
}
@@ -346,139 +373,7 @@ export default defineConfig({
sidebar: {
'/blog/': buildBlogSidebar(),
- '/': [
- {
- text: 'Installation',
- link: '/docs/installation'
- },
- {
- text: 'Getting Started',
- link: '/docs/getting-started'
- },
- {
- text: 'Guide',
- link: '/docs/guide'
- },
- {
- text: 'Remote Taskfiles',
- link: '/docs/remote-taskfiles'
- },
- {
- text: 'Reference',
- collapsed: true,
- items: [
- {
- text: 'Taskfile Schema',
- link: '/docs/reference/schema'
- },
- {
- text: 'Environment',
- link: '/docs/reference/environment'
- },
- {
- text: 'Configuration',
- link: '/docs/reference/config'
- },
- {
- text: 'CLI',
- link: '/docs/reference/cli'
- },
- {
- text: 'Templating',
- link: '/docs/reference/templating'
- },
- {
- text: 'Package API',
- link: '/docs/reference/package'
- }
- ]
- },
- {
- text: 'Experiments',
- collapsed: true,
- link: '/docs/experiments/',
- items: [
- {
- text: 'Env Precedence (#1038)',
- link: '/docs/experiments/env-precedence'
- },
- {
- text: 'Gentle Force (#1200)',
- link: '/docs/experiments/gentle-force'
- },
- {
- text: 'Remote Taskfiles (#1317)',
- link: '/docs/experiments/remote-taskfiles'
- }
- ]
- },
- {
- text: 'Deprecations',
- collapsed: true,
- link: '/docs/deprecations/',
- items: [
- {
- text: 'Completion Scripts',
- link: '/docs/deprecations/completion-scripts'
- },
- {
- text: 'Template Functions',
- link: '/docs/deprecations/template-functions'
- },
- {
- text: 'Version 2 Schema (#1197)',
- link: '/docs/deprecations/version-2-schema'
- }
- ]
- },
- {
- text: 'Taskfile Versions',
- link: '/docs/taskfile-versions'
- },
- {
- text: 'Integrations',
- link: '/docs/integrations'
- },
- {
- text: 'Community',
- link: '/docs/community'
- },
- {
- text: 'Style Guide',
- link: '/docs/styleguide'
- },
- {
- text: 'Contributing',
- link: '/docs/contributing'
- },
- {
- text: 'Releasing',
- link: '/docs/releasing'
- },
- {
- text: 'Security',
- collapsed: true,
- link: '/docs/security/',
- items: [
- {
- text: 'Incident Response Plan',
- link: '/docs/security/incident-response-plan'
- },
- {
- text: 'Threat Model',
- link: '/docs/security/threat-model'
- }
- ]
- },
- {
- text: 'Changelog',
- link: '/docs/changelog'
- },
- {
- text: 'FAQ',
- link: '/docs/faq'
- }
- ],
+ '/': docsSidebar,
// Hacky to disable sidebar for these pages
'/donate': [],
'/team': [],
@@ -495,7 +390,13 @@ export default defineConfig({
editLink: {
text: 'Edit this page on GitHub',
- pattern: 'https://github.com/go-task/task/edit/main/website/src/:path'
+ // Docs are always edited in `src/next`, even when the latest channel
+ // serves them from `src/latest/docs`.
+ // Serialized with toString() and evaluated in the browser, so it must not
+ // reference anything from this module. Both channels are edited in
+ // src/next, so strip whichever prefix the page was built from.
+ pattern: ({ filePath }) =>
+ `https://github.com/go-task/task/edit/main/website/src/next/${filePath.replace(/^(next|latest)\//, '')}`
},
footer: {
diff --git a/website/.vitepress/sidebar/latest.ts b/website/.vitepress/sidebar/latest.ts
new file mode 100644
index 00000000..34cd8c3b
--- /dev/null
+++ b/website/.vitepress/sidebar/latest.ts
@@ -0,0 +1,134 @@
+import type { DefaultTheme } from 'vitepress';
+
+// Navigation for the `/docs` section. next.ts is the source of both sidebars;
+// cmd/release copies it over latest.ts alongside the content it describes. See
+// the "Documentation channels" section of website/src/next/docs/contributing.md.
+export const sidebar: DefaultTheme.SidebarItem[] = [
+ {
+ text: 'Installation',
+ link: '/docs/installation'
+ },
+ {
+ text: 'Getting Started',
+ link: '/docs/getting-started'
+ },
+ {
+ text: 'Guide',
+ link: '/docs/guide'
+ },
+ {
+ text: 'Reference',
+ collapsed: true,
+ items: [
+ {
+ text: 'Taskfile Schema',
+ link: '/docs/reference/schema'
+ },
+ {
+ text: 'Environment',
+ link: '/docs/reference/environment'
+ },
+ {
+ text: 'Configuration',
+ link: '/docs/reference/config'
+ },
+ {
+ text: 'CLI',
+ link: '/docs/reference/cli'
+ },
+ {
+ text: 'Templating',
+ link: '/docs/reference/templating'
+ },
+ {
+ text: 'Package API',
+ link: '/docs/reference/package'
+ }
+ ]
+ },
+ {
+ text: 'Experiments',
+ collapsed: true,
+ link: '/docs/experiments/',
+ items: [
+ {
+ text: 'Env Precedence (#1038)',
+ link: '/docs/experiments/env-precedence'
+ },
+ {
+ text: 'Gentle Force (#1200)',
+ link: '/docs/experiments/gentle-force'
+ },
+ {
+ text: 'Remote Taskfiles (#1317)',
+ link: '/docs/experiments/remote-taskfiles'
+ }
+ ]
+ },
+ {
+ text: 'Deprecations',
+ collapsed: true,
+ link: '/docs/deprecations/',
+ items: [
+ {
+ text: 'Completion Scripts',
+ link: '/docs/deprecations/completion-scripts'
+ },
+ {
+ text: 'Template Functions',
+ link: '/docs/deprecations/template-functions'
+ },
+ {
+ text: 'Version 2 Schema (#1197)',
+ link: '/docs/deprecations/version-2-schema'
+ }
+ ]
+ },
+ {
+ text: 'Taskfile Versions',
+ link: '/docs/taskfile-versions'
+ },
+ {
+ text: 'Integrations',
+ link: '/docs/integrations'
+ },
+ {
+ text: 'Community',
+ link: '/docs/community'
+ },
+ {
+ text: 'Style Guide',
+ link: '/docs/styleguide'
+ },
+ {
+ text: 'Contributing',
+ link: '/docs/contributing'
+ },
+ {
+ text: 'Releasing',
+ link: '/docs/releasing'
+ },
+ {
+ text: 'Security',
+ collapsed: true,
+ link: '/docs/security/',
+ items: [
+ {
+ text: 'Incident Response Plan',
+ link: '/docs/security/incident-response-plan'
+ },
+ {
+ text: 'Threat Model',
+ link: '/docs/security/threat-model'
+ }
+ ]
+ },
+ {
+ text: 'Changelog',
+ link: '/docs/changelog'
+ },
+ {
+ text: 'FAQ',
+ link: '/docs/faq'
+ }
+];
diff --git a/website/.vitepress/sidebar/next.ts b/website/.vitepress/sidebar/next.ts
new file mode 100644
index 00000000..c7171547
--- /dev/null
+++ b/website/.vitepress/sidebar/next.ts
@@ -0,0 +1,138 @@
+import type { DefaultTheme } from 'vitepress';
+
+// Navigation for the `/docs` section. next.ts is the source of both sidebars;
+// cmd/release copies it over latest.ts alongside the content it describes. See
+// the "Documentation channels" section of website/src/next/docs/contributing.md.
+export const sidebar: DefaultTheme.SidebarItem[] = [
+ {
+ text: 'Installation',
+ link: '/docs/installation'
+ },
+ {
+ text: 'Getting Started',
+ link: '/docs/getting-started'
+ },
+ {
+ text: 'Guide',
+ link: '/docs/guide'
+ },
+ {
+ text: 'Remote Taskfiles',
+ link: '/docs/remote-taskfiles'
+ },
+ {
+ text: 'Reference',
+ collapsed: true,
+ items: [
+ {
+ text: 'Taskfile Schema',
+ link: '/docs/reference/schema'
+ },
+ {
+ text: 'Environment',
+ link: '/docs/reference/environment'
+ },
+ {
+ text: 'Configuration',
+ link: '/docs/reference/config'
+ },
+ {
+ text: 'CLI',
+ link: '/docs/reference/cli'
+ },
+ {
+ text: 'Templating',
+ link: '/docs/reference/templating'
+ },
+ {
+ text: 'Package API',
+ link: '/docs/reference/package'
+ }
+ ]
+ },
+ {
+ text: 'Experiments',
+ collapsed: true,
+ link: '/docs/experiments/',
+ items: [
+ {
+ text: 'Env Precedence (#1038)',
+ link: '/docs/experiments/env-precedence'
+ },
+ {
+ text: 'Gentle Force (#1200)',
+ link: '/docs/experiments/gentle-force'
+ },
+ {
+ text: 'Remote Taskfiles (#1317)',
+ link: '/docs/experiments/remote-taskfiles'
+ }
+ ]
+ },
+ {
+ text: 'Deprecations',
+ collapsed: true,
+ link: '/docs/deprecations/',
+ items: [
+ {
+ text: 'Completion Scripts',
+ link: '/docs/deprecations/completion-scripts'
+ },
+ {
+ text: 'Template Functions',
+ link: '/docs/deprecations/template-functions'
+ },
+ {
+ text: 'Version 2 Schema (#1197)',
+ link: '/docs/deprecations/version-2-schema'
+ }
+ ]
+ },
+ {
+ text: 'Taskfile Versions',
+ link: '/docs/taskfile-versions'
+ },
+ {
+ text: 'Integrations',
+ link: '/docs/integrations'
+ },
+ {
+ text: 'Community',
+ link: '/docs/community'
+ },
+ {
+ text: 'Style Guide',
+ link: '/docs/styleguide'
+ },
+ {
+ text: 'Contributing',
+ link: '/docs/contributing'
+ },
+ {
+ text: 'Releasing',
+ link: '/docs/releasing'
+ },
+ {
+ text: 'Security',
+ collapsed: true,
+ link: '/docs/security/',
+ items: [
+ {
+ text: 'Incident Response Plan',
+ link: '/docs/security/incident-response-plan'
+ },
+ {
+ text: 'Threat Model',
+ link: '/docs/security/threat-model'
+ }
+ ]
+ },
+ {
+ text: 'Changelog',
+ link: '/docs/changelog'
+ },
+ {
+ text: 'FAQ',
+ link: '/docs/faq'
+ }
+];
diff --git a/website/Taskfile.yml b/website/Taskfile.yml
index d2e5d973..cfaf794a 100644
--- a/website/Taskfile.yml
+++ b/website/Taskfile.yml
@@ -3,6 +3,9 @@ version: '3'
tasks:
install:
desc: Setup VitePress locally
+ # start:all reaches this task through two parallel branches, and pnpm does
+ # not expect two installs at once.
+ run: once
cmds:
- pnpm install
sources:
@@ -12,13 +15,30 @@ tasks:
default:
desc: Start website
deps: [install]
- aliases: [s, start]
+ aliases: [s, start, start:next]
vars:
HOST: '{{default "0.0.0.0" .HOST}}'
PORT: '{{default "3001" .PORT}}'
+ env:
+ DOCS_CHANNEL: '{{.CHANNEL | default "next"}}'
+ # Only the dev server sets this: it is what keeps the localhost URLs of
+ # the version selector out of a build. See .vitepress/config.ts.
+ DOCS_LOCAL: '1'
cmds:
- pnpm dev --host={{.HOST}} --port={{.PORT}}
+ # The port is half of a pair: config.ts links the two channels to each other
+ # on 3001 and 3002, so both dev servers can run side by side.
+ start:latest:
+ desc: Start website with the content of the released version
+ cmds:
+ - task: default
+ vars: { CHANNEL: latest, PORT: '{{default "3002" .PORT}}' }
+
+ start:all:
+ desc: Start both channels side by side
+ deps: [default, start:latest]
+
lint:
desc: Lint website
deps: [install]
@@ -27,10 +47,19 @@ tasks:
build:
desc: Build website
+ aliases: [build:next]
deps: [install]
+ env:
+ DOCS_CHANNEL: '{{.CHANNEL | default "next"}}'
cmds:
- pnpm build
+ build:latest:
+ desc: Build website with the content of the released version
+ cmds:
+ - task: build
+ vars: { CHANNEL: latest }
+
preview:
desc: Preview Website
deps: [build]
@@ -46,12 +75,17 @@ tasks:
cmds:
- rm -rf ./vitepress/dist
+ # --no-build is what makes the channel stick: the CLI builds by default, and
+ # that build would come from netlify.toml, which knows nothing about the
+ # channel these tasks just built.
deploy:next:
desc: Build and deploy next.taskfile.dev
+ deps: [build:next]
cmds:
- - pnpm netlify deploy --prod --site=4e13dfcf-fc0d-4bec-ad60-b918a8dc3942
+ - pnpm netlify deploy --prod --no-build --site=4e13dfcf-fc0d-4bec-ad60-b918a8dc3942
deploy:prod:
desc: Build and deploy taskfile.dev
+ deps: [build:latest]
cmds:
- - pnpm netlify deploy --prod --site=e625bc6a-1cd3-465d-ad30-7bbddaeb4f31
+ - pnpm netlify deploy --prod --no-build --site=e625bc6a-1cd3-465d-ad30-7bbddaeb4f31
diff --git a/website/src/blog/any-variables.md b/website/src/latest/blog/any-variables.md
similarity index 100%
rename from website/src/blog/any-variables.md
rename to website/src/latest/blog/any-variables.md
diff --git a/website/src/blog/github-secure-open-source-program.md b/website/src/latest/blog/github-secure-open-source-program.md
similarity index 100%
rename from website/src/blog/github-secure-open-source-program.md
rename to website/src/latest/blog/github-secure-open-source-program.md
diff --git a/website/src/blog/go-tool-task.md b/website/src/latest/blog/go-tool-task.md
similarity index 100%
rename from website/src/blog/go-tool-task.md
rename to website/src/latest/blog/go-tool-task.md
diff --git a/website/src/blog/if-and-variable-prompt.md b/website/src/latest/blog/if-and-variable-prompt.md
similarity index 100%
rename from website/src/blog/if-and-variable-prompt.md
rename to website/src/latest/blog/if-and-variable-prompt.md
diff --git a/website/src/blog/index.md b/website/src/latest/blog/index.md
similarity index 83%
rename from website/src/blog/index.md
rename to website/src/latest/blog/index.md
index 540d7e88..d57ceb43 100644
--- a/website/src/blog/index.md
+++ b/website/src/latest/blog/index.md
@@ -5,7 +5,7 @@ editLink: false
---
` to the URL.
+- You can also optionally specify a branch or tag to use by appending
+ `?ref=[` to the end of the URL. If you omit a reference, the default
+ branch will be used.
+
+### Git over SSH
+
+`git@github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=main`
+
+This type of node works by downloading the file from a Git repository over SSH.
+The first part of the URL is the user and base URL of the Git repository. This
+is the same URL that you would use to clone the repo over SSH.
+
+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=][` to the end of the URL. If you omit a reference, the default
+ branch will be used.
+
+Task has an example remote Taskfile in our repository that you can use for
+testing and that we will use throughout this document:
+
+```yaml
+version: '3'
+
+tasks:
+ default:
+ cmds:
+ - task: hello
+
+ hello:
+ cmds:
+ - echo "Hello Task!"
+```
+
+## Specifying a remote entrypoint
+
+By default, Task will look for one of the supported file names on your local
+filesystem. If you want to use a remote file instead, you can pass its URI into
+the `--taskfile`/`-t` flag just like you would to specify a different local
+file. For example:
+
+::: code-group
+
+```shell [HTTP/HTTPS]
+$ task --taskfile https://raw.githubusercontent.com/go-task/task/main/website/src/public/Taskfile.yml
+task: [hello] echo "Hello Task!"
+Hello Task!
+```
+
+```shell [Git over HTTP]
+$ task --taskfile https://github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=main
+task: [hello] echo "Hello Task!"
+Hello Task!
+```
+
+```shell [Git over SSH]
+$ task --taskfile git@github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=main
+task: [hello] echo "Hello Task!"
+Hello Task!
+```
+
+:::
+
+## Including remote Taskfiles
+
+Including a remote file works exactly the same way that including a local file
+does. You just need to replace the local path with a remote URI. Any tasks in
+the remote Taskfile will be available to run from your main Taskfile.
+
+::: code-group
+
+```yaml [HTTP/HTTPS]
+version: '3'
+
+includes:
+ my-remote-namespace: https://raw.githubusercontent.com/go-task/task/main/website/src/public/Taskfile.yml
+```
+
+```yaml [Git over HTTP]
+version: '3'
+
+includes:
+ my-remote-namespace: https://github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=main
+```
+
+```yaml [Git over SSH]
+version: '3'
+
+includes:
+ my-remote-namespace: git@github.com/go-task/task.git//website/src/public/Taskfile.yml?ref=main
+```
+
+:::
+
+```shell
+$ task my-remote-namespace:hello
+task: [hello] echo "Hello Task!"
+Hello Task!
+```
+
+### Authenticating using environment variables
+
+The Taskfile location is processed by the templating system, so you can
+reference environment variables in your URL if you need to add authentication.
+For example:
+
+```yaml
+version: '3'
+
+includes:
+ my-remote-namespace: https://{{.TOKEN}}@raw.githubusercontent.com/my-org/my-repo/main/Taskfile.yml
+```
+
+## Special Variables
+
+The file-path [special variables](../reference/templating.md#file-paths) behave
+differently when a Taskfile is loaded from a remote source, because there is no
+local file or directory that corresponds 1:1 to the Taskfile:
+
+| Variable | Value when loaded remotely |
+| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
+| `TASKFILE` / `ROOT_TASKFILE` | The original URL, unchanged |
+| `TASKFILE_DIR` / `ROOT_DIR` | Empty string — a directory variable cannot point to a URL |
+| `TASK_DIR` | Resolved against `USER_WORKING_DIR` (relative `dir:` → joined with `USER_WORKING_DIR`, empty `dir:` → `USER_WORKING_DIR`, absolute `dir:` → kept as-is) |
+
+If a remote Taskfile includes a local Taskfile (or vice-versa), each variable
+reflects the source of the Taskfile it refers to.
+
+## Security
+
+### 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:
+
+1. 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 code `104` (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.
+2. 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
+ code `104` (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](#trusted-hosts) using
+`remote.trusted-hosts`. Before enabling automatic trust, you should:
+
+1. Be sure that you trust the source and contents of the remote Taskfile.
+2. 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.
+
+### 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:
+
+```yaml
+version: '3'
+
+includes:
+ included:
+ taskfile: https://taskfile.dev
+ checksum: c153e97e0b3a998a7ed2e61064c6ddaddd0de0c525feefd6bba8569827d8efe9
+```
+
+This will disable the automatic checksum prompts discussed above. However, if
+the checksums do not match, Task will exit immediately with an error. When
+setting this up for the first time, you may not know the correct value of the
+checksum. There are a couple of ways you can obtain this:
+
+1. Add the include normally without the `checksum` key. The first time you run
+ the included Taskfile, a `.task/remote` temporary directory is created. Find
+ 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 the `checksum` key of your include. This method is safest as it allows
+ you to inspect the downloaded Taskfile before you pin it.
+2. Alternatively, add the include with a temporary random value in the
+ `checksum` key. 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.
+
+### 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.
+
+#### 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:
+
+```shell
+task --taskfile https://internal.example.com/Taskfile.yml --cacert /path/to/ca.crt
+```
+
+For servers that require client certificate authentication (mTLS), you can
+provide a client certificate and key:
+
+```shell
+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:
+
+```shell
+openssl rsa -in encrypted.key -out decrypted.key
+```
+
+:::
+
+These options can also be configured in the [configuration file](#configuration).
+
+## Caching & Running Offline
+
+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_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
+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, the
+`remote.cache-dir` option in your [configuration file](#cache-dir), or 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.
+
+## Configuration
+
+This experiment adds a new `remote` section to the
+[configuration file](../reference/config.md).
+
+- **Type**: `object`
+- **Description**: Remote configuration settings for handling remote Taskfiles
+
+```yaml
+remote:
+ insecure: false
+ offline: false
+ timeout: "30s"
+ cache-expiry: "24h"
+ cache-dir: ~/.task
+ trusted-hosts:
+ - github.com
+ - gitlab.com
+ cacert: ""
+ cert: ""
+ cert-key: ""
+```
+
+#### `insecure`
+
+- **Type**: `boolean`
+- **Default**: `false`
+- **Description**: Allow insecure connections when fetching remote Taskfiles
+- **CLI equivalent**: `--insecure`
+- **Environment variable**: `TASK_REMOTE_INSECURE`
+
+```yaml
+remote:
+ insecure: true
+```
+
+#### `offline`
+
+- **Type**: `boolean`
+- **Default**: `false`
+- **Description**: Work in offline mode, preventing remote Taskfile fetching
+- **CLI equivalent**: `--offline`
+- **Environment variable**: `TASK_REMOTE_OFFLINE`
+
+```yaml
+remote:
+ offline: true
+```
+
+#### `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`
+
+```yaml
+remote:
+ timeout: "1m"
+```
+
+#### `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`
+
+```yaml
+remote:
+ cache-expiry: "6h"
+```
+
+#### `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`
+
+```yaml
+remote:
+ cache-dir: ~/.task
+```
+
+#### `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)
+
+```yaml
+remote:
+ trusted-hosts:
+ - github.com
+ - gitlab.com
+ - raw.githubusercontent.com
+ - example.com:8080
+```
+
+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.
+
+You can also specify trusted hosts via the command line:
+
+```shell
+# 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
+```
+
+#### `cacert`
+
+- **Type**: `string`
+- **Default**: `""`
+- **Description**: Path to a custom CA certificate file for TLS verification
+
+```yaml
+remote:
+ cacert: "/path/to/ca.crt"
+```
+
+#### `cert`
+
+- **Type**: `string`
+- **Default**: `""`
+- **Description**: Path to a client certificate file for mTLS authentication
+
+```yaml
+remote:
+ cert: "/path/to/client.crt"
+```
+
+#### `cert-key`
+
+- **Type**: `string`
+- **Default**: `""`
+- **Description**: Path to the client certificate private key file
+
+```yaml
+remote:
+ cert-key: "/path/to/client.key"
+```
diff --git a/website/src/docs/experiments/template.md b/website/src/latest/docs/experiments/template.md
similarity index 100%
rename from website/src/docs/experiments/template.md
rename to website/src/latest/docs/experiments/template.md
diff --git a/website/src/docs/faq.md b/website/src/latest/docs/faq.md
similarity index 100%
rename from website/src/docs/faq.md
rename to website/src/latest/docs/faq.md
diff --git a/website/src/docs/getting-started.md b/website/src/latest/docs/getting-started.md
similarity index 100%
rename from website/src/docs/getting-started.md
rename to website/src/latest/docs/getting-started.md
diff --git a/website/src/latest/docs/guide.md b/website/src/latest/docs/guide.md
new file mode 100644
index 00000000..d5ca4622
--- /dev/null
+++ b/website/src/latest/docs/guide.md
@@ -0,0 +1,2888 @@
+---
+outline: deep
+---
+
+# Guide
+
+## Running Taskfiles
+
+Specific Taskfiles can be called by specifying the `--taskfile` flag. If you
+don't specify a Taskfile, Task will automatically look for a file with one of
+the [supported file names](#supported-file-names) in the current directory. If
+you want to search in a different directory, you can use the `--dir` flag.
+
+### Supported file names
+
+Task looks for files with the following names, in order of priority:
+
+- `Taskfile.yml`
+- `taskfile.yml`
+- `Taskfile.yaml`
+- `taskfile.yaml`
+- `Taskfile.dist.yml`
+- `taskfile.dist.yml`
+- `Taskfile.dist.yaml`
+- `taskfile.dist.yaml`
+
+The `.dist` variants allow projects to have one committed file (`.dist`) while
+still allowing individual users to override the Taskfile by adding an additional
+`Taskfile.yml` (which would be in your `.gitignore`).
+
+### Running a Taskfile from a subdirectory
+
+If a Taskfile cannot be found in the current working directory, it will walk up
+the file tree until it finds one (similar to how `git` works). When running Task
+from a subdirectory like this, it will behave as if you ran it from the
+directory containing the Taskfile.
+
+You can use this functionality along with the special
+`{{.USER_WORKING_DIR}}` variable to create some very useful
+reusable tasks. For example, if you have a monorepo with directories for each
+microservice, you can `cd` into a microservice directory and run a task command
+to bring it up without having to create multiple tasks or Taskfiles with
+identical content. For example:
+
+```yaml
+version: '3'
+
+tasks:
+ up:
+ dir: '{{.USER_WORKING_DIR}}'
+ preconditions:
+ - test -f docker-compose.yml
+ cmds:
+ - docker-compose up -d
+```
+
+In this example, we can run `cd ` and `task up` and as long as the
+`` directory contains a `docker-compose.yml`, the Docker composition
+will be brought up.
+
+### Running a global Taskfile
+
+If you call Task with the `--global` (alias `-g`) flag, it will look for your
+home directory instead of your working directory. In short, Task will look for a
+Taskfile that matches `$HOME/{T,t}askfile.{yml,yaml}` .
+
+This is useful to have automation that you can run from anywhere in your system!
+
+::: info
+
+When running your global Taskfile with `-g`, tasks will run on `$HOME` by
+default, and not on your working directory!
+
+As mentioned in the previous section, the
+`{{.USER_WORKING_DIR}}` special variable can be very handy
+here to run stuff on the directory you're calling `task -g` from.
+
+```yaml
+version: '3'
+
+tasks:
+ from-home:
+ cmds:
+ - pwd
+
+ from-working-directory:
+ dir: '{{.USER_WORKING_DIR}}'
+ cmds:
+ - pwd
+```
+
+:::
+
+### Reading a Taskfile from stdin
+
+Taskfile also supports reading from stdin. This is useful if you are generating
+Taskfiles dynamically and don't want write them to disk. To tell task to read
+from stdin, you must specify the `-t/--taskfile` flag with the special `-`
+value. You may then pipe into Task as you would any other program:
+
+```shell
+task -t - < ./Taskfile.yml
+# OR
+cat ./Taskfile.yml | task -t -
+```
+
+## Environment variables
+
+### Task
+
+You can use `env` to set custom environment variables for a specific task:
+
+```yaml
+version: '3'
+
+tasks:
+ greet:
+ cmds:
+ - echo $GREETING
+ env:
+ GREETING: Hey, there!
+```
+
+Additionally, you can set global environment variables that will be available to
+all tasks:
+
+```yaml
+version: '3'
+
+env:
+ GREETING: Hey, there!
+
+tasks:
+ greet:
+ cmds:
+ - echo $GREETING
+```
+
+::: info
+
+`env` supports expansion and retrieving output from a shell command just like
+variables, as you can see in the [Variables](#variables) section.
+
+:::
+
+### .env files
+
+You can also ask Task to include `.env` like files by using the `dotenv:`
+setting:
+
+::: code-group
+
+```shell [.env]
+KEYNAME=VALUE
+```
+
+```shell [testing/.env]
+ENDPOINT=testing.com
+```
+
+:::
+
+```yaml
+version: '3'
+
+env:
+ ENV: testing
+
+dotenv: ['.env', '{{.ENV}}/.env', '{{.HOME}}/.env']
+
+tasks:
+ greet:
+ cmds:
+ - echo "Using $KEYNAME and endpoint $ENDPOINT"
+```
+
+When the same variable is defined in multiple dotenv files, the **first file in
+the list takes precedence**. This allows you to set up override patterns by
+placing higher-priority files first:
+
+```yaml
+version: '3'
+
+dotenv:
+ - .env.local # Highest priority - local developer overrides
+ - .env.{{.ENV}} # Environment-specific settings
+ - .env # Base defaults (lowest priority)
+```
+
+Dotenv files can also be specified at the task level:
+
+```yaml
+version: '3'
+
+env:
+ ENV: testing
+
+tasks:
+ greet:
+ dotenv: ['.env', '{{.ENV}}/.env', '{{.HOME}}/.env']
+ cmds:
+ - echo "Using $KEYNAME and endpoint $ENDPOINT"
+```
+
+Environment variables specified explicitly at the task-level will override
+variables defined in dotfiles:
+
+```yaml
+version: '3'
+
+env:
+ ENV: testing
+
+tasks:
+ greet:
+ dotenv: ['.env', '{{.ENV}}/.env', '{{.HOME}}/.env']
+ env:
+ KEYNAME: DIFFERENT_VALUE
+ cmds:
+ - echo "Using $KEYNAME and endpoint $ENDPOINT"
+```
+
+::: info
+
+Please note that you are not currently able to use the `dotenv` key inside
+included Taskfiles.
+
+:::
+
+## Including other Taskfiles
+
+If you want to share tasks between different projects (Taskfiles), you can use
+the importing mechanism to include other Taskfiles using the `includes` keyword:
+
+```yaml
+version: '3'
+
+includes:
+ docs: ./documentation # will look for ./documentation/Taskfile.yml
+ docker: ./DockerTasks.yml
+```
+
+The tasks described in the given Taskfiles will be available with the informed
+namespace. So, you'd call `task docs:serve` to run the `serve` task from
+`documentation/Taskfile.yml` or `task docker:build` to run the `build` task from
+the `DockerTasks.yml` file.
+
+Relative paths are resolved relative to the directory containing the including
+Taskfile.
+
+### OS-specific Taskfiles
+
+You can include OS-specific Taskfiles by using a templating function:
+
+```yaml
+version: '3'
+
+includes:
+ build: ./Taskfile_{{OS}}.yml
+```
+
+### Directory of included Taskfile
+
+By default, included Taskfile's tasks are run in the current directory, even if
+the Taskfile is in another directory, but you can force its tasks to run in
+another directory by using this alternative syntax:
+
+```yaml
+version: '3'
+
+includes:
+ docs:
+ taskfile: ./docs/Taskfile.yml
+ dir: ./docs
+```
+
+::: info
+
+The included Taskfiles must be using the same schema version as the main
+Taskfile uses.
+
+:::
+
+### Optional includes
+
+Includes marked as optional will allow Task to continue execution as normal if
+the included file is missing.
+
+```yaml
+version: '3'
+
+includes:
+ tests:
+ taskfile: ./tests/Taskfile.yml
+ optional: true
+
+tasks:
+ greet:
+ cmds:
+ - echo "This command can still be successfully executed if
+ ./tests/Taskfile.yml does not exist"
+```
+
+### Internal includes
+
+Includes marked as internal will set all the tasks of the included file to be
+internal as well (see the [Internal tasks](#internal-tasks) section below). This
+is useful when including utility tasks that are not intended to be used directly
+by the user.
+
+```yaml
+version: '3'
+
+includes:
+ tests:
+ taskfile: ./taskfiles/Utils.yml
+ internal: true
+```
+
+### Flatten includes
+
+You can flatten the included Taskfile tasks into the main Taskfile by using the
+`flatten` option. It means that the included Taskfile tasks will be available
+without the namespace.
+
+::: code-group
+
+```yaml [Taskfile.yml]
+version: '3'
+
+includes:
+ lib:
+ taskfile: ./Included.yml
+ flatten: true
+
+tasks:
+ greet:
+ cmds:
+ - echo "Greet"
+ - task: foo
+```
+
+```yaml [Included.yml]
+version: '3'
+
+tasks:
+ foo:
+ cmds:
+ - echo "Foo"
+```
+
+:::
+
+If you run `task -a` it will print :
+
+```sh
+task: Available tasks for this project:
+* greet:
+* foo
+```
+
+You can run `task foo` directly without the namespace.
+
+You can also reference the task in other tasks without the namespace. So if you
+run `task greet` it will run `greet` and `foo` tasks and the output will be :
+
+```text
+Greet
+Foo
+```
+
+If multiple tasks have the same name, an error will be thrown:
+
+::: code-group
+
+```yaml [Taskfile.yml]
+version: '3'
+includes:
+ lib:
+ taskfile: ./Included.yml
+ flatten: true
+
+tasks:
+ greet:
+ cmds:
+ - echo "Greet"
+ - task: foo
+```
+
+```yaml [Included.yml]
+version: '3'
+
+tasks:
+ greet:
+ cmds:
+ - echo "Foo"
+```
+
+:::
+
+If you run `task -a` it will print:
+
+```text
+task: Found multiple tasks (greet) included by "lib"
+```
+
+If the included Taskfile has a task with the same name as a task in the main
+Taskfile, you may want to exclude it from the flattened tasks.
+
+You can do this by using the
+[`excludes` option](#exclude-tasks-from-being-included).
+
+### Exclude tasks from being included
+
+You can exclude tasks from being included by using the `excludes` option. This
+option takes the list of tasks to be excluded from this include.
+
+::: code-group
+
+```yaml [Taskfile.yml]
+version: '3'
+
+includes:
+ included:
+ taskfile: ./Included.yml
+ excludes: [foo]
+```
+
+```yaml [Included.yml]
+version: '3'
+
+tasks:
+ foo: echo "Foo"
+ bar: echo "Bar"
+```
+
+:::
+
+`task included:foo` will throw an error because the `foo` task is excluded but
+`task included:bar` will work and display `Bar`.
+
+It's compatible with the `flatten` option.
+
+### Vars of included Taskfiles
+
+You can also specify variables when including a Taskfile. This may be useful for
+having a reusable Taskfile that can be tweaked or even included more than once:
+
+```yaml
+version: '3'
+
+includes:
+ backend:
+ taskfile: ./taskfiles/Docker.yml
+ vars:
+ DOCKER_IMAGE: backend_image
+
+ frontend:
+ taskfile: ./taskfiles/Docker.yml
+ vars:
+ DOCKER_IMAGE: frontend_image
+```
+
+### Namespace aliases
+
+When including a Taskfile, you can give the namespace a list of `aliases`. This
+works in the same way as [task aliases](#task-aliases) and can be used together
+to create shorter and easier-to-type commands.
+
+```yaml
+version: '3'
+
+includes:
+ generate:
+ taskfile: ./taskfiles/Generate.yml
+ aliases: [gen]
+```
+
+::: info
+
+Vars declared in the included Taskfile have preference over the variables in the
+including Taskfile! If you want a variable in an included Taskfile to be
+overridable, use the
+[default function](https://sprig.taskfile.dev/defaults.html):
+`MY_VAR: '{{.MY_VAR | default "my-default-value"}}'`.
+
+:::
+
+## Internal tasks
+
+Internal tasks are tasks that cannot be called directly by the user. They will
+not appear in the output when running `task --list|--list-all`. Other tasks may
+call internal tasks in the usual way. This is useful for creating reusable,
+function-like tasks that have no useful purpose on the command line.
+
+```yaml
+version: '3'
+
+tasks:
+ build-image-1:
+ cmds:
+ - task: build-image
+ vars:
+ DOCKER_IMAGE: image-1
+
+ build-image:
+ internal: true
+ cmds:
+ - docker build -t {{.DOCKER_IMAGE}} .
+```
+
+## Task directory
+
+By default, tasks will be executed in the directory where the Taskfile is
+located. But you can easily make the task run in another folder, informing
+`dir`:
+
+```yaml
+version: '3'
+
+tasks:
+ serve:
+ dir: public/www
+ cmds:
+ # run http server
+ - caddy
+```
+
+If the directory does not exist, `task` creates it.
+
+## Task dependencies
+
+> Dependencies run in parallel, so dependencies of a task should not depend one
+> another. If you want to force tasks to run serially, take a look at the
+> [Calling Another Task](#calling-another-task) section below.
+
+You may have tasks that depend on others. Just pointing them on `deps` will make
+them run automatically before running the parent task:
+
+```yaml
+version: '3'
+
+tasks:
+ build:
+ deps: [assets]
+ cmds:
+ - go build -v -i main.go
+
+ assets:
+ cmds:
+ - esbuild --bundle --minify css/index.css > public/bundle.css
+```
+
+In the above example, `assets` will always run right before `build` if you run
+`task build`.
+
+A task can have only dependencies and no commands to group tasks together:
+
+```yaml
+version: '3'
+
+tasks:
+ assets:
+ deps: [js, css]
+
+ js:
+ cmds:
+ - esbuild --bundle --minify js/index.js > public/bundle.js
+
+ css:
+ cmds:
+ - esbuild --bundle --minify css/index.css > public/bundle.css
+```
+
+If there is more than one dependency, they always run in parallel for better
+performance.
+
+::: tip
+
+You can also make the tasks given by the command line run in parallel by using
+the `--parallel` flag (alias `-p`). Example: `task --parallel js css`.
+
+:::
+
+If you want to pass information to dependencies, you can do that the same manner
+as you would to [call another task](#calling-another-task):
+
+```yaml
+version: '3'
+
+tasks:
+ default:
+ deps:
+ - task: echo_sth
+ vars: { TEXT: 'before 1' }
+ - task: echo_sth
+ vars: { TEXT: 'before 2' }
+ silent: true
+ cmds:
+ - echo "after"
+
+ echo_sth:
+ cmds:
+ - echo {{.TEXT}}
+```
+
+### Fail-fast dependencies
+
+By default, Task waits for all dependencies to finish running before continuing.
+If you want Task to stop executing further dependencies as soon as one fails,
+you can set `failfast: true` on your [`.taskrc.yml`][config] or for a specific
+task:
+
+```yaml
+# .taskrc.yml
+failfast: true # applies to all tasks
+```
+
+```yaml
+# Taskfile.yml
+version: '3'
+
+tasks:
+ default:
+ deps: [task1, task2, task3]
+ failfast: true # applies only to this task
+```
+
+Alternatively, you can use `--failfast`, which also work for `--parallel`.
+
+## Platform specific tasks and commands
+
+If you want to restrict the running of tasks to explicit platforms, this can be
+achieved using the `platforms:` key. Tasks can be restricted to a specific OS,
+architecture or a combination of both. On a mismatch, the task or command will
+be skipped, and no error will be thrown.
+
+The values allowed as OS or Arch are valid `GOOS` and `GOARCH` values, as
+defined by the Go language
+[here](https://github.com/golang/go/blob/master/src/internal/syslist/syslist.go).
+
+The `build-windows` task below will run only on Windows, and on any
+architecture:
+
+```yaml
+version: '3'
+
+tasks:
+ build-windows:
+ platforms: [windows]
+ cmds:
+ - echo 'Running command on Windows'
+```
+
+This can be restricted to a specific architecture as follows:
+
+```yaml
+version: '3'
+
+tasks:
+ build-windows-amd64:
+ platforms: [windows/amd64]
+ cmds:
+ - echo 'Running command on Windows (amd64)'
+```
+
+It is also possible to restrict the task to specific architectures:
+
+```yaml
+version: '3'
+
+tasks:
+ build-amd64:
+ platforms: [amd64]
+ cmds:
+ - echo 'Running command on amd64'
+```
+
+Multiple platforms can be specified as follows:
+
+```yaml
+version: '3'
+
+tasks:
+ build:
+ platforms: [windows/amd64, darwin]
+ cmds:
+ - echo 'Running command on Windows (amd64) and macOS'
+```
+
+Individual commands can also be restricted to specific platforms:
+
+```yaml
+version: '3'
+
+tasks:
+ build:
+ cmds:
+ - cmd: echo 'Running command on Windows (amd64) and macOS'
+ platforms: [windows/amd64, darwin]
+ - cmd: echo 'Running on all platforms'
+```
+
+## Calling another task
+
+When a task has many dependencies, they are executed concurrently. This will
+often result in a faster build pipeline. However, in some situations, you may
+need to call other tasks serially. In this case, use the following syntax:
+
+```yaml
+version: '3'
+
+tasks:
+ main-task:
+ cmds:
+ - task: task-to-be-called
+ - task: another-task
+ - echo "Both done"
+
+ task-to-be-called:
+ cmds:
+ - echo "Task to be called"
+
+ another-task:
+ cmds:
+ - echo "Another task"
+```
+
+Using the `vars` and `silent` attributes you can choose to pass variables and
+toggle [silent mode](#silent-mode) on a call-by-call basis:
+
+```yaml
+version: '3'
+
+tasks:
+ greet:
+ vars:
+ RECIPIENT: '{{default "World" .RECIPIENT}}'
+ cmds:
+ - echo "Hello, {{.RECIPIENT}}!"
+
+ greet-pessimistically:
+ cmds:
+ - task: greet
+ vars: { RECIPIENT: 'Cruel World' }
+ silent: true
+```
+
+The above syntax is also supported in `deps`.
+
+::: tip
+
+NOTE: If you want to call a task declared in the root Taskfile from within an
+[included Taskfile](#including-other-taskfiles), add a leading `:` like this:
+`task: :task-name`.
+
+:::
+
+## Prevent unnecessary work
+
+### By fingerprinting locally generated files and their sources
+
+If a task generates something, you can inform Task the source and generated
+files, so Task will prevent running them if not necessary.
+
+```yaml
+version: '3'
+
+tasks:
+ build:
+ deps: [js, css]
+ cmds:
+ - go build -v -i main.go
+
+ js:
+ cmds:
+ - esbuild --bundle --minify js/index.js > public/bundle.js
+ sources:
+ - src/js/**/*.js
+ generates:
+ - public/bundle.js
+
+ css:
+ cmds:
+ - esbuild --bundle --minify css/index.css > public/bundle.css
+ sources:
+ - src/css/**/*.css
+ generates:
+ - public/bundle.css
+```
+
+`sources` and `generates` can be files or glob patterns. When given, Task will
+compare the checksum of the source files to determine if it's necessary to run
+the task. If not, it will just print a message like `Task "js" is up to date`.
+
+`exclude:` can also be used to exclude files from fingerprinting. Sources are
+evaluated in order, so `exclude:` must come after the positive glob it is
+negating.
+
+```yaml
+version: '3'
+
+tasks:
+ css:
+ sources:
+ - mysources/**/*.css
+ - exclude: mysources/ignoreme.css
+ generates:
+ - public/bundle.css
+```
+
+If you prefer these check to be made by the modification timestamp of the files,
+instead of its checksum (content), just set the `method` property to
+`timestamp`. This can be done at two levels:
+
+At the task level for a specific task:
+
+```yaml
+version: '3'
+
+tasks:
+ build:
+ cmds:
+ - go build .
+ sources:
+ - ./*.go
+ generates:
+ - app{{exeExt}}
+ method: timestamp
+```
+
+At the root level of the Taskfile to apply it globally to all tasks:
+
+```yaml
+version: '3'
+
+method: timestamp # Will be the default for all tasks
+
+tasks:
+ build:
+ cmds:
+ - go build .
+ sources:
+ - ./*.go
+ generates:
+ - app{{exeExt}}
+```
+
+In situations where you need more flexibility the `status` keyword can be used.
+You can even combine the two. See the documentation for
+[status](#using-programmatic-checks-to-indicate-a-task-is-up-to-date) for an
+example.
+
+::: info
+
+By default, task stores checksums on a local `.task` directory in the project's
+directory. Most of the time, you'll want to have this directory on `.gitignore`
+(or equivalent) so it isn't committed. (If you have a task for code generation
+that is committed it may make sense to commit the checksum of that task as well,
+though).
+
+If you want these files to be stored in another directory, you can set a
+`TASK_TEMP_DIR` environment variable in your machine. It can contain a relative
+path like `tmp/task` that will be interpreted as relative to the project
+directory, or an absolute or home path like `/tmp/.task` or `~/.task`
+(subdirectories will be created for each project).
+
+```shell
+export TASK_TEMP_DIR='~/.task'
+```
+
+:::
+
+::: info
+
+Each task has only one checksum stored for its `sources`. If you want to
+distinguish a task by any of its input variables, you can add those variables as
+part of the task's label, and it will be considered a different task.
+
+This is useful if you want to run a task once for each distinct set of inputs
+until the sources actually change. For example, if the sources depend on the
+value of a variable, or you if you want the task to rerun if some arguments
+change even if the source has not.
+
+:::
+
+::: tip
+
+The method `none` skips any validation and always runs the task.
+
+:::
+
+::: info
+
+For the `checksum` (default) or `timestamp` method to work, it is only necessary
+to inform the source files. When the `timestamp` method is used, the last time
+of the running the task is considered as a generate.
+
+:::
+
+::: tip
+
+If your globs match files that are ignored by Git (build artifacts, caches,
+etc.), you can set `use_gitignore: true` at the root of your Taskfile to
+exclude anything matched by `.gitignore` rules from `sources` and `generates`
+resolution. The setting can also be enabled or disabled per task, which takes
+precedence over the root value.
+
+:::
+
+### Using programmatic checks to indicate a task is up to date
+
+Alternatively, you can inform a sequence of tests as `status`. If no error is
+returned (exit status 0), the task is considered up-to-date:
+
+```yaml
+version: '3'
+
+tasks:
+ generate-files:
+ cmds:
+ - mkdir directory
+ - touch directory/file1.txt
+ - touch directory/file2.txt
+ # test existence of files
+ status:
+ - test -d directory
+ - test -f directory/file1.txt
+ - test -f directory/file2.txt
+```
+
+Normally, you would use `sources` in combination with `generates` - but for
+tasks that generate remote artifacts (Docker images, deploys, CD releases) the
+checksum source and timestamps require either access to the artifact or for an
+out-of-band refresh of the `.checksum` fingerprint file.
+
+Two special variables `{{.CHECKSUM}}` and
+`{{.TIMESTAMP}}` are available for interpolation within
+`cmds` and `status` commands, depending on the method assigned to fingerprint
+the sources. Only `source` globs are fingerprinted.
+
+Note that the `{{.TIMESTAMP}}` variable is a "live" Go
+`time.Time` struct, and can be formatted using any of the methods that
+`time.Time` responds to.
+
+See [the Go Time documentation](https://golang.org/pkg/time/) for more
+information.
+
+You can use `--force` or `-f` if you want to force a task to run even when
+up-to-date.
+
+Also, `task --status [tasks]...` will exit with a non-zero
+[exit code](/docs/reference/cli#exit-codes) if any of the tasks are not up-to-date.
+
+`status` can be combined with the
+[fingerprinting](#by-fingerprinting-locally-generated-files-and-their-sources)
+to have a task run if either the source/generated artifacts changes, or the
+programmatic check fails:
+
+```yaml
+version: '3'
+
+tasks:
+ build:prod:
+ desc: Build for production usage.
+ cmds:
+ - composer install
+ # Run this task if source files changes.
+ sources:
+ - composer.json
+ - composer.lock
+ generates:
+ - ./vendor/composer/installed.json
+ - ./vendor/autoload.php
+ # But also run the task if the last build was not a production build.
+ status:
+ - grep -q '"dev"{{:}} false' ./vendor/composer/installed.json
+```
+
+### Using programmatic checks to cancel the execution of a task and its dependencies
+
+In addition to `status` checks, `preconditions` checks are the logical inverse
+of `status` checks. That is, if you need a certain set of conditions to be
+_true_ you can use the `preconditions` stanza. `preconditions` are similar to
+`status` lines, except they support `sh` expansion, and they SHOULD all
+return 0.
+
+```yaml
+version: '3'
+
+tasks:
+ generate-files:
+ cmds:
+ - mkdir directory
+ - touch directory/file1.txt
+ - touch directory/file2.txt
+ # test existence of files
+ preconditions:
+ - test -f .env
+ - sh: '[ 1 = 0 ]'
+ msg: "One doesn't equal Zero, Halting"
+```
+
+Preconditions can set specific failure messages that can tell a user what steps
+to take using the `msg` field.
+
+If a task has a dependency on a sub-task with a precondition, and that
+precondition is not met - the calling task will fail. Note that a task executed
+with a failing precondition will not run unless `--force` is given.
+
+Unlike `status`, which will skip a task if it is up to date and continue
+executing tasks that depend on it, a `precondition` will fail a task, along with
+any other tasks that depend on it.
+
+```yaml
+version: '3'
+
+tasks:
+ task-will-fail:
+ preconditions:
+ - sh: 'exit 1'
+
+ task-will-also-fail:
+ deps:
+ - task-will-fail
+
+ task-will-still-fail:
+ cmds:
+ - task: task-will-fail
+ - echo "I will not run"
+```
+
+### Conditional execution with `if`
+
+The `if` attribute allows you to conditionally skip tasks or commands based on a
+shell command's exit code. Unlike `preconditions` which fail and stop execution,
+`if` simply skips the task or command when the condition is not met and continues
+with the rest of the Taskfile.
+
+#### Task-level `if`
+
+When `if` is set on a task, the entire task is skipped if the condition fails:
+
+```yaml
+version: '3'
+
+tasks:
+ deploy:
+ if: '[ "$CI" = "true" ]'
+ cmds:
+ - echo "Deploying..."
+ - ./deploy.sh
+```
+
+#### Command-level `if`
+
+When `if` is set on a command, only that specific command is skipped:
+
+```yaml
+version: '3'
+
+tasks:
+ build:
+ cmds:
+ - cmd: echo "Building for production"
+ if: '[ "$ENV" = "production" ]'
+ - cmd: echo "Building for development"
+ if: '[ "$ENV" = "development" ]'
+ - go build ./...
+```
+
+#### Using templates in `if` conditions
+
+You can use Go template expressions in `if` conditions. Template expressions like
+`{{eq .VAR "value"}}` evaluate to `true` or `false`, which are valid shell
+commands (`true` exits with 0, `false` exits with 1):
+
+```yaml
+version: '3'
+
+tasks:
+ conditional:
+ vars:
+ ENABLE_FEATURE: "true"
+ cmds:
+ - cmd: echo "Feature is enabled"
+ if: '{{eq .ENABLE_FEATURE "true"}}'
+ - cmd: echo "Feature is disabled"
+ if: '{{ne .ENABLE_FEATURE "true"}}'
+```
+
+#### Using `if` with `for` loops
+
+When used inside a `for` loop, the `if` condition is evaluated for each iteration:
+
+```yaml
+version: '3'
+
+tasks:
+ process-items:
+ cmds:
+ - for: ['a', 'b', 'c']
+ cmd: echo "processing {{.ITEM}}"
+ if: '[ "{{.ITEM}}" != "b" ]'
+```
+
+This will output:
+
+```
+processing a
+processing c
+```
+
+#### `if` vs `preconditions`
+
+| Aspect | `if` | `preconditions` |
+|--------|------|-----------------|
+| On failure | Skips (continues) | Fails (stops) |
+| Message | Only in verbose mode | Always shown |
+| Use case | "Run if possible" | "Must be true" |
+
+Use `if` when you want optional conditional execution that shouldn't stop the
+workflow. Use `preconditions` when the condition must be met for the task to
+make sense.
+
+### Limiting when tasks run
+
+If a task executed by multiple `cmds` or multiple `deps` you can control when it
+is executed using `run`. `run` can also be set at the root of the Taskfile to
+change the behavior of all the tasks unless explicitly overridden.
+
+Supported values for `run`:
+
+- `always` (default) always attempt to invoke the task regardless of the number
+ of previous executions
+- `once` only invoke this task once regardless of the number of references
+- `when_changed` only invokes the task once for each unique set of variables
+ passed into the task
+
+```yaml
+version: '3'
+
+tasks:
+ default:
+ cmds:
+ - task: generate-file
+ vars: { CONTENT: '1' }
+ - task: generate-file
+ vars: { CONTENT: '2' }
+ - task: generate-file
+ vars: { CONTENT: '2' }
+
+ generate-file:
+ run: when_changed
+ deps:
+ - install-deps
+ cmds:
+ - echo {{.CONTENT}}
+
+ install-deps:
+ run: once
+ cmds:
+ - sleep 5 # long operation like installing packages
+```
+
+### Ensuring required variables are set
+
+If you want to check that certain variables are set before running a task then
+you can use `requires`. This is useful when might not be clear to users which
+variables are needed, or if you want clear message about what is required. Also
+some tasks could have dangerous side effects if run with un-set variables.
+
+Using `requires` you specify an array of strings in the `vars` sub-section under
+`requires`, these strings are variable names which are checked prior to running
+the task. If any variables are un-set then the task will error and not run.
+
+Environmental variables are also checked.
+
+Syntax:
+
+```yaml
+requires:
+ vars: [] # Array of strings
+```
+
+::: info
+
+Variables set to empty zero length strings, will pass the `requires` check.
+
+:::
+
+Example of using `requires`:
+
+```yaml
+version: '3'
+
+tasks:
+ docker-build:
+ cmds:
+ - 'docker build . -t {{.IMAGE_NAME}}:{{.IMAGE_TAG}}'
+
+ # Make sure these variables are set before running
+ requires:
+ vars: [IMAGE_NAME, IMAGE_TAG]
+```
+
+### Ensuring required variables have allowed values
+
+If you want to ensure that a variable is set to one of a predefined set of valid
+values before executing a task, you can use requires. This is particularly
+useful when there are strict requirements for what values a variable can take,
+and you want to provide clear feedback to the user when an invalid value is
+detected.
+
+To use `requires`, you specify an array of allowed values in the vars
+sub-section under requires. Task will check if the variable is set to one of the
+allowed values. If the variable does not match any of these values, the task
+will raise an error and stop execution.
+
+This check applies both to user-defined variables and environment variables.
+
+Example of using `requires`:
+
+```yaml
+version: '3'
+
+tasks:
+ deploy:
+ cmds:
+ - echo "deploying to {{.ENV}}"
+
+ requires:
+ vars:
+ - name: ENV
+ enum: [dev, beta, prod]
+```
+
+If `ENV` is not one of 'dev', 'beta' or 'prod' an error will be raised.
+
+::: info
+
+This is supported only for string variables.
+
+:::
+
+### Using variable references for enum values
+
+Instead of hardcoding enum values, you can reference a variable containing the
+allowed values. This is useful when you want to define allowed values once and
+reuse them, or when the values are computed dynamically.
+
+Use the `ref` key to reference a variable:
+
+```yaml
+version: '3'
+
+vars:
+ ALLOWED_ENVS: [dev, staging, prod]
+
+tasks:
+ deploy:
+ requires:
+ vars:
+ - name: ENV
+ enum:
+ ref: .ALLOWED_ENVS
+ cmds:
+ - echo "Deploying to {{.ENV}}"
+```
+
+You can also use template expressions to transform the value:
+
+```yaml
+version: '3'
+
+vars:
+ CONFIG:
+ sh: cat config.json
+
+tasks:
+ deploy:
+ requires:
+ vars:
+ - name: ENV
+ enum:
+ ref: ( .CONFIG | fromJson ).allowed_environments
+ cmds:
+ - echo "Deploying to {{.ENV}}"
+```
+
+Or generate values dynamically from a shell command:
+
+```yaml
+version: '3'
+
+vars:
+ AVAILABLE_SERVICES:
+ sh: ls services/
+
+tasks:
+ deploy:
+ requires:
+ vars:
+ - name: SERVICE
+ enum:
+ ref: .AVAILABLE_SERVICES | splitLines | compact
+ cmds:
+ - echo "Deploying {{.SERVICE}}"
+```
+
+### Prompting for missing variables interactively
+
+If you want Task to prompt users for missing required variables instead of
+failing, you can enable interactive mode in your `.taskrc.yml`:
+
+```yaml
+# ~/.taskrc.yml
+interactive: true
+```
+
+When enabled, Task will display an interactive prompt for any missing required
+variable. For variables with an `enum`, a selection menu is shown. For variables
+without an enum, a text input is displayed.
+
+```yaml
+# Taskfile.yml
+version: '3'
+
+tasks:
+ deploy:
+ requires:
+ vars:
+ - name: ENVIRONMENT
+ enum: [dev, staging, prod]
+ - VERSION
+ cmds:
+ - echo "Deploying {{.VERSION}} to {{.ENVIRONMENT}}"
+```
+
+```shell
+$ task deploy
+? Select value for ENVIRONMENT:
+❯ dev
+ staging
+ prod
+? Enter value for VERSION: 1.0.0
+Deploying 1.0.0 to prod
+```
+
+If the variable is already set (via CLI, environment, or Taskfile), no prompt
+is shown:
+
+```shell
+$ task deploy ENVIRONMENT=prod VERSION=1.0.0
+Deploying 1.0.0 to prod
+```
+
+::: info
+
+Interactive prompts require a TTY (terminal). Task automatically detects
+non-interactive environments like GitHub Actions, GitLab CI, and other CI
+pipelines where stdin/stdout are not connected to a terminal. In these cases,
+prompts are skipped and missing variables will cause an error as usual.
+
+You can enable prompts from the command line with `--interactive` or by setting
+`interactive: true` in your `.taskrc.yml`.
+
+:::
+
+## Variables
+
+Task allows you to set variables using the `vars` keyword. The following
+variable types are supported:
+
+- `string`
+- `bool`
+- `int`
+- `float`
+- `array`
+- `map`
+
+::: info
+
+Defining a map requires that you use a special `map` subkey (see example below).
+
+:::
+
+```yaml
+version: 3
+
+tasks:
+ foo:
+ vars:
+ STRING: 'Hello, World!'
+ BOOL: true
+ INT: 42
+ FLOAT: 3.14
+ ARRAY: [1, 2, 3]
+ MAP:
+ map: { A: 1, B: 2, C: 3 }
+ cmds:
+ - 'echo {{.STRING}}' # Hello, World!
+ - 'echo {{.BOOL}}' # true
+ - 'echo {{.INT}}' # 42
+ - 'echo {{.FLOAT}}' # 3.14
+ - 'echo {{.ARRAY}}' # [1 2 3]
+ - 'echo {{index .ARRAY 0}}' # 1
+ - 'echo {{.MAP}}' # map[A:1 B:2 C:3]
+ - 'echo {{.MAP.A}}' # 1
+```
+
+Variables can be set in many places in a Taskfile. When executing
+[templates][templating-reference], Task will look for variables in the order
+listed below (most important first):
+
+- Variables declared in the task definition
+- Variables given while calling a task from another (See
+ [Calling another task](#calling-another-task) above)
+- Variables of the [included Taskfile](#including-other-taskfiles) (when the
+ task is included)
+- Variables of the [inclusion of the Taskfile](#vars-of-included-taskfiles)
+ (when the task is included)
+- Global variables (those declared in the `vars:` option in the Taskfile)
+- Environment variables
+
+Example of sending parameters with environment variables:
+
+```shell
+$ TASK_VARIABLE=a-value task do-something
+```
+
+::: tip
+
+A special variable `.TASK` is always available containing the task name.
+
+:::
+
+Since some shells do not support the above syntax to set environment variables
+(Windows) tasks also accept a similar style when not at the beginning of the
+command.
+
+```shell
+$ task write-file FILE=file.txt "CONTENT=Hello, World!" print "MESSAGE=All done!"
+```
+
+Example of locally declared vars:
+
+```yaml
+version: '3'
+
+tasks:
+ print-var:
+ cmds:
+ - echo "{{.VAR}}"
+ vars:
+ VAR: Hello!
+```
+
+Example of global vars in a `Taskfile.yml`:
+
+```yaml
+version: '3'
+
+vars:
+ GREETING: Hello from Taskfile!
+
+tasks:
+ greet:
+ cmds:
+ - echo "{{.GREETING}}"
+```
+
+Example of a `default` value to be overridden from CLI:
+
+```yaml
+version: '3'
+
+tasks:
+ greet_user:
+ desc: 'Greet the user with a name.'
+ vars:
+ USER_NAME: '{{.USER_NAME| default "DefaultUser"}}'
+ cmds:
+ - echo "Hello, {{.USER_NAME}}!"
+```
+
+```shell
+$ task greet_user
+task: [greet_user] echo "Hello, DefaultUser!"
+Hello, DefaultUser!
+$ task greet_user USER_NAME="Bob"
+task: [greet_user] echo "Hello, Bob!"
+Hello, Bob!
+```
+
+### Dynamic variables
+
+The below syntax (`sh:` prop in a variable) is considered a dynamic variable.
+The value will be treated as a command and the output assigned. If there are one
+or more trailing newlines, the last newline will be trimmed.
+
+```yaml
+version: '3'
+
+tasks:
+ build:
+ cmds:
+ - go build -ldflags="-X main.Version={{.GIT_COMMIT}}" main.go
+ vars:
+ GIT_COMMIT:
+ sh: git log -n 1 --format=%h
+```
+
+This works for all types of variables.
+
+### Referencing other variables
+
+Templating is great for referencing string values if you want to pass a value
+from one task to another. However, the templating engine is only able to output
+strings. If you want to pass something other than a string to another task then
+you will need to use a reference (`ref`) instead.
+
+::: code-group
+
+```yaml [Templating Engine]
+version: 3
+
+tasks:
+ foo:
+ vars:
+ FOO: [A, B, C] # <-- FOO is defined as an array
+ cmds:
+ - task: bar
+ vars:
+ FOO: '{{.FOO}}' # <-- FOO gets converted to a string when passed to bar
+ bar:
+ cmds:
+ - 'echo {{index .FOO 0}}' # <-- FOO is a string so the task outputs '91' which is the ASCII code for '[' instead of the expected 'A'
+```
+
+```yaml [Reference]
+version: 3
+
+tasks:
+ foo:
+ vars:
+ FOO: [A, B, C] # <-- FOO is defined as an array
+ cmds:
+ - task: bar
+ vars:
+ FOO:
+ ref: .FOO # <-- FOO gets passed by reference to bar and maintains its type
+ bar:
+ cmds:
+ - 'echo {{index .FOO 0}}' # <-- FOO is still a map so the task outputs 'A' as expected
+```
+
+:::
+
+This also works the same way when calling `deps` and when defining a variable
+and can be used in any combination:
+
+```yaml
+version: 3
+
+tasks:
+ foo:
+ vars:
+ FOO: [A, B, C] # <-- FOO is defined as an array
+ BAR:
+ ref: .FOO # <-- BAR is defined as a reference to FOO
+ deps:
+ - task: bar
+ vars:
+ BAR:
+ ref: .BAR # <-- BAR gets passed by reference to bar and maintains its type
+ bar:
+ cmds:
+ - 'echo {{index .BAR 0}}' # <-- BAR still refers to FOO so the task outputs 'A'
+```
+
+All references use the same templating syntax as regular templates, so in
+addition to calling `.FOO`, you can also pass subkeys (`.FOO.BAR`) or indexes
+(`index .FOO 0`) and use functions (`len .FOO`) as described in the
+[templating-reference][templating-reference]:
+
+```yaml
+version: 3
+
+tasks:
+ foo:
+ vars:
+ FOO: [A, B, C] # <-- FOO is defined as an array
+ cmds:
+ - task: bar
+ vars:
+ FOO:
+ ref: index .FOO 0 # <-- The element at index 0 is passed by reference to bar
+ bar:
+ cmds:
+ - 'echo {{.FOO}}' # <-- FOO is just the letter 'A'
+```
+
+### Parsing JSON/YAML into map variables
+
+If you have a raw JSON or YAML string that you want to process in Task, you can
+use a combination of the `ref` keyword and the `fromJson` or `fromYaml`
+templating functions to parse the string into a map variable. For example:
+
+```yaml
+version: '3'
+
+tasks:
+ task-with-map:
+ vars:
+ JSON: '{"a": 1, "b": 2, "c": 3}'
+ FOO:
+ ref: 'fromJson .JSON'
+ cmds:
+ - echo {{.FOO}}
+```
+
+```txt
+map[a:1 b:2 c:3]
+```
+
+### Secret variables
+
+Task supports marking variables as `secret` to prevent their values from being
+displayed in command logs. When a variable is marked as secret, its value will
+be replaced with `*****` in the task output logs.
+
+::: warning
+
+**Security Notice**: This feature helps prevent accidental exposure of secrets
+in logs, but is **not a substitute** for proper secret management practices.
+
+**What this protects:**
+
+- ✅ Secret values in console/terminal logs
+- ✅ Secret values in CI/CD logs
+- ✅ Accidental copy-paste of logs containing secrets
+
+**What this does NOT protect:**
+
+- ❌ Secrets visible in process inspection (e.g., `ps aux`)
+- ❌ Secrets in shell history
+- ❌ Secrets in command output (stdout/stderr)
+- ❌ Secret values copied into derived (non-secret) variables
+
+Always use proper secret management tools (HashiCorp Vault, AWS Secrets
+Manager, etc.) for production environments.
+
+:::
+
+To mark a variable as secret, add `secret: true` to the variable definition:
+
+```yaml
+version: '3'
+
+vars:
+ API_KEY:
+ value: 'sk-1234567890abcdef'
+ secret: true
+
+tasks:
+ deploy:
+ cmds:
+ - curl -H "Authorization: {{.API_KEY}}" api.example.com
+ # Logged as: task: [deploy] curl -H "Authorization: *****" api.example.com
+```
+
+Secret variables work with all variable types:
+
+::: code-group
+
+```yaml [Simple Value]
+version: '3'
+
+vars:
+ PASSWORD:
+ value: 'my-secret-password'
+ secret: true
+
+tasks:
+ connect:
+ cmds:
+ - psql -U user -p {{.PASSWORD}} mydb
+ # Logged as: psql -U user -p ***** mydb
+```
+
+```yaml [Shell Command]
+version: '3'
+
+vars:
+ DB_PASSWORD:
+ sh: vault read -field=password secret/db
+ secret: true
+
+tasks:
+ migrate:
+ cmds:
+ - psql -U admin -p {{.DB_PASSWORD}} mydb
+ # Password from vault is masked in logs
+```
+
+```yaml [Task-Level Secret]
+version: '3'
+
+vars:
+ PUBLIC_URL: https://example.com
+
+tasks:
+ deploy:
+ vars:
+ DEPLOY_TOKEN:
+ value: 'secret-token-123'
+ secret: true
+ cmds:
+ - echo "Deploying to {{.PUBLIC_URL}} with token {{.DEPLOY_TOKEN}}"
+ # Logged as: echo "Deploying to https://example.com with token *****"
+```
+
+:::
+
+Multiple secrets in the same command are all masked:
+
+```yaml
+version: '3'
+
+vars:
+ API_KEY:
+ value: 'api-key-123'
+ secret: true
+ PASSWORD:
+ value: 'password-456'
+ secret: true
+
+tasks:
+ setup:
+ cmds:
+ - ./setup.sh --api {{.API_KEY}} --pwd {{.PASSWORD}}
+ # Logged as: ./setup.sh --api ***** --pwd *****
+```
+
+::: tip
+
+**Best practices for secret variables:**
+
+1. **Use shell commands to load secrets**, not hardcoded values:
+
+ ```yaml
+ # ❌ BAD - Secret visible in Taskfile
+ vars:
+ API_KEY:
+ value: 'hardcoded-secret'
+ secret: true
+
+ # ✅ GOOD - Secret loaded from external source
+ vars:
+ API_KEY:
+ sh: vault kv get -field=api_key secret/myapp
+ secret: true
+ ```
+
+2. **Combine with environment variables:**
+
+ ```yaml
+ vars:
+ API_KEY:
+ sh: echo $MY_API_KEY
+ secret: true
+ ```
+
+3. **Use .gitignore for secret files:**
+
+ If you use dotenv files, add them to `.gitignore`:
+
+ ```yaml
+ dotenv: ['.env.local'] # Load from .env.local (in .gitignore)
+ ```
+
+:::
+
+::: warning
+
+**Secrets are not propagated to derived variables.** The `secret` flag only
+masks the variable it is set on. A non-secret variable that references a secret
+will expose the resolved value in logs:
+
+```yaml
+version: '3'
+
+vars:
+ API_KEY:
+ value: 'secret-api-key-123'
+ secret: true
+ HEADER:
+ value: 'Bearer {{.API_KEY}}' # ❌ not marked as secret
+
+tasks:
+ call:
+ cmds:
+ - curl -H "{{.HEADER}}" api.example.com
+ # Logged as: curl -H "Bearer secret-api-key-123" api.example.com (LEAK)
+```
+
+Mark every variable that carries a secret value as `secret: true`:
+
+```yaml
+vars:
+ HEADER:
+ value: 'Bearer {{.API_KEY}}'
+ secret: true # ✅ masked
+```
+
+:::
+
+## Looping over values
+
+Task allows you to loop over certain values and execute a command for each.
+There are a number of ways to do this depending on the type of value you want to
+loop over.
+
+### Looping over a static list
+
+The simplest kind of loop is an explicit one. This is useful when you want to
+loop over a set of values that are known ahead of time.
+
+```yaml
+version: '3'
+
+tasks:
+ default:
+ cmds:
+ - for: ['foo.txt', 'bar.txt']
+ cmd: cat {{ .ITEM }}
+```
+
+### Looping over a matrix
+
+If you need to loop over all permutations of multiple lists, you can use the
+`matrix` property. This should be familiar to anyone who has used a matrix in a
+CI/CD pipeline.
+
+```yaml
+version: '3'
+
+tasks:
+ default:
+ silent: true
+ cmds:
+ - for:
+ matrix:
+ OS: ['windows', 'linux', 'darwin']
+ ARCH: ['amd64', 'arm64']
+ cmd:
+ echo "{{.ITEM.OS}}/{{.ITEM.ARCH}}"
+```
+
+This will output:
+
+```txt
+windows/amd64
+windows/arm64
+linux/amd64
+linux/arm64
+darwin/amd64
+darwin/arm64
+```
+
+You can also use references to other variables as long as they are also lists:
+
+```yaml
+version: '3'
+
+vars:
+ OS_VAR: ['windows', 'linux', 'darwin']
+ ARCH_VAR: ['amd64', 'arm64']
+
+tasks:
+ default:
+ cmds:
+ - for:
+ matrix:
+ OS:
+ ref: .OS_VAR
+ ARCH:
+ ref: .ARCH_VAR
+ cmd:
+ echo "{{.ITEM.OS}}/{{.ITEM.ARCH}}"
+```
+
+### Looping over your task's sources or generated files
+
+You are also able to loop over the sources of your task or the files it
+generates:
+
+::: code-group
+
+```yaml [Sources]
+version: '3'
+
+tasks:
+ default:
+ sources:
+ - foo.txt
+ - bar.txt
+ cmds:
+ - for: sources
+ cmd: cat {{ .ITEM }}
+```
+
+```yaml [Generates]
+version: '3'
+
+tasks:
+ default:
+ generates:
+ - foo.txt
+ - bar.txt
+ cmds:
+ - for: generates
+ cmd: cat {{ .ITEM }}
+```
+
+:::
+
+This will also work if you use globbing syntax in `sources` or `generates`. For
+example, if you specify a source for `*.txt`, the loop will iterate over all
+files that match that glob.
+
+Paths will always be returned as paths relative to the task directory. If you
+need to convert this to an absolute path, you can use the built-in `joinPath`
+function. There are some
+[special variables](/docs/reference/templating#special-variables) that you may find
+useful for this.
+
+::: code-group
+
+```yaml [Sources]
+version: '3'
+
+tasks:
+ default:
+ vars:
+ MY_DIR: /path/to/dir
+ dir: '{{.MY_DIR}}'
+ sources:
+ - foo.txt
+ - bar.txt
+ cmds:
+ - for: sources
+ cmd: cat {{joinPath .MY_DIR .ITEM}}
+```
+
+```yaml [Generates]
+version: '3'
+
+tasks:
+ default:
+ vars:
+ MY_DIR: /path/to/dir
+ dir: '{{.MY_DIR}}'
+ generates:
+ - foo.txt
+ - bar.txt
+ cmds:
+ - for: generates
+ cmd: cat {{joinPath .MY_DIR .ITEM}}
+```
+
+:::
+
+### Looping over variables
+
+To loop over the contents of a variable, use the `var` key followed by the name
+of the variable you want to loop over. By default, string variables will be
+split on any whitespace characters.
+
+```yaml
+version: '3'
+
+tasks:
+ default:
+ vars:
+ MY_VAR: foo.txt bar.txt
+ cmds:
+ - for: { var: MY_VAR }
+ cmd: cat {{.ITEM}}
+```
+
+If you need to split a string on a different character, you can do this by
+specifying the `split` property:
+
+```yaml
+version: '3'
+
+tasks:
+ default:
+ vars:
+ MY_VAR: foo.txt,bar.txt
+ cmds:
+ - for: { var: MY_VAR, split: ',' }
+ cmd: cat {{.ITEM}}
+```
+
+You can also loop over arrays and maps directly:
+
+```yaml
+version: 3
+
+tasks:
+ foo:
+ vars:
+ LIST: [foo, bar, baz]
+ cmds:
+ - for:
+ var: LIST
+ cmd: echo {{.ITEM}}
+```
+
+When looping over a map we also make an additional `{{.KEY}}`
+variable available that holds the string value of the map key. Remember that
+maps are unordered, so the order in which the items are looped over is random.
+
+All of this also works with dynamic variables!
+
+```yaml
+version: '3'
+
+tasks:
+ default:
+ vars:
+ MY_VAR:
+ sh: find -type f -name '*.txt'
+ cmds:
+ - for: { var: MY_VAR }
+ cmd: cat {{.ITEM}}
+```
+
+### Renaming variables
+
+If you want to rename the iterator variable to make it clearer what the value
+contains, you can do so by specifying the `as` property:
+
+```yaml
+version: '3'
+
+tasks:
+ default:
+ vars:
+ MY_VAR: foo.txt bar.txt
+ cmds:
+ - for: { var: MY_VAR, as: FILE }
+ cmd: cat {{.FILE}}
+```
+
+### Looping over tasks
+
+Because the `for` property is defined at the `cmds` level, you can also use it
+alongside the `task` keyword to run tasks multiple times with different
+variables.
+
+```yaml
+version: '3'
+
+tasks:
+ default:
+ cmds:
+ - for: [foo, bar]
+ task: my-task
+ vars:
+ FILE: '{{.ITEM}}'
+
+ my-task:
+ cmds:
+ - echo '{{.FILE}}'
+```
+
+Or if you want to run different tasks depending on the value of the loop:
+
+```yaml
+version: '3'
+
+tasks:
+ default:
+ cmds:
+ - for: [foo, bar]
+ task: task-{{.ITEM}}
+
+ task-foo:
+ cmds:
+ - echo 'foo'
+
+ task-bar:
+ cmds:
+ - echo 'bar'
+```
+
+### Looping over dependencies
+
+All of the above looping techniques can also be applied to the `deps` property.
+This allows you to combine loops with concurrency:
+
+```yaml
+version: '3'
+
+tasks:
+ default:
+ deps:
+ - for: [foo, bar]
+ task: my-task
+ vars:
+ FILE: '{{.ITEM}}'
+
+ my-task:
+ cmds:
+ - echo '{{.FILE}}'
+```
+
+It is important to note that as `deps` are run in parallel, the order in which
+the iterations are run is not guaranteed and the output may vary. For example,
+the output of the above example may be either:
+
+```shell
+foo
+bar
+```
+
+or
+
+```shell
+bar
+foo
+```
+
+## Forwarding CLI arguments to commands
+
+If `--` is given in the CLI, all following parameters are added to a special
+`.CLI_ARGS` variable. This is useful to forward arguments to another command.
+
+The below example will run `yarn install`.
+
+```shell
+$ task yarn -- install
+```
+
+```yaml
+version: '3'
+
+tasks:
+ yarn:
+ cmds:
+ - yarn {{.CLI_ARGS}}
+```
+
+## Wildcard arguments
+
+Another way to parse arguments into a task is to use a wildcard in your task's
+name. Wildcards are denoted by an asterisk (`*`) and can be used multiple times
+in a task's name to pass in multiple arguments.
+
+Matching arguments will be captured and stored in the `.MATCH` variable and can
+then be used in your task's commands like any other variable. This variable is
+an array of strings and so will need to be indexed to access the individual
+arguments. We suggest creating a named variable for each argument to make it
+clear what they contain:
+
+```yaml
+version: '3'
+
+tasks:
+ start:*:*:
+ vars:
+ SERVICE: '{{index .MATCH 0}}'
+ REPLICAS: '{{index .MATCH 1}}'
+ cmds:
+ - echo "Starting {{.SERVICE}} with {{.REPLICAS}} replicas"
+
+ start:*:
+ vars:
+ SERVICE: '{{index .MATCH 0}}'
+ cmds:
+ - echo "Starting {{.SERVICE}}"
+```
+
+This call matches the `start:*` task and the string "foo" is captured by the
+wildcard and stored in the `.MATCH` variable. We then index the `.MATCH` array
+and store the result in the `.SERVICE` variable which is then echoed out in the
+cmds:
+
+```shell
+$ task start:foo
+Starting foo
+```
+
+You can use whitespace in your arguments as long as you quote the task name:
+
+```shell
+$ task "start:foo bar"
+Starting foo bar
+```
+
+If multiple matching tasks are found, the first one listed in the Taskfile will
+be used. If you are using included Taskfiles, tasks in parent files will be
+considered first.
+
+```shell
+$ task start:foo:3
+Starting foo with 3 replicas
+```
+
+Using wildcards with aliases
+Wildcards also work with aliases. If a task has an alias, you can use the alias name with wildcards to capture arguments. For example:
+
+```yaml
+version: '3'
+
+tasks:
+ start:*:
+ aliases: [run:*]
+ vars:
+ SERVICE: "{{index .MATCH 0}}"
+ cmds:
+ - echo "Running {{.SERVICE}}"
+```
+In this example, you can call the task using the alias run:*:
+
+```shell
+$ task run:foo
+Running foo
+```
+
+## Doing task cleanup with `defer`
+
+With the `defer` keyword, it's possible to schedule cleanup to be run once the
+task finishes. The difference with just putting it as the last command is that
+this command will run even when the task fails.
+
+In the example below, `rm -rf tmpdir/` will run even if the third command fails:
+
+```yaml
+version: '3'
+
+tasks:
+ default:
+ cmds:
+ - mkdir -p tmpdir/
+ - defer: rm -rf tmpdir/
+ - echo 'Do work on tmpdir/'
+```
+
+If you want to move the cleanup command into another task, that is possible as
+well:
+
+```yaml
+version: '3'
+
+tasks:
+ default:
+ cmds:
+ - mkdir -p tmpdir/
+ - defer: { task: cleanup }
+ - echo 'Do work on tmpdir/'
+
+ cleanup: rm -rf tmpdir/
+```
+
+::: info
+
+Due to the nature of how the
+[Go's own `defer` work](https://go.dev/tour/flowcontrol/13), the deferred
+commands are executed in the reverse order if you schedule multiple of them.
+
+:::
+
+A special variable `.EXIT_CODE` is exposed when a command exited with a non-zero
+[exit code](/docs/reference/cli#exit-codes). You can check its presence to know if
+the task completed successfully or not:
+
+```yaml
+version: '3'
+
+tasks:
+ default:
+ cmds:
+ - defer:
+ echo '{{if .EXIT_CODE}}Failed with {{.EXIT_CODE}}!{{else}}Success!{{end}}'
+ - exit 1
+```
+
+## Help
+
+Running `task --list` (or `task -l`) lists all tasks with a description. The
+following Taskfile:
+
+```yaml
+version: '3'
+
+tasks:
+ build:
+ desc: Build the go binary.
+ cmds:
+ - go build -v -i main.go
+
+ test:
+ desc: Run all the go tests.
+ cmds:
+ - go test -race ./...
+
+ js:
+ cmds:
+ - esbuild --bundle --minify js/index.js > public/bundle.js
+
+ css:
+ cmds:
+ - esbuild --bundle --minify css/index.css > public/bundle.css
+```
+
+would print the following output:
+
+```shell
+* build: Build the go binary.
+* test: Run all the go tests.
+```
+
+If you want to see all tasks, there's a `--list-all` (alias `-a`) flag as well.
+
+## Display summary of task
+
+Running `task --summary task-name` will show a summary of a task. The following
+Taskfile:
+
+```yaml
+version: '3'
+
+tasks:
+ release:
+ deps: [build]
+ summary: |
+ Release your project to github
+
+ It will build your project before starting the release.
+ Please make sure that you have set GITHUB_TOKEN before starting.
+ cmds:
+ - your-release-tool
+
+ build:
+ cmds:
+ - your-build-tool
+```
+
+with running `task --summary release` would print the following output:
+
+```
+task: release
+
+Release your project to github
+
+It will build your project before starting the release.
+Please make sure that you have set GITHUB_TOKEN before starting.
+
+dependencies:
+ - build
+
+commands:
+ - your-release-tool
+```
+
+If a summary is missing, the description will be printed. If the task does not
+have a summary or a description, a warning is printed.
+
+Please note: _showing the summary will not execute the command_.
+
+## 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](#calling-another-task) in your Taskfile
+and when [including tasks](#including-other-taskfiles) with aliases from another
+Taskfile. They can also be used together with
+[namespace aliases](#namespace-aliases).
+
+```yaml
+version: '3'
+
+tasks:
+ generate:
+ aliases: [gen]
+ cmds:
+ - task: gen-mocks
+
+ generate-mocks:
+ aliases: [gen-mocks]
+ cmds:
+ - echo "generating..."
+```
+
+## Overriding task name
+
+Sometimes you may want to override the task name printed on the summary,
+up-to-date messages to STDOUT, etc. In this case, you can just set `label:`,
+which can also be interpolated with variables:
+
+```yaml
+version: '3'
+
+tasks:
+ default:
+ cmds:
+ - task: print
+ vars:
+ MESSAGE: hello
+ - task: print
+ vars:
+ MESSAGE: world
+
+ print:
+ label: 'print-{{.MESSAGE}}'
+ cmds:
+ - echo "{{.MESSAGE}}"
+```
+
+## Warning Prompts
+
+Warning Prompts are used to prompt a user for confirmation before a task is
+executed.
+
+Below is an example using `prompt` with a dangerous command, that is called
+between two safe commands:
+
+```yaml
+version: '3'
+
+tasks:
+ example:
+ cmds:
+ - task: not-dangerous
+ - task: dangerous
+ - task: another-not-dangerous
+
+ not-dangerous:
+ cmds:
+ - echo 'not dangerous command'
+
+ another-not-dangerous:
+ cmds:
+ - echo 'another not dangerous command'
+
+ dangerous:
+ prompt: This is a dangerous command... Do you want to continue?
+ cmds:
+ - echo 'dangerous command'
+```
+
+```shell
+❯ task dangerous
+task: "This is a dangerous command... Do you want to continue?" [y/N]
+```
+
+Prompts can be a single value or a list of prompts, like below:
+
+```yaml
+version: '3'
+
+tasks:
+ example:
+ cmds:
+ - task: dangerous
+
+ dangerous:
+ prompt:
+ - This is a dangerous command... Do you want to continue?
+ - Are you sure?
+ cmds:
+ - echo 'dangerous command'
+```
+
+Warning prompts are called before executing a task. If a prompt is denied Task
+will exit with [exit code](/docs/reference/cli#exit-codes) 205. If approved, Task
+will continue as normal.
+
+```shell
+❯ task example
+not dangerous command
+task: "This is a dangerous command. Do you want to continue?" [y/N]
+y
+dangerous command
+another not dangerous command
+```
+
+To skip warning prompts automatically, you can use the `--yes` (alias `-y`)
+option when calling the task. By including this option, all warnings, will be
+automatically confirmed, and no prompts will be shown.
+
+::: warning
+
+Tasks with prompts always fail by default on non-terminal environments, like a
+CI, where an `stdin` won't be available for the user to answer. In those cases,
+use `--yes` (`-y`) to force all tasks with a prompt to run.
+
+:::
+
+## Silent mode
+
+Silent mode disables the echoing of commands before Task runs it. For the
+following Taskfile:
+
+```yaml
+version: '3'
+
+tasks:
+ echo:
+ cmds:
+ - echo "Print something"
+```
+
+Normally this will be printed:
+
+```shell
+echo "Print something"
+Print something
+```
+
+With silent mode on, the below will be printed instead:
+
+```shell
+Print something
+```
+
+There are four ways to enable silent mode:
+
+- At command level:
+
+```yaml
+version: '3'
+
+tasks:
+ echo:
+ cmds:
+ - cmd: echo "Print something"
+ silent: true
+```
+
+- At task level:
+
+```yaml
+version: '3'
+
+tasks:
+ echo:
+ cmds:
+ - echo "Print something"
+ silent: true
+```
+
+- Globally at Taskfile level:
+
+```yaml
+version: '3'
+
+silent: true
+
+tasks:
+ echo:
+ cmds:
+ - echo "Print something"
+```
+
+- Or globally with `--silent` or `-s` flag
+
+If you want to suppress STDOUT instead, just redirect a command to `/dev/null`:
+
+```yaml
+version: '3'
+
+tasks:
+ echo:
+ cmds:
+ - echo "This will print nothing" > /dev/null
+```
+
+## Dry run mode
+
+Dry run mode (`--dry`) compiles and steps through each task, printing the
+commands that would be run without executing them. This is useful for debugging
+your Taskfiles.
+
+## Ignore errors
+
+You have the option to ignore errors during command execution. Given the
+following Taskfile:
+
+```yaml
+version: '3'
+
+tasks:
+ echo:
+ cmds:
+ - exit 1
+ - echo "Hello World"
+```
+
+Task will abort the execution after running `exit 1` because the status code `1`
+stands for `EXIT_FAILURE`. However, it is possible to continue with execution
+using `ignore_error`:
+
+```yaml
+version: '3'
+
+tasks:
+ echo:
+ cmds:
+ - cmd: exit 1
+ ignore_error: true
+ - echo "Hello World"
+```
+
+`ignore_error` can also be set for a task, which means errors will be suppressed
+for all commands. Nevertheless, keep in mind that this option will not propagate
+to other tasks called either by `deps` or `cmds`!
+
+## Output syntax
+
+By default, Task just redirects the STDOUT and STDERR of the running commands to
+the shell in real-time. This is good for having live feedback for logging
+printed by commands, but the output can become messy if you have multiple
+commands running simultaneously and printing lots of stuff.
+
+To make this more customizable, there are currently three different output
+options you can choose:
+
+- `interleaved` (default)
+- `group`
+- `prefixed`
+
+To choose another one, just set it to root in the Taskfile:
+
+```yaml
+version: '3'
+
+output: 'group'
+
+tasks:
+ # ...
+```
+
+The `group` output will print the entire output of a command once after it
+finishes, so you will not have live feedback for commands that take a long time
+to run.
+
+When using the `group` output, you can optionally provide a templated message to
+print at the start and end of the group. This can be useful for instructing CI
+systems to group all of the output for a given task, such as with
+[GitHub Actions' `::group::` command](https://docs.github.com/en/actions/learn-github-actions/workflow-commands-for-github-actions#grouping-log-lines)
+or
+[Azure Pipelines](https://docs.microsoft.com/en-us/azure/devops/pipelines/scripts/logging-commands?expand=1&view=azure-devops&tabs=bash#formatting-commands).
+
+```yaml
+version: '3'
+
+output:
+ group:
+ begin: '::group::{{.TASK}}'
+ end: '::endgroup::'
+
+tasks:
+ default:
+ cmds:
+ - echo 'Hello, World!'
+ silent: true
+```
+
+```shell
+$ task default
+::group::default
+Hello, World!
+::endgroup::
+```
+
+When using the `group` output, you may swallow the output of the executed
+command on standard output and standard error if it does not fail (zero exit
+code).
+
+```yaml
+version: '3'
+
+silent: true
+
+output:
+ group:
+ error_only: true
+
+tasks:
+ passes: echo 'output-of-passes'
+ errors: echo 'output-of-errors' && exit 1
+```
+
+```shell
+$ task passes
+$ task errors
+output-of-errors
+task: Failed to run task "errors": exit status 1
+```
+
+The `prefix` output will prefix every line printed by a command with
+`[task-name] ` as the prefix, but you can customize the prefix for a command
+with the `prefix:` attribute:
+
+```yaml
+version: '3'
+
+output: prefixed
+
+tasks:
+ default:
+ deps:
+ - task: print
+ vars: { TEXT: foo }
+ - task: print
+ vars: { TEXT: bar }
+ - task: print
+ vars: { TEXT: baz }
+
+ print:
+ cmds:
+ - echo "{{.TEXT}}"
+ prefix: 'print-{{.TEXT}}'
+ silent: true
+```
+
+```shell
+$ task default
+[print-foo] foo
+[print-bar] bar
+[print-baz] baz
+```
+
+::: tip
+
+The `output` option can also be specified by the `--output` or `-o` flags.
+
+:::
+
+## CI Integration
+
+### Colored output
+
+Task automatically enables colored output when running in CI environments
+(`CI=true`). Most CI providers set this variable automatically.
+
+You can also force colored output with `FORCE_COLOR=1` or disable it with
+`NO_COLOR=1`.
+
+### Error annotations
+
+When running in GitHub Actions (`GITHUB_ACTIONS=true`), Task automatically emits
+error annotations when a task fails. These annotations appear in the workflow
+summary, making it easier to spot failures without scrolling through logs.
+
+```shell
+::error title=Task 'build' failed::exit status 1
+```
+
+This feature requires no configuration and works automatically.
+
+## Interactive CLI application
+
+When running interactive CLI applications inside Task they can sometimes behave
+weirdly, especially when the [output mode](#output-syntax) is set to something
+other than `interleaved` (the default), or when interactive apps are run in
+parallel with other tasks.
+
+The `interactive: true` tells Task this is an interactive application and Task
+will try to optimize for it:
+
+```yaml
+version: '3'
+
+tasks:
+ default:
+ cmds:
+ - vim my-file.txt
+ interactive: true
+```
+
+If you still have problems running an interactive app through Task, please open
+an issue about it.
+
+## Short task syntax
+
+Starting on Task v3, you can now write tasks with a shorter syntax if they have
+the default settings (e.g. no custom `env:`, `vars:`, `desc:`, `silent:` , etc):
+
+```yaml
+version: '3'
+
+tasks:
+ build: go build -v -o ./app{{exeExt}} .
+
+ run:
+ - task: build
+ - ./app{{exeExt}} -h localhost -p 8080
+```
+
+## `set` and `shopt`
+
+It's possible to specify options to the
+[`set`](https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html)
+and
+[`shopt`](https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html)
+builtins. This can be added at global, task or command level.
+
+```yaml
+version: '3'
+
+set: [pipefail]
+shopt: [globstar]
+
+tasks:
+ # `globstar` required for double star globs to work
+ default: echo **/*.go
+```
+
+::: info
+
+Keep in mind that not all options are available in the
+[shell interpreter library](https://github.com/mvdan/sh) that Task uses.
+
+:::
+
+## Watch tasks
+
+With the flags `--watch` or `-w` task will watch for file changes and run the
+task again. This requires the `sources` attribute to be given, so task knows
+which files to watch.
+
+The default watch interval is 100 milliseconds, but it's possible to change it
+by either setting `interval: '500ms'` in the root of the Taskfile or by passing
+it as an argument like `--interval=500ms`. This interval is the time Task will
+wait for duplicated events. It will only run the task again once, even if
+multiple changes happen within the interval.
+
+Also, it's possible to set `watch: true` in a given task and it'll automatically
+run in watch mode:
+
+```yaml
+version: '3'
+
+interval: 500ms
+
+tasks:
+ build:
+ desc: Builds the Go application
+ watch: true
+ sources:
+ - '**/*.go'
+ cmds:
+ - go build # ...
+```
+
+::: info
+
+Note that when setting `watch: true` to a task, it'll only run in watch mode
+when running from the CLI via `task my-watch-task`, but won't run in watch mode
+if called by another task, either directly or as a dependency.
+
+:::
+
+::: warning
+
+The watcher can misbehave in certain scenarios, in particular for long-running
+servers. There is a [known bug](https://github.com/go-task/task/issues/160)
+where child processes of the running might not be killed appropriately. It's
+advised to avoid running commands as `go run` and prefer `go build [...] &&
+./binary` instead.
+
+If you are having issues, you might want to try tools specifically designed for
+live-reloading, like [Air](https://github.com/air-verse/air/). Also, be sure to
+[report any issues](https://github.com/go-task/task/issues/new?template=bug_report.yml)
+to us.
+
+:::
+
+[config]: /docs/reference/config
+[gotemplate]: https://golang.org/pkg/text/template/
+[templating-reference]: /docs/reference/templating
diff --git a/website/src/latest/docs/installation.md b/website/src/latest/docs/installation.md
new file mode 100644
index 00000000..a983dc0e
--- /dev/null
+++ b/website/src/latest/docs/installation.md
@@ -0,0 +1,448 @@
+---
+title: Installation
+description: Installation methods for Task
+outline: deep
+---
+
+# Installation
+
+Task offers many installation methods. Check out the available methods below.
+
+## Official Package Managers
+
+These installation methods are maintained by the Task team and are always
+up-to-date.
+
+:::info Package Repository Hosting
+
+[](https://cloudsmith.com)
+
+Package repository hosting for deb/rpm/apk is graciously provided by [Cloudsmith](https://cloudsmith.com).
+Cloudsmith is the only fully hosted, cloud-native, universal package management solution, that
+enables your organization to create, store and share packages in any format, to any place, with total
+confidence.
+
+:::
+
+### [dnf](https://docs.fedoraproject.org/en-US/quick-docs/dnf)    {#dnf}
+
+[[package](https://cloudsmith.io/~task/repos/task/packages/?sort=-format&q=format%3Arpm)]
+
+If you Set up the repository by running :
+
+```shell
+curl -1sLf 'https://dl.cloudsmith.io/public/task/task/setup.rpm.sh' | sudo -E bash
+```
+
+Then you can install Task with:
+
+```shell
+dnf install task
+```
+
+### [apt](https://doc.ubuntu-fr.org/apt)    {#apt}
+
+[[package](https://cloudsmith.io/~task/repos/task/packages/?sort=-format&q=format%3Adeb)]
+
+If you Set up the repository by running:
+
+```shell
+curl -1sLf 'https://dl.cloudsmith.io/public/task/task/setup.deb.sh' | sudo -E bash
+```
+
+Then you can install Task with:
+
+```shell
+apt install task
+```
+
+### [apk](https://wiki.alpinelinux.org/wiki/Alpine_Package_Keeper)  {#apk}
+
+[[package](https://cloudsmith.io/~task/repos/task/packages/?sort=-format&q=format%3Aalpine)]
+
+Set up the repository by running:
+
+```shell
+curl -1sLf 'https://dl.cloudsmith.io/public/task/task/setup.alpine.sh' | sudo -E bash
+```
+
+Then you can install Task with:
+
+```shell
+apk add task
+```
+
+### [Homebrew](https://brew.sh)   {#homebrew}
+
+Task is available via our official Homebrew tap
+[[source](https://github.com/go-task/homebrew-tap/blob/main/Formula/go-task.rb)]:
+
+```shell
+brew install go-task/tap/go-task
+```
+
+Alternatively it can be installed from the official Homebrew repository
+[[package](https://formulae.brew.sh/formula/go-task)]
+[[source](https://github.com/Homebrew/homebrew-core/blob/master/Formula/g/go-task.rb)]
+by running:
+
+```shell
+brew install go-task
+```
+
+### [Snap](https://snapcraft.io/task)   {#snap}
+
+Task is available on [Snapcraft](https://snapcraft.io/task)
+[[source](https://github.com/go-task/snap/blob/main/snap/snapcraft.yaml)], but
+keep in mind that your Linux distribution should allow classic confinement for
+Snaps to Task work correctly:
+
+```shell
+sudo snap install task --classic
+```
+
+### [npm](https://www.npmjs.com)    {#npm}
+
+Npm can be used as cross-platform way to install Task globally or as a
+dependency of your project
+[[package](https://www.npmjs.com/package/@go-task/cli)]
+[[source](https://github.com/go-task/task/blob/main/package.json)]:
+
+```shell
+npm install -g @go-task/cli
+```
+
+### [WinGet](https://github.com/microsoft/winget-cli)  {#winget}
+
+Task is available via the
+[community repository](https://github.com/microsoft/winget-pkgs)
+[[source](https://github.com/microsoft/winget-pkgs/tree/master/manifests/t/Task/Task)]:
+
+```shell
+winget install Task.Task
+```
+
+## Community-Maintained Package Managers
+
+::: warning Community Maintained
+
+These installation methods are maintained by the community and may not always be
+up-to-date with the latest Task version. The Task team does not directly control
+these packages.
+
+:::
+
+### [Mise](https://mise.jdx.dev/)    {#mise}
+
+Mise is a cross-platform package manager that acts as a "frontend" to a variety
+of other package managers "backends" such as `asdf`, `aqua` and `ubi`.
+
+If using Mise, we recommend using the `aqua` or `ubi` backends to install Task
+as these install directly from our GitHub releases.
+
+::: code-group
+
+```shell [aqua]
+mise use -g aqua:go-task/task@latest
+mise install
+```
+
+```shell [ubi]
+mise use -g ubi:go-task/task
+mise install
+```
+
+:::
+
+### [Macports](https://macports.org)  {#macports}
+
+Task repository is tracked by Macports
+[[package](https://ports.macports.org/port/go-task/details/)]
+[[source](https://github.com/macports/macports-ports/blob/master/devel/go-task/Portfile)]:
+
+```shell
+port install go-task
+```
+
+### [pip](https://pip.pypa.io)    {#pip}
+
+Like npm, pip can be used as a cross-platform way to install Task
+[[package](https://pypi.org/project/go-task-bin)]
+[[source](https://github.com/Bing-su/pip-binary-factory/tree/main/task)]:
+
+```shell
+pip install go-task-bin
+```
+
+### [Chocolatey](https://chocolatey.org)  {#chocolatey}
+
+[[package](https://community.chocolatey.org/packages/go-task)]
+[[source](https://github.com/Starz0r/ChocolateyPackagingScripts/blob/master/src/go-task_gh_build.py)]
+
+```shell
+choco install go-task
+```
+
+### [Scoop](https://scoop.sh)  {#scoop}
+
+[[source](https://github.com/ScoopInstaller/Main/blob/master/bucket/task.json)]
+
+```shell
+scoop install task
+```
+
+### Arch ([pacman](https://wiki.archlinux.org/title/Pacman))  {#arch}
+
+[[package](https://archlinux.org/packages/extra/x86_64/go-task/)]
+[[source](https://gitlab.archlinux.org/archlinux/packaging/packages/go-task)]
+
+```shell
+pacman -S go-task
+```
+
+### Fedora ([dnf](https://docs.fedoraproject.org/en-US/quick-docs/dnf))  {#fedora-community}
+
+[[package](https://packages.fedoraproject.org/pkgs/golang-github-task/go-task/)]
+[[source](https://src.fedoraproject.org/rpms/golang-github-task)]
+
+```shell
+dnf install go-task
+```
+
+### FreeBSD ([Ports](https://ports.freebsd.org/cgi/ports.cgi))  {#freebsd}
+
+[[package](https://cgit.freebsd.org/ports/tree/devel/task)]
+[[source](https://cgit.freebsd.org/ports/tree/devel/task/Makefile)]
+
+```shell
+pkg install task
+```
+
+### [Nix](https://nixos.org)     {#nix}
+
+[[source](https://github.com/NixOS/nixpkgs/blob/master/pkgs/by-name/go/go-task/package.nix)]
+
+```shell
+nix-env -iA nixpkgs.go-task
+```
+
+### [pacstall](https://github.com/pacstall/pacstall)   {#pacstall}
+
+[[package](https://pacstall.dev/packages/go-task-deb)]
+[[source](https://github.com/pacstall/pacstall-programs/blob/master/packages/go-task-deb/go-task-deb.pacscript)]
+
+```shell
+pacstall -I go-task-deb
+```
+
+### [pkgx](https://pkgx.sh)   {#pkgx}
+
+[[package](https://pkgx.dev/pkgs/taskfile.dev)]
+[[source](https://github.com/pkgxdev/pantry/blob/main/projects/taskfile.dev/package.yml)]
+
+```shell
+pkgx task
+```
+
+or, if you have pkgx integration enabled:
+
+```shell
+task
+```
+
+## Get The Binary
+
+### Binary
+
+You can download the binary from the
+[releases page on GitHub](https://github.com/go-task/task/releases) and add to
+your `$PATH`.
+
+DEB, RPM and APK packages are also available.
+
+The `task_checksums.txt` file contains the SHA-256 checksum for each file.
+
+### Install Script
+
+We also have an
+[install script](https://github.com/go-task/task/blob/main/install-task.sh)
+which is very useful in scenarios like CI. Many thanks to
+[GoDownloader](https://github.com/goreleaser/godownloader) for enabling the easy
+generation of this script.
+
+By default, it installs on the `./bin` directory relative to the working
+directory:
+
+```shell
+sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d
+```
+
+It is possible to override the installation directory with the `-b` parameter.
+On Linux, common choices are `~/.local/bin` and `~/bin` to install for the
+current user or `/usr/local/bin` to install for all users:
+
+```shell
+sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b ~/.local/bin
+```
+
+::: warning
+
+On macOS and Windows, `~/.local/bin` and `~/bin` are not added to `$PATH` by
+default.
+
+:::
+
+By default, it installs the latest version available. You can also specify a tag
+(available in [releases](https://github.com/go-task/task/releases)) to install a
+specific version:
+
+```shell
+sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d v3.36.0
+```
+
+Parameters are order specific, to set both installation directory and version:
+
+```shell
+sh -c "$(curl --location https://taskfile.dev/install.sh)" -- -d -b ~/.local/bin v3.42.1
+```
+
+### GitHub Actions
+
+We have an [official GitHub Action](https://github.com/go-task/setup-task) to
+install Task in your GitHub workflows. This repository is forked from the
+fantastic project by the Arduino team. Check out the repository for more
+examples and configuration.
+
+```yaml
+- name: Install Task
+ uses: go-task/setup-task@v1
+```
+
+## Build From Source
+
+Ensure that you have a supported version of [Go](https://golang.org) properly
+installed and setup. You can find the minimum required version of Go in the
+[go.mod](https://github.com/go-task/task/blob/main/go.mod#L3) file.
+
+You can then install the latest release globally by running:
+
+```shell
+go install github.com/go-task/task/v3/cmd/task@latest
+```
+
+Or you can install into another directory:
+
+```shell
+env GOBIN=/bin go install github.com/go-task/task/v3/cmd/task@latest
+```
+
+::: tip
+
+For CI environments we recommend using the [install script](#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`.
+
+```bash
+go get -tool github.com/go-task/task/v3/cmd/task@latest
+```
+
+Then, prefix `go tool` when calling Task like below. Go will compile Task on
+demand before calling it.
+
+```bash
+go tool task {arguments...}
+```
+
+## 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 ` to output a completion script for any supported
+shell. 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
+
+```shell [bash]
+# ~/.bashrc
+
+# export TASK_EXE='go-task' if needed
+eval "$(task --completion bash)"
+```
+
+```shell [zsh]
+# ~/.zshrc
+
+# export TASK_EXE='go-task' if needed
+eval "$(task --completion zsh)"
+```
+
+```shell [fish]
+# ~/.config/fish/config.fish
+
+# export TASK_EXE='go-task' if needed
+task --completion fish | source
+```
+
+```powershell [powershell]
+# $PROFILE\Microsoft.PowerShell_profile.ps1
+Invoke-Expression (&task --completion powershell | Out-String)
+```
+
+:::
+
+### 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
+
+```shell [bash]
+task --completion bash > /etc/bash_completion.d/task
+```
+
+```shell [zsh]
+task --completion zsh > /usr/local/share/zsh/site-functions/_task
+```
+
+```shell [fish]
+task --completion fish > ~/.config/fish/completions/task.fish
+```
+
+:::
+
+### 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):
+
+```shell
+zstyle ':completion:*:*:task:*' verbose false
+```
+
+By default, task aliases are also offered as completions. To complete only the
+canonical task names, add the `show-aliases` zstyle:
+
+```shell
+zstyle ':completion:*:*:task:*' show-aliases false
+```
diff --git a/website/src/docs/integrations.md b/website/src/latest/docs/integrations.md
similarity index 96%
rename from website/src/docs/integrations.md
rename to website/src/latest/docs/integrations.md
index 2bf5e34e..9d95151d 100644
--- a/website/src/docs/integrations.md
+++ b/website/src/latest/docs/integrations.md
@@ -36,12 +36,12 @@ In v1.0.0 of the extension, the configuration namespace was changed from `task`
to `taskfile` in order to fix
[an issue](https://github.com/go-task/vscode-task/issues/56).
-
+
If you receive a warning like the one above, you will need to update your
settings to use the new `taskfile` namespace instead:
-
+
## Schema
diff --git a/website/src/latest/docs/reference/cli.md b/website/src/latest/docs/reference/cli.md
new file mode 100644
index 00000000..47b5c7d1
--- /dev/null
+++ b/website/src/latest/docs/reference/cli.md
@@ -0,0 +1,445 @@
+---
+title: Command Line Interface Reference
+description: Complete reference for Task CLI commands, flags, and exit codes
+permalink: /reference/cli/
+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](./config.md)
+- [Environment variables](./environment.md)
+- _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:
+
+```bash
+task [options] [tasks...] [-- CLI_ARGS...]
+```
+
+::: tip
+
+If `--` is given, all remaining arguments will be assigned to a special
+`CLI_ARGS` variable.
+
+:::
+
+## Commands
+
+### `task [tasks...]`
+
+Run one or more tasks defined in your Taskfile.
+
+```bash
+task build
+task test lint
+task deploy --force
+```
+
+### `task --list`
+
+List all available tasks with their descriptions.
+
+```bash
+task --list
+task -l
+```
+
+### `task --list-all`
+
+List all tasks, including those without descriptions.
+
+```bash
+task --list-all
+task -a
+```
+
+### `task --init`
+
+Create a new Taskfile.yml in the current directory.
+
+```bash
+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.
+
+```bash
+task --help
+```
+
+#### `--version`
+
+Show Task version.
+
+```bash
+task --version
+```
+
+#### `-v, --verbose`
+
+Enable verbose mode for detailed output.
+
+- **Config equivalent**: [`verbose`](./config.md#verbose)
+- **Environment variable**: [`TASK_VERBOSE`](./environment.md#task-verbose)
+
+```bash
+task build --verbose
+```
+
+#### `-s, --silent`
+
+Disable command echoing.
+
+- **Config equivalent**: [`silent`](./config.md#silent)
+- **Environment variable**: [`TASK_SILENT`](./environment.md#task-silent)
+
+```bash
+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`](./config.md#disable-fuzzy)
+- **Environment variable**: [`TASK_DISABLE_FUZZY`](./environment.md#task-disable-fuzzy)
+
+```bash
+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`](./config.md#failfast)
+- **Environment variable**: [`TASK_FAILFAST`](./environment.md#task-failfast)
+
+```bash
+task build --failfast
+```
+
+#### `-f, --force`
+
+Force execution even when the task is up-to-date.
+
+```bash
+task build --force
+```
+
+#### `-n, --dry`
+
+Compile and print tasks without executing them.
+
+- **Environment variable**: [`TASK_DRY`](./environment.md#task-dry)
+
+```bash
+task deploy --dry
+```
+
+#### `-p, --parallel`
+
+Execute multiple tasks in parallel.
+
+```bash
+task test lint --parallel
+```
+
+#### `-C, --concurrency `
+
+Limit the number of concurrent tasks. Zero means unlimited.
+
+- **Config equivalent**: [`concurrency`](./config.md#concurrency)
+- **Environment variable**: [`TASK_CONCURRENCY`](./environment.md#task-concurrency)
+
+```bash
+task test --concurrency 4
+```
+
+#### `-x, --exit-code`
+
+Pass through the exit code of failed commands.
+
+```bash
+task test --exit-code
+```
+
+### File and Directory
+
+#### `-d, --dir `
+
+Set the directory where Task will run and look for Taskfiles.
+
+```bash
+task build --dir ./backend
+```
+
+#### `-t, --taskfile `
+
+Specify a custom Taskfile path.
+
+```bash
+task build --taskfile ./custom/Taskfile.yml
+```
+
+#### `-g, --global`
+
+Run the global Taskfile from `$HOME/Taskfile.{yml,yaml}`.
+
+```bash
+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`](./config.md#temp-dir)
+- **Environment variable**: [`TASK_TEMP_DIR`](./environment.md#task-temp-dir)
+
+```bash
+task build --temp-dir .task-cache
+```
+
+### Output Control
+
+#### `-o, --output `
+
+Set output style. Available modes: `interleaved`, `group`, `prefixed`.
+
+- **Environment variable**: [`TASK_OUTPUT`](./environment.md#task-output)
+
+```bash
+task test --output group
+```
+
+#### `--output-group-begin `
+
+Message template to print before grouped output.
+
+- **Environment variable**: [`TASK_OUTPUT_GROUP_BEGIN`](./environment.md#task-output-group-begin)
+
+```bash
+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`](./environment.md#task-output-group-end)
+
+```bash
+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`](./environment.md#task-output-group-error-only)
+
+```bash
+task test --output group --output-group-error-only
+```
+
+#### `-c, --color`
+
+Control colored output. Enabled by default.
+
+- **Config equivalent**: [`color`](./config.md#color)
+- **Environment variable**: [`TASK_COLOR`](./environment.md#task-color)
+
+```bash
+task build --color=false
+# or use environment variable
+NO_COLOR=1 task build
+```
+
+### Task Information
+
+#### `--status`
+
+Check if tasks are up-to-date without running them.
+
+```bash
+task build --status
+```
+
+#### `--summary`
+
+Show detailed information about a task.
+
+```bash
+task build --summary
+```
+
+#### `--json`
+
+Output task information in JSON format (use with `--list` or `--list-all`).
+
+```bash
+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.
+
+```bash
+task --list --sort alphanumeric
+```
+
+### Watch Mode
+
+#### `-w, --watch`
+
+Watch for file changes and re-run tasks automatically.
+
+```bash
+task build --watch
+```
+
+#### `-I, --interval `
+
+Set watch interval (default: `5s`). Must be a valid
+[Go duration](https://pkg.go.dev/time#ParseDuration).
+
+```bash
+task build --watch --interval 1s
+```
+
+### Interactive
+
+#### `-y, --yes`
+
+Automatically answer "yes" to all prompts.
+
+- **Environment variable**: [`TASK_ASSUME_YES`](./environment.md#task-assume-yes)
+
+```bash
+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`](./environment.md#task-interactive)
+
+```bash
+task deploy --interactive
+```
+
+## 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
+
+### 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
+
+::: 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 at
+[`errors/errors.go`](https://github.com/go-task/task/blob/main/errors/errors.go).
+
+:::
+
+## JSON Output Format
+
+When using `--json` with `--list` or `--list-all`:
+
+```json
+{
+ "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"
+}
+```
diff --git a/website/src/latest/docs/reference/config.md b/website/src/latest/docs/reference/config.md
new file mode 100644
index 00000000..cf58ae8f
--- /dev/null
+++ b/website/src/latest/docs/reference/config.md
@@ -0,0 +1,197 @@
+---
+title: Configuration Reference
+description: Complete reference for the Task config files and env vars
+permalink: /reference/config/
+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](./environment.md)
+- [Command-line flags](./cli.md)
+
+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`/`--entrypoint` flags) until we reach the user's
+ home directory or the root directory of that drive.
+- The users `$HOME` directory.
+- The `$XDG_CONFIG_HOME/task` directory.
+
+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:
+
+```yaml [$XDG_CONFIG_HOME/task/taskrc.yml]
+# lowest priority global config
+option_1: foo
+option_2: foo
+option_3: foo
+```
+
+```yaml [$HOME/.taskrc.yml]
+option_1: bar
+option_2: bar
+```
+
+```yaml [$HOME/path/to/project/.taskrc.yml]
+# highest priority project config
+option_1: baz
+```
+
+You would end up with the following configuration:
+
+```yaml
+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.yml
+```
+
+## Configuration 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](../experiments/index.md) for more information.
+
+```yaml
+experiments:
+ feature_name: 1
+ another_feature: 2
+```
+
+### `verbose`
+
+- **Type**: `boolean`
+- **Default**: `false`
+- **Description**: Enable verbose output for all tasks
+- **CLI equivalent**: [`-v, --verbose`](./cli.md#-v---verbose)
+- **Environment variable**: [`TASK_VERBOSE`](./environment.md#task-verbose)
+
+```yaml
+verbose: true
+```
+
+### `silent`
+
+- **Type**: `boolean`
+- **Default**: `false`
+- **Description**: Disables echoing of commands
+- **CLI equivalent**: [`-s, --silent`](./cli.md#-s---silent)
+- **Environment variable**: [`TASK_SILENT`](./environment.md#task-silent)
+
+```yaml
+silent: true
+```
+
+### `color`
+
+- **Type**: `boolean`
+- **Default**: `true`
+- **Description**: Enable colored output. Colors are automatically enabled in CI environments (`CI=true`).
+- **CLI equivalent**: [`-c, --color`](./cli.md#-c---color)
+- **Environment variable**: [`TASK_COLOR`](./environment.md#task-color)
+
+```yaml
+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`](./cli.md#--disable-fuzzy)
+- **Environment variable**: [`TASK_DISABLE_FUZZY`](./environment.md#task-disable-fuzzy)
+
+```yaml
+disable-fuzzy: true
+```
+
+### `concurrency`
+
+- **Type**: `integer`
+- **Minimum**: `1`
+- **Description**: Number of concurrent tasks to run
+- **CLI equivalent**: [`-C, --concurrency`](./cli.md#-c---concurrency-number)
+- **Environment variable**: [`TASK_CONCURRENCY`](./environment.md#task-concurrency)
+
+```yaml
+concurrency: 4
+```
+
+### `failfast`
+
+- **Type**: `boolean`
+- **Default**: `false`
+- **Description**: Stop executing dependencies as soon as one of them fail
+- **CLI equivalent**: [`-F, --failfast`](./cli.md#-f---failfast)
+- **Environment variable**: [`TASK_FAILFAST`](./environment.md#task-failfast)
+
+```yaml
+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`](./cli.md#--interactive)
+
+```yaml
+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`](./environment.md#task-temp-dir)
+
+```yaml
+temp-dir: .task
+```
+
+## Example Configuration
+
+Here's a complete example of a `.taskrc.yml` file with all available options:
+
+```yaml
+# Global settings
+verbose: true
+silent: false
+color: true
+disable-fuzzy: false
+concurrency: 2
+temp-dir: .task
+
+# Enable experimental features
+experiments:
+ REMOTE_TASKFILES: 1
+```
diff --git a/website/src/latest/docs/reference/environment.md b/website/src/latest/docs/reference/environment.md
new file mode 100644
index 00000000..e5fdf42a
--- /dev/null
+++ b/website/src/latest/docs/reference/environment.md
@@ -0,0 +1,162 @@
+---
+title: Environment Reference
+description: A reference for the Taskfile environment variables
+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](./config.md)
+- _Environment variables_
+- [Command-line flags](./cli.md)
+
+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](./config.md) 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`](./config.md#verbose)
+
+### `TASK_SILENT`
+
+- **Type**: `boolean` (`true`, `false`, `1`, `0`)
+- **Default**: `false`
+- **Description**: Disables echoing of commands
+- **Config equivalent**: [`silent`](./config.md#silent)
+
+### `TASK_COLOR`
+
+- **Type**: `boolean` (`true`, `false`, `1`, `0`)
+- **Default**: `true`
+- **Description**: Enable colored output
+- **Config equivalent**: [`color`](./config.md#color)
+
+### `TASK_DISABLE_FUZZY`
+
+- **Type**: `boolean` (`true`, `false`, `1`, `0`)
+- **Default**: `false`
+- **Description**: Disable fuzzy matching for task names
+- **Config equivalent**: [`disable-fuzzy`](./config.md#disable-fuzzy)
+
+### `TASK_CONCURRENCY`
+
+- **Type**: `integer`
+- **Description**: Limit number of tasks to run concurrently
+- **Config equivalent**: [`concurrency`](./config.md#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`](./config.md#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`](./cli.md#--output-string)
+
+### `TASK_OUTPUT_GROUP_BEGIN`
+
+- **Type**: `string`
+- **Description**: Message template to print before a task's grouped output.
+ Only applies when the output style is `group`.
+- **CLI equivalent**: [`--output-group-begin`](./cli.md#--output-group-begin-template)
+
+### `TASK_OUTPUT_GROUP_END`
+
+- **Type**: `string`
+- **Description**: Message template to print after a task's grouped output.
+ Only applies when the output style is `group`.
+- **CLI equivalent**: [`--output-group-end`](./cli.md#--output-group-end-template)
+
+### `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 is `group`.
+- **CLI equivalent**: [`--output-group-error-only`](./cli.md#--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.
+
+### Custom Colors
+
+All color variables are [ANSI color codes][ansi]. 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 to
+`38;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` |
+
+[ansi]: https://en.wikipedia.org/wiki/ANSI_escape_code
diff --git a/website/src/docs/reference/package.md b/website/src/latest/docs/reference/package.md
similarity index 100%
rename from website/src/docs/reference/package.md
rename to website/src/latest/docs/reference/package.md
diff --git a/website/src/latest/docs/reference/schema.md b/website/src/latest/docs/reference/schema.md
new file mode 100644
index 00000000..475c1964
--- /dev/null
+++ b/website/src/latest/docs/reference/schema.md
@@ -0,0 +1,1013 @@
+---
+title: Taskfile Schema Reference
+description: A reference for the Taskfile schema
+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](https://taskfile.dev/schema.json).
+
+## Root Schema
+
+The root Taskfile schema defines the structure of your main `Taskfile.yml`.
+
+### `version`
+
+- **Type**: `string` or `number`
+- **Required**: Yes
+- **Valid values**: `"3"`, `3`, or any valid semver string
+- **Description**: Version of the Taskfile schema
+
+```yaml
+version: '3'
+```
+
+### `output`
+
+- **Type**: `string` or `object`
+- **Default**: `interleaved`
+- **Options**: `interleaved`, `group`, `prefixed`
+- **Description**: Controls how task output is displayed
+
+```yaml
+# 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
+
+```yaml
+method: timestamp
+```
+
+### [`includes`](#include)
+
+- **Type**: `map[string]Include`
+- **Description**: Include other Taskfiles
+
+```yaml
+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
+
+```yaml
+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
+
+```yaml
+env:
+ NODE_ENV: production
+ DATABASE_URL:
+ sh: echo $DATABASE_URL
+```
+
+### [`tasks`](#task)
+
+- **Type**: `map[string]Task`
+- **Description**: Task definitions
+
+```yaml
+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
+
+```yaml
+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.
+
+```yaml
+dotenv:
+ - .env.local # Highest priority
+ - .env # Lowest priority
+```
+
+### `run`
+
+- **Type**: `string`
+- **Default**: `always`
+- **Options**: `always`, `once`, `when_changed`
+- **Description**: Default execution behavior for tasks
+
+```yaml
+run: once
+```
+
+### `interval`
+
+- **Type**: `string`
+- **Default**: `100ms`
+- **Pattern**: `^[0-9]+(?:m|s|ms)$`
+- **Description**: Watch interval for file changes
+
+```yaml
+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
+
+```yaml
+set: [errexit, nounset, pipefail]
+```
+
+### `shopt`
+
+- **Type**: `[]string`
+- **Options**: `expand_aliases`, `globstar`, `nullglob`
+- **Description**: Bash shell options for all commands
+
+```yaml
+shopt: [globstar]
+```
+
+### `use_gitignore`
+
+- **Type**: `bool`
+- **Default**: `false`
+- **Description**: Exclude files matched by `.gitignore` rules when resolving
+ `sources` and `generates` globs for all tasks. Can be overridden per task.
+
+```yaml
+use_gitignore: true
+```
+
+## Include
+
+Configuration for including external Taskfiles.
+
+### `taskfile`
+
+- **Type**: `string`
+- **Required**: Yes
+- **Description**: Path to the Taskfile or directory to include
+
+```yaml
+includes:
+ backend: ./backend/Taskfile.yml
+ # Shorthand for above
+ frontend: ./frontend
+```
+
+### `dir`
+
+- **Type**: `string`
+- **Description**: Working directory for included tasks
+
+```yaml
+includes:
+ api:
+ taskfile: ./api
+ dir: ./api
+```
+
+### `optional`
+
+- **Type**: `bool`
+- **Default**: `false`
+- **Description**: Don't error if the included file doesn't exist
+
+```yaml
+includes:
+ optional-tasks:
+ taskfile: ./optional.yml
+ optional: true
+```
+
+### `flatten`
+
+- **Type**: `bool`
+- **Default**: `false`
+- **Description**: Include tasks without namespace prefix
+
+```yaml
+includes:
+ common:
+ taskfile: ./common.yml
+ flatten: true
+```
+
+### `internal`
+
+- **Type**: `bool`
+- **Default**: `false`
+- **Description**: Hide included tasks from command line and `--list`
+
+```yaml
+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
+
+```yaml
+includes:
+ database:
+ taskfile: ./db.yml
+ aliases: [db, data]
+```
+
+### `excludes`
+
+- **Type**: `[]string`
+- **Description**: Tasks to exclude from inclusion
+
+```yaml
+includes:
+ shared:
+ taskfile: ./shared.yml
+ excludes: [internal-setup, debug-only]
+```
+
+### `vars`
+
+- **Type**: `map[string]Variable`
+- **Description**: Variables to pass to the included Taskfile
+
+```yaml
+includes:
+ deploy:
+ taskfile: ./deploy.yml
+ vars:
+ ENVIRONMENT: production
+```
+
+### `checksum`
+
+- **Type**: `string`
+- **Description**: Expected checksum of the included file
+
+```yaml
+includes:
+ remote:
+ taskfile: https://example.com/tasks.yml
+ checksum: c153e97e0b3a998a7ed2e61064c6ddaddd0de0c525feefd6bba8569827d8efe9
+```
+
+## Variable
+
+Variables support multiple types and can be static values, dynamic commands,
+references, or maps.
+
+### Static Variables
+
+```yaml
+vars:
+ # String
+ APP_NAME: myapp
+ # Number
+ PORT: 8080
+ # Boolean
+ DEBUG: true
+ # Array
+ FEATURES: [auth, logging, metrics]
+ # Null
+ OPTIONAL_VAR: null
+```
+
+### Dynamic Variables (`sh`)
+
+```yaml
+vars:
+ COMMIT_HASH:
+ sh: git rev-parse HEAD
+ BUILD_TIME:
+ sh: date -u +"%Y-%m-%dT%H:%M:%SZ"
+```
+
+### Variable References (`ref`)
+
+```yaml
+vars:
+ BASE_VERSION: 1.0.0
+ FULL_VERSION:
+ ref: .BASE_VERSION
+```
+
+### Map Variables (`map`)
+
+```yaml
+vars:
+ CONFIG:
+ map:
+ database:
+ host: localhost
+ port: 5432
+ cache:
+ type: redis
+ ttl: 3600
+```
+
+### Secret Variables (`secret`)
+
+Mark variables as secret to mask their values in command logs.
+
+```yaml
+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 too
+```
+
+When 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](/docs/guide#secret-variables) section in the Guide.
+
+:::
+
+### Variable Ordering
+
+Variables can reference previously defined variables:
+
+```yaml
+vars:
+ GREETING: Hello
+ TARGET: World
+ MESSAGE: '{{.GREETING}} {{.TARGET}}!'
+```
+
+## Task
+
+Individual task configuration with multiple syntax options.
+
+### Simple Task Formats
+
+```yaml
+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
+
+```yaml
+tasks:
+ build:
+ cmds:
+ - go build ./...
+ - echo "Build complete"
+```
+
+#### `cmd`
+
+- **Type**: `string`
+- **Description**: Single command (alternative to `cmds`)
+
+```yaml
+tasks:
+ test:
+ cmd: go test ./...
+```
+
+#### `deps`
+
+- **Type**: `[]Dependency`
+- **Description**: Tasks to run before this task
+
+```yaml
+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`
+
+```yaml
+tasks:
+ test:
+ desc: Run unit tests
+ cmds:
+ - go test ./...
+```
+
+#### `summary`
+
+- **Type**: `string`
+- **Description**: Detailed description shown in `--summary`
+
+```yaml
+tasks:
+ deploy:
+ desc: Deploy to production
+ summary: |
+ Deploy the application to production environment.
+ This includes building, testing, and uploading artifacts.
+```
+
+#### `prompt`
+
+- **Type**: `string` or `[]string`
+- **Description**: Prompts shown before task execution
+
+```yaml
+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
+
+```yaml
+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 `method` root property for details.
+
+```yaml
+tasks:
+ build:
+ sources:
+ - go.mod
+ method: timestamp
+```
+
+#### `sources`
+
+- **Type**: `[]string` or `[]Glob`
+- **Description**: Source files to monitor for changes
+
+```yaml
+tasks:
+ build:
+ sources:
+ - '**/*.go'
+ - go.mod
+ # With exclusions
+ - exclude: '**/*_test.go'
+ cmds:
+ - go build ./...
+```
+
+#### `generates`
+
+- **Type**: `[]string` or `[]Glob`
+- **Description**: Files generated by this task
+
+```yaml
+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 `.gitignore` rules when resolving
+ this task's `sources` and `generates` globs. Overrides the root-level
+ `use_gitignore` setting.
+
+```yaml
+tasks:
+ build:
+ use_gitignore: true
+ sources:
+ - '**/*.go'
+ cmds:
+ - go build ./...
+```
+
+#### `status`
+
+- **Type**: `[]string`
+- **Description**: Commands to check if task should run
+
+```yaml
+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
+
+```yaml
+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).
+
+```yaml
+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 `dir` is
+ `ROOT_DIR`. For included Taskfiles, the default `dir` is the value specified in
+ their respective `includes.*.dir` field (if any).
+
+```yaml
+tasks:
+ current-dir:
+ dir: '{{.USER_WORKING_DIR}}'
+ cmd: pwd
+```
+
+#### `requires`
+
+- **Type**: `Requires`
+- **Description**: Required variables with optional enum validation
+
+```yaml
+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
+
+```yaml
+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](/docs/guide#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
+
+```yaml
+tasks:
+ dev:
+ watch: true
+ cmds:
+ - npm run dev
+```
+
+#### `platforms`
+
+- **Type**: `[]string`
+- **Description**: Platforms where this task should run
+
+```yaml
+tasks:
+ windows-build:
+ platforms: [windows]
+ cmds:
+ - go build -o app.exe ./cmd
+
+ unix-build:
+ platforms: [linux, darwin]
+ cmds:
+ - go build -o app ./cmd
+```
+
+## Command
+
+Individual command configuration within a task.
+
+### Basic Commands
+
+```yaml
+tasks:
+ example:
+ cmds:
+ - echo "Simple command"
+ - ls -la
+```
+
+### Command Object
+
+```yaml
+tasks:
+ example:
+ cmds:
+ - cmd: echo "Hello World"
+ silent: true
+ ignore_error: false
+ platforms: [linux, darwin]
+ set: [errexit]
+ shopt: [globstar]
+```
+
+### Task References
+
+```yaml
+tasks:
+ example:
+ cmds:
+ - task: other-task
+ vars:
+ PARAM: value
+ silent: false
+```
+
+### Deferred Commands
+
+```yaml
+tasks:
+ with-cleanup:
+ cmds:
+ - echo "Starting work"
+ # Deferred command string
+ - defer: echo "Cleaning up"
+ # Deferred task reference
+ - defer:
+ task: cleanup-task
+ vars:
+ CLEANUP_MODE: full
+```
+
+### For Loops
+
+#### Loop Over List
+
+```yaml
+tasks:
+ greet-all:
+ cmds:
+ - for: [alice, bob, charlie]
+ cmd: echo "Hello {{.ITEM}}"
+```
+
+#### Loop Over Sources/Generates
+
+```yaml
+tasks:
+ process-files:
+ sources: ['*.txt']
+ cmds:
+ - for: sources
+ cmd: wc -l {{.ITEM}}
+ - for: generates
+ cmd: gzip {{.ITEM}}
+```
+
+#### Loop Over Variable
+
+```yaml
+tasks:
+ process-items:
+ vars:
+ ITEMS: 'item1,item2,item3'
+ cmds:
+ - for:
+ var: ITEMS
+ split: ','
+ as: CURRENT
+ cmd: echo "Processing {{.CURRENT}}"
+```
+
+#### Loop Over Matrix
+
+```yaml
+tasks:
+ test-matrix:
+ cmds:
+ - for:
+ matrix:
+ OS: [linux, windows, darwin]
+ ARCH: [amd64, arm64]
+ cmd: echo "Testing {{.ITEM.OS}}/{{.ITEM.ARCH}}"
+```
+
+#### Loop in Dependencies
+
+```yaml
+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.
+
+```yaml
+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" ]'
+```
+
+## Shell Options
+
+### Set Options
+
+Available `set` options for POSIX shell features:
+
+- `allexport` / `a` - Export all variables
+- `errexit` / `e` - Exit on error
+- `noexec` / `n` - Read commands but don't execute
+- `noglob` / `f` - Disable pathname expansion
+- `nounset` / `u` - Error on undefined variables
+- `xtrace` / `x` - Print commands before execution
+- `pipefail` - Pipe failures propagate
+
+```yaml
+# 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 expansion
+- `globstar` - Enable `**` recursive globbing
+- `nullglob` - Null glob expansion
+
+```yaml
+# Global level
+shopt: [globstar]
+
+tasks:
+ find-files:
+ # Task level
+ shopt: [nullglob]
+ cmds:
+ - cmd: ls **/*.go
+ # Command level
+ shopt: [globstar]
+```
diff --git a/website/src/latest/docs/reference/templating.md b/website/src/latest/docs/reference/templating.md
new file mode 100644
index 00000000..ccf968c0
--- /dev/null
+++ b/website/src/latest/docs/reference/templating.md
@@ -0,0 +1,860 @@
+---
+title: Templating Reference
+description:
+ Comprehensive guide to Task's templating system with Go text/template, special
+ variables, and available functions
+outline: deep
+---
+
+# Templating Reference
+
+Task's templating engine uses Go's
+[text/template](https://pkg.go.dev/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](https://sprig.taskfile.dev/) 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
+
+```yaml
+version: '3'
+
+tasks:
+ hello:
+ vars:
+ MESSAGE: 'Hello, World!'
+ cmds:
+ - 'echo {{.MESSAGE}}'
+```
+
+**Output:**
+
+```
+Hello, World!
+```
+
+### Conditional Logic
+
+```yaml
+version: '3'
+
+tasks:
+ maybe-happy:
+ vars:
+ SMILE: ':\)'
+ FROWN: ':\('
+ HAPPY: true
+ cmds:
+ - 'echo {{if .HAPPY}}{{.SMILE}}{{else}}{{.FROWN}}{{end}}'
+```
+
+**Output:**
+
+```
+:)
+```
+
+### Function Calls and Pipes
+
+```yaml
+version: '3'
+
+tasks:
+ uniq:
+ vars:
+ NUMBERS: '0,1,1,1,2,2,3'
+ cmds:
+ - 'echo {{splitList "," .NUMBERS | uniq | join ", "}}'
+```
+
+**Output:**
+
+```
+0, 1, 2, 3
+```
+
+### Control Flow with Loops
+
+```yaml
+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: 1
+```
+
+## Special 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
+
+```yaml
+tasks:
+ test:
+ cmds:
+ - go test {{.CLI_ARGS}}
+```
+
+```bash
+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
+
+```yaml
+tasks:
+ docker-run:
+ cmds:
+ - docker run {{range .CLI_ARGS_LIST}}{{.}} {{end}}myapp
+```
+
+#### `CLI_FORCE`
+
+- **Type**: `bool`
+- **Description**: Whether `--force` or `--force-all` flags were set
+
+```yaml
+tasks:
+ deploy:
+ cmds:
+ - |
+ {{if .CLI_FORCE}}
+ echo "Force deployment enabled"
+ {{end}}
+ ./deploy.sh
+```
+
+#### `CLI_SILENT`
+
+- **Type**: `bool`
+- **Description**: Whether `--silent` flag was set
+
+#### `CLI_VERBOSE`
+
+- **Type**: `bool`
+- **Description**: Whether `--verbose` flag was set
+
+#### `CLI_OFFLINE`
+
+- **Type**: `bool`
+- **Description**: Whether `--offline` flag was set
+
+#### `CLI_ASSUME_YES`
+
+- **Type**: `bool`
+- **Description**: Whether `--yes` flag was set
+
+### Task
+
+#### `TASK`
+
+- **Type**: `string`
+- **Description**: Name of the current task
+
+```yaml
+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
+
+```yaml
+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 `task` was called from
+
+```yaml
+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 `joinPath` in [Path Functions](#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 `joinEnv` in [Environment Variable Functions](#environment-variable-functions) for joining
+> paths for use in environment variables.
+
+:::
+
+### Status
+
+#### `CHECKSUM`
+
+- **Type**: `string`
+- **Description**: Checksum of files in `sources` (only in `status` with
+ `checksum` method)
+
+#### `TIMESTAMP`
+
+- **Type**: `time.Time`
+- **Description**: Greatest timestamp of files in `sources` (only in `status`
+ with `timestamp` method)
+
+```yaml
+tasks:
+ build:
+ method: checksum
+ sources: ['**/*.go']
+ status:
+ - test "{{.CHECKSUM}}" = "$(cat .last-checksum)"
+ cmds:
+ - go build ./...
+ - echo "{{.CHECKSUM}}" > .last-checksum
+```
+
+### Loop
+
+#### `ITEM`
+
+- **Type**: `any`
+- **Description**: Current iteration value when using `for` property
+
+```yaml
+tasks:
+ greet:
+ cmds:
+ - for: [alice, bob, charlie]
+ cmd: echo "Hello {{.ITEM}}"
+```
+
+Can be renamed using `as`:
+
+```yaml
+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)
+
+```yaml
+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
+
+```yaml
+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
+
+```yaml
+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
+
+```yaml
+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
+
+```yaml
+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
+
+```yaml
+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
+
+```yaml
+tasks:
+ slice-demo:
+ vars:
+ ITEMS: [a, b, c, d, e]
+ cmds:
+ - echo "{{slice .ITEMS 1 3}}" # [b c]
+```
+
+### String Functions
+
+#### Basic String Operations
+
+```yaml
+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
+
+```yaml
+tasks:
+ string-test:
+ vars:
+ FILENAME: 'app.tar.gz'
+ EMAIL: 'user@example.com'
+ cmds:
+ - echo "{{.FILENAME | hasPrefix "app"}}" # true
+ - echo "{{.FILENAME | hasSuffix ".gz"}}" # true
+ - echo "{{.EMAIL | contains "@"}}" # true
+```
+
+#### String Replacement and Formatting
+
+```yaml
+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 shellQuote
+```
+
+#### Regular Expressions
+
+```yaml
+tasks:
+ regex:
+ vars:
+ EMAIL: 'user@example.com'
+ 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
+
+```yaml
+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}}" # 4
+```
+
+#### List Manipulation
+
+```yaml
+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}}" # true
+```
+
+#### String Lists
+
+```yaml
+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 spaces
+```
+
+In pipeline form, `join` receives the list from the left-hand side. The
+equivalent non-pipeline form is `{{join " " .WORDS}}`.
+
+#### Shell Argument Parsing
+
+```yaml
+tasks:
+ shell-args:
+ vars:
+ ARGS: 'file1.txt -v --output="result file.txt"'
+ cmds:
+ - |
+ {{range .ARGS | splitArgs}}
+ echo "Arg: {{.}}"
+ {{end}}
+```
+
+### Math Functions
+
+```yaml
+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-999
+```
+
+### Date and Time Functions
+
+```yaml
+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
+
+```yaml
+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
+
+```yaml
+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 path
+```
+
+#### Environment Variable Functions
+
+```yaml
+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}}"
+```
+
+```yaml
+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
+
+```yaml
+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
+
+```yaml
+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
+
+```yaml
+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
+
+```yaml
+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}}" # true
+```
+
+### Encoding and Serialization
+
+#### JSON
+
+```yaml
+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
+
+```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
+
+```yaml
+tasks:
+ base64:
+ vars:
+ SECRET: 'my-secret-key'
+ cmds:
+ - echo "{{.SECRET | b64enc}}" # Encode to base64
+ - echo "{{"bXktc2VjcmV0LWtleQ==" | b64dec}}" # Decode from base64
+```
+
+### Type Conversion
+
+```yaml
+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
+
+```yaml
+tasks:
+ generate:
+ vars:
+ DEPLOYMENT_ID: "{{uuid}}"
+ cmds:
+ - echo "Deployment ID {{.DEPLOYMENT_ID}}"
+```
+
+#### Debugging
+
+```yaml
+tasks:
+ debug:
+ vars:
+ COMPLEX_VAR:
+ map:
+ items: [1, 2, 3]
+ nested:
+ key: value
+ cmds:
+ - echo "{{spew .COMPLEX_VAR}}" # Pretty-print for debugging
+```
+
+### Output Functions
+
+#### Formatted Output
+
+```yaml
+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"}}'
+```
diff --git a/website/src/docs/releasing.md b/website/src/latest/docs/releasing.md
similarity index 69%
rename from website/src/docs/releasing.md
rename to website/src/latest/docs/releasing.md
index 663c3ab8..ac9452ff 100644
--- a/website/src/docs/releasing.md
+++ b/website/src/latest/docs/releasing.md
@@ -9,8 +9,8 @@ outline: deep
# Releasing
The release process of Task is done with the help of [GoReleaser][goreleaser].
-You can test the release process locally by calling the `test-release` task of
-the Taskfile.
+You can test the release process locally by calling the `goreleaser:test` task
+of the Taskfile.
[GitHub Actions](https://github.com/go-task/task/actions) should release
artifacts automatically when a new Git tag is pushed to `main` branch (raw
@@ -20,6 +20,22 @@ 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:` promotes the documentation before tagging: the docs in
+`website/src/next/docs`, their sidebar and the `next-*` JSON schemas are copied over
+their published counterparts, so the released tag carries the docs of the
+version it ships. The release workflow then runs `task website:deploy:prod`.
+
+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:
+
+```shell
+git checkout main && git pull
+task website:deploy:prod
+```
+
## Package managers
GoReleaser will automatically publish the release to most package managers:
diff --git a/website/src/docs/security/incident-response-plan.md b/website/src/latest/docs/security/incident-response-plan.md
similarity index 100%
rename from website/src/docs/security/incident-response-plan.md
rename to website/src/latest/docs/security/incident-response-plan.md
diff --git a/website/src/docs/security/index.md b/website/src/latest/docs/security/index.md
similarity index 100%
rename from website/src/docs/security/index.md
rename to website/src/latest/docs/security/index.md
diff --git a/website/src/docs/security/threat-model.md b/website/src/latest/docs/security/threat-model.md
similarity index 100%
rename from website/src/docs/security/threat-model.md
rename to website/src/latest/docs/security/threat-model.md
diff --git a/website/src/docs/styleguide.md b/website/src/latest/docs/styleguide.md
similarity index 100%
rename from website/src/docs/styleguide.md
rename to website/src/latest/docs/styleguide.md
diff --git a/website/src/docs/taskfile-versions.md b/website/src/latest/docs/taskfile-versions.md
similarity index 100%
rename from website/src/docs/taskfile-versions.md
rename to website/src/latest/docs/taskfile-versions.md
diff --git a/website/src/next/blog/any-variables.md b/website/src/next/blog/any-variables.md
new file mode 100644
index 00000000..66c51dde
--- /dev/null
+++ b/website/src/next/blog/any-variables.md
@@ -0,0 +1,155 @@
+---
+title: Any Variables
+description:
+ Task now supports most variable types, including booleans, integers, floats
+ and arrays!
+author: pd93
+date: 2024-05-09
+tags: ['experiments', 'variables']
+outline: deep
+editLink: false
+---
+
+# Any Variables
+
+
+
+Task has always had variables, but even though you were able to define them
+using different YAML types, they would always be converted to strings by Task.
+This limited users to string manipulation and encouraged messy workarounds for
+simple problems. Starting from [v3.37.0][v3.37.0], this is no longer the case!
+Task now supports most variable types, including **booleans**, **integers**,
+**floats** and **arrays**!
+
+
+
+## What's the big deal?
+
+These changes allow you to use variables in a much more natural way and opens up
+a wide variety of sprig functions that were previously useless. Take a look at
+some of the examples below for some inspiration.
+
+### Evaluating booleans
+
+No more comparing strings to "true" or "false". Now you can use actual boolean
+values in your templates:
+
+::: code-group
+
+```yaml [Before]
+version: 3
+
+tasks:
+ foo:
+ vars:
+ BOOL: true # <-- Parsed as a string even though its a YAML boolean
+ cmds:
+ - '{{if eq .BOOL "true"}}echo foo{{end}}'
+```
+
+```yaml [After]
+version: 3
+
+tasks:
+ foo:
+ vars:
+ BOOL: true # <-- Parsed as a boolean
+ cmds:
+ - '{{if .BOOL}}echo foo{{end}}' # <-- No need to compare to "true"
+```
+
+:::
+
+### Arithmetic
+
+You can now perform basic arithmetic operations on integer and float variables:
+
+```yaml
+version: 3
+
+tasks:
+ foo:
+ vars:
+ INT: 10
+ FLOAT: 3.14159
+ cmds:
+ - 'echo {{add .INT .FLOAT}}'
+```
+
+You can use any of the following arithmetic functions: `add`, `sub`, `mul`,
+`div`, `mod`, `max`, `min`, `floor`, `ceil`, `round` and `randInt`. Check out
+the [slim-sprig math documentation][slim-sprig-math] for more information.
+
+### Arrays
+
+You can now range over arrays inside templates and use list-based functions:
+
+```yaml
+version: 3
+
+tasks:
+ foo:
+ vars:
+ ARRAY: [1, 2, 3]
+ cmds:
+ - 'echo {{range .ARRAY}}{{.}}{{end}}'
+```
+
+You can use any of the following list-based functions: `first`, `rest`, `last`,
+`initial`, `append`, `prepend`, `concat`, `reverse`, `uniq`, `without`, `has`,
+`compact`, `slice` and `chunk`. Check out the [slim-sprig lists
+documentation][slim-sprig-list] for more information.
+
+### Looping over variables using `for`
+
+Previously, you would have to use a delimiter separated string to loop over an
+arbitrary list of items in a variable and split them by using the `split` subkey
+to specify the delimiter. However, we have now added support for looping over
+"collection-type" variables using the `for` keyword, so now you are able to loop
+over list variables directly:
+
+::: code-group
+
+```yaml [Before]
+version: 3
+
+tasks:
+ foo:
+ vars:
+ LIST: 'foo,bar,baz'
+ cmds:
+ - for:
+ var: LIST
+ split: ','
+ cmd: echo {{.ITEM}}
+```
+
+```yaml [After]
+version: 3
+
+tasks:
+ foo:
+ vars:
+ LIST: ['foo', 'bar', 'baz']
+ cmds:
+ - for:
+ var: LIST
+ cmd: echo {{.ITEM}}
+```
+
+:::
+
+## What about maps?
+
+Maps were originally included in the Any Variables experiment. However, they
+weren't quite ready yet. Instead of making you wait for everything to be ready
+at once, we have released support for all other variable types and we will
+continue working on map support in the new "[Map Variables][map-variables]"
+experiment.
+
+We're looking for feedback on a couple of different proposals, so please give
+them a go and let us know what you think. :pray:
+
+[v3.37.0]: https://github.com/go-task/task/releases/tag/v3.37.0
+[slim-sprig-math]: https://sprig.taskfile.dev/math.html
+[slim-sprig-list]: https://sprig.taskfile.dev/lists.html
diff --git a/website/src/next/blog/github-secure-open-source-program.md b/website/src/next/blog/github-secure-open-source-program.md
new file mode 100644
index 00000000..f80950de
--- /dev/null
+++ b/website/src/next/blog/github-secure-open-source-program.md
@@ -0,0 +1,58 @@
+---
+title: GitHub Secure Open Source Fund
+sidebarTitle: GitHub SOSF
+description:
+ Task participated in session 4 of the GitHub Secure Open Source program.
+author: andreynering
+date: 2026-08-15
+tags: ['github', 'security']
+outline: deep
+editLink: false
+---
+
+# GitHub Secure Open Source Fund
+
+
+
+
+
+Did you know that GitHub has a special program to fund security in open source?
+It's the [GitHub Secure Open Source Fund][fund]. We were selected to participate
+in session 4 that happened in May 2026 and it was really special for us.
+
+
+
+71 maintainers from 50 different open source projects and across 22 countries
+were selected to participate in the program. It was amazing to meet so many
+maintainers from other critical open source projects to learn how to make the
+open source software ecosystem more secure. We really acquired a meaningful
+amount of knowledge about security and had the enjoyed opportunity to ask
+questions and interact with both the GitHub Security Lab team and the other
+maintainers.
+
+Some of the topics we learned about:
+
+- How to make CI and GitHub Actions more secure
+- How to handle dependency updates in a secure way
+- How to handle vulnerability reports
+- How to use tools like CodeQL to make code more secure
+- How to better review code contributions to avoid introducing security issues
+- Many more...
+
+During the program we took action to make Task more secure, especially with
+regard to CI. Since then, we also handled a few different vulnerability reports,
+and having the knowledge to do that definitely helped us in the process.
+
+We also formalized our security policies and documented them in a new security
+section of our website. See both our [incident response
+plan][incident-response-plan] and our [threat model][threat-model].
+
+Many thanks to the GitHub Security Lab for this opportunity! Want to read more?
+GitHub wrote a blog post about session 4 that [you can read here][ghblog].
+
+[fund]: https://github.com/open-source/github-secure-open-source-fund
+[incident-response-plan]:
+ https://taskfile.dev/docs/security/incident-response-plan
+[threat-model]: https://taskfile.dev/docs/security/threat-model
+[ghblog]:
+ https://github.blog/open-source/maintainers/what-50-open-source-projects-taught-us-about-security-in-the-ai-era/
diff --git a/website/src/next/blog/go-tool-task.md b/website/src/next/blog/go-tool-task.md
new file mode 100644
index 00000000..41792796
--- /dev/null
+++ b/website/src/next/blog/go-tool-task.md
@@ -0,0 +1,56 @@
+---
+title: Using `go tool task`
+description: How to use Task using go tool.
+author: andreynering
+date: 2026-04-14
+tags: ['installation']
+outline: deep
+editLink: false
+---
+
+# Using `go tool task`
+
+
+
+Do you know that you can use Task without really needing to install it?
+
+If you work with Go, you probably depend on external binaries like linters, code
+generators and... Task.
+
+
+
+But asking your coworkers or contributors to install dependencies can be messy.
+Everyone is on a different operating system, use a different package manager,
+etc. In fact, [Task supports several package managers][install], but even having
+to choose how you want to install it can lead to some fatigue.
+
+Well, turns out you can just use `go tool`!
+
+Step one: add Task as a tool to your Go project:
+
+```bash
+go get -tool github.com/go-task/task/v3/cmd/task@latest
+```
+
+The command above will add a line like this to your `go.mod`:
+
+```
+tool github.com/go-task/task/v3/cmd/task
+```
+
+Step two: prefix `go tool` when calling Task:
+
+```bash
+go tool task {arguments...}
+```
+
+That's all!
+
+Go will compile the specified Task version on demand when calling
+`go tool task`. Don't worry, Go caches the tool, so subsequent calls are faster.
+
+This is useful when running Task on CI, as you don't need to stress about having
+to install it. It also means it'll be pinned to a specific Task version (but
+Dependabot or Renovate should be able to update it for you).
+
+[install]: https://taskfile.dev/docs/installation
diff --git a/website/src/next/blog/if-and-variable-prompt.md b/website/src/next/blog/if-and-variable-prompt.md
new file mode 100644
index 00000000..2beed7ce
--- /dev/null
+++ b/website/src/next/blog/if-and-variable-prompt.md
@@ -0,0 +1,137 @@
+---
+title: Conditional Statements and Variable Prompts
+sidebarTitle: Conditionals Statements
+description: Introduction of the `if:` control and required variable prompts.
+author: vmaerten
+date: 2026-01-24
+tags: ['new-features', 'variables']
+outline: deep
+editLink: false
+---
+
+# Conditional Statements and Variable Prompts
+
+
+
+The [v3.47.0][release] release is here, and it brings two exciting new features
+to Task. Let's take a closer look at them!
+
+
+
+## The New `if:` Control
+
+This first feature is simply the second most upvoted issue of all time (!) with
+58 :thumbsup:s (!!) at the time of writing.
+
+It introduces the `if:` control, which allow you to conditionally skip the
+execution of certain tasks and proceeding. `if:` can be set on a task-level or
+command-level, and can be either a Bash command or a Go template expression.
+
+Let me show a couple of examples.
+
+Task-level with Bash expression:
+
+```yaml
+version: '3'
+
+tasks:
+ deploy:
+ if: '[ "$CI" = "true" ]'
+ cmds:
+ - echo "Deploying..."
+ - ./deploy.sh
+```
+
+Command-level with Go template expression:
+
+```yaml
+version: '3'
+
+tasks:
+ conditional:
+ vars:
+ ENABLE_FEATURE: 'true'
+ cmds:
+ - cmd: echo "Feature is enabled"
+ if: '{{eq .ENABLE_FEATURE "true"}}'
+ - cmd: echo "Feature is disabled"
+ if: '{{ne .ENABLE_FEATURE "true"}}'
+```
+
+For more details, please check out the [documentation][if-docs]. The
+[examples][if-examples] from the test suite may be useful too.
+
+::: info
+
+We had similar functionality before, but nothing that perfectly fits this use
+case. There were [`sources:`][sources] and [`status:`][status], but those were
+meant to check if a task was up-to-date, and [`preconditions:`][preconditions],
+but this would halt the execution of the task instead of skipping it.
+
+:::
+
+## Prompt for Required Variables
+
+For backward-compatibility reasons, this feature is disabled by default. To
+enable it, either pass `--interactive` flag or add `interactive: true` to your
+`.taskrc.yml`.
+
+Once you do that, Task will basically starting prompting you in runtime for any
+required variables. In the example below, `NAME` will be prompted at runtime:
+
+```yaml
+version: '3'
+
+tasks:
+ # Simple text input prompt
+ greet:
+ desc: Greet someone by name
+ requires:
+ vars:
+ - NAME
+ cmds:
+ - echo "Hello, {{.NAME}}!"
+```
+
+If a given variable has an enum, Task will actually show a selection menu so you
+can choose the right option instead of typing:
+
+```yaml
+version: '3'
+
+tasks:
+ # Enum selection (dropdown menu)
+ deploy:
+ desc: Deploy to an environment
+ requires:
+ vars:
+ - name: ENVIRONMENT
+ enum: [dev, staging, prod]
+ cmds:
+ - echo "Deploying to {{.ENVIRONMENT}}..."
+```
+
+Once again, check out the [documentation][prompt-docs] for more details, and the
+[prompt examples][prompt-examples] from the test suite.
+
+## Feedback
+
+Let's us know if you have any feedback! You can find us on our [Discord
+server][discord].
+
+[release]: https://github.com/go-task/task/releases/tag/v3.47.0
+[vmaerten]: https://github.com/vmaerten
+[sources]:
+ https://taskfile.dev/docs/guide#by-fingerprinting-locally-generated-files-and-their-sources
+[status]:
+ https://taskfile.dev/docs/guide#using-programmatic-checks-to-indicate-a-task-is-up-to-date
+[preconditions]:
+ https://taskfile.dev/docs/guide#using-programmatic-checks-to-cancel-the-execution-of-a-task-and-its-dependencies
+[if-docs]: https://taskfile.dev/docs/guide#conditional-execution-with-if
+[if-examples]:
+ https://github.com/go-task/task/blob/main/testdata/if/Taskfile.yml
+[prompt-docs]:
+ https://taskfile.dev/docs/guide#prompting-for-missing-variables-interactively
+[prompt-examples]:
+ https://github.com/go-task/task/blob/main/testdata/interactive_vars/Taskfile.yml
+[discord]: https://discord.com/invite/6TY36E39UK
diff --git a/website/src/next/blog/index.md b/website/src/next/blog/index.md
new file mode 100644
index 00000000..d57ceb43
--- /dev/null
+++ b/website/src/next/blog/index.md
@@ -0,0 +1,20 @@
+---
+title: Blog
+description: Latest news and updates from the Task team
+editLink: false
+---
+
+
+
+
diff --git a/website/src/next/blog/task-in-2023.md b/website/src/next/blog/task-in-2023.md
new file mode 100644
index 00000000..813e4257
--- /dev/null
+++ b/website/src/next/blog/task-in-2023.md
@@ -0,0 +1,141 @@
+---
+title: Introducing Experiments
+description:
+ A look at where task is, where it's going and how we're going to get there.
+author: pd93
+date: 2023-09-02
+tags: ['roadmap', 'experiments', 'community']
+outline: deep
+editLink: false
+---
+
+# Introducing Experiments
+
+
+
+Lately, Task has been growing extremely quickly and I've found myself thinking a
+lot about the future of the project and how we continue to evolve and grow. I'm
+not much of a writer, but I think one of the things we could do better is to
+communicate these kinds of thoughts to the community. So, with that in mind,
+this is the first (hopefully of many) blog posts talking about Task and what
+we're up to.
+
+
+
+## :calendar: So, what have we been up to?
+
+Over the past 12 months or so, @andreynering (Author and maintainer of the
+project) and I (@pd93) have been working in our spare time to maintain and
+improve v3 of Task and we've made some amazing progress. Here are just some of
+the things we've released in that time:
+
+- An official [extension for VS Code][vscode-task].
+- Internal Tasks (#818).
+- Task aliases (#879).
+- Looping over tasks (#1220).
+- A series of refactors to the core codebase to make it more maintainable and
+ extensible.
+- Loads of bug fixes and improvements.
+- An integration with [Crowdin][crowdin]. Work is in progress on making our docs
+ available in **7 new languages** (Special thanks to all our translators for
+ the huge help with this!).
+- And much, much more! :sparkles:
+
+We're also working on adding some really exciting and highly requested features
+to Task such as having the ability to run remote Taskfiles (#1317).
+
+None of this would have been possible without the [150 or so (and growing)
+contributors][contributors] to the project, numerous sponsors and a passionate
+community of users. Together we have more than doubled the number of GitHub
+stars to over 8400 :star: since the beginning of 2022 and this continues to
+accelerate. We can't thank you all enough for your help and support! 🚀
+
+[](https://star-history.com/#go-task/task&Date)
+
+## What's next? :thinking:
+
+It's extremely motivating to see so many people using and loving Task. However,
+in this time we've also seen an increase in the number of issues and feature
+requests. In particular, issues that require some kind of breaking change to
+Task. This isn't a bad thing, but as we grow we need to be more responsible
+about how we address these changes in a way that ensures stability and
+compatibility for existing users and their Taskfiles.
+
+At this point you're probably thinking something like:
+
+> "But you use [semantic versioning][semver] - Just release a new major version
+> with your breaking changes."
+
+And you'd be right... sort of. In theory, this sounds great, but the reality is
+that we don't have the time to commit to a major overhaul of Task in one big
+bang release. This would require a colossal amount of time and coordination and
+with full time jobs and personal lives to tend to, this is a difficult
+commitment to make. Smaller, more frequent major releases are also a significant
+inconvenience for users as they have to constantly keep up-to-date with our
+breaking changes. Fortunately, there is a better way.
+
+## What's going to change? :monocle_face:
+
+Going forwards, breaking changes will be allowed into _minor_ versions of Task
+as "experimental features". To access these features users will need opt-in by
+enabling feature flags. This will allow us to release new features slowly and
+gather feedback from the community before making them the default behavior in a
+future major release.
+
+To prepare users for the next major release, we will maintain a list of
+[deprecated features][deprecations] and [experiments][experiments] on our docs
+website and publish information on how to migrate to the new behavior.
+
+You can read the [full breaking change proposal][breaking-change-proposal] and
+view all the [current experiments and their status][experiments-project] on
+GitHub including the [Gentle Force][gentle-force-experiment] and [Remote
+Taskfiles][remote-taskfiles-experiment] experiments.
+
+## What will happen to v2/v3 features?
+
+v2 has been [officially deprecated][deprecate-version-2-schema]. If you're still
+using a Taskfile with `version: "2"` at the top we _strongly recommend_ that you
+upgrade as soon as possible. Removing v2 will allow us to tidy up the codebase
+and focus on new functionality instead.
+
+When v4 is released, we will continue to support v3 for a period of time (bug
+fixes etc). However, since we are moving from a backward-compatibility model to
+a forwards-compatibility model, **v4 itself will not be backwards compatible
+with v3**.
+
+## v4 When? :eyes:
+
+:man_shrugging: When it's ready.
+
+In all seriousness, we don't have a timeline for this yet. We'll be working on
+the most serious deficiencies of the v3 API first and regularly evaluating the
+state of the project. When we feel its in a good, stable place and we have a
+clear upgrade path for users and a number of stable experiments, we'll start to
+think about v4.
+
+## :wave: Final thoughts
+
+Task is growing fast and we're excited to see where it goes next. We hope that
+the steps we're taking to improve the project and our process will help us to
+continue to grow. As always, if you have any questions or feedback, we encourage
+you to comment on or open [issues][issues] and [discussions][discussions] on
+GitHub. Alternatively, you can join us on [Discord][discord].
+
+I plan to write more of these blog posts in the future on a variety of
+Task-related topics, so make sure to check in occasionally and see what we're up
+to!
+
+[vscode-task]: https://github.com/go-task/vscode-task
+[crowdin]: https://crowdin.com
+[contributors]: https://github.com/go-task/task/graphs/contributors
+[semver]: https://semver.org
+[breaking-change-proposal]: https://github.com/go-task/task/discussions/1191
+[experiments]: https://taskfile.dev/experiments
+[deprecations]: https://taskfile.dev/deprecations
+[deprecate-version-2-schema]: https://github.com/go-task/task/issues/1197
+[issues]: https://github.com/go-task/task/issues
+[discussions]: https://github.com/go-task/task/discussions
+[discord]: https://discord.gg/6TY36E39UK
+[experiments-project]: https://github.com/orgs/go-task/projects/1
+[gentle-force-experiment]: https://github.com/go-task/task/issues/1200
+[remote-taskfiles-experiment]: https://github.com/go-task/task/issues/1317
diff --git a/website/src/next/blog/windows-core-utils.md b/website/src/next/blog/windows-core-utils.md
new file mode 100644
index 00000000..3650bb36
--- /dev/null
+++ b/website/src/next/blog/windows-core-utils.md
@@ -0,0 +1,141 @@
+---
+title: 'Announcing Built-in Core Utilities for Windows'
+sidebarTitle: Built-in Core Utilities
+description: The journey of enhancing Windows support in Task.
+author: andreynering
+date: 2025-09-15
+tags: ['windows', 'core-utils']
+outline: deep
+editLink: false
+---
+
+# Announcing Built-in Core Utilities for Windows
+
+
+
+When I started Task back in 2017, one of my biggest goals was to build a task
+runner that would work well on all major platforms, including Windows. At the
+time, I was using Windows as my main platform, and it caught my attention how
+much of a pain it was to get a working version of Make on Windows, for example.
+
+
+
+## The very beginning
+
+The very first versions, which looked very prototyp-ish, already supported
+Windows, but it was falling back to Command Prompt (`cmd.exe`) to run commands
+if `bash` wasn't available in the system. That didn't mean you couldn't run Bash
+commands on Windows necessarily, because if you used Task inside Git Bash, it
+would expose `bash.exe` into your `$PATH`, which made possible for Task to use
+it. Outside of it, you would be out of luck, though, because running on Command
+Prompt meant that the commands wouldn't be really compatible.
+
+## Adopting a shell interpreter
+
+I didn't take too much time to discover that there was [a shell interpreter for
+Go that was very solid][mvdan], and I quickly adopted it to ensure we would be
+able to run commands with consistency across all platforms. It was fun because
+once adopted, I had the opportunity to [make some contributions to make it more
+stable][mvdan-prs], which I'm sure the author appreciated.
+
+## The lack of core utilities
+
+There was one important thing missing, though. If you needed to use any core
+utilities on Windows, like copying files with `cp`, moving with `mv`, creating a
+directory with `mkdir -p`, that likely would just fail :boom:. There were
+workarounds, of course. You could run `task` inside Git Bash which exposed core
+utils in `$PATH` for you, or you could install these core utils manually (there
+are a good number of alternative implementations available for download).
+
+That was still far from ideal, though. One of my biggest goals with Task is that
+it should "just work", even on Windows. Requiring additional setup to make
+things work is exactly what I wanted to avoid.
+
+## They finally arrive!
+
+And here we are, in 2025, 8 years after the initial release. We might be late,
+but I'm happy nonetheless. From now on, the following core utilities will be
+available on Windows. This is the start. We want to add more with time.
+
+- `base64`
+- `cat`
+- `chmod`
+- `cp`
+- `find`
+- `gzip`
+- `ls`
+- `mkdir`
+- `mktemp`
+- `mv`
+- `rm`
+- `shasum`
+- `tar`
+- `touch`
+- `xargs`
+
+## How we made this possible
+
+This was made possible via a collaboration with the maintainers of other Go
+projects.
+
+### u-root/u-root
+
+We are using the core utilities implementations in Go from the [u-root][u-root]
+project. It wasn't as simple as it sounds because they have originally
+implemented every core util as a standalone `main` package, which means we
+couldn't just import and use them as libraries. We had some discussion and we
+agreed on a common [interface][uroot-interface] and [base
+implementation][uroot-base]. Then, I refactored one-by-one of the core utils in
+the list above. This is the reason we don't have all of them: there are too
+many! But the good news is that we can refactor more with time and include them
+in Task.
+
+### mvdan/sh
+
+The other collaboration was with the maintainer of the shell interpreter. He
+agreed on having [an official middleware][middleware] to expose these core
+utilities. This means that other projects that use the shell interpreter can
+also benefit from this work, and as more utilities are included, those projects
+will benefit as well.
+
+## Can I choose whether to use them or not?
+
+Yes. We added a new environment variable called
+[`TASK_CORE_UTILS`][task-core-utils] to control if the Go implementations are
+used or not. By default, this is `true` on Windows and `false` on other
+platforms. You can override it like this:
+
+```bash
+# Enable, even on non-Windows platforms
+env TASK_CORE_UTILS=1 task ...
+
+# Disable, even on Windows
+env TASK_CORE_UTILS=0 task ...
+```
+
+We'll consider making this enabled by default on all platforms in the future. In
+the meantime, we're still using the system core utils on non-Windows platforms
+to avoid regressions as the Go implementations may not be 100% compatible with
+the system ones.
+
+## Feedback
+
+If you have any feedback about this feature, join our [Discord server][discord]
+or [open an issue][gh-issue] on GitHub.
+
+Also, if Task is useful for you or your company, consider [sponsoring the
+project][sponsor]!
+
+[mvdan]: https://github.com/mvdan/sh
+[mvdan-prs]:
+ https://github.com/mvdan/sh/pulls?q=is%3Apr+author%3Aandreynering+is%3Aclosed+sort%3Acreated-asc
+[u-root]: https://github.com/u-root/u-root
+[uroot-interface]:
+ https://github.com/u-root/u-root/blob/main/pkg/core/command.go
+[uroot-base]: https://github.com/u-root/u-root/blob/main/pkg/core/base.go
+[middleware]:
+ https://github.com/mvdan/sh/blob/master/moreinterp/coreutils/coreutils.go
+[task-core-utils]: /docs/reference/environment#task-core-utils
+[discord]: https://discord.com/invite/6TY36E39UK
+[gh-issue]: https://github.com/go-task/task/issues
+[sponsor]: /donate
diff --git a/website/src/next/docs/changelog.md b/website/src/next/docs/changelog.md
new file mode 100644
index 00000000..f7a0e280
--- /dev/null
+++ b/website/src/next/docs/changelog.md
@@ -0,0 +1,1575 @@
+---
+title: Changelog
+outline: deep
+editLink: false
+---
+
+# Changelog
+
+::: v-pre
+
+## 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's `vendor_completions.d` directory instead of `completions` (#2850, #2859
+ by @Legimity).
+- PowerShell completions now work with aliases of the `task` command, not just
+ the `task` binary itself (#2852 by @kojiishi).
+- Fixed task and namespace aliases not being completed by the Zsh completion. A
+ `show-aliases` zstyle can turn this off (#2865, #2864 by @vmaerten).
+- Fixed task names containing certain characters (e.g. `\`, `_`, `^`) leaking
+ into checksum/timestamp filenames, breaking `sources:`/`generates:` up-to-date
+ detection (#2886 by @s3onghyun).
+- Fixed `for: matrix:` loops using `ref:` rows producing wrong values when the
+ same task was run concurrently (e.g. by parallel `deps`) with different vars
+ (#2890, #2894 by @amitmishra11).
+- Added a `secret: true` flag for variables that masks their value in logs,
+ `task --summary`, and command output (#2514 by @vmaerten).
+- Added the `use_gitignore` setting (global or per-task) to skip files matched
+ by your `.gitignore` when fingerprinting `sources`/`generates` and when
+ watching (#2773 by @vmaerten).
+- Added support for configuring output flags (`--output`,
+ `--output-group-begin`, `--output-group-end`, `--output-group-error-only`) via
+ the `TASK_OUTPUT*` environment variables (#2873 by @liiight).
+- Added a `--temp-dir` flag (with `TASK_TEMP_DIR` env var and `temp-dir` taskrc
+ 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 `.git` suffix (#2904 by @pd93).
+- Re-added the example remote taskfile at
+ [taskfile.dev/Taskfile.yml](https://taskfile.dev/Taskfile.yml) (#2905 by
+ @pd93).
+- Fixed malformed `includes:` entries (missing `taskfile`/`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 `absPath` template function that resolves a path to its absolute form,
+ cleaning `..` and `.` components (#2681, #2788 by @mateenanjum).
+- Added `joinEnv` function to join paths based on your oprating system: `;` for
+ Windows and `:` elsewhere, and `joinUrl` to join URL paths. Also, added two
+ new special variables: `FILE_PATH_SEPARATOR` which returns `\` on Windows and
+ `/` elsewhere, and `PATH_LIST_SEPARATOR` which 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.ref` support in `requires`: enum constraints can now reference
+ variables or template pipelines (e.g., `ref: .ALLOWED_ENVS`) instead of
+ duplicating static lists. Combined with `sh:` variables, this enables fully
+ dynamic enum validation (#2678 by @vmaerten).
+- Fixed Fish completion using hardcoded `task` binary name instead of
+ `$GO_TASK_PROGNAME` for 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: timestamp` and the files listed on `generates:` were deleted. This
+ makes `method: timestamp` behaves the same as `method: 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: true` not 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.yml` option can now be overridden with a `TASK_`-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 by `if:` (#2658, #2660 by @vmaerten).
+- Fixed `ROOT_TASKFILE` variable pointing to directory instead of the actual
+ Taskfile path when no explicit `-t` flag is provided (#2635, #1706 by
+ @trulede).
+- Included Taskfiles with `silent: true` now properly propagate silence to their
+ tasks, while still allowing individual tasks to override with `silent: false`
+ (#2640, #1319 by @trulede).
+- Added TLS certificate options for Remote Taskfiles: use `--cacert` for
+ self-signed certificates and `--cert`/`--cert-key` for 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`, print `prefix:` 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 for `start-*`) (#1900, #2234 by @vmaerten).
+- Added conditional execution with the `if` field: 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 or `interactive: true` in `.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, set `failfast: true` either on your
+ `.taskrc.yml` or per task, or use the `--failfast` flag, which will also work
+ for `--parallel` (#1246, #2525 by @andreynering).
+- The `--summary` flag now displays `vars:` (both global and task-level),
+ `env:`, and `requires:` 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-fuzzy` flag and `disable-fuzzy` taskrc option
+ to allow disabling fuzzy matching entirely (#2521, #2523 by @vmaerten).
+- Added LLM-optimized documentation via VitePress plugin, generating `llms.txt`
+ and `llms-full.txt` for AI-powered development tools (#2513 by @vmaerten).
+- Added `--trusted-hosts` CLI flag and `remote.trusted-hosts` config 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 `--yes` flag is now accessible in templates via the new `CLI_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-stream` Content-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 --init` and to the
+ default Taskfile it generates (#2433 by @andreynering).
+- Added `--remote-cache-dir` flag and `remote.cache-dir` taskrc 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 and `applyOf` is 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_changed` to 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 of `run: once` or
+ `run: when_changed` settings (#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_error` was ignored when using `task:` 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
+ using `for` loops 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.yml` was not returned if reading it failed, and
+ corrected handling of remote entrypoint Taskfiles (#2460, #2461 by @vmaerten).
+- Improved performance of `--list` and `--list-all` by 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 1` when a dependency task failed
+ (#2286 by @GrahamDennis).
+- Fixed YAML library from the unmaintained `gopkg.in/yaml.v3` to the new fork
+ maintained by the official YAML org (#2171, #2434 by @andreynering).
+- On Windows, the built-in version of the `rm` core utils contains a fix related
+ to the `-f` flag (#2426,
+ [u-root/u-root#3464](https://github.com/u-root/u-root/pull/3464),
+ [mvdan/sh#1199](https://github.com/mvdan/sh/pull/1199), #2506 by
+ @andreynering).
+
+## v3.45.4 - 2025-09-17
+
+- Fixed a bug where `cache-expiry` could not be defined in `.taskrc.yml` (#2423
+ by @vmaerten).
+- Fixed a bug where `.taskrc.yml` files 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 uses `cp`, `mv`, `mkdir` or 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](https://taskfile.dev/blog/windows-core-utils).
+ (#197, #2360 by @andreynering).
+- :sparkles: Built and deployed a [brand new website](https://taskfile.dev)
+ using [VitePress](https://vitepress.dev) (#2359, #2369, #2371, #2375, #2378 by
+ @vmaerten, @andreynering, @pd93).
+- Began releasing
+ [nightly builds](https://github.com/go-task/task/releases/tag/nightly). 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.yml` or
+ `$HOME/.taskrc.yml`. Check out our new
+ [configuration guide](https://taskfile.dev/docs/reference/config) 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 `--nested` flag 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](https://github.com/go-task/setup-task). 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](https://github.com/go-task/setup-task/releases/tag/v1.0.0) (by
+@pd93, @shrink, @trim21 and all the previous contributors to
+[arduino/setup-task](https://github.com/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_NAME` and `TEST_DIR` available in fixture tests
+ (#2265 by @pd93).
+
+## v3.44.0 - 2025-06-08
+
+- Added `uuid`, `randInt` and `randIntN` template functions (#1346, #2225 by
+ @pd93).
+- Added new `CLI_ARGS_LIST` array variable which contains the arguments passed
+ to Task after the `--` (the same as `CLI_ARGS`, but an array instead of a
+ string). (#2138, #2139, #2140 by @pd93).
+- Added `toYaml` and `fromYaml` templating functions (#2217, #2219 by @pd93).
+- Added `task` field the `--list --json` output (#2256 by @aleksandersh).
+- Added the ability to
+ [pin included taskfiles](https://taskfile.dev/next/experiments/remote-taskfiles/#manual-checksum-pinning)
+ by specifying a checksum. This works with both local and remote Taskfiles
+ (#2222, #2223 by @pd93).
+- When using the
+ [Remote Taskfiles experiment](https://github.com/go-task/task/issues/1317),
+ 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 the
+`USER_WORKING_DIR` and built-in variables. This fixes #2206, #2195, #2207 and
+#2208.
+
+## v3.43.2 - 2025-04-21
+
+- Fixed regresion of `CLI_ARGS` being 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](https://github.com/radovskyb/watcher) to
+ [fsnotify](https://github.com/fsnotify/fsnotify). The former library used
+ polling, which means Task had a high CPU usage when watching too many files.
+ `fsnotify` uses 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](https://github.com/go-task/task/issues/1585)
+ was made generally available so you can now
+ [define map variables in your Taskfiles!](https://taskfile.dev/usage/#variables)
+ (#1585, #1547, #2081 by @pd93).
+- Wildcards can now
+ [match multiple tasks](https://taskfile.dev/usage/#wildcard-arguments) (#2072,
+ #2121 by @pd93).
+- Added the ability to
+ [loop over the files specified by the `generates` keyword](https://taskfile.dev/usage/#looping-over-your-tasks-sources-or-generated-files).
+ 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](https://github.com/go-task/task/issues/1317)
+ (#1402, #2176 by @pd93):
+ - Cached files are now prioritized over remote ones.
+ - Added an `--expiry` flag 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.
+- `.taskrc` files 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 `--init` flag) 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 `--version` flag 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 in `sources` only 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
+ of `nil` (#1911, #2144 by @pd93).
+- The `USER_WORKING_DIR` special 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 [`Executor`](https://pkg.go.dev/github.com/go-task/task/v3#Executor) now
+ uses the functional options pattern (#2085, #2147, #2148 by @pd93).
+- The functional options for the
+ [`taskfile.Reader`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Reader)
+ and
+ [`taskfile.Snippet`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Snippet)
+ types no longer have the `Reader`/`Snippet` respective prefixes (#2148 by
+ @pd93).
+- [`taskfile.Reader`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Reader)
+ no longer accepts a
+ [`taskfile.Node`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Node).
+ Instead nodes are passed directly into the
+ [`Reader.Read`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Reader.Read)
+ method (#2169 by @pd93).
+- [`Reader.Read`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Reader.Read)
+ also now accepts a [`context.Context`](https://pkg.go.dev/context#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 `--init` less verbose by default and respect `--silent` and `--verbose`
+ flags (#2009, #2011 by @HeCorr).
+- `--init` now 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 `defer` statements in the shorthand
+ `cmds` syntax 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](https://taskfile.dev/getting-started) (#2086
+ by @pd93).
+- Allow `matrix` to 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](https://taskfile.dev/reference/package).
+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`](https://pkg.go.dev/github.com/go-task/task/v3#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.
+- [`TaskfileDecodeError.WithFileInfo`](https://pkg.go.dev/github.com/go-task/task/v3/errors#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`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Snippet)
+ and related code moved from the `errors` package to the `taskfile` package
+ (#2068 by @pd93).
+- Renamed `TaskMissingRequiredVars` to
+ [`TaskMissingRequiredVarsError`](https://pkg.go.dev/github.com/go-task/task/v3/errors#TaskMissingRequiredVarsError)
+ (#2052 by @vmaerten).
+- Renamed `TaskNotAllowedVars` to
+ [`TaskNotAllowedVarsError`](https://pkg.go.dev/github.com/go-task/task/v3/errors#TaskNotAllowedVarsError)
+ (#2052 by @vmaerten).
+- The
+ [`taskfile.Reader`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Reader)
+ is now constructed using the functional options pattern (#2082 by @pd93).
+- Removed our internal `logger.Logger` from the entire `taskfile` package (#2082
+ by @pd93).
+ - Users are now expected to pass a custom debug/prompt functions into
+ [`taskfile.Reader`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Reader)
+ if they want this functionality by using the new
+ [`WithDebugFunc`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#WithDebugFunc)
+ and
+ [`WithPromptFunc`](https://pkg.go.dev/github.com/go-task/task/v3/taskfile#WithPromptFunc)
+ functional options.
+- Remove `Range` functions in the `taskfile/ast` package in favour of new
+ iterator functions (#1798 by @pd93).
+- `ast.Call` was moved from the `taskfile/ast` package to the main `task`
+ package (#2084 by @pd93).
+- `ast.Tasks.FindMatchingTasks` was moved from the `taskfile/ast` package to the
+ `task.Executor.FindMatchingTasks` in the main `task` package (#2084 by @pd93).
+- The `Compiler` and its `GetVariables` and `FastGetVariables` methods were
+ moved from the `internal/compiler` package to the main `task` package (#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 `silent` for 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_DIR` special 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](https://github.com/elliotchance/orderedmap)
+ (#1797 by @pd93).
+- Fixed a bug where variables defined at the task level were being ignored in
+ the `requires` section. (#1960, #1955, #1768 by @vmaerten and @mokeko)
+- The `CHECKSUM` and `TIMESTAMP` variables are now accessible within `cmds`
+ (#1872 by @niklasr22).
+- Updated [installation docs](https://taskfile.dev/installation) 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-urls` by switching to the maintained fork
+ `chainguard-dev/git-urls` (#1917 by @AlekSi).
+- Added missing `platforms` property to `cmds` that use `for` (#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_OFFLINE` environment 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](https://taskfile.dev/experiments/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](https://taskfile.dev/experiments/env-precedence)
+ (#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_CODE` special variable on `defer:` when a command finishes
+ with a non-zero exit code (#1484, #1762 by @dorimon-1 and @andreynering).
+- Expose a new `ALIAS` special variable, which will contain the alias used to
+ call the current task. Falls back to the task name. (#1764 by @DanStory).
+- Fixed `TASK_REMOTE_DIR` environment 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
+ [`--completion` flag](https://taskfile.dev/installation/#setup-completions) 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 `completion` directory
+ [are now deprecated](https://taskfile.dev/deprecations/completion-scripts/).
+- Added the ability to
+ [loop over a matrix of values](https://taskfile.dev/usage/#looping-over-a-matrix)
+ (#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
+ `default` task (#1777, #1778 by @vmaerten).
+- Optimized file existence checks for remote Taskfiles (#1713 by @vmaerten).
+
+## v3.38.0 - 2024-06-30
+
+- Added `TASK_EXE` special 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](https://taskfile.dev/usage/#referencing-other-variables) 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](https://taskfile.dev/reference/templating/) to the
+ documentation (#1614, #1653 by @pd93).
+- If using the
+ [Map Variables experiment (1)](https://taskfile.dev/experiments/map-variables/?proposal=1),
+ references are available by
+ [prefixing a string with a `#`](https://taskfile.dev/experiments/map-variables/?proposal=1#references)
+ (#1654 by @pd93).
+- If using the
+ [Map Variables experiment (2)](https://taskfile.dev/experiments/map-variables/?proposal=2),
+ the `yaml` and `json` keys are no longer available (#1654 by @pd93).
+- Added a new `TASK_REMOTE_DIR` environment variable to configure where cached
+ remote Taskfiles are stored (#1661 by @vmaerten).
+- Added a new `--clear-cache` flag 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 `riscv64` architecture on Linux (#1699 by
+ @mengzhuo).
+- Added `CLI_SILENT` and `CLI_VERBOSE` variables (#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](https://taskfile.dev/blog/any-variables), but
+ [_without support for maps_](https://github.com/go-task/task/issues/1415#issuecomment-2044756925)
+ (#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 `stdin` as 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 `q` for template function `shellQuote` (#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](https://taskfile.dev/experiments/map-variables/) 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](https://taskfile.dev/usage/#looping-over-dependencies)
+ (#1299, #1541 by @pd93).
+- When using the
+ "[Remote Taskfiles](https://taskfile.dev/experiments/remote-taskfiles/)"
+ experiment, you are now able to use
+ [remote Taskfiles as your entrypoint](https://taskfile.dev/experiments/remote-taskfiles/#root-remote-taskfiles).
+ - `includes` in remote Taskfiles will now also resolve correctly (#1347 by
+ @pd93).
+- When using the
+ "[Any Variables](https://taskfile.dev/experiments/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_DIR` variable was sometimes incorrect (#1522,
+ #1523 by @pd93).
+- Added a new `TASKFILE` special 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](https://taskfile.dev/usage/#wildcard-arguments)
+ (#836, #1489 by @pd93).
+- Added the ability to
+ [run Taskfiles via stdin](https://taskfile.dev/usage/#reading-a-taskfile-from-stdin)
+ (#655, #1483 by @pd93).
+- Bumped minimum Go version to 1.21 (#1500 by @pd93).
+- Fixed bug related to the `--list` flag (#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 `requires` on the API docs (#1491 by
+ @teatimeguest).
+
+## v3.34.1 - 2024-01-27
+
+- Fixed prompt regression on
+ [Remote Taskfiles experiment](https://taskfile.dev/experiments/remote-taskfiles/)
+ (#1486, #1487 by @pd93).
+
+## v3.34.0 - 2024-01-25
+
+- Removed support for `version: 2` schemas. See the
+ [deprecation notice on our website](https://taskfile.dev/deprecations/version-2-schema)
+ (#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](https://taskfile.dev/experiments/any-variables/?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.Direct` became
+ `call.Indirect` (#1459 by @pd93).
+- Refactored the public `read` and `taskfile` packages and introduced
+ `taskfile/ast` (#1450 by @pd93).
+- `ast.IncludedTaskfiles` renamed to `ast.Includes` and `orderedmap` package
+ renamed to `omap` plus some internal refactor work (#1456 by @pd93).
+- Fix zsh completion script to allow lowercase `taskfile` file names (#1482 by
+ @xontab).
+- Improvements on how we check the Taskfile version (#1465 by @pd93).
+- Added a new `ROOT_TASKFILE` special variable (#1468, #1469 by @pd93).
+- Fix experiment flags in `.env` when the `--dir` or `--taskfile` flags were
+ used (#1478 by @pd93).
+
+## v3.33.1 - 2023-12-21
+
+- Added support for looping over map variables with the
+ [Any Variables experiment](https://taskfile.dev/experiments/any-variables)
+ 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](https://taskfile.dev/experiments/any-variables)
+ (#1415, #1421 by @pd93).
+- Updated Docusaurus to v3 (#1432 by @pd93).
+- Added `aliases` to `--json` flag output (#1430, #1431 by @pd93).
+- Added new `CLI_FORCE` special variable containing whether the `--force` or
+ `--force-all` flags were set (#1412, #1434 by @pd93).
+
+## v3.32.0 - 2023-11-29
+
+- Added ability to exclude some files from `sources:` by using `exclude:` (#225,
+ #1324 by @pd93 and @andreynering).
+- The
+ [Remote Taskfiles experiment](https://taskfile.dev/experiments/remote-taskfiles)
+ now prefers remote files over cached ones by default (#1317, #1345 by @pd93).
+- Added `--timeout` flag to the
+ [Remote Taskfiles experiment](https://taskfile.dev/experiments/remote-taskfiles)
+ (#1317, #1345 by @pd93).
+- Fix bug where dynamic `vars:` and `env:` were being executed when they should
+ actually be skipped by `platforms:` (#1273, #1377 by @andreynering).
+- Fix `schema.json` to make `silent` valid in `cmds` that use `for` (#1385,
+ #1386 by @iainvm).
+- Add new `--no-status` flag to skip expensive status checks when running
+ `task --list --json` (#1348, #1368 by @amancevice).
+
+## v3.31.0 - 2023-10-07
+
+- Enabled the `--yes` flag for the
+ [Remote Taskfiles experiment](https://taskfile.dev/experiments/remote-taskfiles)
+ (#1317, #1344 by @pd93).
+- Add ability to set `watch: true` in 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](https://taskfile.dev/api/#exit-codes) (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](https://taskfile.dev/experiments/remote-taskfiles)
+ as a draft (#1152, #1317 by @pd93).
+- Improve performance of content checksumming on `sources:` by replacing md5
+ with [XXH3](https://xxhash.com/) 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 `--watch` mode (#1285, #1297 by
+ @FilipSolich).
+- Fix `defer` on JSON Schema (#1288 by @calvinmclean and @andreynering).
+- Fix bug in usage of special variables like `{{.USER_WORKING_DIR}}` in
+ combination with `includes` (#1046, #1205, #1250, #1293, #1312, #1274 by
+ @andarto, #1309 by @andreynering).
+- Fix bug on `--status` flag. 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](https://taskfile.dev/usage/#looping-over-values)
+ using `for` (#82, #1220 by @pd93).
+- Fixed variable propagation in multi-level includes (#778, #996, #1256 by
+ @hudclark).
+- Fixed a bug where the `--exit-code` code flag was not returning the correct
+ exit code when calling commands indirectly (#1266, #1270 by @pd93).
+- Fixed a `nil` panic when a dependency was commented out or left empty (#1263
+ by @neomantra).
+
+## v3.27.1 - 2023-06-30
+
+- Fix panic when a `.env` directory (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`
+- Bug fixes were made to the
+ [npm installation method](https://taskfile.dev/installation/#npm). (#1190, by
+ @sounisi5011).
+- Added the
+ [gentle force experiment](https://taskfile.dev/experiments/gentle-force) as a
+ draft (#1200, #1216 by @pd93).
+- Added an `--experiments` flag 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 `.task` if the checksum has changed (#1185,
+ #1194 by @deviantintegral).
+- Added [experiments documentation](https://taskfile.dev/experiments) to the
+ website (#1198 by @pd93).
+- Deprecated `version: 2` schema. 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](https://taskfile.dev/usage/#warning-prompts)).
+- Added support for single command task syntax. With this change, it's now
+ possible to declare just `cmd:` in a task, avoiding the more complex
+ `cmds: []` 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 `version` is 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 `master` to `main` (#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](https://github.com/mvdan/gofumpt) linter (#1099 by @pd93)
+- Add `--sort` flag for use with `--list` and `--list-all` (#946, #1105 by
+ @pd93).
+- Task now has [custom exit codes](https://taskfile.dev/api/#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](https://marketplace.visualstudio.com/items?itemName=task.vscode-task)
+contributed by @pd93! :tada: The extension is maintained in a
+[new repository](https://github.com/go-task/vscode-task) 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](https://github.com/go-task/vscode-task/discussions),
+[issue](https://github.com/go-task/vscode-task/issues) or on our
+[Discord](https://discord.gg/6TY36E39UK)!
+
+> **NOTE:** The extension _requires_ v3.23.0 to be installed in order to work.
+
+- The website was integrated with
+ [Crowdin](https://crowdin.com/project/taskfile) to allow the community to
+ contribute with translations! [Chinese](https://taskfile.dev/zh-Hans/) is the
+ first language available (#1057, #1058 by @misitebao).
+- Added task location data to the `--json` flag output (#1056 by @pd93)
+- Change the name of the file generated by `task --init` from `Taskfile.yaml` to
+ `Taskfile.yml` (#1062 by @misitebao).
+- Added new `splitArgs` template 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
+ `$HOME` directory. This is useful to have automation that you can run from
+ anywhere in your system!
+ ([Documentation](https://taskfile.dev/usage/#running-a-global-taskfile), #1029
+ by @andreynering).
+- Add ability to set `error_only: true` on the `group` output 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/checksum` file was sometimes not being created when
+ task also declares a `status:` (#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_VERSION` special 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_COLOR` support 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`](https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html)
+ and
+ [`shopt`](https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html)
+ builtins (#908, #929 by @pd93,
+ [Documentation](http://taskfile.dev/usage/#set-and-shopt)).
+- Add new `platforms:` attribute to `task` and `cmd`, 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]` or
+ `platforms: [linux/amd64]`. Other platforms will be skipped (#978, #980 by
+ @leaanthony).
+
+## v3.19.1 - 2022-12-31
+
+- Small bug fix: closing `Taskfile.yml` once we're done reading it (#963, #964
+ by @HeCorr).
+- Fixes a bug in v2 that caused a panic when using a `Taskfile_{{OS}}.yml` file
+ (#961, #971 by @pd93).
+- Fixed a bug where watch intervals set in the Taskfile were not being respected
+ (#969, #970 by @pd93)
+- Add `--json` flag (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](https://pnpm.io/) as well
+ ([go-task/go-npm#2](https://github.com/go-task/go-npm/issues/2),
+ [go-task/go-npm#3](https://github.com/go-task/go-npm/pull/3)).
+- It's now possible to run Taskfiles from subdirectories! A new
+ `USER_WORKING_DIR` special variable was added to add even more flexibility for
+ monorepos (#289, #920).
+- Add task-level `dotenv` support (#389, #904).
+- It's now possible to use global level variables on `includes` (#942, #943).
+- The website got a brand new
+ [translation to Chinese](https://task-zh.readthedocs.io/zh_CN/latest/) by
+ [@DeronW](https://github.com/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-all` output (#806, #890).
+- It's now possible to call a `default` task in an included Taskfile by using
+ just the namespace. For example: `docs:default` is now automatically aliased
+ to `docs` (#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 `aliases` for 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=500ms` flag (#813, #865).
+- Add colored output to `--list`, `--list-all` and `--summary` flags (#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 `npm` as new installation method: `npm i -g @go-task/cli` (#870, #871,
+ [npm package](https://www.npmjs.com/package/@go-task/cli)).
+- Add support to marking tasks and includes as internal, which will hide them
+ from `--list` and `--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-all` with `--list` as
+ already possible on the Bash completion (#861).
+
+## v3.15.0 - 2022-09-03
+
+- Add new special variables `ROOT_DIR` and `TASKFILE_DIR`. This was a highly
+ requested feature (#215, #857,
+ [Documentation](https://taskfile.dev/api/#special-variables)).
+- 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 `.task` directory location with the
+ `TASK_TEMP_DIR` environment 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_MAGENTA` and `TASK_COLOR_RED` (#568, #792).
+- Fixed bug when using the `output: group` mode 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](https://github.com/mvdan/sh/issues/884),
+ [mvdan/sh#893](https://github.com/mvdan/sh/pull/893)).
+
+## v3.13.0 - 2022-06-13
+
+- Added `-n` as 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 `\r` because we were
+ only removing the final `\n` but not `\r\n` (#717).
+
+## v3.12.0 - 2022-03-31
+
+- The `--list` and `--list-all` flags 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](https://taskfile.dev/#/usage?id=vars-of-included-taskfiles)
+ 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](http://taskfile.dev/#/usage?id=output-syntax)
+ for more information (#647, #651).
+- Add `Taskfile.dist.yml` and `Taskfile.dist.yaml` to the supported file name
+ list.
+ [Check out the documentation](https://taskfile.dev/#/usage?id=supported-file-names)
+ 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 the `defer:` keyword
+ ([Documentation](https://taskfile.dev/#/usage?id=doing-task-cleanup-with-defer),
+ #475, #626).
+- Remove long deprecated and undocumented `$` variable prefix and `^` command
+ prefix (#642, #644, #645).
+- Add support for `.yaml` extension (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](https://github.com/mvdan/sh) which contains a fix a for a
+ important regression on Windows (#619,
+ [mvdan/sh#768](https://github.com/mvdan/sh/issues/768),
+ [mvdan/sh#769](https://github.com/mvdan/sh/pull/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](https://github.com/mvdan/sh) which contains two relevant
+ fixes:
+ - Fix quote of empty strings in `shellQuote` (#609,
+ [mvdan/sh#763](https://github.com/mvdan/sh/issues/763)).
+ - Fix issue of wrong environment variable being picked when there's another
+ very similar one (#586,
+ [mvdan/sh#745](https://github.com/mvdan/sh/pull/745)).
+- Install shell completions automatically when installing via Homebrew (#264,
+ #592,
+ [go-task/homebrew-tap#2](https://github.com/go-task/homebrew-tap/pull/2)).
+
+## v3.9.0 - 2021-10-02
+
+- A new `shellQuote` function was added to the template system
+ (`{{shellQuote "a string"}}`) to ensure a string is safe for use in shell
+ ([mvdan/sh#727](https://github.com/mvdan/sh/pull/727),
+ [mvdan/sh#737](https://github.com/mvdan/sh/pull/737),
+ [Documentation](https://pkg.go.dev/mvdan.cc/sh/v3@v3.4.0/syntax#Quote))
+- In this version [mvdan.cc/sh](https://github.com/mvdan/sh) was upgraded with
+ some small fixes and features
+ - The `read -p` flag is now supported (#314,
+ [mvdan/sh#551](https://github.com/mvdan/sh/issues/551),
+ [mvdan/sh#772](https://github.com/mvdan/sh/pull/722))
+ - The `pwd -P` and `pwd -L` flags are now supported (#553,
+ [mvdan/sh#724](https://github.com/mvdan/sh/issues/724),
+ [mvdan/sh#728](https://github.com/mvdan/sh/pull/728))
+ - The `$GID` environment variable is now correctly being set (#561,
+ [mvdan/sh#723](https://github.com/mvdan/sh/pull/723))
+
+## v3.8.0 - 2021-09-26
+
+- Add `interactive: true` setting to improve support for interactive CLI apps
+ (#217, #563).
+- Fix some `nil` errors (#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](https://github.com/go-task/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 are `always` (the default), `when_changed` (if a variable
+ modified the task) and `once` (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:` and `status:` 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_COLOR` environment variable. (#459,
+ [fatih/color#137](https://github.com/fatih/color/pull/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](https://json.schemastore.org/taskfile.json)
+ 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 special
+ `CLI_ARGS` variable (#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 `--list` and `--summary` by 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](https://github.com/go-task/slim-sprig) package was updated
+ with the upstream [sprig](https://github.com/Masterminds/sprig).
+
+## v3.2.0 - 2021-01-07
+
+- Fix the `.task` directory 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 `--watch` flag) 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
+ custom `label:` 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 -e` is 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 `.env` like 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 `expansions` on v3 since it has no effect.
+- `Taskvars.yml` is not automatically included anymore.
+- `Taskfile_{{OS}}.yml` is not automatically included anymore.
+- Allow interpolation on `includes`, so you can manually include a Taskfile
+ based on operation system, for example.
+- Expose `.TASK` variable 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 `timestamp` to `checksum` (#246).
+- New magic variables are now available when using `status:`: `.TIMESTAMP` which
+ contains the greatest modification date from the files listed in `sources:`,
+ and `.CHECKSUM`, which contains a checksum of all files listed in `status:`.
+ This is useful for manual checking when using external, or even remote,
+ artifacts when using `status:` (#216).
+- We're now using [slim-sprig](https://github.com/go-task/slim-sprig) instead of
+ [sprig](https://github.com/Masterminds/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 `--help` flag (#300, #330).
+- Print version to stdout instead of stderr (#299, #329).
+- Suppress `context` errors when using the `--watch` flag (#313, #317).
+- Support templating on description (#276, #283).
+
+## v2.8.0 - 2019-12-07
+
+- Add `--parallel` flag (alias `-p`) to run tasks given by the command line in
+ parallel (#266).
+- Fixed bug where calling the `task` CLI only informing global vars would not
+ execute the `default` task.
+- Add ability to silent all tasks by adding `silent: true` a the root of the
+ Taskfile.
+
+## v2.7.1 - 2019-11-10
+
+- Fix error being raised when `exit 0` was called (#251).
+
+## v2.7.0 - 2019-09-22
+
+- Fixed panic bug when assigning a global variable (#229, #243).
+- A task with `method: checksum` will 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 `--taskfile` flag (alias `-t`), which can be used to run another
+ Taskfile (other than the default `Taskfile.yml`) (#221).
+- It's now possible to install Task using Homebrew on Linux
+ ([go-task/homebrew-tap#1](https://github.com/go-task/homebrew-tap/pull/1)).
+
+## v2.5.2 - 2019-05-11
+
+- Reverted YAML upgrade due issues with CRLF on Windows (#201,
+ [go-yaml/yaml#450](https://github.com/go-yaml/yaml/issues/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](https://github.com/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](https://taskfile.dev/#/installation?id=install-script)
+ to use the new taskfile.dev domain on scripts from now on.
+- Fixed to the ZSH completion (#182).
+- Add
+ [`--summary` flag along with `summary:` task attribute](https://taskfile.org/#/usage?id=display-summary-of-task)
+ (#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 `output` option (#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](https://scoop.sh/) (#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](https://taskfile.org/#/usage?id=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.
+- Task now have a dedicated documentation site: https://taskfile.org
+ - Thanks to [Docsify](https://docsify.js.org/) for making this pretty easy. To
+ check the source code, just take a look at the
+ [docs](https://github.com/go-task/task/tree/main/docs) directory of this
+ repository. Contributions to the documentation is really appreciated.
+
+## v2.1.1 - 2018-09-17
+
+- Fix suggestion to use `task --init` not being shown anymore (when a
+ `Taskfile.yml` is not found)
+- Fix error when using checksum method and no file exists for a source glob
+ (#131)
+- Fix signal handling when the `--watch` flag is given (#132)
+
+## v2.1.0 - 2018-08-19
+
+- Add a `ignore_error` option to task and command (#123)
+- Add a dry run mode (`--dry` flag) (#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 `output` option. Please check out the
+ [documentation](https://github.com/go-task/task#output-syntax)
+
+## 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](https://github.com/go-task/task/blob/main/TASKFILE_VERSIONS.md)
+document, since it describes in depth what changed for this version.
+
+- New Taskfile version 2 (#77)
+- Possibility to have global variables in the `Taskfile.yml` instead of
+ `Taskvars.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 `set` keyword;
+- 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 of `VAR: $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 (`-v` flag)
+- 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 `--init` flag to create a new Taskfile
+- Add status option to prevent task from running (#27)
+- Allow interpolation on `generates` and `sources` attributes (#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, `cmd` is 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 `context` and `errgroup` packages (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)
+- `--force` or `-f` flag 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
+
+:::
\ No newline at end of file
diff --git a/website/src/next/docs/community.md b/website/src/next/docs/community.md
new file mode 100644
index 00000000..53beb7f2
--- /dev/null
+++ b/website/src/next/docs/community.md
@@ -0,0 +1,41 @@
+---
+title: Community
+description:
+ Task community contributions, installation methods, and integrations
+ maintained by third parties
+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](./integrations.md#community-integrations).
+
+## Installation methods
+
+Some installation methods are maintained by third party:
+
+- [Arch Linux](https://archlinux.org/packages/extra/x86_64/go-task/)
+- [AUR](https://aur.archlinux.org/packages/go-task-git) by @C0rn3j
+- [Scoop](https://github.com/ScoopInstaller/Main/blob/master/bucket/task.json)
+- [Fedora](https://packages.fedoraproject.org/pkgs/golang-github-task/go-task/)
+- [Nix](https://github.com/NixOS/nixpkgs/blob/master/pkgs/by-name/go/go-task/package.nix)
+- [Conda](https://github.com/conda-forge/go-task-feedstock/)
+
+## More
+
+Also, thanks for all the
+[code contributors](https://github.com/go-task/task/graphs/contributors),
+[financial contributors](https://opencollective.com/task), all those who
+[reported bugs](https://github.com/go-task/task/issues?q=is%3Aissue) and
+[answered questions](https://github.com/go-task/task/discussions).
+
+If you know something that is missing in this document, please submit a pull
+request.
diff --git a/website/src/next/docs/contributing.md b/website/src/next/docs/contributing.md
new file mode 100644
index 00000000..993f570b
--- /dev/null
+++ b/website/src/next/docs/contributing.md
@@ -0,0 +1,261 @@
+---
+title: Contributing
+description:
+ Comprehensive guide for contributing to the Task project, including setup,
+ development, testing, and submitting PRs
+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](https://discord.gg/6TY36E39UK) 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](https://github.com/go-task/task/contribute).
+
+::: info
+
+This document applies to the core [Task][task] repository _and_ [Task for Visual
+Studio Code][vscode-task].
+
+:::
+
+## 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][experiments]". If you're intending to work on an
+ experiment, then please read the [experiments workflow][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][mise].
+From the repository root, run:
+
+```shell
+mise install
+```
+
+This 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][go]. We always support the latest two major
+ Go versions, so make sure your version is recent enough.
+- **Node.js** - [Node.js][nodejs] 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][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 by [`golangci-lint`][golangci-lint]. This
+ wraps the [`gofumpt`][gofumpt] and [`gci`][gci] formatters and a number of
+ linters. We recommend that you take a look at the [golangci-lint
+ docs][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][prettier]. This style is enforced by our CI to ensure
+ that we have a consistent style across the project. You can use the
+ `task lint` command to lint the code locally and the `task lint:fix` command
+ to try to automatically fix any issues that are found. You can also use the
+ `task fmt` command 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](#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](#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 use
+`go run ./cmd/task --dir ./testdata/ `.
+
+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 run
+`task package` which will generate a `.vsix` file that can be used to manually
+install the extension.
+
+### Updating documentation
+
+Task uses [Vitepress][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).
+
+When making a change, consider whether a change to the [Usage
+Guide][usage-guide] is necessary. This document contains descriptions and
+examples of how to use Task features. If you're adding a new feature, try to
+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][styleguide].
+
+If you added a new command or flag, ensure that you add it to the [CLI
+Reference][cli-reference]. New fields also need to be added to the [Schema
+Reference][schema-reference] and [JSON Schema][json-schema]. The descriptions
+for fields in the docs and the schema should match.
+
+#### Documentation channels
+
+The docs and the blog exist in two copies, so that taskfile.dev never announces
+a feature that is not in the released binary yet:
+
+| Directory | Channel | Published on |
+| -------------------------------- | -------- | ----------------- |
+| `website/src/next/{docs,blog}` | `next` | next.taskfile.dev |
+| `website/src/latest/{docs,blog}` | `latest` | taskfile.dev |
+
+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, and
+`cmd/release` copies it over `website/src/latest` at every release. The same
+split applies to the JSON schemas: edit `next-schema.json` and
+`next-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 under
+`website/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][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][task-open-issues] or [Task for
+Visual Studio Code][vscode-task-open-issues]. We have a [good first
+issue][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](./community.md).
+
+> 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][discord-server] or open a [Discussion][discussion] on GitHub.
+
+---
+
+[task]: https://github.com/go-task/task
+[vscode-task]: https://github.com/go-task/vscode-task
+[go]: https://go.dev
+[gofumpt]: https://github.com/mvdan/gofumpt
+[gci]: https://github.com/daixiang0/gci
+[golangci-lint]: https://golangci-lint.run
+[golangci-lint-docs]: https://golangci-lint.run/welcome/integrations/
+[prettier]: https://prettier.io
+[nodejs]: https://nodejs.org/en/
+[pnpm]: https://pnpm.io/
+[mise]: https://mise.jdx.dev
+[vitepress]: https://vitepress.dev
+[json-schema]:
+ https://github.com/go-task/task/blob/main/website/src/public/schema.json
+[task-open-issues]: https://github.com/go-task/task/issues
+[vscode-task-open-issues]: https://github.com/go-task/vscode-task/issues
+[good-first-issue]:
+ https://github.com/go-task/task/issues?q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22
+[discord-server]: https://discord.gg/6TY36E39UK
+[discussion]: https://github.com/go-task/task/discussions
+[conventional-commits]: https://www.conventionalcommits.org
+[experiments]: ./experiments/
+[experiments-workflow]: ./experiments/#workflow
+[styleguide]: ./styleguide
+[cli-reference]: ./reference/cli
+[schema-reference]: ./reference/schema
+[usage-guide]: ./guide
diff --git a/website/src/next/docs/deprecations/completion-scripts.md b/website/src/next/docs/deprecations/completion-scripts.md
new file mode 100644
index 00000000..d1cfbbc8
--- /dev/null
+++ b/website/src/next/docs/deprecations/completion-scripts.md
@@ -0,0 +1,25 @@
+---
+title: 'Completion Scripts'
+description: Deprecation of direct completion scripts in Task’s Git directory
+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][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][completions] instead.
+
+[completions]: /docs/installation#setup-completions
+[task]: https://github.com/go-task/task
diff --git a/website/src/next/docs/deprecations/index.md b/website/src/next/docs/deprecations/index.md
new file mode 100644
index 00000000..d58ee2d3
--- /dev/null
+++ b/website/src/next/docs/deprecations/index.md
@@ -0,0 +1,22 @@
+---
+title: Deprecations
+description:
+ Guide to deprecated features in Task and how to migrate to the new
+ alternatives
+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.
diff --git a/website/src/next/docs/deprecations/template-functions.md b/website/src/next/docs/deprecations/template-functions.md
new file mode 100644
index 00000000..64374188
--- /dev/null
+++ b/website/src/next/docs/deprecations/template-functions.md
@@ -0,0 +1,27 @@
+---
+title: 'Template Functions'
+description:
+ Deprecation of some templating functions in Task, with guidance on their
+ replacements.
+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` |
diff --git a/website/src/next/docs/deprecations/template.md b/website/src/next/docs/deprecations/template.md
new file mode 100644
index 00000000..b02f6676
--- /dev/null
+++ b/website/src/next/docs/deprecations/template.md
@@ -0,0 +1,24 @@
+---
+# This is a template for deprecation documentation
+# Copy this page and fill in the details as necessary
+title: '--- Template ---'
+description: Template for documenting deprecated features in Task
+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}
diff --git a/website/src/next/docs/deprecations/version-2-schema.md b/website/src/next/docs/deprecations/version-2-schema.md
new file mode 100644
index 00000000..15be1dfc
--- /dev/null
+++ b/website/src/next/docs/deprecations/version-2-schema.md
@@ -0,0 +1,33 @@
+---
+title: 'Version 2 Schema (#1197)'
+description: Deprecation of Taskfile schema version 2 and migration to version 3
+outline: deep
+---
+
+# Version 2 Schema (#1197)
+
+::: danger
+
+This deprecation breaks the following functionality:
+
+- Any Taskfiles that use the version 2 schema
+- `Taskvar.yml` files
+
+:::
+
+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][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][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][v3.0.0].
+
+[v3.0.0]: https://github.com/go-task/task/releases/tag/v3.0.0
+[v3.33.0]: https://github.com/go-task/task/releases/tag/v3.33.0
+[deprecation-notice]: https://github.com/go-task/task/issues/1197
diff --git a/website/src/next/docs/experiments/env-precedence.md b/website/src/next/docs/experiments/env-precedence.md
new file mode 100644
index 00000000..5df9f3ca
--- /dev/null
+++ b/website/src/next/docs/experiments/env-precedence.md
@@ -0,0 +1,77 @@
+---
+title: 'Env Precedence (#1038)'
+description:
+ Experiment to change the precedence of environment variables in Task
+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](./index.md#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:
+
+```yml
+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"}}`.
+
+```yml
+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:
+
+```yml
+MY_ENV: '{{.MY_ENV | default "fallback"}}'
+```
diff --git a/website/src/next/docs/experiments/gentle-force.md b/website/src/next/docs/experiments/gentle-force.md
new file mode 100644
index 00000000..cd303106
--- /dev/null
+++ b/website/src/next/docs/experiments/gentle-force.md
@@ -0,0 +1,48 @@
+---
+title: 'Gentle Force (#1200)'
+description: Experiment to modify the behavior of the --force flag in Task
+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 `--force` flag
+
+:::
+
+::: info
+
+To enable this experiment, set the environment variable:
+`TASK_X_GENTLE_FORCE=1`. Check out
+[our guide to enabling experiments](./index.md#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!
diff --git a/website/src/docs/experiments/index.md b/website/src/next/docs/experiments/index.md
similarity index 100%
rename from website/src/docs/experiments/index.md
rename to website/src/next/docs/experiments/index.md
diff --git a/website/src/docs/experiments/remote-taskfiles.md b/website/src/next/docs/experiments/remote-taskfiles.md
similarity index 100%
rename from website/src/docs/experiments/remote-taskfiles.md
rename to website/src/next/docs/experiments/remote-taskfiles.md
diff --git a/website/src/next/docs/experiments/template.md b/website/src/next/docs/experiments/template.md
new file mode 100644
index 00000000..9df41586
--- /dev/null
+++ b/website/src/next/docs/experiments/template.md
@@ -0,0 +1,36 @@
+---
+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 ][enabling-experiments] for more
+information.
+
+:::
+
+\{Short description of the feature\}
+
+\{Short explanation of how users should migrate to the new behavior\}
+
+[enabling-experiments]: /docs/experiments/#enabling-experiments
diff --git a/website/src/next/docs/faq.md b/website/src/next/docs/faq.md
new file mode 100644
index 00000000..1efdbda7
--- /dev/null
+++ b/website/src/next/docs/faq.md
@@ -0,0 +1,135 @@
+---
+title: FAQ
+description:
+ Frequently asked questions about Task, including ETAs, shell limitations, and
+ Windows compatibility
+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](./contributing.md).
+
+## 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:
+
+```yaml
+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:
+
+```yaml
+version: '3'
+
+tasks:
+ foo:
+ cmds:
+ - a=foo
+ - echo $a
+ # outputs ""
+```
+
+To work around this you can either use a multiline command:
+
+```yaml
+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:
+
+```yaml
+version: '3'
+
+tasks:
+ foo:
+ cmds:
+ - ./foo-printer.bash
+```
+
+```shell
+#!/bin/bash
+a=foo
+echo $a
+```
+
+## Are 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`](/docs/reference/environment#task-core-utils)
+environment variable:
+
+```bash
+# 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:
+
+* `base64`
+* `cat`
+* `chmod`
+* `cp`
+* `find`
+* `gzip`
+* `ls`
+* `mkdir`
+* `mktemp`
+* `mv`
+* `rm`
+* `shasum`
+* `tar`
+* `touch`
+* `xargs`
+* (more might be added in the future)
diff --git a/website/src/next/docs/getting-started.md b/website/src/next/docs/getting-started.md
new file mode 100644
index 00000000..a6e8f7d9
--- /dev/null
+++ b/website/src/next/docs/getting-started.md
@@ -0,0 +1,135 @@
+---
+title: Getting Started
+description: Guide for getting started with Task
+outline: deep
+---
+
+# Getting Started
+
+The following guide will help introduce you to the basics of Task. We'll cover
+how to create a Taskfile, how to write a basic task and how to call it. If you
+haven't installed Task yet, head over to our [installation guide](installation).
+
+## Creating your first Taskfile
+
+Once Task is installed, you can create your first Taskfile by running:
+
+```shell
+task --init
+```
+
+This 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:
+
+```shell
+task --init ./subdirectory
+```
+
+Or if you want the Taskfile to have a specific name, you can pass in the name of
+the file:
+
+```shell
+task --init Custom.yml
+```
+
+This will create a Taskfile that looks something like this:
+
+```yaml [Taskfile.yml]
+version: '3'
+
+vars:
+ GREETING: Hello, World!
+
+tasks:
+ default:
+ desc: Print a greeting message
+ cmds:
+ - echo "{{.GREETING}}"
+ silent: true
+```
+
+As you can see, all Taskfiles are written in [YAML format](https://yaml.org/).
+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 the
+`GREETING` 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:
+
+```shell
+task default
+```
+
+Note that we don't have to specify the name of the Taskfile. Task will
+automatically look for a file called `Taskfile.yml` (or any of Task's
+[supported file names](/docs/guide#supported-file-names)) in the current
+directory. Additionally, tasks with the name `default` are special. They can
+also be run without specifying the task name.
+
+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:
+
+```shell
+task --dir ./subdirectory
+```
+
+Or 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:
+
+```shell
+task --taskfile Custom.yml
+```
+
+## Adding a build task
+
+Let's create a task to build a program in Go. Start by adding a new task called
+`build` below the existing `default` task. We can then add a `cmds` attribute
+with a single command to build the program.
+
+Task uses [mvdan/sh](https://github.com/mvdan/sh), a native Go sh interpreter.
+So you can write sh/bash-like commands - even in environments where `sh` or
+`bash` 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:
+
+```yaml
+version: '3'
+
+vars:
+ GREETING: Hello, World!
+
+tasks:
+ default:
+ desc: Print a greeting message
+ cmds:
+ - echo "{{.GREETING}}"
+ silent: true
+
+ build:
+ cmds:
+ - go build ./cmd/main.go
+```
+
+Call the task by running:
+
+```shell
+task build
+```
+
+That's about it for the basics, but there's _so much_ more that you can do with
+Task. Check out the rest of the documentation to learn more about all the
+features Task has to offer! We recommend taking a look at the
+[usage guide](/docs/guide) next. Alternatively, you can check out our reference
+docs for the [Taskfile schema](reference/schema) and [CLI](reference/cli).
diff --git a/website/src/docs/guide.md b/website/src/next/docs/guide.md
similarity index 100%
rename from website/src/docs/guide.md
rename to website/src/next/docs/guide.md
diff --git a/website/src/docs/installation.md b/website/src/next/docs/installation.md
similarity index 100%
rename from website/src/docs/installation.md
rename to website/src/next/docs/installation.md
diff --git a/website/src/next/docs/integrations.md b/website/src/next/docs/integrations.md
new file mode 100644
index 00000000..9d95151d
--- /dev/null
+++ b/website/src/next/docs/integrations.md
@@ -0,0 +1,126 @@
+---
+title: Integrations
+description:
+ Official and community integrations for Task, including VS Code, JSON schemas,
+ and other tools
+outline: deep
+---
+
+# Integrations
+
+## Visual Studio Code Extension
+
+Task has an
+[official extension for Visual Studio Code](https://marketplace.visualstudio.com/items?itemName=task.vscode-task).
+The code for this project can be found in
+[our GitHub repository](https://github.com/go-task/vscode-task). 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](#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](https://github.com/go-task/vscode-task/issues/56).
+
+
+
+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](https://gist.github.com/KROSF/c5435acf590acd632f71bb720f685895) and
+is now officially maintained in
+[this file](https://github.com/go-task/task/blob/main/website/src/public/schema.json)
+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](https://marketplace.visualstudio.com/items?itemName=redhat.vscode-yaml)
+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`:
+
+```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
+# yaml-language-server: $schema=https://taskfile.dev/schema.json
+version: '3'
+```
+
+You can find more information on this in the
+[YAML language server project](https://github.com/redhat-developer/yaml-language-server).
+
+## 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](https://github.com/okineadev/vitepress-plugin-llms).
+
+This integration provides:
+
+- Structured documentation in LLM-friendly formats
+- Context-optimized content for AI assistants
+- Automatic generation of `llms.txt` and `llms-full.txt` files
+- Enhanced discoverability of Task features for AI tools
+
+AI assistants can access Task documentation through:
+
+- **[llms.txt](https://taskfile.dev/llms.txt)**: Lightweight overview of Task documentation
+- **[llms-full.txt](https://taskfile.dev/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](https://packagecontrol.io/packages/Taskfile)
+ [[source](https://github.com/biozz/sublime-taskfile)] by @biozz
+- [IntelliJ Plugin](https://plugins.jetbrains.com/plugin/17058-taskfile)
+ [[source](https://github.com/lechuckroh/task-intellij-plugin)] by @lechuckroh
+- [Zed Extension](https://zed.dev/extensions/taskfile)
+ [[source](https://github.com/nickalie/zed-taskfile)] by @nickalie
+- [mk](https://github.com/pycontribs/mk) command line tool recognizes Taskfiles
+ natively.
+- [fzf-make](https://github.com/kyu08/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.
diff --git a/website/src/docs/reference/cli.md b/website/src/next/docs/reference/cli.md
similarity index 100%
rename from website/src/docs/reference/cli.md
rename to website/src/next/docs/reference/cli.md
diff --git a/website/src/docs/reference/config.md b/website/src/next/docs/reference/config.md
similarity index 100%
rename from website/src/docs/reference/config.md
rename to website/src/next/docs/reference/config.md
diff --git a/website/src/docs/reference/environment.md b/website/src/next/docs/reference/environment.md
similarity index 100%
rename from website/src/docs/reference/environment.md
rename to website/src/next/docs/reference/environment.md
diff --git a/website/src/next/docs/reference/package.md b/website/src/next/docs/reference/package.md
new file mode 100644
index 00000000..7f710124
--- /dev/null
+++ b/website/src/next/docs/reference/package.md
@@ -0,0 +1,181 @@
+---
+title: Package API Reference
+description: A reference for Task's Golang package API
+---
+
+# 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. A `Node` is an
+ interface that has several implementations:
+ - [`taskfile.FileNode`] - Local files
+ - [`taskfile.HTTPNode`] - Remote files via HTTP/HTTPS
+ - [`taskfile.GitNode`] - Remote files via Git
+ - [`taskfile.StdinNode`] - In-memory strings (via stdin)
+- [`taskfile.Reader`] - Accepts a `Node` and 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"][ast]. 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.
+ The `Taskfile` type contains all of the subtypes for the Taskfile syntax, such
+ as `tasks`, `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 the
+[`errors.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:
+
+```go
+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 the
+[`taskfile.FileNode`] type. You can create this by calling the
+[`taskfile.NewFileNode`] function:
+
+```go
+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:
+
+```go
+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:
+
+```go
+ctx := context.Background()
+tfg, err := reader.Read(ctx, node)
+// handle error
+```
+
+This 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:
+
+```go
+tf, err := tfg.Merge()
+// handle error
+```
+
+This 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.
+
+:::
+
+[`github.com/go-task/task/v3`]: https://pkg.go.dev/github.com/go-task/task/v3
+[`github.com/go-task/task/v3/taskfile`]:
+ https://pkg.go.dev/github.com/go-task/task/v3/taskfile
+[`github.com/go-task/task/v3/taskfile/ast`]:
+ https://pkg.go.dev/github.com/go-task/task/v3/taskfile/ast
+[`github.com/go-task/task/v3/errors`]:
+ https://pkg.go.dev/github.com/go-task/task/v3/errors
+[`ast.TaskfileGraph`]:
+ https://pkg.go.dev/github.com/go-task/task/v3/taskfile/ast#TaskfileGraph
+[`ast.Taskfile`]:
+ https://pkg.go.dev/github.com/go-task/task/v3/taskfile/ast#Taskfile
+[`taskfile.Node`]: https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Node
+[`taskfile.FileNode`]:
+ https://pkg.go.dev/github.com/go-task/task/v3/taskfile#FileNode
+[`taskfile.HTTPNode`]:
+ https://pkg.go.dev/github.com/go-task/task/v3/taskfile#HTTPNode
+[`taskfile.GitNode`]:
+ https://pkg.go.dev/github.com/go-task/task/v3/taskfile#GitNode
+[`taskfile.StdinNode`]:
+ https://pkg.go.dev/github.com/go-task/task/v3/taskfile#StdinNode
+[`taskfile.NewFileNode`]:
+ https://pkg.go.dev/github.com/go-task/task/v3/taskfile#NewFileNode
+[`taskfile.Reader`]:
+ https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Reader
+[`taskfile.NewReader`]:
+ https://pkg.go.dev/github.com/go-task/task/v3/taskfile#NewReader
+[`taskfile.Snippet`]:
+ https://pkg.go.dev/github.com/go-task/task/v3/taskfile#Snippet
+[`task.Executor`]: https://pkg.go.dev/github.com/go-task/task/v3#Executor
+[`task.Formatter`]: https://pkg.go.dev/github.com/go-task/task/v3#Formatter
+[`errors.TaskError`]:
+ https://pkg.go.dev/github.com/go-task/task/v3/errors#TaskError
+[`error`]: https://pkg.go.dev/builtin#error
+[ast]: https://en.wikipedia.org/wiki/Abstract_syntax_tree
diff --git a/website/src/docs/reference/schema.md b/website/src/next/docs/reference/schema.md
similarity index 100%
rename from website/src/docs/reference/schema.md
rename to website/src/next/docs/reference/schema.md
diff --git a/website/src/docs/reference/templating.md b/website/src/next/docs/reference/templating.md
similarity index 100%
rename from website/src/docs/reference/templating.md
rename to website/src/next/docs/reference/templating.md
diff --git a/website/src/next/docs/releasing.md b/website/src/next/docs/releasing.md
new file mode 100644
index 00000000..ac9452ff
--- /dev/null
+++ b/website/src/next/docs/releasing.md
@@ -0,0 +1,63 @@
+---
+title: Releasing
+description:
+ Task release process including GoReleaser, Homebrew, npm, Snapcraft, winget,
+ and other package managers
+outline: deep
+---
+
+# Releasing
+
+The release process of Task is done with the help of [GoReleaser][goreleaser].
+You can test the release process locally by calling the `goreleaser:test` task
+of the Taskfile.
+
+[GitHub Actions](https://github.com/go-task/task/actions) should release
+artifacts automatically when a new Git tag is pushed to `main` branch (raw
+executables and DEB and RPM packages).
+
+Raw executables can also be reproduced and verified locally by
+checking out a specific tag and calling `goreleaser build`, using the Go version
+defined in the above GitHub Actions.
+
+## Website
+
+`task release:` promotes the documentation before tagging: the docs in
+`website/src/next/docs`, their sidebar and the `next-*` JSON schemas are copied over
+their published counterparts, so the released tag carries the docs of the
+version it ships. The release workflow then runs `task website:deploy:prod`.
+
+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:
+
+```shell
+git checkout main && git pull
+task website:deploy:prod
+```
+
+## Package managers
+
+GoReleaser will automatically publish the release to most package managers:
+
+* Cloudsmith (DEB and RPM repositories)
+* Homebrew
+* npm
+* winget
+
+A single package manager still require manual steps:
+
+* Snapcraft:
+ * Update the `version:` field on [snapcraft.yaml][snapcraftyaml]
+ * Trigger a new build on [Snapcraft -> Builds][snapcraftbuilds]
+ * Once finished, move the new build to "stable" on [Snapcraft -> Releases][snapcraftreleases]
+
+These package managers are updated automatically by the community:
+
+* [Scoop](https://github.com/ScoopInstaller/Main/blob/master/bucket/task.json)
+* [Nix](https://github.com/NixOS/nixpkgs/blob/master/pkgs/by-name/go/go-task/package.nix)
+
+[goreleaser]: https://goreleaser.com/
+[snapcraftyaml]: https://github.com/go-task/snap/blob/main/snap/snapcraft.yaml#L2
+[snapcraftbuilds]: https://snapcraft.io/task/builds
+[snapcraftreleases]: https://snapcraft.io/task/releases
diff --git a/website/src/docs/remote-taskfiles.md b/website/src/next/docs/remote-taskfiles.md
similarity index 100%
rename from website/src/docs/remote-taskfiles.md
rename to website/src/next/docs/remote-taskfiles.md
diff --git a/website/src/next/docs/security/incident-response-plan.md b/website/src/next/docs/security/incident-response-plan.md
new file mode 100644
index 00000000..a1b35fae
--- /dev/null
+++ b/website/src/next/docs/security/incident-response-plan.md
@@ -0,0 +1,91 @@
+---
+title: Incident Response Plan
+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][security-docs].
+- 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.
+- Open a draft
+ [GitHub Security Advisory (GHSA)](https://github.com/go-task/task/security/advisories)
+ in the Task repository.
+ - Optionally create a CVE. This can be skipped for low/medium impact issues at
+ the discretion of the maintainers.
+
+### 🩹 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.
+- 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.
+
+[security-docs]: ../security/
diff --git a/website/src/next/docs/security/index.md b/website/src/next/docs/security/index.md
new file mode 100644
index 00000000..a80aef94
--- /dev/null
+++ b/website/src/next/docs/security/index.md
@@ -0,0 +1,22 @@
+---
+title: Security
+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][pvr] or send an email to
+[task@taskfile.dev](mailto:task@taskfile.dev). 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][irp] and [Threat Model][tm].
+
+[pvr]: https://github.com/go-task/task/security/advisories/new
+[irp]: ./incident-response-plan
+[tm]: ./threat-model
diff --git a/website/src/next/docs/security/threat-model.md b/website/src/next/docs/security/threat-model.md
new file mode 100644
index 00000000..7cd40ed2
--- /dev/null
+++ b/website/src/next/docs/security/threat-model.md
@@ -0,0 +1,174 @@
+---
+title: Threat Model
+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 `govulncheck` on 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 `--insecure` flag)
+- 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](https://taskfile.dev/)
+- [Incident Response Plan](./incident-response-plan)
+- [OWASP Top 10](https://owasp.org/www-project-top-ten/)
+- [Supply Chain Security](https://slsa.dev/)
+- [GitHub Security Best Practices](https://docs.github.com/en/code-security)
diff --git a/website/src/next/docs/styleguide.md b/website/src/next/docs/styleguide.md
new file mode 100644
index 00000000..f1061680
--- /dev/null
+++ b/website/src/next/docs/styleguide.md
@@ -0,0 +1,230 @@
+---
+title: Style Guide
+description:
+ Official style guide for Taskfile.yml files with best practices and
+ recommended conventions
+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
+
+```yaml
+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.
+
+```yaml
+# bad
+tasks:
+ foo:
+ cmds:
+ - echo 'foo'
+
+
+# good
+tasks:
+ foo:
+ cmds:
+ - echo 'foo'
+```
+
+## Separate the main sections with empty lines
+
+```yaml
+# 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
+
+```yaml
+# 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
+
+```yaml
+# 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
+
+```yaml
+# 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
+
+```yaml
+# 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
+
+```yaml
+# 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
+
+```yaml
+# 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.sh
+```
diff --git a/website/src/next/docs/taskfile-versions.md b/website/src/next/docs/taskfile-versions.md
new file mode 100644
index 00000000..44f90778
--- /dev/null
+++ b/website/src/next/docs/taskfile-versions.md
@@ -0,0 +1,83 @@
+---
+title: Taskfile Versions
+description:
+ How to use the Taskfile schema version to ensure users are using the correct
+ versions of Task
+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:
+
+```yaml
+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][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:
+
+```yaml
+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:
+
+```yaml
+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 to
+`v3.17.0` or greater.
+
+:::info
+
+Note that this functionality was introduced in
+[v3.34.0](https://github.com/go-task/task/releases/tag/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.
+
+[semver]: https://semver.org/
diff --git a/website/src/public/next-schema-taskrc.json b/website/src/public/next-schema-taskrc.json
new file mode 100644
index 00000000..d12f4460
--- /dev/null
+++ b/website/src/public/next-schema-taskrc.json
@@ -0,0 +1,94 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema",
+ "title": "Taskrc YAML Schema",
+ "description": "Schema for .taskrc files.",
+ "type": "object",
+ "properties": {
+ "experiments": {
+ "type": "object",
+ "properties": {
+ "ENV_PRECEDENCE": {
+ "type": "number",
+ "enum": [0, 1]
+ },
+ "GENTLE_FORCE": {
+ "type": "number",
+ "enum": [0, 1]
+ }
+ }
+ },
+ "remote": {
+ "type": "object",
+ "description": "Remote configuration settings",
+ "properties": {
+ "insecure": {
+ "type": "boolean",
+ "description": "Forces Task to download Taskfiles over insecure connections."
+ },
+ "offline": {
+ "type": "boolean",
+ "description": "Forces Task to only use local or cached Taskfiles."
+ },
+ "timeout": {
+ "type": "string",
+ "description": "Timeout for downloading remote Taskfiles (e.g., '30s', '5m')",
+ "pattern": "^[0-9]+(ns|us|µs|ms|s|m|h)$"
+ },
+ "cache-expiry": {
+ "type": "string",
+ "description": "Expiry duration for cached remote Taskfiles (e.g., '1h', '24h')",
+ "pattern": "^[0-9]+(ns|us|µs|ms|s|m|h)$"
+ },
+ "cache-dir": {
+ "type": "string",
+ "description": "Directory to cache remote Taskfiles"
+ },
+ "trusted-hosts": {
+ "type": "array",
+ "description": "List of trusted hosts for remote Taskfiles (e.g., 'github.com', 'gitlab.com', 'example.com:8080').",
+ "items": {
+ "type": "string"
+ }
+ }
+ },
+ "additionalProperties": false
+ },
+ "verbose": {
+ "type": "boolean",
+ "description": "Enable verbose output"
+ },
+ "silent": {
+ "type": "boolean",
+ "description": "Disables echoing",
+ "default": false
+ },
+ "color": {
+ "type": "boolean",
+ "description": "Enable colored output"
+ },
+ "disable-fuzzy": {
+ "type": "boolean",
+ "description": "Disable fuzzy matching for task names"
+ },
+ "concurrency": {
+ "type": "integer",
+ "description": "Number of concurrent tasks to run",
+ "minimum": 1
+ },
+ "failfast": {
+ "description": "When running tasks in parallel, stop all tasks if one fails.",
+ "type": "boolean",
+ "default": false
+ },
+ "interactive": {
+ "description": "Prompt for missing required variables instead of failing. Requires a TTY.",
+ "type": "boolean",
+ "default": false
+ },
+ "temp-dir": {
+ "type": "string",
+ "description": "Directory to store Task temporary files, such as checksums and temporary metadata. Relative paths are relative to the root Taskfile."
+ }
+ },
+ "additionalProperties": false
+}
diff --git a/website/src/public/next-schema.json b/website/src/public/next-schema.json
new file mode 100644
index 00000000..74ebfe9d
--- /dev/null
+++ b/website/src/public/next-schema.json
@@ -0,0 +1,920 @@
+{
+ "$schema": "http://json-schema.org/draft-07/schema#",
+ "title": "Taskfile YAML Schema",
+ "description": "Schema for Taskfile files.",
+ "definitions": {
+ "env": {
+ "$ref": "#/definitions/vars"
+ },
+ "platforms": {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "tasks": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "array",
+ "items": {
+ "oneOf": [
+ {
+ "type": "string"
+ },
+ {
+ "$ref": "#/definitions/task_call"
+ },
+ {
+ "$ref": "#/definitions/defer_task_call"
+ },
+ {
+ "$ref": "#/definitions/defer_cmd_call"
+ }
+ ]
+ }
+ },
+ {
+ "$ref": "#/definitions/task"
+ }
+ ]
+ }
+ }
+ },
+ "task": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "cmds": {
+ "description": "A list of commands to be executed.",
+ "$ref": "#/definitions/cmds"
+ },
+ "cmd": {
+ "description": "The command to be executed.",
+ "$ref": "#/definitions/cmd"
+ },
+ "deps": {
+ "description": "A list of dependencies of this task. Tasks defined here will run in parallel before this task.",
+ "$ref": "#/definitions/deps"
+ },
+ "label": {
+ "description": "Overrides the name of the task in the output when a task is run. Supports variables.",
+ "type": "string"
+ },
+ "desc": {
+ "description": "A short description of the task. This is displayed when calling `task --list`.",
+ "type": "string"
+ },
+ "prompt": {
+ "description": "One or more prompts that will be presented before a task is run. Declining will cancel running the current and any subsequent tasks.",
+ "oneOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ ]
+ },
+ "summary": {
+ "description": "A longer description of the task. This is displayed when calling `task --summary [task]`.",
+ "type": "string"
+ },
+ "aliases": {
+ "description": "A list of alternative names by which the task can be called.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "sources": {
+ "description": "A list of sources to check before running this task. Relevant for `checksum` and `timestamp` methods. Can be file paths or star globs.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/glob"
+ }
+ },
+ "generates": {
+ "description": "A list of files meant to be generated by this task. Relevant for `timestamp` method. Can be file paths or star globs.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/glob"
+ }
+ },
+ "status": {
+ "description": "A list of commands to check if this task should run. The task is skipped otherwise. This overrides `method`, `sources` and `generates`.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "preconditions": {
+ "description": "A list of commands to check if this task should run. If a condition is not met, the task will error.",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/precondition"
+ }
+ },
+ "dir": {
+ "description": "The directory in which this task should run. Defaults to the current working directory.",
+ "type": "string"
+ },
+ "set": {
+ "description": "Enables POSIX shell options for all of a task's commands. See https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/set"
+ }
+ },
+ "shopt": {
+ "description": "Enables Bash shell options for all of a task's commands. See https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/shopt"
+ }
+ },
+ "vars": {
+ "description": "A set of variables that can be used in the task.",
+ "$ref": "#/definitions/vars"
+ },
+ "env": {
+ "description": "A set of environment variables that will be made available to shell commands.",
+ "$ref": "#/definitions/env"
+ },
+ "dotenv": {
+ "description": "A list of `.env` file paths to be parsed.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "silent": {
+ "description": "Hides task name and command from output. The command's output will still be redirected to `STDOUT` and `STDERR`. When combined with the `--list` flag, task descriptions will be hidden.",
+ "type": "boolean",
+ "default": false
+ },
+ "interactive": {
+ "description": "Tells task that the command is interactive.",
+ "type": "boolean",
+ "default": false
+ },
+ "internal": {
+ "description": "Stops a task from being callable on the command line. It will also be omitted from the output when used with `--list`.",
+ "type": "boolean",
+ "default": false
+ },
+ "method": {
+ "description": "Defines which method is used to check the task is up-to-date. `timestamp` will compare the timestamp of the sources and generates files. `checksum` will check the checksum (You probably want to ignore the .task folder in your .gitignore file). `none` skips any validation and always run the task.",
+ "type": "string",
+ "enum": ["none", "checksum", "timestamp"],
+ "default": "none"
+ },
+ "use_gitignore": {
+ "description": "When set to true, files matching .gitignore rules will be excluded from sources and generates glob resolution. Overrides the global gitignore setting.",
+ "type": "boolean",
+ "default": false
+ },
+ "prefix": {
+ "description": "Defines a string to prefix the output of tasks running in parallel. Only used when the output mode is `prefixed`.",
+ "type": "string"
+ },
+ "ignore_error": {
+ "description": "Continue execution if errors happen while executing commands.",
+ "type": "boolean"
+ },
+ "run": {
+ "description": "Specifies whether the task should run again or not if called more than once. Available options: `always`, `once` and `when_changed`.",
+ "$ref": "#/definitions/run"
+ },
+ "platforms": {
+ "description": "Specifies which platforms the task should be run on.",
+ "$ref": "#/definitions/platforms"
+ },
+ "if": {
+ "description": "A shell command to evaluate. If the exit code is non-zero, the task is skipped.",
+ "type": "string"
+ },
+ "requires": {
+ "description": "A list of variables which should be set if this task is to run, if any of these variables are unset the task will error and not run",
+ "$ref": "#/definitions/requires_obj"
+ },
+ "watch": {
+ "description": "Configures a task to run in watch mode automatically.",
+ "type": "boolean",
+ "default": false
+ },
+ "failfast": {
+ "description": "When running tasks in parallel, stop all tasks if one fails.",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ },
+ "cmds": {
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/cmd"
+ }
+ },
+ "cmd": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "$ref": "#/definitions/cmd_call"
+ },
+ {
+ "$ref": "#/definitions/task_call"
+ },
+ {
+ "$ref": "#/definitions/defer_task_call"
+ },
+ {
+ "$ref": "#/definitions/defer_cmd_call"
+ },
+ {
+ "$ref": "#/definitions/for_cmd_call"
+ },
+ {
+ "$ref": "#/definitions/for_task_call"
+ }
+ ]
+ },
+ "deps": {
+ "type": "array",
+ "items": {
+ "oneOf": [
+ {
+ "type": "string"
+ },
+ {
+ "$ref": "#/definitions/task_call"
+ },
+ {
+ "$ref": "#/definitions/for_deps_call"
+ }
+ ]
+ }
+ },
+ "set": {
+ "type": "string",
+ "enum": [
+ "allexport",
+ "a",
+ "errexit",
+ "e",
+ "noexec",
+ "n",
+ "noglob",
+ "f",
+ "nounset",
+ "u",
+ "xtrace",
+ "x",
+ "pipefail"
+ ]
+ },
+ "shopt": {
+ "type": "string",
+ "enum": ["expand_aliases", "globstar", "nullglob"]
+ },
+ "vars": {
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "anyOf": [
+ {
+ "type": [
+ "boolean",
+ "integer",
+ "null",
+ "number",
+ "string",
+ "array"
+ ]
+ },
+ {
+ "$ref": "#/definitions/var_subkey"
+ }
+ ]
+ }
+ }
+ },
+ "var_subkey": {
+ "type": "object",
+ "properties": {
+ "sh": {
+ "type": "string",
+ "description": "The value will be treated as a command and the output assigned to the variable"
+ },
+ "ref": {
+ "type": "string",
+ "description": "The value will be used to lookup the value of another variable which will then be assigned to this variable"
+ },
+ "map": {
+ "type": "object",
+ "description": "The value will be treated as a literal map type and stored in the variable"
+ },
+ "value": {
+ "description": "A literal value assigned to the variable. Useful together with other keys such as 'secret'"
+ },
+ "secret": {
+ "type": "boolean",
+ "description": "Marks the variable as secret. Secret values will be masked as ***** in command logs to prevent accidental exposure of sensitive information."
+ }
+ },
+ "additionalProperties": false
+ },
+ "task_call": {
+ "type": "object",
+ "properties": {
+ "task": {
+ "description": "Name of the task to run",
+ "type": "string"
+ },
+ "vars": {
+ "description": "Values passed to the task called",
+ "$ref": "#/definitions/vars"
+ },
+ "silent": {
+ "description": "Hides task name and command from output. The command's output will still be redirected to `STDOUT` and `STDERR`.",
+ "type": "boolean"
+ },
+ "ignore_error": {
+ "description": "Prevent the command from aborting the execution of the task when it exits with a non-zero status code",
+ "type": "boolean"
+ },
+ "if": {
+ "description": "A shell command to evaluate. If the exit code is non-zero, the command is skipped.",
+ "type": "string"
+ },
+ "timeout": {
+ "description": "Maximum duration the command is allowed to run before being terminated. Supports Go duration syntax (e.g., '5m', '30s', '1h').",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["task"]
+ },
+ "cmd_call": {
+ "type": "object",
+ "properties": {
+ "cmd": {
+ "description": "Command to run",
+ "type": "string"
+ },
+ "silent": {
+ "description": "Silent mode disables echoing of command before Task runs it",
+ "type": "boolean"
+ },
+ "set": {
+ "description": "Enables POSIX shell options for this command. See https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/set"
+ }
+ },
+ "shopt": {
+ "description": "Enables Bash shell options for this command. See https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/shopt"
+ }
+ },
+ "ignore_error": {
+ "description": "Prevent the command from aborting the execution of the task when it exits with a non-zero status code",
+ "type": "boolean"
+ },
+ "platforms": {
+ "description": "Specifies which platforms the command should be run on.",
+ "$ref": "#/definitions/platforms"
+ },
+ "if": {
+ "description": "A shell command to evaluate. If the exit code is non-zero, the command is skipped.",
+ "type": "string"
+ },
+ "timeout": {
+ "description": "Maximum duration the command is allowed to run before being terminated. Supports Go duration syntax (e.g., '5m', '30s', '1h').",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["cmd"]
+ },
+ "deferred_task_call": {
+ "type": "object",
+ "properties": {
+ "task": {
+ "description": "Name of the task to run",
+ "type": "string"
+ },
+ "vars": {
+ "description": "Values passed to the task called",
+ "$ref": "#/definitions/vars"
+ },
+ "silent": {
+ "description": "Hides task name and command from output. The command's output will still be redirected to `STDOUT` and `STDERR`.",
+ "type": "boolean"
+ },
+ "if": {
+ "description": "A shell command to evaluate. If the exit code is non-zero, the command is skipped.",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["task"]
+ },
+ "defer_task_call": {
+ "type": "object",
+ "properties": {
+ "defer": {
+ "description": "Run a command when the task completes. This command will run even when the task fails",
+ "anyOf": [
+ {
+ "$ref": "#/definitions/deferred_task_call"
+ }
+ ]
+ },
+ "timeout": {
+ "description": "Maximum duration the command is allowed to run before being terminated. Supports Go duration syntax (e.g., '5m', '30s', '1h').",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["defer"]
+ },
+ "defer_cmd_call": {
+ "type": "object",
+ "properties": {
+ "defer": {
+ "description": "Name of the command to defer",
+ "type": "string"
+ },
+ "silent": {
+ "description": "Hides task name and command from output. The command's output will still be redirected to `STDOUT` and `STDERR`.",
+ "type": "boolean"
+ },
+ "timeout": {
+ "description": "Maximum duration the command is allowed to run before being terminated. Supports Go duration syntax (e.g., '5m', '30s', '1h').",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["defer"]
+ },
+ "for_cmd_call": {
+ "type": "object",
+ "properties": {
+ "for": {
+ "$ref": "#/definitions/for"
+ },
+ "cmd": {
+ "description": "Command to run",
+ "type": "string"
+ },
+ "silent": {
+ "description": "Silent mode disables echoing of command before Task runs it",
+ "type": "boolean"
+ },
+ "set": {
+ "description": "Enables POSIX shell options for this command. See https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/set"
+ }
+ },
+ "shopt": {
+ "description": "Enables Bash shell options for this command. See https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/shopt"
+ }
+ },
+ "ignore_error": {
+ "description": "Prevent the command from aborting the execution of the task when it exits with a non-zero status code",
+ "type": "boolean"
+ },
+ "platforms": {
+ "description": "Specifies which platforms the command should be run on.",
+ "$ref": "#/definitions/platforms"
+ },
+ "if": {
+ "description": "A shell command to evaluate. If the exit code is non-zero, the command is skipped.",
+ "type": "string"
+ },
+ "timeout": {
+ "description": "Maximum duration the command is allowed to run before being terminated. Supports Go duration syntax (e.g., '5m', '30s', '1h').",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["for", "cmd"]
+ },
+ "for_task_call": {
+ "type": "object",
+ "properties": {
+ "for": {
+ "$ref": "#/definitions/for"
+ },
+ "task": {
+ "description": "Task to run",
+ "type": "string"
+ },
+ "vars": {
+ "description": "Values passed to the task called",
+ "$ref": "#/definitions/vars"
+ },
+ "silent": {
+ "description": "Silent mode disables echoing of command before Task runs it",
+ "type": "boolean"
+ },
+ "ignore_error": {
+ "description": "Prevent the command from aborting the execution of the task when it exits with a non-zero status code",
+ "type": "boolean"
+ },
+ "platforms": {
+ "description": "Specifies which platforms the command should be run on.",
+ "$ref": "#/definitions/platforms"
+ },
+ "if": {
+ "description": "A shell command to evaluate. If the exit code is non-zero, the command is skipped.",
+ "type": "string"
+ },
+ "timeout": {
+ "description": "Maximum duration the command is allowed to run before being terminated. Supports Go duration syntax (e.g., '5m', '30s', '1h').",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["for", "task"]
+ },
+ "for_deps_call": {
+ "type": "object",
+ "properties": {
+ "for": {
+ "$ref": "#/definitions/for"
+ },
+ "silent": {
+ "description": "Silent mode disables echoing of command before Task runs it",
+ "type": "boolean"
+ },
+ "task": {
+ "description": "Task to run",
+ "type": "string"
+ },
+ "vars": {
+ "description": "Values passed to the task called",
+ "$ref": "#/definitions/vars"
+ },
+ "timeout": {
+ "description": "Maximum duration the command is allowed to run before being terminated. Supports Go duration syntax (e.g., '5m', '30s', '1h').",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["for", "task"]
+ },
+ "for": {
+ "anyOf": [
+ {
+ "$ref": "#/definitions/for_list"
+ },
+ {
+ "$ref": "#/definitions/for_attribute"
+ },
+ {
+ "$ref": "#/definitions/for_var"
+ },
+ {
+ "$ref": "#/definitions/for_matrix"
+ }
+ ]
+ },
+ "for_list": {
+ "description": "A list of values to iterate over",
+ "type": "array",
+ "items": {
+ "type": ["string", "number"]
+ }
+ },
+ "for_attribute": {
+ "description": "The task attribute to iterate over",
+ "type": "string",
+ "enum": ["sources", "generates"]
+ },
+ "for_var": {
+ "description": "Which variables to iterate over. The variable will be split using any whitespace character by default. This can be changed by using the `split` attribute.",
+ "type": "object",
+ "properties": {
+ "var": {
+ "description": "Name of the variable to iterate over",
+ "type": "string"
+ },
+ "split": {
+ "description": "String to split the variable on",
+ "type": "string"
+ },
+ "as": {
+ "description": "What the loop variable should be named",
+ "default": "ITEM",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["var"]
+ },
+ "for_matrix": {
+ "description": "A matrix of values to iterate over",
+ "type": "object",
+ "additionalProperties": true,
+ "required": ["matrix"]
+ },
+ "precondition": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "$ref": "#/definitions/precondition_obj"
+ }
+ ]
+ },
+ "precondition_obj": {
+ "type": "object",
+ "properties": {
+ "sh": {
+ "description": "Command to run. If that command returns 1, the condition will fail",
+ "type": "string"
+ },
+ "msg": {
+ "description": "Failure message to display when the condition fails",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "glob": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "$ref": "#/definitions/glob_obj"
+ }
+ ]
+ },
+ "glob_obj": {
+ "type": "object",
+ "properties": {
+ "exclude": {
+ "description": "File or glob pattern to exclude from the list",
+ "type": "string"
+ }
+ },
+ "additionalProperties": false
+ },
+ "run": {
+ "type": "string",
+ "enum": ["always", "once", "when_changed"]
+ },
+ "outputString": {
+ "type": "string",
+ "enum": ["interleaved", "prefixed", "group"],
+ "default": "interleaved"
+ },
+ "outputObject": {
+ "type": "object",
+ "properties": {
+ "group": {
+ "type": "object",
+ "properties": {
+ "begin": {
+ "type": "string"
+ },
+ "end": {
+ "type": "string"
+ },
+ "error_only": {
+ "description": "Swallows command output on zero exit code",
+ "type": "boolean",
+ "default": false
+ }
+ }
+ }
+ },
+ "additionalProperties": false
+ },
+ "requires_obj": {
+ "type": "object",
+ "properties": {
+ "vars": {
+ "description": "List of variables that must be defined for the task to run",
+ "type": "array",
+ "items": {
+ "oneOf": [
+ { "type": "string" },
+ {
+ "type": "object",
+ "properties": {
+ "name": { "type": "string" },
+ "enum": {
+ "oneOf": [
+ { "type": "array", "items": { "type": "string" } },
+ {
+ "type": "object",
+ "properties": {
+ "ref": { "type": "string" }
+ },
+ "required": ["ref"],
+ "additionalProperties": false
+ }
+ ]
+ }
+ },
+ "required": ["name"],
+ "additionalProperties": false
+ }
+ ]
+ }
+ }
+ },
+ "additionalProperties": false
+ }
+ },
+ "allOf": [
+ {
+ "type": "object",
+ "properties": {
+ "version": {
+ "description": "Specify the Taskfile format that this file conforms to.",
+ "oneOf": [
+ {
+ "type": "string",
+ "pattern": "^(0|[1-9]\\d*)(?:\\.(0|[1-9]\\d*))?(?:\\.(0|[1-9]\\d*))?(?:-((?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\\.(?:0|[1-9]\\d*|\\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\\+([0-9a-zA-Z-]+(?:\\.[0-9a-zA-Z-]+)*))?$"
+ },
+ {
+ "type": "number",
+ "enum": [3]
+ }
+ ]
+ },
+ "output": {
+ "description": "Defines how the STDOUT and STDERR are printed when running tasks in parallel. The interleaved output prints lines in real time (default). The group output will print the entire output of a command once, after it finishes, so you won't have live feedback for commands that take a long time to run. The prefix output will prefix every line printed by a command with [task-name] as the prefix, but you can customize the prefix for a command with the prefix: attribute.",
+ "anyOf": [
+ { "$ref": "#/definitions/outputString" },
+ { "$ref": "#/definitions/outputObject" }
+ ]
+ },
+ "method": {
+ "description": "Defines which method is used to check the task is up-to-date. (default: checksum)",
+ "type": "string",
+ "enum": ["none", "checksum", "timestamp"],
+ "default": "checksum"
+ },
+ "use_gitignore": {
+ "description": "When set to true, files matching .gitignore rules will be excluded from sources and generates glob resolution for all tasks. Can be overridden per task.",
+ "type": "boolean",
+ "default": false
+ },
+ "includes": {
+ "description": "Imports tasks from the specified taskfiles. The tasks described in the given Taskfiles will be available with the informed namespace.",
+ "type": "object",
+ "patternProperties": {
+ "^.*$": {
+ "anyOf": [
+ {
+ "type": "string"
+ },
+ {
+ "type": "object",
+ "properties": {
+ "taskfile": {
+ "description": "The path for the Taskfile or directory to be included. If a directory, Task will look for files named `Taskfile.yml` or `Taskfile.yaml` inside that directory. If a relative path, resolved relative to the directory containing the including Taskfile.",
+ "type": "string",
+ "minLength": 1
+ },
+ "dir": {
+ "description": "The working directory of the included tasks when run.",
+ "type": "string",
+ "minLength": 1
+ },
+ "optional": {
+ "description": "If `true`, no errors will be thrown if the specified file does not exist.",
+ "type": "boolean"
+ },
+ "flatten": {
+ "description": "If `true`, the tasks from the included Taskfile will be available in the including Taskfile without a namespace. If a task with the same name already exists in the including Taskfile, an error will be thrown.",
+ "type": "boolean"
+ },
+ "internal": {
+ "description": "Stops any task in the included Taskfile from being callable on the command line. These commands will also be omitted from the output when used with `--list`.",
+ "type": "boolean"
+ },
+ "aliases": {
+ "description": "Alternative names for the namespace of the included Taskfile.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "excludes": {
+ "description": "A list of task names or namespace patterns ending in `:*` to be excluded from inclusion.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ },
+ "vars": {
+ "description": "A set of variables to apply to the included Taskfile.",
+ "$ref": "#/definitions/vars"
+ },
+ "checksum": {
+ "description": "The checksum of the file you expect to include. If the checksum does not match, the file will not be included.",
+ "type": "string"
+ }
+ },
+ "anyOf": [
+ {
+ "required": ["taskfile"]
+ },
+ {
+ "required": ["dir"]
+ }
+ ]
+ }
+ ]
+ }
+ }
+ },
+ "vars": {
+ "description": "A set of global variables.",
+ "$ref": "#/definitions/vars"
+ },
+ "env": {
+ "description": "A set of global environment variables.",
+ "$ref": "#/definitions/env"
+ },
+ "tasks": {
+ "description": "A set of task definitions.",
+ "$ref": "#/definitions/tasks"
+ },
+ "silent": {
+ "description": "Default 'silent' options for this Taskfile. If `false`, can be overridden with `true` in a task by task basis.",
+ "type": "boolean"
+ },
+ "set": {
+ "description": "Enables POSIX shell options for all commands in the Taskfile. See https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/set"
+ }
+ },
+ "shopt": {
+ "description": "Enables Bash shell options for all commands in the Taskfile. See https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html",
+ "type": "array",
+ "items": {
+ "$ref": "#/definitions/shopt"
+ }
+ },
+ "dotenv": {
+ "type": "array",
+ "description": "A list of `.env` file paths to be parsed.",
+ "items": {
+ "type": "string"
+ }
+ },
+ "run": {
+ "description": "Default 'run' option for this Taskfile. Available options: `always`, `once` and `when_changed`.",
+ "$ref": "#/definitions/run"
+ },
+ "interval": {
+ "description": "Sets a different watch interval when using `--watch`, the default being 100 milliseconds. This string should be a valid Go duration: https://pkg.go.dev/time#ParseDuration.",
+ "type": "string",
+ "pattern": "^[0-9]+(?:m|s|ms)$"
+ }
+ },
+ "additionalProperties": false,
+ "required": ["version"],
+ "anyOf": [
+ {
+ "required": ["includes"]
+ },
+ {
+ "required": ["tasks"]
+ },
+ {
+ "required": ["includes", "tasks"]
+ }
+ ]
+ }
+ ]
+}
diff --git a/website/src/public/schema-taskrc.json b/website/src/public/schema-taskrc.json
index d12f4460..f25cb5dc 100644
--- a/website/src/public/schema-taskrc.json
+++ b/website/src/public/schema-taskrc.json
@@ -11,6 +11,10 @@
"type": "number",
"enum": [0, 1]
},
+ "REMOTE_TASKFILES": {
+ "type": "number",
+ "enum": [0, 1]
+ },
"GENTLE_FORCE": {
"type": "number",
"enum": [0, 1]
diff --git a/website/src/public/schema.json b/website/src/public/schema.json
index 74ebfe9d..df0637b7 100644
--- a/website/src/public/schema.json
+++ b/website/src/public/schema.json
@@ -349,17 +349,9 @@
"description": "Hides task name and command from output. The command's output will still be redirected to `STDOUT` and `STDERR`.",
"type": "boolean"
},
- "ignore_error": {
- "description": "Prevent the command from aborting the execution of the task when it exits with a non-zero status code",
- "type": "boolean"
- },
"if": {
"description": "A shell command to evaluate. If the exit code is non-zero, the command is skipped.",
"type": "string"
- },
- "timeout": {
- "description": "Maximum duration the command is allowed to run before being terminated. Supports Go duration syntax (e.g., '5m', '30s', '1h').",
- "type": "string"
}
},
"additionalProperties": false,
@@ -391,7 +383,7 @@
}
},
"ignore_error": {
- "description": "Prevent the command from aborting the execution of the task when it exits with a non-zero status code",
+ "description": "Prevent command from aborting the execution of task even after receiving a status code of 1",
"type": "boolean"
},
"platforms": {
@@ -401,38 +393,11 @@
"if": {
"description": "A shell command to evaluate. If the exit code is non-zero, the command is skipped.",
"type": "string"
- },
- "timeout": {
- "description": "Maximum duration the command is allowed to run before being terminated. Supports Go duration syntax (e.g., '5m', '30s', '1h').",
- "type": "string"
}
},
"additionalProperties": false,
"required": ["cmd"]
},
- "deferred_task_call": {
- "type": "object",
- "properties": {
- "task": {
- "description": "Name of the task to run",
- "type": "string"
- },
- "vars": {
- "description": "Values passed to the task called",
- "$ref": "#/definitions/vars"
- },
- "silent": {
- "description": "Hides task name and command from output. The command's output will still be redirected to `STDOUT` and `STDERR`.",
- "type": "boolean"
- },
- "if": {
- "description": "A shell command to evaluate. If the exit code is non-zero, the command is skipped.",
- "type": "string"
- }
- },
- "additionalProperties": false,
- "required": ["task"]
- },
"defer_task_call": {
"type": "object",
"properties": {
@@ -440,13 +405,9 @@
"description": "Run a command when the task completes. This command will run even when the task fails",
"anyOf": [
{
- "$ref": "#/definitions/deferred_task_call"
+ "$ref": "#/definitions/task_call"
}
]
- },
- "timeout": {
- "description": "Maximum duration the command is allowed to run before being terminated. Supports Go duration syntax (e.g., '5m', '30s', '1h').",
- "type": "string"
}
},
"additionalProperties": false,
@@ -462,10 +423,6 @@
"silent": {
"description": "Hides task name and command from output. The command's output will still be redirected to `STDOUT` and `STDERR`.",
"type": "boolean"
- },
- "timeout": {
- "description": "Maximum duration the command is allowed to run before being terminated. Supports Go duration syntax (e.g., '5m', '30s', '1h').",
- "type": "string"
}
},
"additionalProperties": false,
@@ -485,35 +442,9 @@
"description": "Silent mode disables echoing of command before Task runs it",
"type": "boolean"
},
- "set": {
- "description": "Enables POSIX shell options for this command. See https://www.gnu.org/software/bash/manual/html_node/The-Set-Builtin.html",
- "type": "array",
- "items": {
- "$ref": "#/definitions/set"
- }
- },
- "shopt": {
- "description": "Enables Bash shell options for this command. See https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html",
- "type": "array",
- "items": {
- "$ref": "#/definitions/shopt"
- }
- },
- "ignore_error": {
- "description": "Prevent the command from aborting the execution of the task when it exits with a non-zero status code",
- "type": "boolean"
- },
"platforms": {
"description": "Specifies which platforms the command should be run on.",
"$ref": "#/definitions/platforms"
- },
- "if": {
- "description": "A shell command to evaluate. If the exit code is non-zero, the command is skipped.",
- "type": "string"
- },
- "timeout": {
- "description": "Maximum duration the command is allowed to run before being terminated. Supports Go duration syntax (e.g., '5m', '30s', '1h').",
- "type": "string"
}
},
"additionalProperties": false,
@@ -537,10 +468,6 @@
"description": "Silent mode disables echoing of command before Task runs it",
"type": "boolean"
},
- "ignore_error": {
- "description": "Prevent the command from aborting the execution of the task when it exits with a non-zero status code",
- "type": "boolean"
- },
"platforms": {
"description": "Specifies which platforms the command should be run on.",
"$ref": "#/definitions/platforms"
@@ -548,10 +475,6 @@
"if": {
"description": "A shell command to evaluate. If the exit code is non-zero, the command is skipped.",
"type": "string"
- },
- "timeout": {
- "description": "Maximum duration the command is allowed to run before being terminated. Supports Go duration syntax (e.g., '5m', '30s', '1h').",
- "type": "string"
}
},
"additionalProperties": false,
@@ -574,10 +497,6 @@
"vars": {
"description": "Values passed to the task called",
"$ref": "#/definitions/vars"
- },
- "timeout": {
- "description": "Maximum duration the command is allowed to run before being terminated. Supports Go duration syntax (e.g., '5m', '30s', '1h').",
- "type": "string"
}
},
"additionalProperties": false,
@@ -827,7 +746,7 @@
}
},
"excludes": {
- "description": "A list of task names or namespace patterns ending in `:*` to be excluded from inclusion.",
+ "description": "A list of tasks to be excluded from inclusion.",
"type": "array",
"items": {
"type": "string"
]