Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
63 changes: 34 additions & 29 deletions .github/workflows/AfterAll-ModuleLocal.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,17 @@ name: AfterAll-ModuleLocal
on:
workflow_call:
secrets:
TEST_APP_ENT_CLIENT_ID:
description: The client ID of an Enterprise GitHub App for running tests.
required: false
TEST_APP_ENT_PRIVATE_KEY:
description: The private key of an Enterprise GitHub App for running tests.
required: false
TEST_APP_ORG_CLIENT_ID:
description: The client ID of an Organization GitHub App for running tests.
required: false
TEST_APP_ORG_PRIVATE_KEY:
description: The private key of an Organization GitHub App for running tests.
required: false
TEST_USER_ORG_FG_PAT:
description: The fine-grained personal access token with org access for running tests.
required: false
TEST_USER_USER_FG_PAT:
description: The fine-grained personal access token with user account access for running tests.
required: false
TEST_USER_PAT:
description: The classic personal access token for running tests.
TestSecrets:
description: |
Optional JSON object mapping environment variable names to secret values. Each entry is
exposed as an environment variable available to the AfterAll teardown script.
required: false
inputs:
Settings:
type: string
description: The complete settings object including test suites.
required: true

env:
TEST_APP_ENT_CLIENT_ID: ${{ secrets.TEST_APP_ENT_CLIENT_ID }}
TEST_APP_ENT_PRIVATE_KEY: ${{ secrets.TEST_APP_ENT_PRIVATE_KEY }}
TEST_APP_ORG_CLIENT_ID: ${{ secrets.TEST_APP_ORG_CLIENT_ID }}
TEST_APP_ORG_PRIVATE_KEY: ${{ secrets.TEST_APP_ORG_PRIVATE_KEY }}
TEST_USER_ORG_FG_PAT: ${{ secrets.TEST_USER_ORG_FG_PAT }}
TEST_USER_USER_FG_PAT: ${{ secrets.TEST_USER_USER_FG_PAT }}
TEST_USER_PAT: ${{ secrets.TEST_USER_PAT }}

permissions:
contents: read # to checkout the repo

Expand All @@ -55,6 +30,36 @@ jobs:
persist-credentials: false
fetch-depth: 0

- name: Expose caller-provided test secrets
shell: pwsh
env:
PSMODULE_TEST_SECRETS: ${{ secrets.TestSecrets }}
run: |
Comment thread
MariusStorhaug marked this conversation as resolved.
if ([string]::IsNullOrWhiteSpace($env:PSMODULE_TEST_SECRETS)) {
Write-Host 'No test secrets were provided by the calling workflow.'
return
}
try {
$secrets = $env:PSMODULE_TEST_SECRETS | ConvertFrom-Json -ErrorAction Stop
} catch {
throw "The 'TestSecrets' secret must be a JSON object mapping names to values. $_"
}
Comment thread
MariusStorhaug marked this conversation as resolved.
Outdated
foreach ($secret in $secrets.PSObject.Properties) {
$name = $secret.Name
$value = [string]$secret.Value
Comment thread
MariusStorhaug marked this conversation as resolved.
Outdated
foreach ($line in ($value -split "`n")) {
Comment thread
MariusStorhaug marked this conversation as resolved.
Outdated
Comment thread
MariusStorhaug marked this conversation as resolved.
Outdated
$line = $line.TrimEnd("`r")
if ($line.Length -gt 0) {
Write-Host "::add-mask::$line"
}
}
$delimiter = "GHENV_$([guid]::NewGuid().ToString('N'))"
Add-Content -Path $env:GITHUB_ENV -Value "$name<<$delimiter"
Add-Content -Path $env:GITHUB_ENV -Value $value
Add-Content -Path $env:GITHUB_ENV -Value $delimiter
Write-Host "Exposed [$name] as an environment variable."
}
Comment thread
MariusStorhaug marked this conversation as resolved.
Outdated
Comment thread
MariusStorhaug marked this conversation as resolved.
Outdated

- name: Run AfterAll Teardown Scripts
if: always()
uses: PSModule/GitHub-Script@1ee97bbc652d19c38ae12f6e1e47e9d9fbd12d0a # v1.8.0
Expand Down
63 changes: 34 additions & 29 deletions .github/workflows/BeforeAll-ModuleLocal.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,42 +3,17 @@ name: BeforeAll-ModuleLocal
on:
workflow_call:
secrets:
TEST_APP_ENT_CLIENT_ID:
description: The client ID of an Enterprise GitHub App for running tests.
required: false
TEST_APP_ENT_PRIVATE_KEY:
description: The private key of an Enterprise GitHub App for running tests.
required: false
TEST_APP_ORG_CLIENT_ID:
description: The client ID of an Organization GitHub App for running tests.
required: false
TEST_APP_ORG_PRIVATE_KEY:
description: The private key of an Organization GitHub App for running tests.
required: false
TEST_USER_ORG_FG_PAT:
description: The fine-grained personal access token with org access for running tests.
required: false
TEST_USER_USER_FG_PAT:
description: The fine-grained personal access token with user account access for running tests.
required: false
TEST_USER_PAT:
description: The classic personal access token for running tests.
TestSecrets:
description: |
Optional JSON object mapping environment variable names to secret values. Each entry is
exposed as an environment variable available to the BeforeAll setup script.
required: false
inputs:
Settings:
type: string
description: The complete settings object including test suites.
required: true

env:
TEST_APP_ENT_CLIENT_ID: ${{ secrets.TEST_APP_ENT_CLIENT_ID }}
TEST_APP_ENT_PRIVATE_KEY: ${{ secrets.TEST_APP_ENT_PRIVATE_KEY }}
TEST_APP_ORG_CLIENT_ID: ${{ secrets.TEST_APP_ORG_CLIENT_ID }}
TEST_APP_ORG_PRIVATE_KEY: ${{ secrets.TEST_APP_ORG_PRIVATE_KEY }}
TEST_USER_ORG_FG_PAT: ${{ secrets.TEST_USER_ORG_FG_PAT }}
TEST_USER_USER_FG_PAT: ${{ secrets.TEST_USER_USER_FG_PAT }}
TEST_USER_PAT: ${{ secrets.TEST_USER_PAT }}

permissions:
contents: read # to checkout the repo

Expand All @@ -55,6 +30,36 @@ jobs:
persist-credentials: false
fetch-depth: 0

- name: Expose caller-provided test secrets
shell: pwsh
env:
PSMODULE_TEST_SECRETS: ${{ secrets.TestSecrets }}
run: |
Comment thread
MariusStorhaug marked this conversation as resolved.
if ([string]::IsNullOrWhiteSpace($env:PSMODULE_TEST_SECRETS)) {
Write-Host 'No test secrets were provided by the calling workflow.'
return
}
try {
$secrets = $env:PSMODULE_TEST_SECRETS | ConvertFrom-Json -ErrorAction Stop
} catch {
throw "The 'TestSecrets' secret must be a JSON object mapping names to values. $_"
}
Comment thread
MariusStorhaug marked this conversation as resolved.
Outdated
foreach ($secret in $secrets.PSObject.Properties) {
$name = $secret.Name
$value = [string]$secret.Value
Comment thread
MariusStorhaug marked this conversation as resolved.
Outdated
foreach ($line in ($value -split "`n")) {
Comment thread
MariusStorhaug marked this conversation as resolved.
Outdated
Comment thread
MariusStorhaug marked this conversation as resolved.
Outdated
$line = $line.TrimEnd("`r")
if ($line.Length -gt 0) {
Write-Host "::add-mask::$line"
}
}
$delimiter = "GHENV_$([guid]::NewGuid().ToString('N'))"
Add-Content -Path $env:GITHUB_ENV -Value "$name<<$delimiter"
Add-Content -Path $env:GITHUB_ENV -Value $value
Add-Content -Path $env:GITHUB_ENV -Value $delimiter
Write-Host "Exposed [$name] as an environment variable."
}
Comment thread
MariusStorhaug marked this conversation as resolved.
Outdated
Comment thread
MariusStorhaug marked this conversation as resolved.
Outdated

- name: Run BeforeAll Setup Scripts
uses: PSModule/GitHub-Script@1ee97bbc652d19c38ae12f6e1e47e9d9fbd12d0a # v1.8.0
with:
Expand Down
61 changes: 34 additions & 27 deletions .github/workflows/Test-ModuleLocal.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,10 @@ name: Test-ModuleLocal
on:
workflow_call:
secrets:
TEST_APP_ENT_CLIENT_ID:
description: The client ID of an Enterprise GitHub App for running tests.
required: false
TEST_APP_ENT_PRIVATE_KEY:
description: The private key of an Enterprise GitHub App for running tests.
required: false
TEST_APP_ORG_CLIENT_ID:
description: The client ID of an Organization GitHub App for running tests.
required: false
TEST_APP_ORG_PRIVATE_KEY:
description: The private key of an Organization GitHub App for running tests.
required: false
TEST_USER_ORG_FG_PAT:
description: The fine-grained personal access token with org access for running tests.
required: false
TEST_USER_USER_FG_PAT:
description: The fine-grained personal access token with user account access for running tests.
required: false
TEST_USER_PAT:
description: The classic personal access token for running tests.
TestSecrets:
description: |
Optional JSON object mapping environment variable names to secret values. Each entry is
exposed as an environment variable that the module's Pester tests read via $env:<name>.
required: false
inputs:
Settings:
Expand All @@ -34,13 +18,6 @@ permissions:
contents: read # to checkout the repo and create releases on the repo

env:
TEST_APP_ENT_CLIENT_ID: ${{ secrets.TEST_APP_ENT_CLIENT_ID }}
TEST_APP_ENT_PRIVATE_KEY: ${{ secrets.TEST_APP_ENT_PRIVATE_KEY }}
TEST_APP_ORG_CLIENT_ID: ${{ secrets.TEST_APP_ORG_CLIENT_ID }}
TEST_APP_ORG_PRIVATE_KEY: ${{ secrets.TEST_APP_ORG_PRIVATE_KEY }}
TEST_USER_ORG_FG_PAT: ${{ secrets.TEST_USER_ORG_FG_PAT }}
TEST_USER_USER_FG_PAT: ${{ secrets.TEST_USER_USER_FG_PAT }}
TEST_USER_PAT: ${{ secrets.TEST_USER_PAT }}
GITHUB_TOKEN: ${{ github.token }}

jobs:
Expand All @@ -58,6 +35,36 @@ jobs:
persist-credentials: false
fetch-depth: 0

- name: Expose caller-provided test secrets
shell: pwsh
env:
PSMODULE_TEST_SECRETS: ${{ secrets.TestSecrets }}
run: |
Comment thread
MariusStorhaug marked this conversation as resolved.
if ([string]::IsNullOrWhiteSpace($env:PSMODULE_TEST_SECRETS)) {
Write-Host 'No test secrets were provided by the calling workflow.'
return
}
Comment thread
MariusStorhaug marked this conversation as resolved.
Outdated
try {
$secrets = $env:PSMODULE_TEST_SECRETS | ConvertFrom-Json -ErrorAction Stop
} catch {
throw "The 'TestSecrets' secret must be a JSON object mapping names to values. $_"
}
Comment thread
MariusStorhaug marked this conversation as resolved.
Outdated
foreach ($secret in $secrets.PSObject.Properties) {
$name = $secret.Name
$value = [string]$secret.Value
Comment thread
MariusStorhaug marked this conversation as resolved.
Outdated
foreach ($line in ($value -split "`n")) {
Comment thread
MariusStorhaug marked this conversation as resolved.
Outdated
Comment thread
MariusStorhaug marked this conversation as resolved.
Outdated
$line = $line.TrimEnd("`r")
if ($line.Length -gt 0) {
Write-Host "::add-mask::$line"
}
}
$delimiter = "GHENV_$([guid]::NewGuid().ToString('N'))"
Add-Content -Path $env:GITHUB_ENV -Value "$name<<$delimiter"
Add-Content -Path $env:GITHUB_ENV -Value $value
Add-Content -Path $env:GITHUB_ENV -Value $delimiter
Write-Host "Exposed [$name] as an environment variable."
}
Comment thread
MariusStorhaug marked this conversation as resolved.
Outdated
Comment thread
MariusStorhaug marked this conversation as resolved.
Outdated

