Skip to content

[Tracking] PowerShellBuild v1.0.0 roadmap #120

Description

@tablackburn

[Tracking] PowerShellBuild v1.0.0 roadmap

Goal: ship PowerShellBuild 1.0.0 — the first version with a stable public-API contract per SemVer. Treats the 0.x line as initial development per SemVer §4; 1.0.0 defines the public API per SemVer §5.

Status: planning → execution
Current version: 0.8.2
Target version: 1.0.0
Prerelease cadence: 1.0.0-previewN to PSGallery once there is meaningful breaking/behavioral change to soak. Preview numbers increment from the first preview cut — they are not tied to phase numbers (Phase 1 was conventions/guardrails and shipped almost nothing consumer-facing, so the first preview is cut after Phase 2).
Branching: PRs land directly on main (allowed under 0.x); 1.0.0 cuts when scope is complete

Why 1.0.0 and not 2.0.0: there has never been a stable 1.x. Jumping to 2.0.0 would imply a prior stable 1.x existed. SemVer says go to 1.0.0.

Destination

PowerShellBuild 1.0.0 published to PSGallery. This issue is the wayfinder map for
that route: it indexes every decision already made and points at the tickets holding the
detail. The map is complete when 1.0.0 ships — not when planning ends.

Working this map

Route steps are sub-issues of this issue (and of #105 for the PlatyPS chain), wired
with GitHub's native dependency edges, so the tracker itself shows what is takeable.

Read the frontier without a script by opening this issue: blocked children render with a
blocked marker, and the rest are the frontier.


Locked-in decisions

Decision Choice
Version 1.0.0 (not 2.0.0)
Tracking This issue + v1.0.0 milestone + GitHub Project board
AIM deployment Phase 0 (first PR)
Branching PRs to main + 1.0.0-previewN prereleases
Breaking changes Hard cut + migration guide
Migration guide docs/migration-v0.8-to-v1.0.md; per-PR entries; AI-assisted prompt at top
Auto-migration tool None
Deprecation cycle None (skip 0.9.0)
psake 5.x In scope for 1.0.0
Minimum PS version Windows PowerShell 5.1; PowerShell 7.4+ for PS 7 (decided 2026-07-21; PlatyPS 1.x validated on 5.1, Pester 6 floor drives the 7.4+)
Consumer Pester minimum Keep ≥ 5.x (decided 2026-07-22; RequiredModules stays at 5.6.1 — Test-PSBuildPester supports Pester 5 and 6, verified by the #137 integration matrix)
Preview numbering Decoupled from phase numbers (decided 2026-07-22). No preview is cut after Phase 1 — it shipped only two small changes (Test-PSBuildPester fixes #102 + the manifest floor #141), nothing risky to soak. The first preview is preview1, cut after Phase 2, and it carries the Phase 1 shipped changes along with it.
Migration guide scope Breaking changes plus behavioral changes that can require action on upgrade (decided 2026-07-25). The guide previously said "breaking changes only", which excluded fixes like #143 that can turn a passing consumer build red. Preamble widened to match.
Destination 1.0.0 published to PSGallery (decided 2026-08-19). The route is done when the release ships, not when the planning does.
Route tracking This issue is the map (decided 2026-08-19). Route steps are sub-issues wired with native dependency edges rather than checkboxes, so the frontier is visible in the tracker and claimable by parallel sessions.
psake 5.x In scope, clean re-spike (decided 2026-08-19) — #155. The extras that sank #117 (task caching, LLM Pester output, external PesterConfiguration file, Format-PSBuildResult) are 1.1.0 features, not part of a dependency bump.
psake 5.x outcome MIGRATE (#155, resolved 2026-08-19). Consumer-facing psakeFile.ps1 needs zero changes under 5.0.4 — no task renames, no $PSBPreference change — so the abort criterion did not fire. All four breaking changes in psake's own v4→v5 guide were checked and none apply. Full suite 428/0 under 5.0.4, matching the 4.9.1 baseline. psake 5.x does differ behaviorally — Invoke-psake returns a PsakeBuildResult where v4 returned nothing, and Set-BuildEnvironment in a Pester BeforeAll fails the container — but neither is triggered by upgrading PowerShellBuild, so neither is documented here. Migration filed as #161.
BuildHelpers break escape Found by the #155 spike, undocumented upstream (2026-08-19). Set-BuildEnvironment in a Pester BeforeAll leaks an escaping break from Get-BuildVariable's switch blocks; psake 4.9.x absorbs it, psake 5.x does not, and Pester fails the whole container. Guarding the call on $env:BHProjectName fixes it. Affects any consumer whose Pester tests call Set-BuildEnvironment.
psake abort criterion Fixed in advance, before the spike runs (decided 2026-08-19). Migrate if the consumer-facing PowerShellBuild/psakeFile.ps1 needs only mechanical changes; cut psake 5.x to 1.1.0 and ship 1.0.0 on 4.9.0 if task names or the $PSBPreference contract must change. Set ahead of the findings so the call is made on evidence rather than sunk cost.
Phase 2 ordering PlatyPS and psake chains run in parallel (decided 2026-08-19), gated by a single preview1 cut. They touch disjoint files, so serializing them buys nothing and halves the frontier.
FailBuildOnSeverityLevel #144 option 3, extended to cover #147 (decided 2026-08-19): fold ParseError into the Error threshold and add 'Any' wired to the catch-all branch. The ParseError half is a behavior change and needs a migration-guide entry. Corrected 2026-08-20: this row originally also said the gate should fail on analyzer-level errors "so a crashed rule no longer reads as 'no findings'". That premise was wrong — #147 measured that a crashed rule does not cost findings (100 cold runs, never fewer than the known-good count). #163 therefore implements #147's preferred fix, a retry on RULE_ERROR that leaves failure semantics untouched, rather than a hard failure that would have cost some consumers a red build to help others. Implemented in #163.
#83 design Grilling ticket first (#156, decided 2026-08-19). Precedence between a supplied PesterConfiguration and $PSBPreference.Test.* is public API and must settle before implementation. The former pointer to "joshooaj's design in #80" was stale#80 is a different, closed request.
Phase 4 milestone discrepancy Resolved 2026-08-19 — milestone stripped. #94, #95, #98, and #103 no longer carry v1.0.0, matching this issue's prose and the 2026-05-19 comment. The milestone now shows only genuinely blocking work.
Changelog and guide scope Internal changes get neither (decided 2026-08-20, applied to #162). CHANGELOG.md records user-facing changes only, and the migration guide covers changes triggered by upgrading PowerShellBuild. A build-toolchain pin in requirements.psd1 is neither, even when the upgraded dependency behaves differently — that belongs in the dependency's own migration guide. Sharpens the existing "Migration guide scope" row: the test is who is affected by this upgrade, not how interesting the change is.
Scope additions #124 and #138 pulled in (decided 2026-08-19). Both touch the public surface freezing at 1.0.0: #124 adds a PlatyPS setting to functions Phase 2 already rewrites, #138 is a correctness bug in a public function's output.

Migration guide

Lives at docs/migration-v0.8-to-v1.0.md. Every breaking-change PR must add an entry
using the standard structure (What changed / Why / Detection / Migration / Notes). Enforced
through instructions/git-workflow.instructions.md (AIM) plus reviewer catch — not a PR
template checkbox, which Phase 1 explicitly skipped. The top-of-file section includes a
canonical AI prompt users can paste into their agent to migrate their build.ps1
automatically; #159 tests that prompt before release.


Phase 0 — Foundation

  • Deploy AIM to the repo (feat: deploy AIM (AI Agent Instruction Modules) #122, merged 2026-05-18)
    • Add AGENTS.md, aim.config.json, instructions/
    • Migrate CLAUDE.md content → instructions/repository-specific.instructions.md
    • Modules to include: agent-workflow, shorthand, git-workflow, testing, powershell, markdown, releases, github-cli, readme, contributing, update, repository-specific
    • Fix stale version reference (CLAUDE.md says 0.7.3; actual is 0.8.0)

Phase 1 — Conventions & guardrails ✅ complete (2026-07-22)

No preview cut after Phase 1. Phase 1 was conventions/guardrails: the only consumer-facing changes since v0.8.2 are the Test-PSBuildPester bug fixes (#102) and the manifest version floor (#141) — nothing risky enough to warrant a prerelease soak. These ride along in preview1 (cut after Phase 2). See the Preview numbering decision above.

Phase 2 — Breaking dependency upgrades

Both chains below are open in parallel — they touch disjoint files — and both gate the
same preview cut.

PlatyPS migration (#105)

One reviewable PR per link. Each link is blocked by the one before it, except the docs
conversion, which only needs the module installed and runs alongside the function work.

  1. PlatyPS 2a: add Microsoft.PowerShell.PlatyPS 1.x alongside platyPS #1492a add Microsoft.PowerShell.PlatyPS 1.x alongside platyPS, update CI
  2. PlatyPS 2b: migrate Build-PSBuildMarkdown to New-MarkdownCommandHelp #1502b migrate Build-PSBuildMarkdown (closes Tests: Build-PSBuildMarkdown #99)
  3. PlatyPS 2c: migrate Build-PSBuildMAMLHelp to Export-MamlCommandHelp #1512c migrate Build-PSBuildMAMLHelp (closes Tests: Build-PSBuildMAMLHelp #100)
  4. PlatyPS 2d: migrate Build-PSBuildUpdatableHelp to the 1.x cab pipeline #1522d migrate Build-PSBuildUpdatableHelp (closes Tests: Build-PSBuildUpdatableHelp #101) — highest risk in the
    chain: Windows-only, makecab.exe-dependent, and untested today
  5. PlatyPS 2e: convert committed docs/ markdown to the 1.x schema #1542e convert committed docs/ markdown to the 1.x schema (needs only 2a)
  6. PlatyPS 2f: remove the old platyPS 0.14.2 dependency #1532f remove the old platyPS 0.14.2 dependency (needs every link above)

psake 5.x bump

Gate

Phase 3 — API improvements

Phase 4 — Test infrastructure

In v1.0.0:

Related test-infra work that landed during the cycle: #128/#133 (fail the build on Pester
block/container failures, not just failed tests), #140 (code-coverage tracking in the
Pester task), #143 (severity gate actually fails the build; also closed #125).

Tracked but not blocking 1.0.0 — see "Out of scope" below.

Phase 5 — Release


Not yet specified

In scope, but not yet sharp enough to ticket. Graduates as the frontier advances.

  • Whether updatable help survives PlatyPS 1.x. If the 1.x cab story is materially
    different from 0.14.x, or absent, PlatyPS 2d: migrate Build-PSBuildUpdatableHelp to the 1.x cab pipeline #152 surfaces a scope decision about Build-PSBuildUpdatableHelp
    that belongs on this map rather than inside that PR.
  • The shape of Scope PlatyPS to Specific Paths #124's path scoping — whether it needs a new $PSBPreference.Docs.*
    setting or the 1.x API makes it inferable is unknown until 2b–2d reveal the new surface.
  • Consumer guidance for the docs/ schema conversion. 2e converts this repo's docs;
    what consumers with committed docs/ must do is learned by doing it.
  • Whether psake 4.x compatibility stays continuously tested. chore: Move the build toolchain to psake 5.0.4 #162 bumps the toolchain to
    psake 5.0.4 while the manifest still claims psake >= 4.9.0. Both majors were verified
    locally (428/0 each), but CI now exercises only 5.0.4, so the claim is asserted rather than
    tested. Options are a side-by-side matrix like requirements.pester-matrix.psd1, raising the
    manifest floor to 5.x, or accepting the gap. Not sharp enough to ticket until chore: Move the build toolchain to psake 5.0.4 #162 lands.
  • rc1 blocker triage. If the soak surfaces blockers, the response is a route decision.

Out of scope

Ruled beyond this destination. These do not graduate; they return only if the destination
is redrawn.


Definition of done


AI-assisted-development notes

  • Keep PRs small (≤ ~400 lines diff where feasible) so they fit in agent context
  • Each PR description should reference this tracking issue and the relevant phase
  • The AIM instructions/ files are the canonical guide for any agent working in this repo — agents must read agent-workflow.instructions.md first
  • Conventional commit prefixes (feat:, fix:, docs:, chore:, BREAKING CHANGE:) to keep history machine-parseable

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or requestwayfinder:mapWayfinder map: the canonical route artifact for an effort

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions