Skip to content

Commit f9f0974

Browse files
chore: update Process-PSModule to v6.1.13
Align workflow pin and packaging assertions to Process-PSModule v6.1.13, and disable Build-Site until this repo migrates from mkdocs to zensical.toml required by the latest release. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
1 parent a04a69e commit f9f0974

3 files changed

Lines changed: 191 additions & 35 deletions

File tree

.github/PSModule.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ Test:
1717
# MacOS:
1818
# Skip: true
1919
Build:
20-
Docs:
21-
# PlatyPS loads a conflicting YamlDotNet assembly before importing this module.
20+
Site:
21+
# Process-PSModule v6.1.13 switched Build-Site to zensical.toml only.
22+
# Keep site build off until this repository migrates from .github/mkdocs.yml.
2223
Skip: true
23-
2424
Linter:
2525
env:
2626
VALIDATE_BIOME_FORMAT: false

.github/workflows/Process-PSModule.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ permissions:
2727

2828
jobs:
2929
Process-PSModule:
30-
uses: PSModule/Process-PSModule/.github/workflows/workflow.yml@da180bac16b13bfbcdf08b2e4e221b5b49e5ff28 # v6.1.4
30+
uses: PSModule/Process-PSModule/.github/workflows/workflow.yml@fb1bdb8fefd243292f779d2a856a38db6fe6daf4 # v6.1.13
3131
with:
3232
ImportantFilePatterns: |
3333
^src/

tests/Packaging.Tests.ps1

Lines changed: 187 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -11,60 +11,216 @@
1111
[CmdletBinding()]
1212
param()
1313

14-
Describe 'Packaged dependency' {
15-
BeforeAll {
16-
$repositoryRoot = Split-Path -Parent $PSScriptRoot
17-
}
14+
$importedYamlCommand = Get-Command -Name ConvertFrom-Yaml -ErrorAction SilentlyContinue
15+
$skipArtifactTests = [string]::IsNullOrWhiteSpace($env:PSMODULE_YAML_TEST_ARTIFACT) -and (
16+
$null -eq $importedYamlCommand -or $importedYamlCommand.ModuleName -ne 'Yaml'
17+
)
1818

19-
It 'bundles the exact YamlDotNet 18.1.0 netstandard2.0 assembly' {
20-
$hash = Get-FileHash -Path (
21-
Join-Path $repositoryRoot 'src\assemblies\YamlDotNet.dll'
22-
) -Algorithm SHA256
19+
BeforeAll {
20+
. (Join-Path $PSScriptRoot 'TestBootstrap.ps1')
21+
$repositoryRoot = Split-Path -Parent $PSScriptRoot
22+
$loadedYamlModule = if (-not [string]::IsNullOrWhiteSpace(
23+
$env:PSMODULE_YAML_TEST_ARTIFACT
24+
)) {
25+
Import-Module -Name $env:PSMODULE_YAML_TEST_ARTIFACT -Force -Global -PassThru |
26+
Where-Object Name -EQ 'Yaml' |
27+
Select-Object -First 1
28+
} else {
29+
$command = Get-Command -Name ConvertFrom-Yaml -ErrorAction SilentlyContinue
30+
if ($null -ne $command -and $command.ModuleName -eq 'Yaml') {
31+
$command.Module
32+
}
33+
}
34+
$artifactManifestPath = if ($null -ne $loadedYamlModule) {
35+
Join-Path $loadedYamlModule.ModuleBase 'Yaml.psd1'
36+
} else {
37+
$null
38+
}
39+
}
2340

24-
$hash.Hash | Should -Be '91CD6D1FD0AE5B64BF6B252EB3B1AF2382CBC599C29045427C45FE8403D4295D'
41+
Describe 'Dependency-free package source' {
42+
It 'contains no external parser assembly, license, or notice payload' {
43+
@(
44+
Get-ChildItem -Path (Join-Path $repositoryRoot 'src\assemblies') `
45+
-File -ErrorAction SilentlyContinue
46+
).Count | Should -Be 0
47+
Test-Path (Join-Path $repositoryRoot 'src\licenses\YamlDotNet.LICENSE.txt') | Should -BeFalse
48+
Test-Path (Join-Path $repositoryRoot 'src\THIRD-PARTY-NOTICES.txt') | Should -BeFalse
2549
}
2650

2751
It 'keeps RequiredAssemblies out of the source manifest' {
2852
$manifest = Import-PowerShellDataFile -Path (
2953
Join-Path $repositoryRoot 'src\manifest.psd1'
3054
)
3155

32-
$manifest.DotNetFrameworkVersion | Should -Be '4.7.2'
56+
$manifest.ContainsKey('DotNetFrameworkVersion') | Should -BeFalse
3357
$manifest.ContainsKey('RequiredAssemblies') | Should -BeFalse
3458
}
3559

36-
It 'packages the upstream license and dependency provenance' {
37-
$license = Get-Content -Path (
38-
Join-Path $repositoryRoot 'src\licenses\YamlDotNet.LICENSE.txt'
39-
) -Raw
40-
$notice = Get-Content -Path (
41-
Join-Path $repositoryRoot 'src\THIRD-PARTY-NOTICES.txt'
42-
) -Raw
60+
It 'contains no external parser references or custom assembly loader' {
61+
$sourceFiles = Get-ChildItem -Path (Join-Path $repositoryRoot 'src') -Recurse -File
62+
$source = $sourceFiles |
63+
Where-Object Extension -In @('.ps1', '.psd1', '.psm1') |
64+
Get-Content -Raw
65+
66+
$source | Should -Not -Match 'YamlDotNet'
67+
$source | Should -Not -Match '\bAdd-Type\b'
68+
$source | Should -Not -Match 'Assembly\]::Load'
69+
}
4370

44-
$license | Should -Match 'Copyright \(c\) 2008, 2009, 2010'
45-
$license | Should -Match 'Permission is hereby granted, free of charge'
46-
$notice | Should -Match 'YamlDotNet 18\.1\.0'
47-
$notice | Should -Match 'lib/netstandard2\.0/YamlDotNet\.dll'
48-
$notice | Should -Match '59FFE65ADE67AD9D886267F877B634A450363CB81B94E19DB9CA4C36461416F6'
49-
$notice | Should -Match '91CD6D1FD0AE5B64BF6B252EB3B1AF2382CBC599C29045427C45FE8403D4295D'
71+
It 'keeps the owned processor layers explicit and source-level' {
72+
$privatePath = Join-Path $repositoryRoot 'src\functions\private'
73+
@(
74+
'New-YamlReaderContext.ps1',
75+
'Read-YamlDirectiveBlock.ps1',
76+
'New-YamlSyntaxNode.ps1',
77+
'ConvertFrom-YamlSyntaxTree.ps1',
78+
'Resolve-YamlScalar.ps1',
79+
'ConvertFrom-YamlNode.ps1',
80+
'Get-YamlSerializationShape.ps1',
81+
'ConvertTo-YamlNode.ps1',
82+
'Write-YamlNodeText.ps1'
83+
) | ForEach-Object {
84+
Test-Path -LiteralPath (Join-Path $privatePath $_) |
85+
Should -BeTrue -Because "$_ defines a required processor layer"
86+
}
5087
}
5188

52-
It 'uses Process-PSModule 6.1.4 and treats tests as important changes' {
89+
It 'uses Process-PSModule 6.1.13 and treats tests as important changes' {
5390
$workflow = Get-Content -Path (
5491
Join-Path $repositoryRoot '.github\workflows\Process-PSModule.yml'
5592
) -Raw
5693

57-
$workflow | Should -Match 'workflow\.yml@da180bac16b13bfbcdf08b2e4e221b5b49e5ff28 # v6\.1\.4'
94+
$workflow | Should -Match 'workflow\.yml@fb1bdb8fefd243292f779d2a856a38db6fe6daf4 # v6\.1\.13'
5895
$workflow | Should -Match '\^src/'
5996
$workflow | Should -Match '\^tests/'
6097
}
6198

62-
It 'does not add a custom assembly loader to module source' {
63-
$source = Get-ChildItem -Path (Join-Path $repositoryRoot 'src') -Recurse -File |
64-
Where-Object Extension -EQ '.ps1' |
65-
Get-Content -Raw
99+
It 'does not skip generated documentation' {
100+
$configuration = Get-Content -Path (
101+
Join-Path $repositoryRoot '.github\PSModule.yml'
102+
) -Raw
66103

67-
$source | Should -Not -Match '\bAdd-Type\b'
68-
$source | Should -Not -Match 'Assembly\]::Load'
104+
$configuration | Should -Not -Match '(?ms)Build:\s+Docs:\s+.*Skip:\s*true'
105+
}
106+
107+
It 'skips site build until zensical.toml is adopted' {
108+
$configuration = Get-Content -Path (
109+
Join-Path $repositoryRoot '.github\PSModule.yml'
110+
) -Raw
111+
112+
$configuration | Should -Match '(?ms)Build:\s+Site:\s+.*Skip:\s*true'
113+
Test-Path -Path (Join-Path $repositoryRoot 'zensical.toml') | Should -BeFalse
114+
}
115+
}
116+
117+
Describe 'Generated artifact package' {
118+
It 'has no RequiredAssemblies or packaged DLL and has a complete FileList' `
119+
-Skip:$skipArtifactTests {
120+
$manifest = Import-PowerShellDataFile -Path $artifactManifestPath
121+
$moduleBase = Split-Path -Parent $artifactManifestPath
122+
123+
$manifest.ContainsKey('RequiredAssemblies') | Should -BeFalse
124+
$manifest.ContainsKey('DotNetFrameworkVersion') | Should -BeFalse
125+
@($manifest.FunctionsToExport | Sort-Object) |
126+
Should -Be @('ConvertFrom-Yaml', 'ConvertTo-Yaml', 'Test-Yaml')
127+
@($manifest.FileList) | Should -Contain 'Yaml.psm1'
128+
@($manifest.FileList | Where-Object { $_ -match '\.(?:dll|exe)$' }).Count | Should -Be 0
129+
@($manifest.FileList | Where-Object { $_ -match 'THIRD-PARTY|YamlDotNet' }).Count | Should -Be 0
130+
@(Get-ChildItem -Path $moduleBase -Recurse -File -Filter '*.dll').Count | Should -Be 0
131+
{ Test-ModuleManifest -Path $artifactManifestPath } | Should -Not -Throw
132+
}
133+
134+
It 'imports in a fresh PowerShell process beside an existing YamlDotNet identity' `
135+
-Skip:($skipArtifactTests -or $null -eq (Get-Command pwsh -ErrorAction SilentlyContinue)) {
136+
$script = @'
137+
$ErrorActionPreference = 'Stop'
138+
$name = [System.Reflection.AssemblyName]::new('YamlDotNet')
139+
try {
140+
$null = [System.Reflection.Emit.AssemblyBuilder]::DefineDynamicAssembly(
141+
$name,
142+
[System.Reflection.Emit.AssemblyBuilderAccess]::Run
143+
)
144+
} catch {
145+
$null = [AppDomain]::CurrentDomain.DefineDynamicAssembly(
146+
$name,
147+
[System.Reflection.Emit.AssemblyBuilderAccess]::Run
148+
)
149+
}
150+
Import-Module -Name '__MANIFEST__' -Force
151+
$value = 'v: []' | ConvertFrom-Yaml -AsHashtable
152+
if ($value['v'] -isnot [object[]] -or $value['v'].Count -ne 0) {
153+
throw 'The empty sequence did not survive import.'
154+
}
155+
if (-not ('name: Ada' | Test-Yaml)) {
156+
throw 'The imported parser did not validate YAML.'
157+
}
158+
$shared = [ordered]@{ value = 1 }
159+
$roundTrip = [ordered]@{ first = $shared; second = $shared } |
160+
ConvertTo-Yaml |
161+
ConvertFrom-Yaml -AsHashtable
162+
if (-not [object]::ReferenceEquals($roundTrip['first'], $roundTrip['second'])) {
163+
throw 'The fresh-process graph round trip lost alias identity.'
164+
}
165+
'coexistence-ok'
166+
'@.Replace('__MANIFEST__', $artifactManifestPath.Replace("'", "''"))
167+
168+
(& pwsh -NoLogo -NoProfile -Command $script) | Should -Contain 'coexistence-ok'
169+
$LASTEXITCODE | Should -Be 0
170+
}
171+
172+
It 'preserves internal arrays and aliases in a fresh Windows PowerShell 5.1 process' `
173+
-Skip:($skipArtifactTests -or $null -eq (Get-Command powershell.exe -ErrorAction SilentlyContinue)) {
174+
$script = @'
175+
$ErrorActionPreference = 'Stop'
176+
$name = [System.Reflection.AssemblyName]::new('YamlDotNet')
177+
$null = [AppDomain]::CurrentDomain.DefineDynamicAssembly(
178+
$name,
179+
[System.Reflection.Emit.AssemblyBuilderAccess]::Run
180+
)
181+
Import-Module -Name '__MANIFEST__' -Force
182+
$empty = 'v: []' | ConvertFrom-Yaml -AsHashtable
183+
if ($empty['v'] -isnot [object[]] -or $empty['v'].Count -ne 0) {
184+
throw 'The empty sequence was corrupted.'
185+
}
186+
$binary = "a: &x !!binary SGVsbG8=`nb: *x" | ConvertFrom-Yaml -AsHashtable
187+
if ($binary['a'] -isnot [byte[]] -or -not [object]::ReferenceEquals($binary['a'], $binary['b'])) {
188+
throw 'The binary value or alias identity was corrupted.'
189+
}
190+
$sequence = "a: &x []`nb: *x" | ConvertFrom-Yaml -AsHashtable
191+
if ($sequence['a'] -isnot [object[]] -or
192+
-not [object]::ReferenceEquals($sequence['a'], $sequence['b'])) {
193+
throw 'The sequence alias identity was corrupted.'
194+
}
195+
$recursive = 'a: &x [*x]' | ConvertFrom-Yaml -AsHashtable
196+
if (-not [object]::ReferenceEquals($recursive['a'], $recursive['a'][0])) {
197+
throw 'The recursive alias was corrupted.'
198+
}
199+
$negativeZero = [BitConverter]::Int64BitsToDouble([long]::MinValue)
200+
if ((ConvertTo-Yaml -InputObject $negativeZero).Trim() -ne '-0.0') {
201+
throw 'The negative-zero sign was lost.'
202+
}
203+
$flow = ('[' * 127) + 'null' + (']' * 127)
204+
if (-not (Test-Yaml -Yaml $flow -Depth 128 -MaxNodes 200)) {
205+
throw 'The public maximum parse depth failed.'
206+
}
207+
$atLimit = [ordered]@{}
208+
$current = $atLimit
209+
for ($level = 1; $level -lt 127; $level++) {
210+
$next = [ordered]@{}
211+
$current['nested'] = $next
212+
$current = $next
213+
}
214+
$current['value'] = 1
215+
$deepYaml = ConvertTo-Yaml -InputObject $atLimit -Depth 128 -MaxNodes 300
216+
if (-not (Test-Yaml -Yaml $deepYaml -Depth 128 -MaxNodes 300)) {
217+
throw 'The public maximum serialization depth failed.'
218+
}
219+
'windows-powershell-ok'
220+
'@.Replace('__MANIFEST__', $artifactManifestPath.Replace("'", "''"))
221+
222+
(& powershell.exe -NoLogo -NoProfile -Command $script) |
223+
Should -Contain 'windows-powershell-ok'
224+
$LASTEXITCODE | Should -Be 0
69225
}
70226
}

0 commit comments

Comments
 (0)