- name: Download module artifact
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
Expand Down
23 changes: 16 additions & 7 deletions .github/workflows/Workflow-Test-Default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,22 @@ jobs:
uses: ./.github/workflows/workflow.yml
secrets:
APIKey: ${{ secrets.APIKey }}
TEST_APP_ENT_CLIENT_ID: ${{ secrets.TEST_APP_ENT_CLIENT_ID }}
TEST_APP_ENT_PRIVATE_KEY: ${{ secrets.TEST_APP_ENT_PRIVATE_KEY }}
TEST_APP_ORG_CLIENT_ID: ${{ secrets.TEST_APP_ORG_CLIENT_ID }}
TEST_APP_ORG_PRIVATE_KEY: ${{ secrets.TEST_APP_ORG_PRIVATE_KEY }}
TEST_USER_ORG_FG_PAT: ${{ secrets.TEST_USER_ORG_FG_PAT }}
TEST_USER_USER_FG_PAT: ${{ secrets.TEST_USER_USER_FG_PAT }}
TEST_USER_PAT: ${{ secrets.TEST_USER_PAT }}
# Self-test only: THROWAWAY, non-sensitive placeholder values (not real secrets), so the
# framework's own tests never depend on repository secrets and masking can be verified with
# known values. A real caller would use `toJSON(secrets.<name>)` for each entry instead.
# The folded '>-' block with flat indentation produces a SINGLE-LINE secret value; a literal
# '|' multi-line value makes GitHub register every line as its own mask and over-masks logs.
TestSecrets: >-
{
"TEST_APP_ENT_CLIENT_ID": "tmp-ent-client-id-01",
"TEST_APP_ENT_PRIVATE_KEY": "tmp-ent-key-a1\ntmp-ent-key-a2",
"TEST_APP_ORG_CLIENT_ID": "tmp-org-client-id-02",
"TEST_APP_ORG_PRIVATE_KEY": "tmp-org-key-b1\ntmp-org-key-b2",
"TEST_USER_ORG_FG_PAT": "tmp-user-org-fgpat-03",
"TEST_USER_USER_FG_PAT": "tmp-user-usr-fgpat-04",
"TEST_USER_PAT": "tmp-user-pat-05",
"CUSTOM_TEST_ENV_VAR": "caller-provided-value"
}
with:
WorkingDirectory: tests/srcTestRepo
ImportantFilePatterns: |
Expand Down
23 changes: 16 additions & 7 deletions .github/workflows/Workflow-Test-WithManifest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,22 @@ jobs:
uses: ./.github/workflows/workflow.yml
secrets:
APIKey: ${{ secrets.APIKey }}
TEST_APP_ENT_CLIENT_ID: ${{ secrets.TEST_APP_ENT_CLIENT_ID }}
TEST_APP_ENT_PRIVATE_KEY: ${{ secrets.TEST_APP_ENT_PRIVATE_KEY }}
TEST_APP_ORG_CLIENT_ID: ${{ secrets.TEST_APP_ORG_CLIENT_ID }}
TEST_APP_ORG_PRIVATE_KEY: ${{ secrets.TEST_APP_ORG_PRIVATE_KEY }}
TEST_USER_ORG_FG_PAT: ${{ secrets.TEST_USER_ORG_FG_PAT }}
TEST_USER_USER_FG_PAT: ${{ secrets.TEST_USER_USER_FG_PAT }}
TEST_USER_PAT: ${{ secrets.TEST_USER_PAT }}
# Self-test only: THROWAWAY, non-sensitive placeholder values (not real secrets), so the
# framework's own tests never depend on repository secrets and masking can be verified with
# known values. A real caller would use `toJSON(secrets.<name>)` for each entry instead.
# The folded '>-' block with flat indentation produces a SINGLE-LINE secret value; a literal
# '|' multi-line value makes GitHub register every line as its own mask and over-masks logs.
TestSecrets: >-
{
"TEST_APP_ENT_CLIENT_ID": "tmp-ent-client-id-01",
"TEST_APP_ENT_PRIVATE_KEY": "tmp-ent-key-a1\ntmp-ent-key-a2",
"TEST_APP_ORG_CLIENT_ID": "tmp-org-client-id-02",
"TEST_APP_ORG_PRIVATE_KEY": "tmp-org-key-b1\ntmp-org-key-b2",
"TEST_USER_ORG_FG_PAT": "tmp-user-org-fgpat-03",
"TEST_USER_USER_FG_PAT": "tmp-user-usr-fgpat-04",
"TEST_USER_PAT": "tmp-user-pat-05",
"CUSTOM_TEST_ENV_VAR": "caller-provided-value"
}
with:
WorkingDirectory: tests/srcWithManifestTestRepo
ImportantFilePatterns: |
Expand Down
55 changes: 14 additions & 41 deletions .github/workflows/workflow.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,26 +6,17 @@ on:
APIKey:
description: The API key for the PowerShell Gallery.
required: true
TEST_APP_ENT_CLIENT_ID:
description: The client ID of an Enterprise GitHub App for running tests.
required: false
TEST_APP_ENT_PRIVATE_KEY:
description: The private key of an Enterprise GitHub App for running tests.
required: false
TEST_APP_ORG_CLIENT_ID:
description: The client ID of an Organization GitHub App for running tests.
required: false
TEST_APP_ORG_PRIVATE_KEY:
description: The private key of an Organization GitHub App for running tests.
required: false
TEST_USER_ORG_FG_PAT:
description: The fine-grained personal access token with org access for running tests.
required: false
TEST_USER_USER_FG_PAT:
description: The fine-grained personal access token with user account access for running tests.
required: false
TEST_USER_PAT:
description: The classic personal access token for running tests.
TestSecrets:
description: |
Comment thread
MariusStorhaug marked this conversation as resolved.
Optional JSON object mapping environment variable names to secret values that are exposed to
the module test jobs (BeforeAll-ModuleLocal, Test-ModuleLocal, AfterAll-ModuleLocal).
The calling workflow decides which secrets to provide and builds a single-line JSON object
using toJSON(secrets.<name>) so that quoting and multi-line values (such as private keys) are
encoded correctly. Keep the value on a single line: a multi-line secret makes GitHub register
each line as a separate mask, which over-masks unrelated log output. Each entry is exposed as
an environment variable that the module's Pester tests read via $env:<name>. Values are
masked in the logs. Omit it entirely when the module needs no secrets. See the README for a
complete example.
required: false
inputs:
SettingsPath:
Expand Down Expand Up @@ -168,13 +159,7 @@ jobs:
if: fromJson(needs.Get-Settings.outputs.Settings).Run.BeforeAllModuleLocal && needs.Build-Module.result == 'success' && !cancelled()
uses: ./.github/workflows/BeforeAll-ModuleLocal.yml
secrets:
TEST_APP_ENT_CLIENT_ID: ${{ secrets.TEST_APP_ENT_CLIENT_ID }}
TEST_APP_ENT_PRIVATE_KEY: ${{ secrets.TEST_APP_ENT_PRIVATE_KEY }}
TEST_APP_ORG_CLIENT_ID: ${{ secrets.TEST_APP_ORG_CLIENT_ID }}
TEST_APP_ORG_PRIVATE_KEY: ${{ secrets.TEST_APP_ORG_PRIVATE_KEY }}
TEST_USER_ORG_FG_PAT: ${{ secrets.TEST_USER_ORG_FG_PAT }}
TEST_USER_USER_FG_PAT: ${{ secrets.TEST_USER_USER_FG_PAT }}
TEST_USER_PAT: ${{ secrets.TEST_USER_PAT }}
TestSecrets: ${{ secrets.TestSecrets }}
needs:
Comment thread
MariusStorhaug marked this conversation as resolved.
- Build-Module
- Get-Settings
Expand All @@ -194,13 +179,7 @@ jobs:
- BeforeAll-ModuleLocal
uses: ./.github/workflows/Test-ModuleLocal.yml
secrets:
TEST_APP_ENT_CLIENT_ID: ${{ secrets.TEST_APP_ENT_CLIENT_ID }}
TEST_APP_ENT_PRIVATE_KEY: ${{ secrets.TEST_APP_ENT_PRIVATE_KEY }}
TEST_APP_ORG_CLIENT_ID: ${{ secrets.TEST_APP_ORG_CLIENT_ID }}
TEST_APP_ORG_PRIVATE_KEY: ${{ secrets.TEST_APP_ORG_PRIVATE_KEY }}
TEST_USER_ORG_FG_PAT: ${{ secrets.TEST_USER_ORG_FG_PAT }}
TEST_USER_USER_FG_PAT: ${{ secrets.TEST_USER_USER_FG_PAT }}
TEST_USER_PAT: ${{ secrets.TEST_USER_PAT }}
TestSecrets: ${{ secrets.TestSecrets }}
with:
Settings: ${{ needs.Get-Settings.outputs.Settings }}

Expand All @@ -213,13 +192,7 @@ jobs:
if: fromJson(needs.Get-Settings.outputs.Settings).Run.AfterAllModuleLocal && needs.Test-ModuleLocal.result != 'skipped' && always()
uses: ./.github/workflows/AfterAll-ModuleLocal.yml
secrets:
TEST_APP_ENT_CLIENT_ID: ${{ secrets.TEST_APP_ENT_CLIENT_ID }}
TEST_APP_ENT_PRIVATE_KEY: ${{ secrets.TEST_APP_ENT_PRIVATE_KEY }}
TEST_APP_ORG_CLIENT_ID: ${{ secrets.TEST_APP_ORG_CLIENT_ID }}
TEST_APP_ORG_PRIVATE_KEY: ${{ secrets.TEST_APP_ORG_PRIVATE_KEY }}
TEST_USER_ORG_FG_PAT: ${{ secrets.TEST_USER_ORG_FG_PAT }}
TEST_USER_USER_FG_PAT: ${{ secrets.TEST_USER_USER_FG_PAT }}
TEST_USER_PAT: ${{ secrets.TEST_USER_PAT }}
TestSecrets: ${{ secrets.TestSecrets }}
needs:
- Get-Settings
- Test-ModuleLocal
Expand Down
Loading
Loading