Skip to content

Commit 705fc27

Browse files
🩹 [Patch]: Green the Process-PSModule v6 pipeline (markers, long line, TestData bridge)
Repinning to v6.1.0 surfaced three gaps in the source/test wiring: - Add the #SkipTest:FunctionTest marker to Connect-Confluence and Get-ConfluenceAccessibleResource, the two public functions the marker pass missed. The FunctionTest source-code check requires every public function to have a test or the marker; slimming the integration suite removed the calls that previously covered them, so both were flagged. - Wrap the 152-character query line in Update-ConfluenceSpace so it satisfies PSAvoidLongLines (the repo linter sets MaximumLineLength = 150). - Add .github/scripts/Expose-TestData.ps1 (the canonical Process-PSModule v6 script) so the ModuleLocal/Module test jobs can expose the caller-provided TestData secret. The caller workflow already passes TestData but the bridge script that turns it into environment variables was missing.
1 parent 17c45bd commit 705fc27

4 files changed

Lines changed: 144 additions & 3 deletions

File tree

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
if ([string]::IsNullOrWhiteSpace($env:PSMODULE_TEST_DATA)) {
2+
Write-Output 'No test data was provided by the calling workflow.'
3+
return
4+
}
5+
try {
6+
$data = $env:PSMODULE_TEST_DATA | ConvertFrom-Json -ErrorAction Stop
7+
} catch {
8+
throw "The 'TestData' secret must be valid JSON with 'secrets' and/or 'variables' maps."
9+
}
10+
if ($null -eq $data -or $data -isnot [pscustomobject]) {
11+
throw "The 'TestData' secret must be a JSON object with 'secrets' and/or 'variables' maps."
12+
}
13+
$allowedTopLevelKeys = @('secrets', 'variables')
14+
foreach ($propertyName in $data.PSObject.Properties.Name) {
15+
if ($allowedTopLevelKeys -notcontains $propertyName) {
16+
throw "The 'TestData' secret only supports 'secrets' and 'variables' maps."
17+
}
18+
}
19+
$reservedNames = @('CI', 'HOME', 'PATH', 'PWD', 'SHELL', 'PSMODULE_TEST_DATA')
20+
$reservedPrefixes = @('GITHUB_', 'RUNNER_', 'ACTIONS_')
21+
function Assert-EnvironmentName {
22+
<#
23+
.SYNOPSIS
24+
Validates that a TestData key can safely be written to GITHUB_ENV.
25+
#>
26+
param([string] $Name)
27+
if ($Name -notmatch '^[A-Za-z_][A-Za-z0-9_]*$') {
28+
throw 'TestData keys must be valid environment variable names.'
29+
}
30+
$normalized = $Name.ToUpperInvariant()
31+
if ($reservedNames -contains $normalized) {
32+
throw 'TestData keys must not override reserved environment variables.'
33+
}
34+
foreach ($prefix in $reservedPrefixes) {
35+
if ($normalized.StartsWith($prefix)) {
36+
throw 'TestData keys must not override reserved environment variables.'
37+
}
38+
}
39+
}
40+
function Assert-Map {
41+
<#
42+
.SYNOPSIS
43+
Validates that a TestData section is a JSON object map.
44+
#>
45+
param(
46+
[object] $Map,
47+
[string] $Name
48+
)
49+
if ($null -eq $Map) { return }
50+
if ($Map -isnot [pscustomobject]) {
51+
throw "The 'TestData.$Name' value must be a JSON object."
52+
}
53+
}
54+
function Get-EnvironmentValue {
55+
<#
56+
.SYNOPSIS
57+
Converts a scalar TestData value to an environment variable value.
58+
#>
59+
param(
60+
[object] $Value,
61+
[string] $Name
62+
)
63+
if ($null -eq $Value) { return '' }
64+
if (
65+
$Value -is [pscustomobject] -or
66+
($Value -is [System.Collections.IEnumerable] -and $Value -isnot [string])
67+
) {
68+
throw "Values in 'TestData.$Name' must be scalar values."
69+
}
70+
return [string]$Value
71+
}
72+
function Add-EnvFromMap {
73+
<#
74+
.SYNOPSIS
75+
Writes validated TestData entries to GITHUB_ENV.
76+
#>
77+
param(
78+
[object] $Map,
79+
[string] $Name,
80+
[switch] $Mask
81+
)
82+
Assert-Map -Map $Map -Name $Name
83+
if ($null -eq $Map) { return }
84+
$count = 0
85+
foreach ($item in $Map.PSObject.Properties) {
86+
$name = $item.Name
87+
Assert-EnvironmentName -Name $name
88+
$value = Get-EnvironmentValue -Value $item.Value -Name $Name
89+
if ($Mask) {
90+
foreach ($line in ($value -split "`n")) {
91+
$line = $line.TrimEnd("`r")
92+
if ($line.Length -gt 0) {
93+
Write-Output "::add-mask::$line"
94+
}
95+
}
96+
}
97+
do {
98+
$delimiter = "GHENV_$([guid]::NewGuid().ToString('N'))"
99+
} while ($value.Contains($delimiter))
100+
Add-Content -Path $env:GITHUB_ENV -Value "$name<<$delimiter" -Encoding utf8
101+
Add-Content -Path $env:GITHUB_ENV -Value $value -Encoding utf8
102+
Add-Content -Path $env:GITHUB_ENV -Value $delimiter -Encoding utf8
103+
$count++
104+
}
105+
if ($count -gt 0) {
106+
if ($Mask) {
107+
Write-Output "Exposed $count secret value(s) as environment variables."
108+
} else {
109+
Write-Output "Exposed $count variable value(s) as environment variables."
110+
}
111+
}
112+
}
113+
114+
Assert-Map -Map $data.secrets -Name 'secrets'
115+
Assert-Map -Map $data.variables -Name 'variables'
116+
117+
$secretNames = @()
118+
if ($null -ne $data.secrets) {
119+
$secretNames = @($data.secrets.PSObject.Properties.Name)
120+
}
121+
$variableNames = @()
122+
if ($null -ne $data.variables) {
123+
$variableNames = @($data.variables.PSObject.Properties.Name)
124+
}
125+
$secretNameSet = [System.Collections.Generic.HashSet[string]]::new(
126+
[System.StringComparer]::OrdinalIgnoreCase
127+
)
128+
foreach ($secretName in $secretNames) {
129+
[void] $secretNameSet.Add($secretName)
130+
}
131+
foreach ($variableName in $variableNames) {
132+
if ($secretNameSet.Contains($variableName)) {
133+
throw 'TestData keys must not be duplicated across secrets and variables.'
134+
}
135+
}
136+
137+
Add-EnvFromMap -Map $data.secrets -Name 'secrets' -Mask
138+
Add-EnvFromMap -Map $data.variables -Name 'variables'

‎src/functions/public/Auth/Connect-Confluence.ps1‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
function Connect-Confluence {
1+
#SkipTest:FunctionTest:Integration tests are added once the repository Confluence credentials are configured.
2+
function Connect-Confluence {
23
<#
34
.SYNOPSIS
45
Connect to Confluence and store a credential profile in the context vault.

‎src/functions/public/Auth/Get-ConfluenceAccessibleResource.ps1‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
function Get-ConfluenceAccessibleResource {
1+
#SkipTest:FunctionTest:Integration tests are added once the repository Confluence credentials are configured.
2+
function Get-ConfluenceAccessibleResource {
23
<#
34
.SYNOPSIS
45
List the Atlassian sites (resources) a token can reach.

‎src/functions/public/Spaces/Update-ConfluenceSpace.ps1‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ function Update-ConfluenceSpace {
4343

4444
# Read the current space (with its plain-text description) so a caller who
4545
# updates only one field does not blank the other on the full-body v1 PUT.
46-
$response = Invoke-ConfluenceRestMethod -ApiEndpoint '/wiki/api/v2/spaces' -Query @{ keys = $Key; 'description-format' = 'plain' } -Context $Context
46+
$query = @{ keys = $Key; 'description-format' = 'plain' }
47+
$response = Invoke-ConfluenceRestMethod -ApiEndpoint '/wiki/api/v2/spaces' -Query $query -Context $Context
4748
$current = $response.results | Where-Object { $_.key -eq $Key } | Select-Object -First 1
4849
if (-not $current) {
4950
throw "Confluence space '$Key' was not found."

0 commit comments

Comments
 (0)