Skip to content

docs: Document the $PSBPreference.Sign settings in the README - #190

Merged
tablackburn merged 1 commit into
mainfrom
docs/readme-sign-settings
Aug 27, 2026
Merged

docs: Document the $PSBPreference.Sign settings in the README#190
tablackburn merged 1 commit into
mainfrom
docs/readme-sign-settings

Conversation

@tablackburn

Copy link
Copy Markdown
Contributor

Stacked on #186
(docs/readme-alphabeticparamsorder-drift). That PR edits the same README
table and adds the drift test this one extends; neither is on main yet.
GitHub will retarget this PR to main once #186 merges.

Summary

Closes #189.

  • Adds the sixteen $PSBPreference.Sign rows (thirteen Sign.*, three
    Sign.Catalog.*) to the README settings table, after the Publish block,
    matching build.properties.ps1 section order and the table's existing
    61/45/174 column padding. No unrelated row is reflowed.
  • Adds a ## Code signing prose section covering the five
    CertificateSource modes.
  • Adds Sign to the Primary Tasks table, and SignModule, BuildCatalog, and
    SignCatalog to the Secondary Tasks table.
  • Adds $PSBSignModuleDependency, $PSBBuildCatalogDependency,
    $PSBSignCatalogDependency, and $PSBSignDependency to the
    $PSB{TaskName}Dependency table, which stopped at $PSBPublishDependency.
  • Flips Describe 'Settings documented in the README' to assert both
    directions, and replaces the comment that explained why it could not.

Where the defaults came from

Every default value in the new rows is read from
PowerShellBuild/build.properties.ps1, not from function parameter defaults —
the confusion #186 exists to correct. Two descriptions could not be taken from
the inline comments there, because those comments disagree with the code:

Sign.SkipCertificateValidation. The inline comment says it applies "when
true and using the Store or Thumbprint sources". Get-PSBuildCertificate does
the opposite: SkipValidation is only consulted for EnvVar and PfxFile
(if ($cert -and -not $SkipValidation -and ($resolvedSource -eq 'EnvVar' -or $resolvedSource -eq 'PfxFile'))), and the Store/Thumbprint branches already
filter on HasPrivateKey and NotAfter inside the query, so there is nothing
there for the switch to skip. The README documents the implemented behavior.
build.properties.ps1 is left alone — whether the comment or the code is the
bug is a maintainer call, not a docs change, and worth a follow-up issue either
way.

Sign.Catalog.FileName. Defaults to $null; the effective
<ModuleName>.cat fallback is computed in the BuildCatalog and SignCatalog
task bodies. The row states the fallback rather than just the literal $null.

Nothing else surprised: the other fourteen defaults match their inline
documentation exactly.

Why prose as well as rows

CertificateSource has five values whose differences are setup decisions —
which environment variables a pipeline sets, whether a PFX is on disk, whether
the certificate store is even reachable — and the Auto fallback chain
(EnvVar when CertificateEnvVar is populated, else Store) is the reason the
default works for a project that builds both locally and in CI. That does not
fit in a table cell, and the README already carries narrative sections
alongside its tables. The section is prose and a five-item list only; no code
fence was added, because the existing Examples section already shows how to set
$PSBPreference values under both runners.

Reverse-direction allow-list: none

Get-PreferenceLeafPath walks the defaults recursively and returns the dotted
path of every leaf; nested hashtables (Test.ScriptAnalysis,
Test.CodeCoverage, Sign.Catalog) are containers, not settings, so only their
leaves are compared. All 52 leaves are now in the table, so the new assertion
needs no exclusions.

Build.ModuleOutDir — the candidate exclusion — is already documented, with a
description that says it is for internal use and points at
$PSBPreference.Build.OutDir instead. That is the pattern to follow for
anything else that turns out to be internal; an allow-list entry would hide the
setting from the readers the table exists for. A comment in the test says so,
so the next person is not left guessing why there is no allow-list.

The forward direction keeps its existing four-entry allow-list
(Build.CompileHeader, CompileFooter, CompileScriptHeader,
CompileScriptFooter), unchanged from #186.

Red before green

With README.md intact:

Describing Settings documented in the README
  [+] every setting the README table lists resolves against build.properties.ps1 74ms
  [+] every setting build.properties.ps1 defines is listed in the README table 8ms
Tests Passed: 2, Failed: 0

