Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,9 @@
yourself if you build help. `$PSBPreference.Docs.AlphabeticParamsOrder` is
removed, because PlatyPS 1.x always sorts parameters alphabetically and
offers no way back. Generated markdown carries the 1.x schema, though its
on-disk layout is unchanged. `Build-PSBuildUpdatableHelp` warns and returns
until the cabinet pipeline migrates in
[#152](https://github.com/psake/PowerShellBuild/issues/152); it could never
succeed in 0.8.x either, see
[#169](https://github.com/psake/PowerShellBuild/issues/169). See the
[v0.8 → v1.0 migration guide](docs/migration-v0.8-to-v1.0.md).
on-disk layout is unchanged, and now includes a module landing page that
0.14.x never produced. Updatable help is covered separately under **Fixed**.
See the [v0.8 → v1.0 migration guide](docs/migration-v0.8-to-v1.0.md).

- [**#144**](https://github.com/psake/PowerShellBuild/issues/144)
**Breaking:** `Test-PSBuildScriptAnalysis` now counts PSScriptAnalyzer
Expand Down Expand Up @@ -56,6 +53,18 @@

### Fixed

- [**#169**](https://github.com/psake/PowerShellBuild/issues/169)
`Build-PSBuildUpdatableHelp` produces a help cabinet. It never could before:
it needed a module landing page that `Build-PSBuildMarkdown` did not
generate, passed an undefined variable as the cabinet source folder, and was
never given the module name — so any build that reached the
`GenerateUpdatableHelp` task failed with a parameter-binding error.
`Build-PSBuildMarkdown` now writes the landing page, and the task passes the
module name and output path it always should have. Using the task requires a
`HelpInfoUri` in your module manifest; without one it warns and produces
nothing, rather than writing a cabinet with no `HelpInfo.xml` to find it by.
See the [v0.8 → v1.0 migration guide](docs/migration-v0.8-to-v1.0.md).

- [**#147**](https://github.com/psake/PowerShellBuild/issues/147)
`Test-PSBuildScriptAnalysis` retries the analysis when a PSScriptAnalyzer rule
crashes on an internal race
Expand All @@ -79,7 +88,7 @@
that passed before may now correctly fail.
- [**#96**](https://github.com/psake/PowerShellBuild/issues/96)
`Test-PSBuildScriptAnalysis` no longer fails with a path-resolution error
when `SettingsPath` is not supplied. An unsupplied path was forwarded to

Check warning on line 91 in CHANGELOG.md

View workflow job for this annotation

GitHub Actions / CI / Run Linters

Unknown word (unsupplied) Suggestions: (unapplied, unsullied, unspoiled, unstapled, unsupported)
PSScriptAnalyzer as `-Settings ''`, which resolved against the current
directory and threw before any analysis ran, so the function's own
documented example could not run as written.
Expand Down
8 changes: 7 additions & 1 deletion PowerShellBuild/IB.tasks.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@



$analyzePreReqs = {

Check warning on line 48 in PowerShellBuild/IB.tasks.ps1

View workflow job for this annotation

GitHub Actions / CI / Run Linters

Unknown word (Reqs) Suggestions: (re's, Re's, rebs, recs, reds)
$result = $true
if (-not $PSBPreference.Test.ScriptAnalysis.Enabled) {
Write-Warning 'Script analysis is not enabled.'
Expand All @@ -59,7 +59,7 @@
}

# Synopsis: Execute PSScriptAnalyzer tests
Task Analyze -If (. $analyzePreReqs) Build, {

Check warning on line 62 in PowerShellBuild/IB.tasks.ps1

View workflow job for this annotation

GitHub Actions / CI / Run Linters

Unknown word (Reqs) Suggestions: (re's, Re's, rebs, recs, reds)
$analyzeParams = @{
Path = $PSBPreference.Build.ModuleOutDir
SeverityThreshold = $PSBPreference.Test.ScriptAnalysis.FailBuildOnSeverityLevel
Expand All @@ -68,7 +68,7 @@
Test-PSBuildScriptAnalysis @analyzeParams
}

$pesterPreReqs = {

Check warning on line 71 in PowerShellBuild/IB.tasks.ps1

View workflow job for this annotation

GitHub Actions / CI / Run Linters

Unknown word (Reqs) Suggestions: (re's, Re's, rebs, recs, reds)
$result = $true
if (-not $PSBPreference.Test.Enabled) {
Write-Warning 'Pester testing is not enabled.'
Expand All @@ -86,7 +86,7 @@
}

# Synopsis: Execute Pester tests
Task Pester -If (. $pesterPreReqs) Build, {

Check warning on line 89 in PowerShellBuild/IB.tasks.ps1

View workflow job for this annotation

GitHub Actions / CI / Run Linters

Unknown word (Reqs) Suggestions: (re's, Re's, rebs, recs, reds)
$pesterParams = @{
Path = $PSBPreference.Test.RootDir
ModuleName = $PSBPreference.General.ModuleName
Expand All @@ -107,7 +107,7 @@



$genMarkdownPreReqs = {

Check warning on line 110 in PowerShellBuild/IB.tasks.ps1

View workflow job for this annotation

GitHub Actions / CI / Run Linters

Unknown word (Reqs) Suggestions: (re's, Re's, rebs, recs, reds)
$result = $true
if (-not (Get-Module Microsoft.PowerShell.PlatyPS -ListAvailable)) {
Write-Warning "Microsoft.PowerShell.PlatyPS module is not installed. Skipping [$($task.name)] task."
Expand Down Expand Up @@ -155,7 +155,13 @@

# Synopsis: Create updatable help .cab file based on PlatyPS markdown help
Task GenerateUpdatableHelp -if (. $genUpdatableHelpPreReqs) BuildHelp, {
Build-PSBuildUpdatableHelp -DocsPath $PSBPreference.Docs.RootDir -OutputPath $PSBPreference.Help.UpdatableHelpOutDir
$buildUpdatableHelpParameters = @{
DocsPath = $PSBPreference.Docs.RootDir
OutputPath = $PSBPreference.Help.UpdatableHelpOutDir
ModulePath = $PSBPreference.Build.ModuleOutDir
Module = $PSBPreference.General.ModuleName
}
Build-PSBuildUpdatableHelp @buildUpdatableHelpParameters
}

# Synopsis: Publish module to the defined PowerShell repository
Expand Down
17 changes: 15 additions & 2 deletions PowerShellBuild/Public/Build-PSBuildMarkdown.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
.PARAMETER Overwrite
Overwrite existing markdown files and use comment based help as the source of truth.
.PARAMETER ExcludeDontShow
Exclude the parameters marked with `DontShow` in the parameter attribute from the help content.

Check warning on line 22 in PowerShellBuild/Public/Build-PSBuildMarkdown.ps1

View workflow job for this annotation

GitHub Actions / CI / Run Linters

Unknown word (Dont) Suggestions: (dent, dint, doit, dolt, dona)
.PARAMETER UseFullTypeName
Indicates that the target document will use a full type name instead of a short name for parameters.
.EXAMPLE
Expand Down Expand Up @@ -95,6 +95,10 @@
ModuleInfo = $moduleInfo
OutputFolder = $stagingPath
Locale = $Locale
# The landing page is what carries the module GUID, locale, and help
# version into the updatable-help cabinet. 0.14.x never produced one,
# which is why Build-PSBuildUpdatableHelp could not work.
WithModulePage = $true
# PlatyPS 1.x defaults this front matter key to "<Module>-Help.xml", where
# 0.14.x wrote "<Module>-help.xml". The key is what Export-MamlCommandHelp
# names the MAML file after, so pinning it here keeps the markdown, the MAML
Expand Down Expand Up @@ -124,10 +128,19 @@
)
foreach ($markdownFile in $generatedMarkdown) {
$destinationPath = Join-Path -Path $localePath -ChildPath $markdownFile.Name
if ((Test-Path -LiteralPath $destinationPath) -and -not $Overwrite) {
# Already refreshed above; regenerating would discard hand-written prose.
$isModuleLandingPage = $markdownFile.BaseName -eq $ModuleName

# The landing page is always replaced. It is generated content -- an index of
# the module's commands, plus the module GUID and locale that the cabinet step
# stamps its .cab name from -- so a copy left in place goes stale the moment a
# command is added or removed. PlatyPS has no refresh that would preserve an
# edited body either: Update-MarkdownModuleFile rewrites it wholesale. Command
# help is different, and is skipped here because it was already refreshed in
# place above, where hand-written prose survives.
if (-not $isModuleLandingPage -and (Test-Path -LiteralPath $destinationPath) -and -not $Overwrite) {
continue
}

Move-Item -LiteralPath $markdownFile.FullName -Destination $destinationPath -Force
}
} finally {
Expand Down
111 changes: 91 additions & 20 deletions PowerShellBuild/Public/Build-PSBuildUpdatableHelp.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,23 @@ function Build-PSBuildUpdatableHelp {
.DESCRIPTION
Create updatable help .cab file based on PlatyPS markdown help.

Not implemented against PlatyPS 1.x yet. The cabinet pipeline is migrated in
psake/PowerShellBuild#152 along with the three defects in #169 that prevented this
function from ever succeeding. Until then it reports that updatable help was skipped
and returns without writing anything.
Requires the module manifest to declare a HelpInfoUri. That URI is where Update-Help
looks for the help content, so a cabinet built without one cannot be consumed.
.PARAMETER DocsPath
Path to PlatyPS markdown help files.
Path to PlatyPS markdown help files. Must contain a locale directory holding the
module landing page, <locale>/<Module>.md.
.PARAMETER OutputPath
Path to create updatable help .cab file in.
.PARAMETER ModulePath
Path to the built module. The MAML written by Build-PSBuildMAMLHelp is read from
<ModulePath>/<locale>, and the manifest is read from <ModulePath>/<Module>.psd1.
.PARAMETER Module
Name of the module to create a .cab file for. Defaults to the
$ModuleName variable from the parent scope.
Name of the module to create a .cab file for.
.EXAMPLE
PS> Build-PSBuildUpdatableHelp -DocsPath ./docs -OutputPath ./Output/UpdatableHelp
PS> Build-PSBuildUpdatableHelp -DocsPath ./docs -OutputPath ./Output/UpdatableHelp -ModulePath ./Output/MyModule/1.0.0 -Module MyModule

Reports that updatable help is not available and returns.
Create help .cab file based on PlatyPS markdown help.
#>
# The parameters are unused only because the body is stubbed. They stay so the public
# signature does not change twice -- once here and again when #152 restores the body.
[Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSReviewUnusedParameter', '')]
[CmdletBinding()]
param(
[parameter(Mandatory)]
Expand All @@ -32,14 +30,87 @@ function Build-PSBuildUpdatableHelp {
[parameter(Mandatory)]
[string]$OutputPath,

[string]$Module = $ModuleName
[parameter(Mandatory)]
[string]$ModulePath,

[parameter(Mandatory)]
[string]$Module
)

# Deliberately references no PlatyPS command. Naming New-ExternalHelpCab here is enough to
# make PowerShell autoload platyPS 0.14.2 on any session that resolves it, and once that
# module is loaded, Microsoft.PowerShell.PlatyPS can no longer be imported in the same
# process -- both ship their own YamlDotNet with different assembly identities. Leaving the
# old call in place would poison every session that still has 0.14.2 installed, which is
# every consumer part-way through the upgrade.
Write-Warning $LocalizedData.UpdatableHelpNotMigrated
if ($null -ne $IsWindows -and -not $IsWindows) {
Write-Warning $LocalizedData.MakeCabNotAvailable
return
}

# Update-Help resolves help content through the manifest's HelpInfoUri. Without one,
# New-HelpCabinetFile still writes the cabinet and its zip but fails before writing the
# HelpInfo.xml that makes them findable, leaving output that looks complete and is not.
# Refusing up front is better than producing that.
$manifestPath = [IO.Path]::Combine($ModulePath, "$Module.psd1")
if (-not (Test-Path -LiteralPath $manifestPath)) {
Write-Warning ($LocalizedData.UnableToFindModuleManifest -f $manifestPath)
return
}
$helpInfoUri = (Import-PowerShellDataFile -Path $manifestPath).HelpInfoUri
if ([string]::IsNullOrWhiteSpace($helpInfoUri)) {
Write-Warning ($LocalizedData.HelpInfoUriRequired -f $Module)
return
}

# Work out what can actually be built before touching OutputPath. Clearing it first and
# then skipping every locale would delete a previous build's cabinet and replace it with
# nothing, which is the same half-produced outcome the guards above exist to prevent.
$cabinetWork = foreach ($locale in (Get-ChildItem -Path $DocsPath -Directory).Name) {
# The landing page is a module document rather than command help. It is what carries
# the module GUID and locale into the cabinet, and it is generated by
# Build-PSBuildMarkdown; a docs tree from an older build will not have one.
$markdownModuleFile = [IO.Path]::Combine($DocsPath, $locale, "$Module.md")
if (-not (Test-Path -LiteralPath $markdownModuleFile)) {
Write-Warning ($LocalizedData.ModuleLandingPageNotFound -f $markdownModuleFile, $locale)
continue
}

$cabinetFilesFolder = [IO.Path]::Combine($ModulePath, $locale)
if (-not (Test-Path -LiteralPath $cabinetFilesFolder)) {
Write-Warning ($LocalizedData.FolderDoesNotExist -f $cabinetFilesFolder)
continue
}

[PSCustomObject]@{
CabinetFilesFolder = $cabinetFilesFolder
MarkdownModuleFile = $markdownModuleFile
}
}

if (-not $cabinetWork) {
return
}

# Create updatable help output directory
if (-not (Test-Path -LiteralPath $OutputPath)) {
$newItemSplat = @{
ItemType = 'Directory'
Verbose = ($VerbosePreference -eq 'Continue')
Path = $OutputPath
}
New-Item @newItemSplat > $null
} else {
Write-Verbose ($LocalizedData.DirectoryAlreadyExists -f $OutputPath)
$removeItemSplat = @{
Recurse = $true
Force = $true
Verbose = ($VerbosePreference -eq 'Continue')
}
Get-ChildItem $OutputPath | Remove-Item @removeItemSplat
}

foreach ($work in $cabinetWork) {
$cabinetParameters = @{
CabinetFilesFolder = $work.CabinetFilesFolder
MarkdownModuleFile = $work.MarkdownModuleFile
OutputFolder = $OutputPath
Verbose = ($VerbosePreference -eq 'Continue')
}
New-HelpCabinetFile @cabinetParameters > $null
}
}
3 changes: 2 additions & 1 deletion PowerShellBuild/en-US/Messages.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ NoCommandsExported=No commands have been exported. Skipping markdown generation.
FailedToGenerateMarkdownHelp=Failed to generate markdown help. : {0}
AddingFileToPsm1=Adding [{0}] to PSM1
MakeCabNotAvailable=MakeCab.exe is not available. Cannot create help cab.
UpdatableHelpNotMigrated=Updatable help was skipped. The cabinet pipeline has not been migrated to Microsoft.PowerShell.PlatyPS 1.x yet; see psake/PowerShellBuild#152.
HelpInfoUriRequired=Updatable help was skipped for [{0}]. The module manifest does not declare a HelpInfoUri, which is where Update-Help looks for the help content, so a cabinet built without one cannot be used.
ModuleLandingPageNotFound=Updatable help was skipped for locale [{1}]. The module landing page [{0}] does not exist. It is generated by the GenerateMarkdown task; regenerate the documentation and try again.
DirectoryAlreadyExists=Directory already exists [{0}].
PathLongerThan3Chars=Path [{0}] must be longer than 3 characters.
BuildSystemDetails=Build System Details:
Expand Down
9 changes: 8 additions & 1 deletion PowerShellBuild/psakeFile.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,14 @@ $genUpdatableHelpPreReqs = {
$result
}
Task GenerateUpdatableHelp -Depends $PSBGenerateUpdatableHelpDependency -PreCondition $genUpdatableHelpPreReqs {
Build-PSBuildUpdatableHelp -DocsPath $PSBPreference.Docs.RootDir -OutputPath $PSBPreference.Help.UpdatableHelpOutDir -Verbose:($VerbosePreference -eq 'Continue')
$buildUpdatableHelpParameters = @{
DocsPath = $PSBPreference.Docs.RootDir
OutputPath = $PSBPreference.Help.UpdatableHelpOutDir
ModulePath = $PSBPreference.Build.ModuleOutDir
Module = $PSBPreference.General.ModuleName
Verbose = ($VerbosePreference -eq 'Continue')
}
Build-PSBuildUpdatableHelp @buildUpdatableHelpParameters
} -Description 'Create updatable help .cab file based on PlatyPS markdown help'

Task Publish -Depends $PSBPublishDependency {
Expand Down
86 changes: 69 additions & 17 deletions docs/migration-v0.8-to-v1.0.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@ One line per break; follow the link for details and migration steps.
— PlatyPS 1.x always sorts alphabetically, so the setting could no longer do anything.
- [Generated markdown uses the PlatyPS 1.x schema](#generated-markdown-uses-the-platyps-1x-schema)
— expect a large diff in `docs/` on the first 1.0.0 build.
- [Updatable help is temporarily unavailable](#updatable-help-is-temporarily-unavailable)
— the cabinet pipeline is migrated before 1.0.0 ships.
- [Updatable help works, and now requires a `HelpInfoUri`](#updatable-help-works-and-now-requires-a-helpinfouri)
— it could never succeed in 0.8.x; using it now needs a `HelpInfoUri` in your manifest.
- [Your `docs/` tree gains a module landing page](#your-docs-tree-gains-a-module-landing-page)
— a new `<Module>.md` appears alongside the per-command documents.

> More entries will follow as the remaining Phase 2 work lands.

Expand Down Expand Up @@ -307,24 +309,74 @@ this should be schema churn rather than content loss — but verify.
Consumer guidance for converting a committed tree is
[#154](https://github.com/psake/PowerShellBuild/issues/154).

### Updatable help is temporarily unavailable
### Updatable help works, and now requires a `HelpInfoUri`

`Build-PSBuildUpdatableHelp` and the `GenerateUpdatableHelp` task write a
warning and return without producing a cabinet. The 1.x cabinet pipeline
is migrated in [#152](https://github.com/psake/PowerShellBuild/issues/152)
before 1.0.0 ships.
`Build-PSBuildUpdatableHelp` and the `GenerateUpdatableHelp` task produce a
help cabinet, its `.zip`, and a `HelpInfo.xml`. In 0.8.x they could not:
the function needed a module landing page that `Build-PSBuildMarkdown`
never generated, passed an undefined variable as the cabinet source
folder, and never received the module name — three separate defects,
recorded in [#169](https://github.com/psake/PowerShellBuild/issues/169).
Any 0.8.x build that reached this task failed with a parameter-binding
error, so nothing that worked before stops working.

This costs nothing in practice: the function could never succeed in
0.8.x either. It required a module landing page that
`Build-PSBuildMarkdown` never generated, and it passed an undefined
variable as the cabinet source folder — three separate defects, recorded
in [#169](https://github.com/psake/PowerShellBuild/issues/169). The task
is opt-in and is not part of the default build, so most consumers never
reached it.
**Your module manifest must declare a `HelpInfoUri`.** That URI is where
`Update-Help` looks for the content, so a cabinet built without one cannot
be consumed. If it is missing, the task now writes a warning and produces
nothing:

**Detection:** `Updatable help was skipped. The cabinet pipeline has not
been migrated to Microsoft.PowerShell.PlatyPS 1.x yet` in the build
output, where 0.8.x raised a parameter-binding error.
```text
Updatable help was skipped for [MyModule]. The module manifest does not
declare a HelpInfoUri, ...
```

Refusing is deliberate. `New-HelpCabinetFile` will otherwise write the
cabinet and its `.zip` and then fail before writing the `HelpInfo.xml`
that makes them findable — output that looks complete and is useless.

**Migration:** add the URI where you publish help.

```powershell
# In your module manifest
HelpInfoUri = 'https://example.com/mymodule/help'
```

Nothing is needed if you do not use the `GenerateUpdatableHelp` task; it
is opt-in and not part of the default build.

**Calling the function directly?** Its signature changed. `Module` is now
mandatory rather than defaulting from a caller-scope variable, and
`ModulePath` is new — it is where the MAML written by the `GenerateMAML`
task is read from.

**Before (0.8.x):**

```powershell
Build-PSBuildUpdatableHelp -DocsPath ./docs -OutputPath ./Output/UpdatableHelp
```

**After (1.0.0):**

```powershell
Build-PSBuildUpdatableHelp -DocsPath ./docs -OutputPath ./Output/UpdatableHelp `
-ModulePath ./Output/MyModule/1.0.0 -Module MyModule
```

### Your `docs/` tree gains a module landing page

`Build-PSBuildMarkdown` now generates `<Docs.RootDir>/<locale>/<Module>.md`
alongside the per-command documents. 0.14.x never produced one.

The page carries the module GUID, locale, and help version into the
updatable-help cabinet, which is why its absence was one of the three
defects above. It is also a different document type from command help, and
is excluded from MAML generation automatically — a module page in a MAML
export batch aborts the entire export
([PowerShell/platyPS#862](https://github.com/PowerShell/platyPS/issues/862)),
so `Build-PSBuildMAMLHelp` filters it out.

**Detection:** a new `<Module>.md` file appears in your docs tree on the
first 1.0.0 build. If you commit `docs/`, commit it too.

## Adding an entry (for PR contributors)

Expand Down
Loading
Loading