Skip to content

Decide: raise the consumer psake floor to 5.x before 1.0.0 #166

Description

@tablackburn

Part of #120 (Phase 3 — API improvements). Follow-up to #155 / #161 / #162.

Question

Before 1.0.0 ships: should RequiredModules in PowerShellBuild.psd1 raise the psake floor
from 4.9.0 to 5.0.4, or stay at 4.9.0?

#162 moved this repository's own build toolchain to psake 5.0.4 and deliberately left the
consumer floor at 4.9.0. That split was the right call for the toolchain change, but it
leaves the module supporting two psake majors indefinitely, and 1.0.0 is the cheapest moment
to change a floor — the hard-cut-plus-migration-guide strategy is already locked in for this
release.

Decision recorded so far: keeping 4.9.0 for now (@tablackburn, 2026-08-22). This ticket
is to assess it properly rather than let the status quo win by default.

Framing that matters

RequiredModules = @{ModuleName = 'psake'; ModuleVersion = '4.9.0'} declares a minimum,
not a pin. Consumers already on psake 5.x satisfy it today. So this is not "can consumers use
psake 5" — they can. Raising the floor is a decision to stop supporting psake 4.x.

Assess

For raising to 5.0.4

  • One supported psake major means PowerShellBuild/psakeFile.ps1 only has to be correct
    against one task-runner API, and the test matrix only has to prove it against one
  • psake 5 surfaces failures that 4.9.x silently absorbed. The break-escape found in psake 5.x spike: assess breakage under psake 5.0.4 (clean bump, no extras) #155 is
    the concrete example: under psake 4 a break escaping a Pester BeforeAll was swallowed,
    under psake 5 it fails the build. A consumer on psake 4 has build failures that do not fail
    their build
  • A floor raised at 1.0.0 costs one migration-guide entry; raised at 1.1.0 it costs a major

For staying at 4.9.0

  • Nothing in the shipped tasks needs psake 5 — the module works under both today
  • Consumers pin psake in CI. Excluding 4.9.x forces a coordinated upgrade on people whose
    builds are working fine
  • psake 4.9.1 is what most installs have; the adoption curve for 5.x is young
  • The floor can be raised later in a major without ever having claimed support it did not have

Facts to gather before deciding

  1. psake 5.0.4's own support floor — its PowerShellVersion and CompatiblePSEditions.
    PowerShellBuild committed to Windows PowerShell 5.1 (Desktop) in [Tracking] PowerShellBuild v1.0.0 roadmap #120. If psake 5 does not
    support Desktop edition, raising the floor contradicts a decision already made and the
    assessment ends there
  2. What psake 4 → 5 changes for a consumer's own psakeFile, not just for ours — the
    migration notes reviewed during psake 5.x spike: assess breakage under psake 5.0.4 (clean bump, no extras) #155 are the starting point
  3. Whether PowerShellBuild/psakeFile.ps1 has any version-conditional behavior today, or
    whether supporting both majors is currently free
  4. PSGallery adoption signal for psake 5.x versus 4.9.x, as a rough proxy for how much
    real-world breakage a raised floor causes

Done when

The decision is recorded here with its rationale, and:

  • If raising — a ticket exists for the manifest change plus a migration-guide entry, and it is
    sequenced before the 1.0.0 release
  • If keeping — the migration guide says so explicitly, so consumers on psake 4.x know it is a
    supported configuration rather than an oversight

Out of scope

