Skip to content

v6.0.0

Choose a tag to compare

@github-actions github-actions released this 09 Jul 02:18
364ddd6

🌟 [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.

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.

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 }}"
          }
        }
$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.

TestData: >-
  {
    "secrets": {
      "CONFLUENCE_API_TOKEN": "${{ secrets.CONFLUENCE_API_TOKEN }}"
    },
    "variables": {
      "CONFLUENCE_SITE": ${{ toJSON(vars.CONFLUENCE_SITE) }},
      "CONFLUENCE_SPACE_KEY": ${{ toJSON(vars.CONFLUENCE_SPACE_KEY) }}
    }
  }
$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:

"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.

"CONFLUENCE_API_TOKEN": ${{ toJSON(vars.CONFLUENCE_API_TOKEN) }}

Use toJSON(vars.NAME) for variables so normal configuration values are JSON-encoded safely:

"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.