Deleting one new row ($PSBPreference.Sign.Catalog.FileName) and rerunning the
new assertion alone:

Describing Settings documented in the README
  [-] every setting build.properties.ps1 defines is listed in the README table 88ms
   Expected $null or empty, but got 'Sign.Catalog.FileName'.
   at $undocumented -join ', ' | Should -BeNullOrEmpty, tests\IBTasks.tests.ps1:177
Tests Passed: 0, Failed: 1

The row was restored and the suite reruns green.

Test Plan

  • ./build.ps1 -Task Test485 passed, 0 failed, 3 skipped. The
    branch point (2aa6c97) is 484/0/3; the one added test is the new
    reverse-direction assertion.
  • Analyze (PSScriptAnalyzer) clean.
  • Every new table row padded to the existing column widths; verified with
    awk that all rows in the settings table are 284 characters and all rows
    in the dependency table are 129.
  • Prose wraps under 80 characters (.markdownlint.json leaves MD013 on for
    prose, exempting only tables and code blocks); no trailing whitespace; the
    README stays pure ASCII.

No CHANGELOG entry

The signing feature is already changelogged, under released ## [0.8.0] rather
than ## Unreleased — see the #92 entry listing the three public functions,
the four tasks, and the $PSBPreference.Sign section. This PR fills in the
README side of that shipped feature after the fact; it changes no behavior of
the shipped module, so per instructions/repository-specific.instructions.md
("CHANGELOG.md documents user-facing changes to the shipped module") there is
nothing to add. Adding an entry now would also read as a competing claim
against the 0.8.0 one.

Breaking Changes

None.

🤖 Generated with Claude Code

https://claude.ai/code/session_01U1Jhu7fgTRJq7LK5MuKteE

Copilot AI lite review requested due to automatic review settings August 27, 2026 19:25

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot was unable to review this pull request because the user who requested the review has reached their quota limit.

@github-actions

github-actions Bot commented Aug 27, 2026

Copy link
Copy Markdown

Test Results

    4 files    764 suites   2m 10s ⏱️
  487 tests   484 ✅  3 💤 0 ❌
1 952 runs  1 885 ✅ 67 💤 0 ❌

Results for commit d5a8ab7.

♻️ This comment has been updated with latest results.

Authenticode signing and catalog support shipped in 0.8.0 (#92), but none of
the sixteen settings it added to build.properties.ps1 ever reached the README
settings table. The only way to discover how to sign a module was to read
build.properties.ps1 and psakeFile.ps1, which is not a reference a consumer
should have to reconstruct for themselves on the way to 1.0.0.

The defaults are read from build.properties.ps1 rather than from the function
parameters, which is the mistake #186 was opened to correct in four existing
rows. The descriptions are condensed from the inline documentation there, with
two exceptions taken from the implementation instead:

  - Sign.SkipCertificateValidation is documented as applying to the EnvVar and
    PfxFile sources, because that is what Get-PSBuildCertificate does. Its
    inline comment claims Store and Thumbprint, where the query already filters
    on private key and expiry and there is nothing left to skip.
  - Sign.Catalog.FileName documents the computed <ModuleName>.cat fallback,
    which lives in the tasks rather than in the defaults.

A short "Code signing" section covers the five CertificateSource modes. The
choice between them is a setup decision about where a pipeline keeps its
certificate, and the Auto fallback chain in particular cannot be explained in a
table cell.

Also adds what the table rows imply exist: the Sign, SignModule, BuildCatalog,
and SignCatalog tasks, and the four $PSB{TaskName}Dependency variables the
dependency table stopped short of.

With the gap closed, the README drift guard now asserts both directions. The
reverse assertion needs no allow-list: every leaf of the defaults is in the
table, Build.ModuleOutDir included, which is documented with a note that it is
for internal use rather than hidden from the readers the table exists for.

Closes #189

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01U1Jhu7fgTRJq7LK5MuKteE
@tablackburn
tablackburn force-pushed the docs/readme-sign-settings branch from df6921d to d5a8ab7 Compare August 27, 2026 22:27
@tablackburn
tablackburn merged commit 6796caf into main Aug 27, 2026
9 checks passed
@tablackburn
tablackburn deleted the docs/readme-sign-settings branch August 27, 2026 22:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

docs: The sixteen $PSBPreference.Sign settings are undocumented in the README

2 participants