|
| 1 | +--- |
| 2 | +title: "psake 5.0.0 Is Here: Declarative Tasks, Caching, and Structured Output" |
| 3 | +description: "psake 5.0.0 is a major leap forward for PowerShell build automation—bringing declarative task syntax, compile-time validation, file-based caching, structured output, and CI-native integrations." |
| 4 | +date: 2026-04-15T12:00:00.000Z |
| 5 | +slug: psake-5-0-0-released |
| 6 | +authors: |
| 7 | + - heyitsgilbert |
| 8 | +tags: |
| 9 | + - release |
| 10 | + - announcement |
| 11 | + - psake |
| 12 | + - powershell |
| 13 | + - build-automation |
| 14 | + - ci-cd |
| 15 | +keywords: |
| 16 | + - psake |
| 17 | + - psake 5.0 |
| 18 | + - PowerShell build automation |
| 19 | + - declarative tasks |
| 20 | + - task caching |
| 21 | + - structured output |
| 22 | + - GitHub Actions |
| 23 | + - build system |
| 24 | +image: /img/social-card.png |
| 25 | +draft: false |
| 26 | +fmContentType: blog |
| 27 | +title_meta: "psake 5.0.0 Released" |
| 28 | +--- |
| 29 | + |
| 30 | +After years of steady iteration on the v4 line, we're thrilled to announce the release of **psake 5.0.0**—the biggest update to the PowerShell build automation framework since its inception. This release introduces a declarative task syntax, two-phase compilation, local file-based caching, structured output, and first-class CI integration. Here's everything that's new. |
| 31 | + |
| 32 | +<!-- truncate --> |
| 33 | + |
| 34 | +## Declarative Task Syntax |
| 35 | + |
| 36 | +The flagship feature of psake 5 is a new hashtable-based syntax for defining tasks. Rather than relying on positional parameters, you can now describe tasks as structured data with named, validated keys: |
| 37 | + |
| 38 | +```powershell |
| 39 | +Task 'Build' @{ |
| 40 | + DependsOn = 'Clean' |
| 41 | + Action = { dotnet build -c $Configuration } |
| 42 | +} |
| 43 | +``` |
| 44 | + |
| 45 | +Every key is validated at compile time—typos like `DependsOn` or `Action` are caught before a single task runs. The original parameter-based syntax still works, so your existing build scripts don't need to change. |
| 46 | + |
| 47 | +## Two-Phase Compilation |
| 48 | + |
| 49 | +psake 5 separates build file loading from task execution. When you call `Invoke-psake`, the dependency graph is built first via a topological sort, and circular dependencies are caught at **compile time** rather than halfway through a run. This means faster, clearer feedback—and no more builds that silently fail mid-execution. |
| 50 | + |
| 51 | +You can also use the new `-CompileOnly` parameter to inspect the build plan without running anything: |
| 52 | + |
| 53 | +```powershell |
| 54 | +Invoke-psake -CompileOnly |
| 55 | +``` |
| 56 | + |
| 57 | +This is especially useful in code review and CI pre-flight checks. |
| 58 | + |
| 59 | +## Local File-Based Caching |
| 60 | + |
| 61 | +For tasks that process files—compilation, transpilation, packaging—psake 5 introduces content-addressed caching. Declare `Inputs` and `Outputs` on a task, and psake will SHA256-hash the inputs to determine whether the task actually needs to run: |
| 62 | + |
| 63 | +```powershell |
| 64 | +Task 'Build' @{ |
| 65 | + Inputs = 'src/**/*.cs', 'src/**/*.csproj' |
| 66 | + Outputs = 'bin/**/*.dll' |
| 67 | + Action = { dotnet build -c $Configuration } |
| 68 | +} |
| 69 | +``` |
| 70 | + |
| 71 | +Cache state is stored in `.psake/cache/`. If nothing changed, the task is skipped and the build report marks it as **Cached**. To bypass caching for a single run, pass `-NoCache`: |
| 72 | + |
| 73 | +```powershell |
| 74 | +Invoke-psake -NoCache |
| 75 | +``` |
| 76 | + |
| 77 | +And to clear the cache entirely, use the new `Clear-PsakeCache` function. |
| 78 | + |
| 79 | +## Structured Build Results |
| 80 | + |
| 81 | +`Invoke-psake` now returns a `PsakeBuildResult` object containing per-task metrics, success status, duration, and error information. Scripting against build output no longer requires parsing console text: |
| 82 | + |
| 83 | +```powershell |
| 84 | +$result = Invoke-psake |
| 85 | +$result.Tasks | Where-Object Cached | Select-Object Name, Duration |
| 86 | +``` |
| 87 | + |
| 88 | +The `$psake.build_success` variable is still set after every run, so existing CI scripts that check build status continue to work without modification. |
| 89 | + |
| 90 | +## CI-Native Output Formats |
| 91 | + |
| 92 | +Building for GitHub Actions? Pass `-OutputFormat GitHubActions` and psake will emit workflow annotations—warnings and errors that surface directly in pull request diffs. For pipelines that consume build data programmatically, `-OutputFormat JSON` outputs the full `PsakeBuildResult` as structured JSON. |
| 93 | + |
| 94 | +The output format can also be set via the `PSAKE_OUTPUT_FORMAT` environment variable, making it easy to configure in CI without changing your build scripts. |
| 95 | + |
| 96 | +## Quiet Mode |
| 97 | + |
| 98 | +The new `-Quiet` parameter suppresses all console output while still returning the full `PsakeBuildResult` object—including complete error records for any failed tasks. No output is swallowed; it's simply not printed. |
| 99 | + |
| 100 | +This is particularly valuable when psake is invoked by an LLM agent or AI coding tool. Console build logs are noisy: progress messages, separator lines, and timing output all burn through context that the model could spend on the actual problem. With `-Quiet`, the agent gets silence on stdout and a precise, structured result it can inspect programmatically: |
| 101 | + |
| 102 | +```powershell |
| 103 | +$result = Invoke-psake -Quiet |
| 104 | +if (-not $result.Success) { |
| 105 | + # Full error records are available—no log scraping needed |
| 106 | + $result.Tasks | Where-Object { $_.Error } | ForEach-Object { |
| 107 | + Write-Host "Task '$($_.Name)' failed: $($_.Error.Message)" |
| 108 | + } |
| 109 | +} |
| 110 | +``` |
| 111 | + |
| 112 | +Rather than parsing wall-of-text build output, the agent can check `$result.Success`, iterate `$result.Tasks`, and read `$_.Error` directly—structured data that maps cleanly to a tool call response. Pair this with `-OutputFormat JSON` if you need to pass the result across a process boundary or into a prompt. |
| 113 | + |
| 114 | +## New Testing APIs |
| 115 | + |
| 116 | +Two new functions let you inspect and test your build scripts without running a full build: |
| 117 | + |
| 118 | +- **`Get-PsakeBuildPlan`** — Returns the full execution plan for a build file without running it. Inspect task order, dependencies, and caching configuration in tests. |
| 119 | +- **`Test-PsakeTask`** — Executes a single named task with custom variable overrides. Great for unit-testing individual task logic in isolation. |
| 120 | + |
| 121 | +## Version Declaration |
| 122 | + |
| 123 | +Build files can now declare the minimum psake major version they require: |
| 124 | + |
| 125 | +```powershell |
| 126 | +Version 5 |
| 127 | +``` |
| 128 | + |
| 129 | +If someone runs your build script on an older psake installation, they get a clear error instead of a confusing failure deep inside a task. |
| 130 | + |
| 131 | +## Hashtable Properties |
| 132 | + |
| 133 | +The `Properties` block gains a more concise hashtable syntax alongside the original scriptblock form: |
| 134 | + |
| 135 | +```powershell |
| 136 | +Properties @{ |
| 137 | + Configuration = 'Release' |
| 138 | + OutputDir = './artifacts' |
| 139 | +} |
| 140 | +``` |
| 141 | + |
| 142 | +Both styles are supported and can be mixed within the same build file. |
| 143 | + |
| 144 | +## `NO_COLOR` Support |
| 145 | + |
| 146 | +psake 5 respects the `$env:NO_COLOR` convention for suppressing colored output. Set it in environments where ANSI escape codes cause issues—terminals without color support, log aggregators, or accessibility tools. |
| 147 | + |
| 148 | +## Breaking Changes |
| 149 | + |
| 150 | +psake 5 is a major version, and it includes a few breaking changes. Most build scripts will work without modification, but there are three things to check: |
| 151 | + |
| 152 | +1. **Rename `default.ps1` to `psakefile.ps1`** — The `default.ps1` fallback file name is no longer auto-detected. |
| 153 | +2. **Replace the wrapper scripts** — `psake.ps1` and `psake.cmd` are removed. Use `Import-Module psake; Invoke-psake` instead. |
| 154 | +3. **Update Framework calls** — .NET Framework versions below 4.0 are no longer supported, and the default is now 4.7.2. The `$framework` global variable is removed; use `Framework '4.7.2'` instead. |
| 155 | + |
| 156 | +Additionally, the minimum required PowerShell version is now **5.1** (raised from 3.0), and the output handler configuration properties have been removed in favor of the new `-OutputFormat` and `-Quiet` parameters. |
| 157 | + |
| 158 | +Full details are in the [migration guide](https://github.com/psake/psake/blob/master/docs/migration-v4-to-v5.md). |
| 159 | + |
| 160 | +## Upgrading |
| 161 | + |
| 162 | +```powershell |
| 163 | +# Install from the PowerShell Gallery |
| 164 | +Install-Module -Name psake -MinimumVersion 5.0.0 -Force |
| 165 | +
|
| 166 | +# Verify the version |
| 167 | +Get-Module psake -ListAvailable | Select-Object Version |
| 168 | +``` |
| 169 | + |
| 170 | +Then run your existing build to check for any breaking changes. For most projects, it'll just work. |
| 171 | + |
| 172 | +--- |
| 173 | + |
| 174 | +psake 5 is the result of years of community feedback, and we're excited to see what you build with it. If you run into anything unexpected, [open an issue](https://github.com/psake/psake/issues). And if you're using the new features in interesting ways, we'd love to hear about it. |
0 commit comments