Skip to content

Commit 364ddd6

Browse files
🌟 [Major]: Fixed test secret inputs replaced by TestData (#365)
Module test jobs now use a `TestData` object for optional test secrets and non-secret variables. This replaces the previous fixed `TEST_*` workflow secret inputs: callers that used those inputs must pass the same names inside `TestData`, while callers that need different names can expose them without changing the shared workflow. - Fixes #52 ## Breaking Changes ### Removed: fixed `TEST_*` workflow secret inputs The reusable workflow no longer declares or accepts these individual test-secret inputs: - `TEST_APP_ENT_CLIENT_ID` - `TEST_APP_ENT_PRIVATE_KEY` - `TEST_APP_ORG_CLIENT_ID` - `TEST_APP_ORG_PRIVATE_KEY` - `TEST_USER_ORG_FG_PAT` - `TEST_USER_USER_FG_PAT` - `TEST_USER_PAT` Callers using any of these inputs must move them into the `secrets` map inside `TestData`. The names can stay the same, so existing Pester tests can continue reading the same environment variables. ```yaml jobs: Process-PSModule: uses: PSModule/Process-PSModule/.github/workflows/workflow.yml@v5 secrets: APIKey: ${{ secrets.APIKey }} TestData: >- { "secrets": { "TEST_USER_PAT": "${{ secrets.TEST_USER_PAT }}", "TEST_APP_ORG_CLIENT_ID": "${{ secrets.TEST_APP_ORG_CLIENT_ID }}" } } ``` ```powershell $env:TEST_USER_PAT $env:TEST_APP_ORG_CLIENT_ID ``` ## New: Caller-selected `TestData` `TestData` is an optional single-line JSON object with `secrets` and `variables` maps. Entries from both maps become environment variables in `BeforeAll-ModuleLocal`, `Test-ModuleLocal`, and `AfterAll-ModuleLocal`. ```yaml TestData: >- { "secrets": { "CONFLUENCE_API_TOKEN": "${{ secrets.CONFLUENCE_API_TOKEN }}" }, "variables": { "CONFLUENCE_SITE": ${{ toJSON(vars.CONFLUENCE_SITE) }}, "CONFLUENCE_SPACE_KEY": ${{ toJSON(vars.CONFLUENCE_SPACE_KEY) }} } } ``` ```powershell $env:CONFLUENCE_API_TOKEN # from the secrets map, masked in logs $env:CONFLUENCE_SITE # from the variables map, not masked ``` Values under `secrets` are masked before being exposed to the test jobs. Values under `variables` are exposed without masking for normal, non-sensitive configuration. Modules that do not need secrets or variables can omit `TestData` entirely. Because the workflow does not use `secrets: inherit`, only the values explicitly listed in `TestData` are exposed to module tests. ## New: Safe `TestData` validation and formatting `TestData` must parse as a JSON object containing only optional `secrets` and `variables` maps. Values in those maps must be scalar values. Keys must be safe environment-variable names matching `^[A-Za-z_][A-Za-z0-9_]*$`, must not be duplicated across `secrets` and `variables`, and must not override reserved variables such as `PATH`, `CI`, `GITHUB_*`, `RUNNER_*` or `ACTIONS_*`. Pass `TestData` as a single-line value after YAML folding. The folded `>-` form is safe when the JSON is compact, or when every JSON content line stays at the same indentation level inside the block. Avoid normal pretty-printed JSON with nested indentation inside `>-`. YAML preserves more-indented lines instead of folding them, so that shape can still produce a multi-line secret value. Keeping `TestData` single-line after folding avoids GitHub treating line fragments as separate mask values. Use the direct quoted form for single-line secrets: ```yaml "CONFLUENCE_API_TOKEN": "${{ secrets.CONFLUENCE_API_TOKEN }}" ``` Using the JSON-encoded approach, github-advanced security will warn that all secrets available to the runner gets exposed. ```yaml "CONFLUENCE_API_TOKEN": ${{ toJSON(vars.CONFLUENCE_API_TOKEN) }} ``` Use `toJSON(vars.NAME)` for variables so normal configuration values are JSON-encoded safely: ```yaml "CONFLUENCE_SITE": ${{ toJSON(vars.CONFLUENCE_SITE) }} ``` For multi-line secrets, or secrets containing quotes or backslashes, base64-encode the secret and decode it in the test. ## Technical Details - `workflow.yml` declares and forwards a single optional `TestData` secret instead of the seven fixed `TEST_*` secrets. - `.github/scripts/Expose-TestData.ps1` contains the shared `TestData` parsing, validation, masking, and UTF-8 `GITHUB_ENV` export logic used by the ModuleLocal workflows. - `BeforeAll-ModuleLocal.yml`, `Test-ModuleLocal.yml`, and `AfterAll-ModuleLocal.yml` call the shared helper instead of duplicating the security-sensitive exposure logic. - `Test-Module.yml` no longer declares or exports the obsolete fixed `TEST_*` secrets. - The fixture-backed self-test workflows skip forked `pull_request` runs where repository secrets and variables are unavailable, while still running for trusted PRs, schedules, and manual dispatches. - The parse failure path uses stable messages that do not echo the raw secret payload, and secret keys are no longer printed in logs. - The self-test workflows pass dedicated fixture data through `TestData`, and the environment Pester tests assert the exact exposed secret and variable values. - `README.md` documents the breaking migration path, the `TestData` contract, safe YAML folding, safe key names, environment-scoped value usage, the difference between masked secrets and unmasked variables, and base64 guidance for complex secret values. - The diff also addresses #322's duplicated fixed-secret pass-through without adopting broad `secrets: inherit`.
1 parent 8b75537 commit 364ddd6

11 files changed

Lines changed: 356 additions & 214 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'

.github/workflows/AfterAll-ModuleLocal.yml

Lines changed: 12 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,42 +3,18 @@ name: AfterAll-ModuleLocal
33
on:
44
workflow_call:
55
secrets:
6-
TEST_APP_ENT_CLIENT_ID:
7-
description: The client ID of an Enterprise GitHub App for running tests.
8-
required: false
9-
TEST_APP_ENT_PRIVATE_KEY:
10-
description: The private key of an Enterprise GitHub App for running tests.
11-
required: false
12-
TEST_APP_ORG_CLIENT_ID:
13-
description: The client ID of an Organization GitHub App for running tests.
14-
required: false
15-
TEST_APP_ORG_PRIVATE_KEY:
16-
description: The private key of an Organization GitHub App for running tests.
17-
required: false
18-
TEST_USER_ORG_FG_PAT:
19-
description: The fine-grained personal access token with org access for running tests.
20-
required: false
21-
TEST_USER_USER_FG_PAT:
22-
description: The fine-grained personal access token with user account access for running tests.
23-
required: false
24-
TEST_USER_PAT:
25-
description: The classic personal access token for running tests.
6+
TestData:
7+
description: |
8+
Optional single-line JSON object with 'secrets' and 'variables' maps. Each entry is exposed
9+
as an environment variable available to the AfterAll teardown script; 'secrets' values are
10+
masked in the logs, 'variables' values are not.
2611
required: false
2712
inputs:
2813
Settings:
2914
type: string
3015
description: The complete settings object including test suites.
3116
required: true
3217

33-
env:
34-
TEST_APP_ENT_CLIENT_ID: ${{ secrets.TEST_APP_ENT_CLIENT_ID }}
35-
TEST_APP_ENT_PRIVATE_KEY: ${{ secrets.TEST_APP_ENT_PRIVATE_KEY }}
36-
TEST_APP_ORG_CLIENT_ID: ${{ secrets.TEST_APP_ORG_CLIENT_ID }}
37-
TEST_APP_ORG_PRIVATE_KEY: ${{ secrets.TEST_APP_ORG_PRIVATE_KEY }}
38-
TEST_USER_ORG_FG_PAT: ${{ secrets.TEST_USER_ORG_FG_PAT }}
39-
TEST_USER_USER_FG_PAT: ${{ secrets.TEST_USER_USER_FG_PAT }}
40-
TEST_USER_PAT: ${{ secrets.TEST_USER_PAT }}
41-
4218
permissions:
4319
contents: read # to checkout the repo
4420

@@ -55,6 +31,13 @@ jobs:
5531
persist-credentials: false
5632
fetch-depth: 0
5733

34+
- name: Expose caller-provided test data
35+
shell: pwsh
36+
env:
37+
PSMODULE_TEST_DATA: ${{ secrets.TestData }}
38+
run: |
39+
./.github/scripts/Expose-TestData.ps1
40+
5841
- name: Run AfterAll Teardown Scripts
5942
if: always()
6043
uses: PSModule/GitHub-Script@1ee97bbc652d19c38ae12f6e1e47e9d9fbd12d0a # v1.8.0

.github/workflows/BeforeAll-ModuleLocal.yml

Lines changed: 12 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -3,42 +3,18 @@ name: BeforeAll-ModuleLocal
33
on:
44
workflow_call:
55
secrets:
6-
TEST_APP_ENT_CLIENT_ID:
7-
description: The client ID of an Enterprise GitHub App for running tests.
8-
required: false
9-
TEST_APP_ENT_PRIVATE_KEY:
10-
description: The private key of an Enterprise GitHub App for running tests.
11-
required: false
12-
TEST_APP_ORG_CLIENT_ID:
13-
description: The client ID of an Organization GitHub App for running tests.
14-
required: false
15-
TEST_APP_ORG_PRIVATE_KEY:
16-
description: The private key of an Organization GitHub App for running tests.
17-
required: false
18-
TEST_USER_ORG_FG_PAT:
19-
description: The fine-grained personal access token with org access for running tests.
20-
required: false
21-
TEST_USER_USER_FG_PAT:
22-
description: The fine-grained personal access token with user account access for running tests.
23-
required: false
24-
TEST_USER_PAT:
25-
description: The classic personal access token for running tests.
6+
TestData:
7+
description: |
8+
Optional single-line JSON object with 'secrets' and 'variables' maps. Each entry is exposed
9+
as an environment variable available to the BeforeAll setup script; 'secrets' values are
10+
masked in the logs, 'variables' values are not.
2611
required: false
2712
inputs:
2813
Settings:
2914
type: string
3015
description: The complete settings object including test suites.
3116
required: true
3217

33-
env:
34-
TEST_APP_ENT_CLIENT_ID: ${{ secrets.TEST_APP_ENT_CLIENT_ID }}
35-
TEST_APP_ENT_PRIVATE_KEY: ${{ secrets.TEST_APP_ENT_PRIVATE_KEY }}
36-
TEST_APP_ORG_CLIENT_ID: ${{ secrets.TEST_APP_ORG_CLIENT_ID }}
37-
TEST_APP_ORG_PRIVATE_KEY: ${{ secrets.TEST_APP_ORG_PRIVATE_KEY }}
38-
TEST_USER_ORG_FG_PAT: ${{ secrets.TEST_USER_ORG_FG_PAT }}
39-
TEST_USER_USER_FG_PAT: ${{ secrets.TEST_USER_USER_FG_PAT }}
40-
TEST_USER_PAT: ${{ secrets.TEST_USER_PAT }}
41-
4218
permissions:
4319
contents: read # to checkout the repo
4420

@@ -55,6 +31,13 @@ jobs:
5531
persist-credentials: false
5632
fetch-depth: 0
5733

34+
- name: Expose caller-provided test data
35+
shell: pwsh
36+
env:
37+
PSMODULE_TEST_DATA: ${{ secrets.TestData }}
38+
run: |
39+
./.github/scripts/Expose-TestData.ps1
40+
5841
- name: Run BeforeAll Setup Scripts
5942
uses: PSModule/GitHub-Script@1ee97bbc652d19c38ae12f6e1e47e9d9fbd12d0a # v1.8.0
6043
with:

.github/workflows/Test-Module.yml

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -2,43 +2,12 @@ name: Test-Module
22

33
on:
44
workflow_call:
5-
secrets:
6-
TEST_APP_ENT_CLIENT_ID:
7-
description: The client ID of an Enterprise GitHub App for running tests.
8-
required: false
9-
TEST_APP_ENT_PRIVATE_KEY:
10-
description: The private key of an Enterprise GitHub App for running tests.
11-
required: false
12-
TEST_APP_ORG_CLIENT_ID:
13-
description: The client ID of an Organization GitHub App for running tests.
14-
required: false
15-
TEST_APP_ORG_PRIVATE_KEY:
16-
description: The private key of an Organization GitHub App for running tests.
17-
required: false
18-
TEST_USER_ORG_FG_PAT:
19-
description: The fine-grained personal access token with org access for running tests.
20-
required: false
21-
TEST_USER_USER_FG_PAT:
22-
description: The fine-grained personal access token with user account access for running tests.
23-
required: false
24-
TEST_USER_PAT:
25-
description: The classic personal access token for running tests.
26-
required: false
275
inputs:
286
Settings:
297
type: string
308
description: The settings object as a JSON string.
319
required: true
3210

33-
env:
34-
TEST_APP_ENT_CLIENT_ID: ${{ secrets.TEST_APP_ENT_CLIENT_ID }}
35-
TEST_APP_ENT_PRIVATE_KEY: ${{ secrets.TEST_APP_ENT_PRIVATE_KEY }}
36-
TEST_APP_ORG_CLIENT_ID: ${{ secrets.TEST_APP_ORG_CLIENT_ID }}
37-
TEST_APP_ORG_PRIVATE_KEY: ${{ secrets.TEST_APP_ORG_PRIVATE_KEY }}
38-
TEST_USER_ORG_FG_PAT: ${{ secrets.TEST_USER_ORG_FG_PAT }}
39-
TEST_USER_USER_FG_PAT: ${{ secrets.TEST_USER_USER_FG_PAT }}
40-
TEST_USER_PAT: ${{ secrets.TEST_USER_PAT }}
41-
4211
permissions:
4312
contents: read # to checkout the repo and create releases on the repo
4413

.github/workflows/Test-ModuleLocal.yml

Lines changed: 12 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,26 +3,11 @@ name: Test-ModuleLocal
33
on:
44
workflow_call:
55
secrets:
6-
TEST_APP_ENT_CLIENT_ID:
7-
description: The client ID of an Enterprise GitHub App for running tests.
8-
required: false
9-
TEST_APP_ENT_PRIVATE_KEY:
10-
description: The private key of an Enterprise GitHub App for running tests.
11-
required: false
12-
TEST_APP_ORG_CLIENT_ID:
13-
description: The client ID of an Organization GitHub App for running tests.
14-
required: false
15-
TEST_APP_ORG_PRIVATE_KEY:
16-
description: The private key of an Organization GitHub App for running tests.
17-
required: false
18-
TEST_USER_ORG_FG_PAT:
19-
description: The fine-grained personal access token with org access for running tests.
20-
required: false
21-
TEST_USER_USER_FG_PAT:
22-
description: The fine-grained personal access token with user account access for running tests.
23-
required: false
24-
TEST_USER_PAT:
25-
description: The classic personal access token for running tests.
6+
TestData:
7+
description: |
8+
Optional single-line JSON object with 'secrets' and 'variables' maps. Each entry is exposed
9+
as an environment variable the module's Pester tests read via $env:<name>; 'secrets' values
10+
are masked in the logs, 'variables' values are not.
2611
required: false
2712
inputs:
2813
Settings:
@@ -34,13 +19,6 @@ permissions:
3419
contents: read # to checkout the repo and create releases on the repo
3520

3621
env:
37-
TEST_APP_ENT_CLIENT_ID: ${{ secrets.TEST_APP_ENT_CLIENT_ID }}
38-
TEST_APP_ENT_PRIVATE_KEY: ${{ secrets.TEST_APP_ENT_PRIVATE_KEY }}
39-
TEST_APP_ORG_CLIENT_ID: ${{ secrets.TEST_APP_ORG_CLIENT_ID }}
40-
TEST_APP_ORG_PRIVATE_KEY: ${{ secrets.TEST_APP_ORG_PRIVATE_KEY }}
41-
TEST_USER_ORG_FG_PAT: ${{ secrets.TEST_USER_ORG_FG_PAT }}
42-
TEST_USER_USER_FG_PAT: ${{ secrets.TEST_USER_USER_FG_PAT }}
43-
TEST_USER_PAT: ${{ secrets.TEST_USER_PAT }}
4422
GITHUB_TOKEN: ${{ github.token }}
4523

4624
jobs:
@@ -58,6 +36,13 @@ jobs:
5836
persist-credentials: false
5937
fetch-depth: 0
6038

39+
- name: Expose caller-provided test data
40+
shell: pwsh
41+
env:
42+
PSMODULE_TEST_DATA: ${{ secrets.TestData }}
43+
run: |
44+
./.github/scripts/Expose-TestData.ps1
45+
6146
- name: Download module artifact
6247
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
6348
with:

.github/workflows/Workflow-Test-Default.yml

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,21 @@ permissions:
2525

2626
jobs:
2727
WorkflowTestDefault:
28+
if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
2829
uses: ./.github/workflows/workflow.yml
2930
secrets:
3031
APIKey: ${{ secrets.APIKey }}
31-
TEST_APP_ENT_CLIENT_ID: ${{ secrets.TEST_APP_ENT_CLIENT_ID }}
32-
TEST_APP_ENT_PRIVATE_KEY: ${{ secrets.TEST_APP_ENT_PRIVATE_KEY }}
33-
TEST_APP_ORG_CLIENT_ID: ${{ secrets.TEST_APP_ORG_CLIENT_ID }}
34-
TEST_APP_ORG_PRIVATE_KEY: ${{ secrets.TEST_APP_ORG_PRIVATE_KEY }}
35-
TEST_USER_ORG_FG_PAT: ${{ secrets.TEST_USER_ORG_FG_PAT }}
36-
TEST_USER_USER_FG_PAT: ${{ secrets.TEST_USER_USER_FG_PAT }}
37-
TEST_USER_PAT: ${{ secrets.TEST_USER_PAT }}
32+
# Self-test only: a dedicated, NON-SENSITIVE repository secret + variable exist purely to prove
33+
# the TestData plumbing end to end - the "secrets" entry is masked and the "variables" entry is
34+
# not, and both are exposed as $env:<name>. Their known values are asserted (value + length) in
35+
# tests/.../Environment.Tests.ps1.
36+
# Secrets use the direct "${{ secrets.X }}" form (CodeQL-clean; avoids toJSON(secrets.*)), which
37+
# requires single-line secret values with no embedded quotes or backslashes; variables use
38+
# toJSON(vars.X) so any characters are encoded safely. The folded '>-' scalar keeps the whole blob
39+
# on ONE line so GitHub registers a single mask instead of one per line.
40+
TestData: >-
41+
{ "secrets": { "PSMODULE_TEST_SINGLELINE_SECRET": "${{ secrets.PSMODULE_TEST_SINGLELINE_SECRET }}" },
42+
"variables": { "PSMODULE_TEST_VARIABLE": ${{ toJSON(vars.PSMODULE_TEST_VARIABLE) }} } }
3843
with:
3944
WorkingDirectory: tests/srcTestRepo
4045
ImportantFilePatterns: |

0 commit comments

Comments
 (0)