{{ description }}
+
diff --git a/website/.vitepress/config.ts b/website/.vitepress/config.ts
index 066b18ea76..16b1ac1b90 100644
--- a/website/.vitepress/config.ts
+++ b/website/.vitepress/config.ts
@@ -1,7 +1,8 @@
import { defineConfig, HeadConfig } from 'vitepress';
import githubLinksPlugin from './plugins/github-links';
-import { readFileSync } from 'fs';
+import { readdirSync, readFileSync } from 'fs';
import { resolve } from 'path';
+import matter from 'gray-matter';
import { tabsMarkdownPlugin } from 'vitepress-plugin-tabs';
import {
groupIconMdPlugin,
@@ -19,6 +20,39 @@ const version = readFileSync(
'utf8'
).trim();
+// Builds the "/blog/" sidebar from each blog post's frontmatter.
+function buildBlogSidebar() {
+ const blogDir = resolve(__dirname, '../src/blog');
+ const posts = readdirSync(blogDir)
+ .filter((file) => file.endsWith('.md') && file !== 'index.md')
+ .map((file) => {
+ const { data: frontmatter } = matter(
+ readFileSync(resolve(blogDir, file), 'utf8')
+ );
+ return {
+ slug: file.replace(/\.md$/, ''),
+ title: frontmatter.sidebarTitle ?? frontmatter.title,
+ date: new Date(frontmatter.date)
+ };
+ })
+ .sort((a, b) => b.date.getTime() - a.date.getTime());
+
+ const byYear = new Map();
+ for (const post of posts) {
+ const year = post.date.getFullYear();
+ if (!byYear.has(year)) byYear.set(year, []);
+ byYear.get(year)!.push({ text: post.title, link: `/blog/${post.slug}` });
+ }
+
+ return [...byYear.entries()]
+ .sort((a, b) => b[0] - a[0])
+ .map(([year, items]) => ({
+ text: String(year),
+ collapsed: false,
+ items
+ }));
+}
+
const urlVersion =
process.env.NODE_ENV === 'development'
? {
@@ -311,56 +345,7 @@ export default defineConfig({
],
sidebar: {
- '/blog/': [
- {
- text: '2026',
- collapsed: false,
- items: [
- {
- text: 'GitHub SOSF',
- link: '/blog/github-secure-open-source-program'
- },
- {
- text: 'Using `go tool task`',
- link: '/blog/go-tool-task'
- },
- {
- text: 'Conditionals Statements',
- link: '/blog/if-and-variable-prompt'
- }
- ]
- },
- {
- text: '2025',
- collapsed: false,
- items: [
- {
- text: 'Built-in Core Utilities',
- link: '/blog/windows-core-utils'
- }
- ]
- },
- {
- text: '2024',
- collapsed: false,
- items: [
- {
- text: 'Any Variables',
- link: '/blog/any-variables'
- }
- ]
- },
- {
- text: '2023',
- collapsed: false,
- items: [
- {
- text: 'Introducing Experiments',
- link: '/blog/task-in-2023'
- }
- ]
- }
- ],
+ '/blog/': buildBlogSidebar(),
'/': [
{
text: 'Installation',
diff --git a/website/package.json b/website/package.json
index 739c78ce85..79e812c20f 100644
--- a/website/package.json
+++ b/website/package.json
@@ -15,6 +15,7 @@
"devDependencies": {
"@types/markdown-it": "^14.1.2",
"@types/node": "^24.1.0",
+ "gray-matter": "^4.0.3",
"netlify-cli": "^27.0.0",
"prettier": "^3.6.2",
"vitepress": "^1.6.3",
diff --git a/website/pnpm-lock.yaml b/website/pnpm-lock.yaml
index 07760f098a..dc69646726 100644
--- a/website/pnpm-lock.yaml
+++ b/website/pnpm-lock.yaml
@@ -14,6 +14,9 @@ importers:
'@types/node':
specifier: ^24.1.0
version: 24.13.3
+ gray-matter:
+ specifier: ^4.0.3
+ version: 4.0.3
netlify-cli:
specifier: ^27.0.0
version: 27.1.1(@parcel/watcher@2.5.6)(@types/node@24.13.3)(picomatch@4.0.5)(rollup@4.46.2)(supports-color@10.2.2)
@@ -1720,6 +1723,9 @@ packages:
arg@4.1.3:
resolution: {integrity: sha512-58S9QDqG0Xx27YwPSt9fJxivjYl432YCwfDMfZ+71RAqUrZef7LrKQZ3LHLOwCS4FLNBplP533Zx895SeOCHvA==}
+ argparse@1.0.10:
+ resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==}
+
argparse@2.0.1:
resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
@@ -2833,6 +2839,10 @@ packages:
graceful-fs@4.2.11:
resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
+ gray-matter@4.0.3:
+ resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==}
+ engines: {node: '>=6.0'}
+
h3@1.15.11:
resolution: {integrity: sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg==}
@@ -3255,6 +3265,10 @@ packages:
js-tokens@4.0.0:
resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
+ js-yaml@3.15.1:
+ resolution: {integrity: sha512-S99WuO3HlhO3XN41EtYUNl9zzXjoJx7QvmipxsJVxtCBT0YHEFy+iOJhjSvrmV12nYhWpZaM8lPHkJm0yUMbag==}
+ hasBin: true
+
js-yaml@4.3.1:
resolution: {integrity: sha512-CY6crGq313MX8GkwvB7tzgp99vjQxY1++5y10/BKN/GUfHqWaOGQMNZkBvqSzsZKWk/ijwHlWzzkLulsGHhjWQ==}
hasBin: true
@@ -3648,11 +3662,6 @@ packages:
nan@2.28.0:
resolution: {integrity: sha512-fTsDz99OTq2sVePhGdp4qQhggZFtKr64ZNVyVajRKtMOkJxYekplBh577PiJB12v/D3s2E5cGtOI45LWp6rnLQ==}
- nanoid@3.3.16:
- resolution: {integrity: sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==}
- engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
- hasBin: true
-
nanoid@3.3.18:
resolution: {integrity: sha512-DTg4MJbGMWkfi6VZFdNt2/caMbQy4Ou+Op/hJQvGEWcnVfoA1QA+xzRKAzw9jD6+GVOOeYr/mIcuDSdug6F6+w==}
engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
@@ -4029,10 +4038,6 @@ packages:
peerDependencies:
postcss: ^8.2.9
- postcss@8.5.22:
- resolution: {integrity: sha512-KBDEIpLrvpv16pp3K0Fw+UCoZfopFjjgeB+0tA/aaThfEE74kKDLrgg603YvOWJyg3+WYtyq3xYsQWsIyZlPqQ==}
- engines: {node: ^10 || ^12 || >=14}
-
postcss@8.5.26:
resolution: {integrity: sha512-u82N74LFzG8ca+dD8puPnplTXoGH4fTPpVGuIbt36G3qvNlkvfD0lEAZSxaly3KX8TS/L1A1gsCEmvKmBcVbkQ==}
engines: {node: ^10 || ^12 || >=14}
@@ -4500,6 +4505,9 @@ packages:
resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
engines: {node: '>= 10.x'}
+ sprintf-js@1.0.3:
+ resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
+
stack-generator@2.0.10:
resolution: {integrity: sha512-mwnua/hkqM6pF4k8SnmZ2zfETsRUpWXREfA/goT8SLCV4iOFa4bzOX2nDipWAZFPTjLvQB82f5yaodMVhK0yJQ==}
@@ -4572,6 +4580,10 @@ packages:
resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==}
engines: {node: '>=12'}
+ strip-bom-string@1.0.0:
+ resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==}
+ engines: {node: '>=0.10.0'}
+
strip-final-newline@2.0.0:
resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==}
engines: {node: '>=6'}
@@ -6996,6 +7008,10 @@ snapshots:
arg@4.1.3: {}
+ argparse@1.0.10:
+ dependencies:
+ sprintf-js: 1.0.3
+
argparse@2.0.1: {}
array-buffer-byte-length@1.0.2:
@@ -8216,6 +8232,13 @@ snapshots:
graceful-fs@4.2.11: {}
+ gray-matter@4.0.3:
+ dependencies:
+ js-yaml: 3.15.1
+ kind-of: 6.0.3
+ section-matter: 1.0.0
+ strip-bom-string: 1.0.0
+
h3@1.15.11:
dependencies:
cookie-es: 1.2.3
@@ -8660,6 +8683,11 @@ snapshots:
js-tokens@4.0.0: {}
+ js-yaml@3.15.1:
+ dependencies:
+ argparse: 1.0.10
+ esprima: 4.0.1
+
js-yaml@4.3.1:
dependencies:
argparse: 2.0.1
@@ -9157,8 +9185,6 @@ snapshots:
nan@2.28.0:
optional: true
- nanoid@3.3.16: {}
-
nanoid@3.3.18: {}
nanospinner@1.2.2:
@@ -9659,12 +9685,6 @@ snapshots:
postcss: 8.5.26
quote-unquote: 1.0.0
- postcss@8.5.22:
- dependencies:
- nanoid: 3.3.16
- picocolors: 1.1.1
- source-map-js: 1.2.1
-
postcss@8.5.26:
dependencies:
nanoid: 3.3.18
@@ -10250,6 +10270,8 @@ snapshots:
split2@4.2.0: {}
+ sprintf-js@1.0.3: {}
+
stack-generator@2.0.10:
dependencies:
stackframe: 1.3.4
@@ -10346,6 +10368,8 @@ snapshots:
dependencies:
ansi-regex: 6.2.2
+ strip-bom-string@1.0.0: {}
+
strip-final-newline@2.0.0: {}
strip-final-newline@3.0.0: {}
@@ -10703,7 +10727,7 @@ snapshots:
vite@5.4.21(@types/node@24.13.3):
dependencies:
esbuild: 0.21.5
- postcss: 8.5.22
+ postcss: 8.5.26
rollup: 4.46.2
optionalDependencies:
'@types/node': 24.13.3
diff --git a/website/src/blog/any-variables.md b/website/src/blog/any-variables.md
index 30cff63c17..66c51dde19 100644
--- a/website/src/blog/any-variables.md
+++ b/website/src/blog/any-variables.md
@@ -1,7 +1,11 @@
---
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
---
@@ -17,6 +21,8 @@ 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
diff --git a/website/src/blog/github-secure-open-source-program.md b/website/src/blog/github-secure-open-source-program.md
index 7d9a419f30..f80950de7c 100644
--- a/website/src/blog/github-secure-open-source-program.md
+++ b/website/src/blog/github-secure-open-source-program.md
@@ -1,9 +1,11 @@
---
title: GitHub Secure Open Source Fund
+sidebarTitle: GitHub SOSF
description:
- Task participated in the session 4 of the GitHub Secure Open Source program.
+ 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
---
@@ -18,6 +20,8 @@ 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
@@ -50,4 +54,5 @@ GitHub wrote a blog post about session 4 that [you can read here][ghblog].
[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/
+[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/blog/go-tool-task.md b/website/src/blog/go-tool-task.md
index fc913b7bcd..417927966b 100644
--- a/website/src/blog/go-tool-task.md
+++ b/website/src/blog/go-tool-task.md
@@ -1,8 +1,9 @@
---
-title: go tool task
+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
---
@@ -16,6 +17,8 @@ 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
diff --git a/website/src/blog/if-and-variable-prompt.md b/website/src/blog/if-and-variable-prompt.md
index f48a6ca907..2beed7ce1e 100644
--- a/website/src/blog/if-and-variable-prompt.md
+++ b/website/src/blog/if-and-variable-prompt.md
@@ -1,8 +1,10 @@
---
-title: New `if:` Control and Variable Prompt
+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
---
@@ -14,6 +16,8 @@ editLink: false
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
diff --git a/website/src/blog/index.md b/website/src/blog/index.md
index 68ea7ef45e..540d7e88d4 100644
--- a/website/src/blog/index.md
+++ b/website/src/blog/index.md
@@ -4,56 +4,17 @@ description: Latest news and updates from the Task team
editLink: false
---
-
-
-
-
-
-
-
-
-
+
diff --git a/website/src/blog/task-in-2023.md b/website/src/blog/task-in-2023.md
index 34546156f1..813e425718 100644
--- a/website/src/blog/task-in-2023.md
+++ b/website/src/blog/task-in-2023.md
@@ -3,7 +3,8 @@ 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: 2024-05-09
+date: 2023-09-02
+tags: ['roadmap', 'experiments', 'community']
outline: deep
editLink: false
---
@@ -19,6 +20,8 @@ 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
diff --git a/website/src/blog/windows-core-utils.md b/website/src/blog/windows-core-utils.md
index a4ca92185d..3650bb3657 100644
--- a/website/src/blog/windows-core-utils.md
+++ b/website/src/blog/windows-core-utils.md
@@ -1,8 +1,10 @@
---
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
---
@@ -16,6 +18,8 @@ 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