Activity

  1. added this to the v1.0.0 milestone on Aug 22, 2026
  2. tablackburn commented on Aug 26, 2026

    @tablackburn
    ContributorAuthor

    Facts gathered (2026-08-26)

    The four facts this issue asked for, plus two things it did not anticipate. The decision itself
    is still open — this is the evidence, not the answer.

    1. psake 5.0.4's support floor — no contradiction; the gate opens

    PowerShellVersion    = 5.1
    CompatiblePSEditions = Core, Desktop

    psake 4.9.1 declares PowerShellVersion = '3.0' and no CompatiblePSEditions at all. psake's own
    changelog for 5.0.0 records "Minimum PowerShell version raised to 5.1 (was 3.0)".

    5.0.4 declares exactly the floor PowerShellBuild.psd1 already declares. The assessment does
    not end here, and nothing in #120 blocks a raise. Empirically confirmed too: requirements.psd1
    has pinned 5.0.4 since #162, and the shared CI workflow runs the suite on the real Windows
    PowerShell 5.1 Desktop engine on every push.

    2. What psake 4 → 5 changes for a consumer's psakeFile

    psake's own migration guide opens with "Most v4 build scripts work in v5 without changes." Seven
    breaking changes exist; most miss this audience:

    Change Hits a PowerShellBuild consumer?
    default.ps1 no longer auto-detected Maybe — PowerShellBuild's documented convention is already psakeFile.ps1
    psake.ps1 / psake.cmd runners removed Maybe — the documented pattern is a build.ps1 wrapper calling Invoke-psake
    Invoke-psake now returns a PsakeBuildResult Maybe — only if their wrapper assigns or pipes the result. $psake.build_success is retained
    OutputHandler / ColoredOutput config removed Rare — only consumers who customized psake output
    .NET Framework < 4.0 dropped; default 4.0 → 4.7.2 No — compiled-code concern
    $framework global removed No
    LegacyBuildFileName, PowerShell 2.0 compat removed No

    Task <name> -FromModule PowerShellBuild — the entry point everything here depends on — survives
    intact in 5.0.4.

    The cost is real but scattered: four unrelated slices of users, each hitting a different thing.
    That is hard to write one clean migration entry for.

    3. Version-conditional behavior today — none. This is the important one.

    IB.tasks.ps1 contains the string "psake" zero times. build.properties.ps1 mentions it once, in
    a comment. psakeFile.ps1 touches the psake API in exactly two ways —
    $psake.context.currentTaskName and $psake.context.Peek().Tasks.Keys — and both still exist in
    5.0.4. Every other branch in that file is on $PSBPreference.* or Get-Module -ListAvailable.

    Supporting both majors is free right now. There is no version-branching code to delete, so the
    "one supported major simplifies the psakeFile" argument in the issue body is buying a
    simplification that does not currently exist.

    4. PSGallery adoption — weak, and worth saying how weak

    Version Published Downloads
    5.x total from 2026-04-13 93,284
    4.9.1 2024-10-07 282,919
    4.9.0 2019-09-21 742,839

    On a per-month basis 5.x is pulled roughly 1.7× faster than 4.9.1 ever was — but that is dominated
    by CI runners doing unpinned Install-Module psake, which now resolves to 5.0.4 by default. It
    measures what the gallery hands out, not what anyone chose, and says nothing about the installed
    base of pinned builds, which is exactly the population a raised floor would break. Evidence that
    5.x is not stillborn; evidence of nothing else.

    Aside: psake/psake has no v5.0.0 GitHub release — the releases page still flags v4.9.1 as
    Latest. A small signal about how discoverable 5.x is to a human.

    On the #155 break escape

    It cuts for raising, and it is the best argument available: a consumer on psake 4 whose Pester
    tests call Set-BuildEnvironment has a test container failing silently. On this repository that
    was twelve tests not running with nobody aware.

    Two things blunt it. The remedy a raised floor delivers is "your build turns red", not "your build
    gets fixed" — correct, but a cost transferred rather than a service rendered. And the root cause is
    in BuildHelpers, not psake; fixing it upstream would moot the argument for both majors.

    Two things not in the issue

    The break is total, not graceful. RequiredModules is enforced at import. A consumer on psake
    4.9.1 who upgrades does not get degraded behavior — Import-Module PowerShellBuild fails outright.
    There is no partial-functionality middle ground and no warning path.

    README.md is already wrong, independently of this decision. Lines 16-22 say psake 4.8.0 is
    required and show Install-Module -Name psake -RequiredVersion 4.8.0, while the manifest floor has
    been 4.9.0. Worth fixing before 1.0.0 whichever way this lands.


    Recommendation — maintainer's call

    Keep 4.9.0 for 1.0.0, and say so explicitly in the migration guide, because fact 3 removes the
    leading argument for raising: the code simplification being bought does not exist. The consumer
    cost in fact 2 is real and scattered, and the #155 argument, while genuine, has its root cause
    elsewhere.

    The strongest counter, stated so it gets weighed rather than buried: the issue is right that
    1.0.0 is the cheapest moment, and a raise at 1.1.0 costs a major. If psake 5's additive features —
    Inputs/Outputs caching, -OutputFormat GitHubActions, Get-PsakeBuildPlan — are wanted inside
    the 1.x line, and #117's history suggests someone will want them, then "free today" becomes
    "expensive the moment we adopt anything from 5.x". That hinges on a roadmap question the repository
    cannot answer.

    If the decision is to keep 4.9.0, the issue's own "Done when" applies: a migration-guide line saying
    psake 4.9.x is a supported configuration rather than an oversight, plus a note about the
    Set-BuildEnvironment-in-BeforeAll hazard so psake 4 consumers know their test container may be
    failing silently. The README fix belongs in the same pass.

  3. tablackburn commented on Aug 26, 2026

    @tablackburn
    ContributorAuthor

    Decision: raise the consumer floor to psake 5.0.4 (@tablackburn, 2026-08-26)

    This supersedes the "keeping 4.9.0 for now" note in the issue body, and it goes against my own
    recommendation in the facts comment above. The reasoning below is the reasoning that decided it,
    not the reasoning I gave.

    Why — the argument that holds

    The floors this module declares are not all earned the same way:

    Dependency Floor What CI actually tests
    BuildHelpers 2.0.16 2.0.16
    Pester 5.6.1 6.0.0 and 5.9.0 — both majors, via the #137 matrix
    psake 4.9.0 5.0.4 only

    Pester's lower floor is earned: Test-PSBuildPester genuinely supports both majors and the matrix
    proves it on every run. psake's lower floor is asserted and untested. #162 moved the toolchain to
    5.0.4 and CI has exercised only 5.0.4 since; nothing verifies the 4.9.0 claim. The issue body of
    #120 already flags this under Not yet specified: "CI now exercises only 5.0.4, so the claim is
    asserted rather than tested."

    That leaves two honest options — add a psake 4.x CI leg, or stop claiming 4.x. For a volunteer
    project with few maintainers, adding and maintaining a second task-runner matrix leg to support a
    major nobody has asked for is the more expensive of the two, and 1.0.0 is the cheapest moment to
    change a floor.

    So the principle is do not claim support you do not test, not "everything on latest" — which
    matters, because "everything on latest" would also have raised the Pester floor, and #120
    deliberately decided against that for good reasons that still stand.

    Arguments deliberately not relied on

    Recording these so the decision is not re-litigated on grounds that do not survive checking:

    • "One supported major simplifies the psakeFile." It does not, today. There is no
      version-conditional psake code anywhere — IB.tasks.ps1 does not contain the string "psake", and
      psakeFile.ps1 touches only $psake.context.currentTaskName and $psake.context.Peek().Tasks.Keys,
      both of which exist in 4.9.x and 5.0.4 alike. The simplification is prospective, not current.
    • "Nobody should be running anything older than PowerShell 5.x." True, and already enforced by
      PowerShellVersion = '5.1' from chore: Raise minimum PowerShell version to 5.1 in module manifest #141. It does not bear on this decision: psake 4.9.1 runs
      perfectly well on PowerShell 7, so a consumer can be fully modern and on psake 4.

    Known impact

    RequiredModules is enforced at import, so this is not a graceful degradation — a consumer with
    only psake 4.9.x installed will find Import-Module PowerShellBuild fails outright. There is no
    partial-functionality path and no warning.

    One concrete consumer to notify rather than surprise: devblackops/Terminal-Icons pins
    psake = '4.9.0'
    in its requirements.psd1 and uses PowerShellBuild. Found by searching real
    requirements.psd1 files rather than assuming; poshbotio/PoshBot also pins 4.9.0 but does not use
    PowerShellBuild.

    What upgrading costs a consumer, from psake's own migration guide: most v4 build scripts work
    unchanged. The breaks are default.ps1 no longer being auto-detected, the removal of the
    psake.ps1/psake.cmd runners, .NET Framework < 4.0, the $framework global, the output-handler
    config, and Invoke-psake now returning a PsakeBuildResult. $psake.build_success, the
    Task ... -Depends syntax, and -FromModule are all explicitly retained — this repository is proof,
    since it still uses all three under 5.0.4.

    There is also a benefit consumers get for free: psake 5 stops silently absorbing an escaping
    break. Under 4.9.x a break leaking out of a Pester BeforeAll — which BuildHelpers'
    Get-BuildVariable does — is swallowed, so the container fails invisibly. On this repository that
    was twelve tests not running with nobody aware (#155).

    Follow-up

    Implementation, migration-guide entry, and the stale README.md psake 4.8.0 reference are in the
    pull request linked below.

  4. added a commit that references this issue on Aug 26, 2026
    8cb163c
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestpsakewayfinder:grillingWayfinder ticket: resolved by conversation with a human

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions